1 : /* $Id: tif_dirwrite.c,v 1.73 2010-04-02 19:26:22 fwarmerdam Exp $ */
2 :
3 : /*
4 : * Copyright (c) 1988-1997 Sam Leffler
5 : * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 : *
7 : * Permission to use, copy, modify, distribute, and sell this software and
8 : * its documentation for any purpose is hereby granted without fee, provided
9 : * that (i) the above copyright notices and this permission notice appear in
10 : * all copies of the software and related documentation, and (ii) the names of
11 : * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 : * publicity relating to the software without the specific, prior written
13 : * permission of Sam Leffler and Silicon Graphics.
14 : *
15 : * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 : * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 : * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 : *
19 : * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 : * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 : * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 : * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 : * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 : * OF THIS SOFTWARE.
25 : */
26 :
27 : /*
28 : * TIFF Library.
29 : *
30 : * Directory Write Support Routines.
31 : */
32 : #include "tiffiop.h"
33 :
34 : #ifdef HAVE_IEEEFP
35 : #define TIFFCvtNativeToIEEEFloat(tif, n, fp)
36 : #define TIFFCvtNativeToIEEEDouble(tif, n, dp)
37 : #else
38 : extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp);
39 : extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp);
40 : #endif
41 :
42 : static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
43 :
44 : static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
45 :
46 : static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
47 : static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
48 : #ifdef notdef
49 : static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
50 : #endif
51 : static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
52 : static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
53 : #ifdef notdef
54 : static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
55 : #endif
56 : static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
57 : static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
58 : static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
59 : static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
60 : static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
61 : #ifdef notdef
62 : static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
63 : #endif
64 : static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
65 : static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
66 : static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
67 : static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
68 : static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
69 : #ifdef notdef
70 : static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
71 : #endif
72 : static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
73 : static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
74 : #ifdef notdef
75 : static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
76 : #endif
77 : static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
78 : #ifdef notdef
79 : static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
80 : #endif
81 : static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
82 : static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
83 : static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
84 : static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
85 : #ifdef notdef
86 : static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
87 : #endif
88 : static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
89 : static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
90 : #ifdef notdef
91 : static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
92 : #endif
93 : static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
94 : static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
95 : static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
96 : #ifdef notdef
97 : static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
98 : #endif
99 : static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
100 : static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
101 : static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
102 : #ifdef notdef
103 : static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
104 : #endif
105 : static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
106 : static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
107 : static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
108 :
109 : static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
110 : static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
111 : #ifdef notdef
112 : static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
113 : #endif
114 : static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
115 : #ifdef notdef
116 : static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
117 : #endif
118 : static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
119 : static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
120 : static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
121 : #ifdef notdef
122 : static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
123 : #endif
124 : static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
125 : static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
126 : static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
127 : #ifdef notdef
128 : static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
129 : #endif
130 : static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
131 : #ifdef notdef
132 : static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
133 : #endif
134 : static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
135 : #ifdef notdef
136 : static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
137 : #endif
138 : static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
139 : static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
140 : static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
141 : static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
142 : #ifdef notdef
143 : static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
144 : #endif
145 : static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
146 : #ifdef notdef
147 : static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
148 : #endif
149 : static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
150 : static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
151 : static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
152 :
153 : static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data);
154 :
155 : static int TIFFLinkDirectory(TIFF*);
156 :
157 : /*
158 : * Write the contents of the current directory
159 : * to the specified file. This routine doesn't
160 : * handle overwriting a directory with auxiliary
161 : * storage that's been changed.
162 : */
163 : int
164 : TIFFWriteDirectory(TIFF* tif)
165 1197 : {
166 1197 : return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
167 : }
168 :
169 : /*
170 : * Similar to TIFFWriteDirectory(), writes the directory out
171 : * but leaves all data structures in memory so that it can be
172 : * written again. This will make a partially written TIFF file
173 : * readable before it is successfully completed/closed.
174 : */
175 : int
176 : TIFFCheckpointDirectory(TIFF* tif)
177 0 : {
178 : int rc;
179 : /* Setup the strips arrays, if they haven't already been. */
180 0 : if (tif->tif_dir.td_stripoffset == NULL)
181 0 : (void) TIFFSetupStrips(tif);
182 0 : rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
183 0 : (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
184 0 : return rc;
185 : }
186 :
187 : int
188 : TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff)
189 0 : {
190 0 : return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
191 : }
192 :
193 : /*
194 : * Similar to TIFFWriteDirectory(), but if the directory has already
195 : * been written once, it is relocated to the end of the file, in case it
196 : * has changed in size. Note that this will result in the loss of the
197 : * previously used directory space.
198 : */
199 : int
200 : TIFFRewriteDirectory( TIFF *tif )
201 88 : {
202 : static const char module[] = "TIFFRewriteDirectory";
203 :
204 : /* We don't need to do anything special if it hasn't been written. */
205 88 : if( tif->tif_diroff == 0 )
206 0 : return TIFFWriteDirectory( tif );
207 :
208 : /*
209 : * Find and zero the pointer to this directory, so that TIFFLinkDirectory
210 : * will cause it to be added after this directories current pre-link.
211 : */
212 :
213 88 : if (!(tif->tif_flags&TIFF_BIGTIFF))
214 : {
215 88 : if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
216 : {
217 75 : tif->tif_header.classic.tiff_diroff = 0;
218 75 : tif->tif_diroff = 0;
219 :
220 75 : TIFFSeekFile(tif,4,SEEK_SET);
221 75 : if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
222 : {
223 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
224 : "Error updating TIFF header");
225 0 : return (0);
226 : }
227 : }
228 : else
229 : {
230 : uint32 nextdir;
231 13 : nextdir = tif->tif_header.classic.tiff_diroff;
232 : while(1) {
233 : uint16 dircount;
234 : uint32 nextnextdir;
235 :
236 15 : if (!SeekOK(tif, nextdir) ||
237 : !ReadOK(tif, &dircount, 2)) {
238 0 : TIFFErrorExt(tif->tif_clientdata, module,
239 : "Error fetching directory count");
240 0 : return (0);
241 : }
242 15 : if (tif->tif_flags & TIFF_SWAB)
243 7 : TIFFSwabShort(&dircount);
244 15 : (void) TIFFSeekFile(tif,
245 : nextdir+2+dircount*12, SEEK_SET);
246 15 : if (!ReadOK(tif, &nextnextdir, 4)) {
247 0 : TIFFErrorExt(tif->tif_clientdata, module,
248 : "Error fetching directory link");
249 0 : return (0);
250 : }
251 15 : if (tif->tif_flags & TIFF_SWAB)
252 7 : TIFFSwabLong(&nextnextdir);
253 15 : if (nextnextdir==tif->tif_diroff)
254 : {
255 : uint32 m;
256 13 : m=0;
257 13 : (void) TIFFSeekFile(tif,
258 : nextdir+2+dircount*12, SEEK_SET);
259 13 : if (!WriteOK(tif, &m, 4)) {
260 0 : TIFFErrorExt(tif->tif_clientdata, module,
261 : "Error writing directory link");
262 0 : return (0);
263 : }
264 13 : tif->tif_diroff=0;
265 13 : break;
266 : }
267 2 : nextdir=nextnextdir;
268 2 : }
269 : }
270 : }
271 : else
272 : {
273 0 : if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
274 : {
275 0 : tif->tif_header.big.tiff_diroff = 0;
276 0 : tif->tif_diroff = 0;
277 :
278 0 : TIFFSeekFile(tif,8,SEEK_SET);
279 0 : if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
280 : {
281 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
282 : "Error updating TIFF header");
283 0 : return (0);
284 : }
285 : }
286 : else
287 : {
288 : uint64 nextdir;
289 0 : nextdir = tif->tif_header.big.tiff_diroff;
290 : while(1) {
291 : uint64 dircount64;
292 : uint16 dircount;
293 : uint64 nextnextdir;
294 :
295 0 : if (!SeekOK(tif, nextdir) ||
296 : !ReadOK(tif, &dircount64, 8)) {
297 0 : TIFFErrorExt(tif->tif_clientdata, module,
298 : "Error fetching directory count");
299 0 : return (0);
300 : }
301 0 : if (tif->tif_flags & TIFF_SWAB)
302 0 : TIFFSwabLong8(&dircount64);
303 0 : if (dircount64>0xFFFF)
304 : {
305 0 : TIFFErrorExt(tif->tif_clientdata, module,
306 : "Sanity check on tag count failed, likely corrupt TIFF");
307 0 : return (0);
308 : }
309 0 : dircount=(uint16)dircount64;
310 0 : (void) TIFFSeekFile(tif,
311 : nextdir+8+dircount*20, SEEK_SET);
312 0 : if (!ReadOK(tif, &nextnextdir, 8)) {
313 0 : TIFFErrorExt(tif->tif_clientdata, module,
314 : "Error fetching directory link");
315 0 : return (0);
316 : }
317 0 : if (tif->tif_flags & TIFF_SWAB)
318 0 : TIFFSwabLong8(&nextnextdir);
319 0 : if (nextnextdir==tif->tif_diroff)
320 : {
321 : uint64 m;
322 0 : m=0;
323 0 : (void) TIFFSeekFile(tif,
324 : nextdir+8+dircount*20, SEEK_SET);
325 0 : if (!WriteOK(tif, &m, 8)) {
326 0 : TIFFErrorExt(tif->tif_clientdata, module,
327 : "Error writing directory link");
328 0 : return (0);
329 : }
330 0 : tif->tif_diroff=0;
331 0 : break;
332 : }
333 0 : nextdir=nextnextdir;
334 0 : }
335 : }
336 : }
337 :
338 : /*
339 : * Now use TIFFWriteDirectory() normally.
340 : */
341 :
342 88 : return TIFFWriteDirectory( tif );
343 : }
344 :
345 : static int
346 : TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
347 1197 : {
348 : static const char module[] = "TIFFWriteDirectorySec";
349 : uint32 ndir;
350 : TIFFDirEntry* dir;
351 : uint32 dirsize;
352 : void* dirmem;
353 : uint32 m;
354 1197 : if (tif->tif_mode == O_RDONLY)
355 0 : return (1);
356 : /*
357 : * Clear write state so that subsequent images with
358 : * different characteristics get the right buffers
359 : * setup for them.
360 : */
361 1197 : if (imagedone)
362 : {
363 1197 : if (tif->tif_flags & TIFF_POSTENCODE)
364 : {
365 0 : tif->tif_flags &= ~TIFF_POSTENCODE;
366 0 : if (!(*tif->tif_postencode)(tif))
367 : {
368 0 : TIFFErrorExt(tif->tif_clientdata,module,
369 : "Error post-encoding before directory write");
370 0 : return (0);
371 : }
372 : }
373 1197 : (*tif->tif_close)(tif); /* shutdown encoder */
374 : /*
375 : * Flush any data that might have been written
376 : * by the compression close+cleanup routines. But
377 : * be careful not to write stuff if we didn't add data
378 : * in the previous steps as the "rawcc" data may well be
379 : * a previously read tile/strip in mixed read/write mode.
380 : */
381 1197 : if (tif->tif_rawcc > 0
382 : && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
383 : {
384 0 : if( !TIFFFlushData1(tif) )
385 : {
386 0 : TIFFErrorExt(tif->tif_clientdata, module,
387 : "Error flushing data before directory write");
388 0 : return (0);
389 : }
390 : }
391 1197 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
392 : {
393 69 : _TIFFfree(tif->tif_rawdata);
394 69 : tif->tif_rawdata = NULL;
395 69 : tif->tif_rawcc = 0;
396 69 : tif->tif_rawdatasize = 0;
397 69 : tif->tif_rawdataoff = 0;
398 69 : tif->tif_rawdataloaded = 0;
399 : }
400 1197 : tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
401 : }
402 1197 : dir=NULL;
403 1197 : dirmem=NULL;
404 1197 : dirsize=0;
405 : while (1)
406 : {
407 2394 : ndir=0;
408 2394 : if (isimage)
409 : {
410 2394 : if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
411 : {
412 2394 : if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
413 0 : goto bad;
414 2394 : if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
415 0 : goto bad;
416 : }
417 2394 : if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
418 : {
419 422 : if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
420 0 : goto bad;
421 422 : if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
422 0 : goto bad;
423 : }
424 2394 : if (TIFFFieldSet(tif,FIELD_RESOLUTION))
425 : {
426 14 : if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
427 0 : goto bad;
428 14 : if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
429 0 : goto bad;
430 : }
431 2394 : if (TIFFFieldSet(tif,FIELD_POSITION))
432 : {
433 0 : if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
434 0 : goto bad;
435 0 : if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
436 0 : goto bad;
437 : }
438 2394 : if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
439 : {
440 388 : if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
441 0 : goto bad;
442 : }
443 2394 : if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
444 : {
445 2394 : if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
446 0 : goto bad;
447 : }
448 2394 : if (TIFFFieldSet(tif,FIELD_COMPRESSION))
449 : {
450 2394 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
451 0 : goto bad;
452 : }
453 2394 : if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
454 : {
455 2394 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
456 0 : goto bad;
457 : }
458 2394 : if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
459 : {
460 0 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
461 0 : goto bad;
462 : }
463 2394 : if (TIFFFieldSet(tif,FIELD_FILLORDER))
464 : {
465 4 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
466 0 : goto bad;
467 : }
468 2394 : if (TIFFFieldSet(tif,FIELD_ORIENTATION))
469 : {
470 0 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
471 0 : goto bad;
472 : }
473 2394 : if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
474 : {
475 2394 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
476 0 : goto bad;
477 : }
478 2394 : if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
479 : {
480 1972 : if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
481 0 : goto bad;
482 : }
483 2394 : if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
484 : {
485 0 : if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
486 0 : goto bad;
487 : }
488 2394 : if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
489 : {
490 0 : if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
491 0 : goto bad;
492 : }
493 2394 : if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
494 : {
495 2394 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
496 0 : goto bad;
497 : }
498 2394 : if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
499 : {
500 14 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
501 0 : goto bad;
502 : }
503 2394 : if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
504 : {
505 0 : if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
506 0 : goto bad;
507 : }
508 2394 : if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
509 : {
510 2394 : if (!isTiled(tif))
511 : {
512 1972 : if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
513 0 : goto bad;
514 : }
515 : else
516 : {
517 422 : if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
518 0 : goto bad;
519 : }
520 : }
521 2394 : if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
522 : {
523 2394 : if (!isTiled(tif))
524 : {
525 1972 : if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
526 0 : goto bad;
527 : }
528 : else
529 : {
530 422 : if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
531 0 : goto bad;
532 : }
533 : }
534 2394 : if (TIFFFieldSet(tif,FIELD_COLORMAP))
535 : {
536 64 : if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
537 0 : goto bad;
538 : }
539 2394 : if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
540 : {
541 218 : if (tif->tif_dir.td_extrasamples)
542 : {
543 : uint16 na;
544 : uint16* nb;
545 218 : TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
546 218 : if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
547 0 : goto bad;
548 : }
549 : }
550 2394 : if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
551 : {
552 2394 : if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
553 0 : goto bad;
554 : }
555 2394 : if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
556 : {
557 0 : if (!TIFFWriteDirectoryTagSampleformatPerSample(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_sminsamplevalue))
558 0 : goto bad;
559 : }
560 2394 : if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
561 : {
562 0 : if (!TIFFWriteDirectoryTagSampleformatPerSample(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_smaxsamplevalue))
563 0 : goto bad;
564 : }
565 2394 : if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
566 : {
567 0 : if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
568 0 : goto bad;
569 : }
570 2394 : if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
571 : {
572 0 : if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
573 0 : goto bad;
574 : }
575 2394 : if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
576 : {
577 0 : if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
578 0 : goto bad;
579 : }
580 2394 : if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
581 : {
582 0 : if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
583 0 : goto bad;
584 : }
585 2394 : if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
586 : {
587 0 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
588 0 : goto bad;
589 : }
590 2394 : if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
591 : {
592 0 : if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
593 0 : goto bad;
594 : }
595 2394 : if (TIFFFieldSet(tif,FIELD_INKNAMES))
596 : {
597 0 : if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
598 0 : goto bad;
599 : }
600 2394 : if (TIFFFieldSet(tif,FIELD_SUBIFD))
601 : {
602 0 : if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
603 0 : goto bad;
604 : }
605 : {
606 : uint32 n;
607 354724 : for (n=0; n<tif->tif_nfields; n++) {
608 : const TIFFField* o;
609 352330 : o = tif->tif_fields[n];
610 352330 : if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
611 : {
612 128 : switch (o->get_field_type)
613 : {
614 : case TIFF_SETGET_ASCII:
615 : {
616 : uint32 pa;
617 : char* pb;
618 0 : assert(o->field_type==TIFF_ASCII);
619 0 : assert(o->field_readcount==TIFF_VARIABLE);
620 0 : assert(o->field_passcount==0);
621 0 : TIFFGetField(tif,o->field_tag,&pb);
622 0 : pa=(uint32)(strlen(pb));
623 0 : if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb))
624 0 : goto bad;
625 : }
626 0 : break;
627 : case TIFF_SETGET_UINT16:
628 : {
629 : uint16 p;
630 98 : assert(o->field_type==TIFF_SHORT);
631 98 : assert(o->field_readcount==1);
632 98 : assert(o->field_passcount==0);
633 98 : TIFFGetField(tif,o->field_tag,&p);
634 98 : if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p))
635 0 : goto bad;
636 : }
637 98 : break;
638 : case TIFF_SETGET_UINT32:
639 : {
640 : uint32 p;
641 2 : assert(o->field_type==TIFF_LONG);
642 2 : assert(o->field_readcount==1);
643 2 : assert(o->field_passcount==0);
644 2 : TIFFGetField(tif,o->field_tag,&p);
645 2 : if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p))
646 0 : goto bad;
647 : }
648 2 : break;
649 : case TIFF_SETGET_C32_UINT8:
650 : {
651 : uint32 pa;
652 : void* pb;
653 28 : assert(o->field_type==TIFF_UNDEFINED);
654 28 : assert(o->field_readcount==TIFF_VARIABLE2);
655 28 : assert(o->field_passcount==1);
656 28 : TIFFGetField(tif,o->field_tag,&pa,&pb);
657 28 : if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb))
658 0 : goto bad;
659 : }
660 28 : break;
661 : default:
662 0 : assert(0); /* we should never get here */
663 : break;
664 : }
665 : }
666 : }
667 : }
668 : }
669 9544 : for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
670 : {
671 7150 : switch (tif->tif_dir.td_customValues[m].info->field_type)
672 : {
673 : case TIFF_ASCII:
674 1718 : if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
675 0 : goto bad;
676 1718 : break;
677 : case TIFF_UNDEFINED:
678 0 : if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
679 0 : goto bad;
680 0 : break;
681 : case TIFF_BYTE:
682 0 : if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
683 0 : goto bad;
684 0 : break;
685 : case TIFF_SBYTE:
686 0 : if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
687 0 : goto bad;
688 0 : break;
689 : case TIFF_SHORT:
690 1430 : if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
691 0 : goto bad;
692 1430 : break;
693 : case TIFF_SSHORT:
694 0 : if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
695 0 : goto bad;
696 0 : break;
697 : case TIFF_LONG:
698 0 : if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
699 0 : goto bad;
700 0 : break;
701 : case TIFF_SLONG:
702 0 : if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
703 0 : goto bad;
704 0 : break;
705 : case TIFF_LONG8:
706 0 : if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
707 0 : goto bad;
708 0 : break;
709 : case TIFF_SLONG8:
710 0 : if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
711 0 : goto bad;
712 0 : break;
713 : case TIFF_RATIONAL:
714 0 : if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
715 0 : goto bad;
716 0 : break;
717 : case TIFF_SRATIONAL:
718 0 : if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
719 0 : goto bad;
720 0 : break;
721 : case TIFF_FLOAT:
722 0 : if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
723 0 : goto bad;
724 0 : break;
725 : case TIFF_DOUBLE:
726 4002 : if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
727 0 : goto bad;
728 4002 : break;
729 : case TIFF_IFD:
730 0 : if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
731 0 : goto bad;
732 0 : break;
733 : case TIFF_IFD8:
734 0 : if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
735 0 : goto bad;
736 0 : break;
737 : default:
738 0 : assert(0); /* we should never get here */
739 : break;
740 : }
741 : }
742 2394 : if (dir!=NULL)
743 1197 : break;
744 1197 : dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
745 1197 : if (dir==NULL)
746 : {
747 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
748 0 : goto bad;
749 : }
750 1197 : if (isimage)
751 : {
752 1197 : if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
753 0 : goto bad;
754 : }
755 : else
756 0 : tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1);
757 1197 : if (pdiroff!=NULL)
758 0 : *pdiroff=tif->tif_diroff;
759 1197 : if (!(tif->tif_flags&TIFF_BIGTIFF))
760 1178 : dirsize=2+ndir*12+4;
761 : else
762 19 : dirsize=8+ndir*20+8;
763 1197 : tif->tif_dataoff=tif->tif_diroff+dirsize;
764 1197 : if (!(tif->tif_flags&TIFF_BIGTIFF))
765 1178 : tif->tif_dataoff=(uint32)tif->tif_dataoff;
766 1197 : if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
767 : {
768 0 : TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
769 0 : goto bad;
770 : }
771 1197 : if (tif->tif_dataoff&1)
772 0 : tif->tif_dataoff++;
773 1197 : if (isimage)
774 1197 : tif->tif_curdir++;
775 1197 : }
776 1197 : if (isimage)
777 : {
778 1197 : if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
779 : {
780 : uint32 na;
781 : TIFFDirEntry* nb;
782 0 : for (na=0, nb=dir; ; na++, nb++)
783 : {
784 0 : assert(na<ndir);
785 0 : if (nb->tdir_tag==TIFFTAG_SUBIFD)
786 0 : break;
787 0 : }
788 0 : if (!(tif->tif_flags&TIFF_BIGTIFF))
789 0 : tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
790 : else
791 0 : tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
792 : }
793 : }
794 1197 : dirmem=_TIFFmalloc(dirsize);
795 1197 : if (dirmem==NULL)
796 : {
797 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
798 0 : goto bad;
799 : }
800 1197 : if (!(tif->tif_flags&TIFF_BIGTIFF))
801 : {
802 : uint8* n;
803 : uint32 nTmp;
804 : TIFFDirEntry* o;
805 1178 : n=dirmem;
806 1178 : *(uint16*)n=ndir;
807 1178 : if (tif->tif_flags&TIFF_SWAB)
808 53 : TIFFSwabShort((uint16*)n);
809 1178 : n+=2;
810 1178 : o=dir;
811 18328 : for (m=0; m<ndir; m++)
812 : {
813 17150 : *(uint16*)n=o->tdir_tag;
814 17150 : if (tif->tif_flags&TIFF_SWAB)
815 724 : TIFFSwabShort((uint16*)n);
816 17150 : n+=2;
817 17150 : *(uint16*)n=o->tdir_type;
818 17150 : if (tif->tif_flags&TIFF_SWAB)
819 724 : TIFFSwabShort((uint16*)n);
820 17150 : n+=2;
821 17150 : nTmp = (uint32)o->tdir_count;
822 17150 : _TIFFmemcpy(n,&nTmp,4);
823 17150 : if (tif->tif_flags&TIFF_SWAB)
824 724 : TIFFSwabLong((uint32*)n);
825 17150 : n+=4;
826 : /* This is correct. The data has been */
827 : /* swabbed previously in TIFFWriteDirectoryTagData */
828 17150 : _TIFFmemcpy(n,&o->tdir_offset,4);
829 17150 : n+=4;
830 17150 : o++;
831 : }
832 1178 : nTmp = (uint32)tif->tif_nextdiroff;
833 1178 : if (tif->tif_flags&TIFF_SWAB)
834 53 : TIFFSwabLong(&nTmp);
835 1178 : _TIFFmemcpy(n,&nTmp,4);
836 : }
837 : else
838 : {
839 : uint8* n;
840 : TIFFDirEntry* o;
841 19 : n=dirmem;
842 19 : *(uint64*)n=ndir;
843 19 : if (tif->tif_flags&TIFF_SWAB)
844 4 : TIFFSwabLong8((uint64*)n);
845 19 : n+=8;
846 19 : o=dir;
847 244 : for (m=0; m<ndir; m++)
848 : {
849 225 : *(uint16*)n=o->tdir_tag;
850 225 : if (tif->tif_flags&TIFF_SWAB)
851 44 : TIFFSwabShort((uint16*)n);
852 225 : n+=2;
853 225 : *(uint16*)n=o->tdir_type;
854 225 : if (tif->tif_flags&TIFF_SWAB)
855 44 : TIFFSwabShort((uint16*)n);
856 225 : n+=2;
857 225 : _TIFFmemcpy(n,&o->tdir_count,8);
858 225 : if (tif->tif_flags&TIFF_SWAB)
859 44 : TIFFSwabLong8((uint64*)n);
860 225 : n+=8;
861 225 : _TIFFmemcpy(n,&o->tdir_offset,8);
862 225 : n+=8;
863 225 : o++;
864 : }
865 19 : _TIFFmemcpy(n,&tif->tif_nextdiroff,8);
866 19 : if (tif->tif_flags&TIFF_SWAB)
867 4 : TIFFSwabLong8((uint64*)n);
868 : }
869 1197 : _TIFFfree(dir);
870 1197 : dir=NULL;
871 1197 : if (!SeekOK(tif,tif->tif_diroff))
872 : {
873 0 : TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
874 0 : goto bad;
875 : }
876 1197 : if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
877 : {
878 0 : TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
879 0 : goto bad;
880 : }
881 1197 : _TIFFfree(dirmem);
882 1197 : if (imagedone)
883 : {
884 1197 : TIFFFreeDirectory(tif);
885 1197 : tif->tif_flags &= ~TIFF_DIRTYDIRECT;
886 1197 : tif->tif_flags &= ~TIFF_DIRTYSTRIP;
887 1197 : (*tif->tif_cleanup)(tif);
888 : /*
889 : * Reset directory-related state for subsequent
890 : * directories.
891 : */
892 1197 : TIFFCreateDirectory(tif);
893 : }
894 1197 : return(1);
895 0 : bad:
896 0 : if (dir!=NULL)
897 0 : _TIFFfree(dir);
898 0 : if (dirmem!=NULL)
899 0 : _TIFFfree(dirmem);
900 0 : return(0);
901 : }
902 :
903 : static int
904 : TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
905 0 : {
906 0 : switch (tif->tif_dir.td_sampleformat)
907 : {
908 : case SAMPLEFORMAT_IEEEFP:
909 0 : if (tif->tif_dir.td_bitspersample<=32)
910 0 : return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
911 : else
912 0 : return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
913 : case SAMPLEFORMAT_INT:
914 0 : if (tif->tif_dir.td_bitspersample<=8)
915 0 : return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
916 0 : else if (tif->tif_dir.td_bitspersample<=16)
917 0 : return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
918 : else
919 0 : return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
920 : case SAMPLEFORMAT_UINT:
921 0 : if (tif->tif_dir.td_bitspersample<=8)
922 0 : return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
923 0 : else if (tif->tif_dir.td_bitspersample<=16)
924 0 : return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
925 : else
926 0 : return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
927 : default:
928 0 : return(1);
929 : }
930 : }
931 :
932 : static int
933 : TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
934 1718 : {
935 1718 : if (dir==NULL)
936 : {
937 859 : (*ndir)++;
938 859 : return(1);
939 : }
940 859 : return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
941 : }
942 :
943 : static int
944 : TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
945 28 : {
946 28 : if (dir==NULL)
947 : {
948 14 : (*ndir)++;
949 14 : return(1);
950 : }
951 14 : return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
952 : }
953 :
954 : #ifdef notdef
955 : static int
956 : TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
957 : {
958 : if (dir==NULL)
959 : {
960 : (*ndir)++;
961 : return(1);
962 : }
963 : return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
964 : }
965 : #endif
966 :
967 : static int
968 : TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
969 0 : {
970 0 : if (dir==NULL)
971 : {
972 0 : (*ndir)++;
973 0 : return(1);
974 : }
975 0 : return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
976 : }
977 :
978 : static int
979 : TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
980 0 : {
981 : static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
982 : uint8* m;
983 : uint8* na;
984 : uint16 nb;
985 : int o;
986 0 : if (dir==NULL)
987 : {
988 0 : (*ndir)++;
989 0 : return(1);
990 : }
991 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
992 0 : if (m==NULL)
993 : {
994 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
995 0 : return(0);
996 : }
997 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
998 0 : *na=value;
999 0 : o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1000 0 : _TIFFfree(m);
1001 0 : return(o);
1002 : }
1003 :
1004 : #ifdef notdef
1005 : static int
1006 : TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1007 : {
1008 : if (dir==NULL)
1009 : {
1010 : (*ndir)++;
1011 : return(1);
1012 : }
1013 : return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
1014 : }
1015 : #endif
1016 :
1017 : static int
1018 : TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
1019 0 : {
1020 0 : if (dir==NULL)
1021 : {
1022 0 : (*ndir)++;
1023 0 : return(1);
1024 : }
1025 0 : return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
1026 : }
1027 :
1028 : static int
1029 : TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1030 0 : {
1031 : static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
1032 : int8* m;
1033 : int8* na;
1034 : uint16 nb;
1035 : int o;
1036 0 : if (dir==NULL)
1037 : {
1038 0 : (*ndir)++;
1039 0 : return(1);
1040 : }
1041 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
1042 0 : if (m==NULL)
1043 : {
1044 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1045 0 : return(0);
1046 : }
1047 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1048 0 : *na=value;
1049 0 : o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1050 0 : _TIFFfree(m);
1051 0 : return(o);
1052 : }
1053 :
1054 : static int
1055 : TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1056 9692 : {
1057 9692 : if (dir==NULL)
1058 : {
1059 4846 : (*ndir)++;
1060 4846 : return(1);
1061 : }
1062 4846 : return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
1063 : }
1064 :
1065 : static int
1066 : TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
1067 1648 : {
1068 1648 : if (dir==NULL)
1069 : {
1070 824 : (*ndir)++;
1071 824 : return(1);
1072 : }
1073 824 : return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
1074 : }
1075 :
1076 : static int
1077 : TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1078 4788 : {
1079 : static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
1080 : uint16* m;
1081 : uint16* na;
1082 : uint16 nb;
1083 : int o;
1084 4788 : if (dir==NULL)
1085 : {
1086 2394 : (*ndir)++;
1087 2394 : return(1);
1088 : }
1089 2394 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
1090 2394 : if (m==NULL)
1091 : {
1092 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1093 0 : return(0);
1094 : }
1095 267790 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1096 265396 : *na=value;
1097 2394 : o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1098 2394 : _TIFFfree(m);
1099 2394 : return(o);
1100 : }
1101 :
1102 : #ifdef notdef
1103 : static int
1104 : TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1105 : {
1106 : if (dir==NULL)
1107 : {
1108 : (*ndir)++;
1109 : return(1);
1110 : }
1111 : return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
1112 : }
1113 : #endif
1114 :
1115 : static int
1116 : TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
1117 0 : {
1118 0 : if (dir==NULL)
1119 : {
1120 0 : (*ndir)++;
1121 0 : return(1);
1122 : }
1123 0 : return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
1124 : }
1125 :
1126 : static int
1127 : TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1128 0 : {
1129 : static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
1130 : int16* m;
1131 : int16* na;
1132 : uint16 nb;
1133 : int o;
1134 0 : if (dir==NULL)
1135 : {
1136 0 : (*ndir)++;
1137 0 : return(1);
1138 : }
1139 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
1140 0 : if (m==NULL)
1141 : {
1142 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1143 0 : return(0);
1144 : }
1145 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1146 0 : *na=value;
1147 0 : o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1148 0 : _TIFFfree(m);
1149 0 : return(o);
1150 : }
1151 :
1152 : static int
1153 : TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1154 390 : {
1155 390 : if (dir==NULL)
1156 : {
1157 195 : (*ndir)++;
1158 195 : return(1);
1159 : }
1160 195 : return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
1161 : }
1162 :
1163 : static int
1164 : TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1165 0 : {
1166 0 : if (dir==NULL)
1167 : {
1168 0 : (*ndir)++;
1169 0 : return(1);
1170 : }
1171 0 : return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
1172 : }
1173 :
1174 : static int
1175 : TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1176 0 : {
1177 : static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
1178 : uint32* m;
1179 : uint32* na;
1180 : uint16 nb;
1181 : int o;
1182 0 : if (dir==NULL)
1183 : {
1184 0 : (*ndir)++;
1185 0 : return(1);
1186 : }
1187 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
1188 0 : if (m==NULL)
1189 : {
1190 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1191 0 : return(0);
1192 : }
1193 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1194 0 : *na=value;
1195 0 : o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1196 0 : _TIFFfree(m);
1197 0 : return(o);
1198 : }
1199 :
1200 : #ifdef notdef
1201 : static int
1202 : TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1203 : {
1204 : if (dir==NULL)
1205 : {
1206 : (*ndir)++;
1207 : return(1);
1208 : }
1209 : return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
1210 : }
1211 : #endif
1212 :
1213 : static int
1214 : TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
1215 0 : {
1216 0 : if (dir==NULL)
1217 : {
1218 0 : (*ndir)++;
1219 0 : return(1);
1220 : }
1221 0 : return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
1222 : }
1223 :
1224 : static int
1225 : TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1226 0 : {
1227 : static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
1228 : int32* m;
1229 : int32* na;
1230 : uint16 nb;
1231 : int o;
1232 0 : if (dir==NULL)
1233 : {
1234 0 : (*ndir)++;
1235 0 : return(1);
1236 : }
1237 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
1238 0 : if (m==NULL)
1239 : {
1240 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1241 0 : return(0);
1242 : }
1243 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1244 0 : *na=value;
1245 0 : o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1246 0 : _TIFFfree(m);
1247 0 : return(o);
1248 : }
1249 :
1250 : #ifdef notdef
1251 : static int
1252 : TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
1253 : {
1254 : if (dir==NULL)
1255 : {
1256 : (*ndir)++;
1257 : return(1);
1258 : }
1259 : return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
1260 : }
1261 : #endif
1262 :
1263 : static int
1264 : TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1265 0 : {
1266 0 : if (dir==NULL)
1267 : {
1268 0 : (*ndir)++;
1269 0 : return(1);
1270 : }
1271 0 : return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
1272 : }
1273 :
1274 : #ifdef notdef
1275 : static int
1276 : TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
1277 : {
1278 : if (dir==NULL)
1279 : {
1280 : (*ndir)++;
1281 : return(1);
1282 : }
1283 : return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
1284 : }
1285 : #endif
1286 :
1287 : static int
1288 : TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
1289 0 : {
1290 0 : if (dir==NULL)
1291 : {
1292 0 : (*ndir)++;
1293 0 : return(1);
1294 : }
1295 0 : return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
1296 : }
1297 :
1298 : static int
1299 : TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1300 28 : {
1301 28 : if (dir==NULL)
1302 : {
1303 14 : (*ndir)++;
1304 14 : return(1);
1305 : }
1306 14 : return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
1307 : }
1308 :
1309 : static int
1310 : TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1311 0 : {
1312 0 : if (dir==NULL)
1313 : {
1314 0 : (*ndir)++;
1315 0 : return(1);
1316 : }
1317 0 : return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
1318 : }
1319 :
1320 : static int
1321 : TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1322 0 : {
1323 0 : if (dir==NULL)
1324 : {
1325 0 : (*ndir)++;
1326 0 : return(1);
1327 : }
1328 0 : return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
1329 : }
1330 :
1331 : #ifdef notdef
1332 : static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
1333 : {
1334 : if (dir==NULL)
1335 : {
1336 : (*ndir)++;
1337 : return(1);
1338 : }
1339 : return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
1340 : }
1341 : #endif
1342 :
1343 : static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1344 0 : {
1345 0 : if (dir==NULL)
1346 : {
1347 0 : (*ndir)++;
1348 0 : return(1);
1349 : }
1350 0 : return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
1351 : }
1352 :
1353 : static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
1354 0 : {
1355 : static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
1356 : float* m;
1357 : float* na;
1358 : uint16 nb;
1359 : int o;
1360 0 : if (dir==NULL)
1361 : {
1362 0 : (*ndir)++;
1363 0 : return(1);
1364 : }
1365 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
1366 0 : if (m==NULL)
1367 : {
1368 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1369 0 : return(0);
1370 : }
1371 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1372 0 : *na=value;
1373 0 : o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1374 0 : _TIFFfree(m);
1375 0 : return(o);
1376 : }
1377 :
1378 : #ifdef notdef
1379 : static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1380 : {
1381 : if (dir==NULL)
1382 : {
1383 : (*ndir)++;
1384 : return(1);
1385 : }
1386 : return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
1387 : }
1388 : #endif
1389 :
1390 : static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
1391 4002 : {
1392 4002 : if (dir==NULL)
1393 : {
1394 2001 : (*ndir)++;
1395 2001 : return(1);
1396 : }
1397 2001 : return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
1398 : }
1399 :
1400 : static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1401 0 : {
1402 : static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
1403 : double* m;
1404 : double* na;
1405 : uint16 nb;
1406 : int o;
1407 0 : if (dir==NULL)
1408 : {
1409 0 : (*ndir)++;
1410 0 : return(1);
1411 : }
1412 0 : m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
1413 0 : if (m==NULL)
1414 : {
1415 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1416 0 : return(0);
1417 : }
1418 0 : for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
1419 0 : *na=value;
1420 0 : o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
1421 0 : _TIFFfree(m);
1422 0 : return(o);
1423 : }
1424 :
1425 : static int
1426 : TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1427 0 : {
1428 0 : if (dir==NULL)
1429 : {
1430 0 : (*ndir)++;
1431 0 : return(1);
1432 : }
1433 0 : return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
1434 : }
1435 :
1436 : #ifdef notdef
1437 : static int
1438 : TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1439 : {
1440 : if (dir==NULL)
1441 : {
1442 : (*ndir)++;
1443 : return(1);
1444 : }
1445 : return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
1446 : }
1447 : #endif
1448 :
1449 : static int
1450 : TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1451 7604 : {
1452 7604 : if (dir==NULL)
1453 : {
1454 3802 : (*ndir)++;
1455 3802 : return(1);
1456 : }
1457 3802 : if (value<=0xFFFF)
1458 3779 : return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
1459 : else
1460 23 : return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
1461 : }
1462 :
1463 : /************************************************************************/
1464 : /* TIFFWriteDirectoryTagLongLong8Array() */
1465 : /* */
1466 : /* Write out LONG8 array as LONG8 for BigTIFF or LONG for */
1467 : /* Classic TIFF with some checking. */
1468 : /************************************************************************/
1469 :
1470 : static int
1471 : TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1472 4788 : {
1473 : static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1474 : uint64* ma;
1475 : uint32 mb;
1476 : uint32* p;
1477 : uint32* q;
1478 : int o;
1479 :
1480 : /* is this just a counting pass? */
1481 4788 : if (dir==NULL)
1482 : {
1483 2394 : (*ndir)++;
1484 2394 : return(1);
1485 : }
1486 :
1487 : /* We always write LONG8 for BigTIFF, no checking needed. */
1488 2394 : if( tif->tif_flags&TIFF_BIGTIFF )
1489 38 : return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
1490 : tag,count,value);
1491 :
1492 : /*
1493 : ** For classic tiff we want to verify everything is in range for LONG
1494 : ** and convert to long format.
1495 : */
1496 :
1497 2356 : p = _TIFFmalloc(count*sizeof(uint32));
1498 2356 : if (p==NULL)
1499 : {
1500 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1501 0 : return(0);
1502 : }
1503 :
1504 1309268 : for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
1505 : {
1506 1306912 : if (*ma>0xFFFFFFFF)
1507 : {
1508 0 : TIFFErrorExt(tif->tif_clientdata,module,
1509 : "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
1510 0 : _TIFFfree(p);
1511 0 : return(0);
1512 : }
1513 1306912 : *q= (uint32)(*ma);
1514 : }
1515 :
1516 2356 : o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
1517 2356 : _TIFFfree(p);
1518 :
1519 2356 : return(o);
1520 : }
1521 :
1522 : /************************************************************************/
1523 : /* TIFFWriteDirectoryTagIfdIfd8Array() */
1524 : /* */
1525 : /* Write either IFD8 or IFD array depending on file type. */
1526 : /************************************************************************/
1527 :
1528 : static int
1529 : TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1530 0 : {
1531 : static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
1532 : uint64* ma;
1533 : uint32 mb;
1534 : uint32* p;
1535 : uint32* q;
1536 : int o;
1537 :
1538 : /* is this just a counting pass? */
1539 0 : if (dir==NULL)
1540 : {
1541 0 : (*ndir)++;
1542 0 : return(1);
1543 : }
1544 :
1545 : /* We always write IFD8 for BigTIFF, no checking needed. */
1546 0 : if( tif->tif_flags&TIFF_BIGTIFF )
1547 0 : return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
1548 : tag,count,value);
1549 :
1550 : /*
1551 : ** For classic tiff we want to verify everything is in range for IFD
1552 : ** and convert to long format.
1553 : */
1554 :
1555 0 : p = _TIFFmalloc(count*sizeof(uint32));
1556 0 : if (p==NULL)
1557 : {
1558 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1559 0 : return(0);
1560 : }
1561 :
1562 0 : for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
1563 : {
1564 0 : if (*ma>0xFFFFFFFF)
1565 : {
1566 0 : TIFFErrorExt(tif->tif_clientdata,module,
1567 : "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
1568 0 : _TIFFfree(p);
1569 0 : return(0);
1570 : }
1571 0 : *q= (uint32)(*ma);
1572 : }
1573 :
1574 0 : o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
1575 0 : _TIFFfree(p);
1576 :
1577 0 : return(o);
1578 : }
1579 :
1580 : #ifdef notdef
1581 : static int
1582 : TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1583 : {
1584 : static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
1585 : uint64* ma;
1586 : uint32 mb;
1587 : uint8 n;
1588 : int o;
1589 : if (dir==NULL)
1590 : {
1591 : (*ndir)++;
1592 : return(1);
1593 : }
1594 : n=0;
1595 : for (ma=value, mb=0; mb<count; ma++, mb++)
1596 : {
1597 : if ((n==0)&&(*ma>0xFFFF))
1598 : n=1;
1599 : if ((n==1)&&(*ma>0xFFFFFFFF))
1600 : {
1601 : n=2;
1602 : break;
1603 : }
1604 : }
1605 : if (n==0)
1606 : {
1607 : uint16* p;
1608 : uint16* q;
1609 : p=_TIFFmalloc(count*sizeof(uint16));
1610 : if (p==NULL)
1611 : {
1612 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1613 : return(0);
1614 : }
1615 : for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
1616 : *q=(uint16)(*ma);
1617 : o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
1618 : _TIFFfree(p);
1619 : }
1620 : else if (n==1)
1621 : {
1622 : uint32* p;
1623 : uint32* q;
1624 : p=_TIFFmalloc(count*sizeof(uint32));
1625 : if (p==NULL)
1626 : {
1627 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1628 : return(0);
1629 : }
1630 : for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
1631 : *q=(uint32)(*ma);
1632 : o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
1633 : _TIFFfree(p);
1634 : }
1635 : else
1636 : {
1637 : assert(n==2);
1638 : o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
1639 : }
1640 : return(o);
1641 : }
1642 : #endif
1643 : static int
1644 : TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1645 64 : {
1646 : static const char module[] = "TIFFWriteDirectoryTagColormap";
1647 : uint32 m;
1648 : uint16* n;
1649 : int o;
1650 64 : if (dir==NULL)
1651 : {
1652 32 : (*ndir)++;
1653 32 : return(1);
1654 : }
1655 32 : m=(1<<tif->tif_dir.td_bitspersample);
1656 32 : n=_TIFFmalloc(3*m*sizeof(uint16));
1657 32 : if (n==NULL)
1658 : {
1659 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1660 0 : return(0);
1661 : }
1662 32 : _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
1663 32 : _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
1664 32 : _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
1665 32 : o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
1666 32 : _TIFFfree(n);
1667 32 : return(o);
1668 : }
1669 :
1670 : static int
1671 : TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1672 0 : {
1673 : static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
1674 : uint32 m;
1675 : uint16 n;
1676 : uint16* o;
1677 : int p;
1678 0 : if (dir==NULL)
1679 : {
1680 0 : (*ndir)++;
1681 0 : return(1);
1682 : }
1683 0 : m=(1<<tif->tif_dir.td_bitspersample);
1684 0 : n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
1685 : /*
1686 : * Check if the table can be written as a single column,
1687 : * or if it must be written as 3 columns. Note that we
1688 : * write a 3-column tag if there are 2 samples/pixel and
1689 : * a single column of data won't suffice--hmm.
1690 : */
1691 0 : if (n>3)
1692 0 : n=3;
1693 0 : if (n==3)
1694 : {
1695 0 : if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
1696 0 : n=2;
1697 : }
1698 0 : if (n==2)
1699 : {
1700 0 : if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
1701 0 : n=1;
1702 : }
1703 0 : if (n==0)
1704 0 : n=1;
1705 0 : o=_TIFFmalloc(n*m*sizeof(uint16));
1706 0 : if (o==NULL)
1707 : {
1708 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1709 0 : return(0);
1710 : }
1711 0 : _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
1712 0 : if (n>1)
1713 0 : _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
1714 0 : if (n>2)
1715 0 : _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
1716 0 : p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
1717 0 : _TIFFfree(o);
1718 0 : return(p);
1719 : }
1720 :
1721 : static int
1722 : TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
1723 0 : {
1724 : static const char module[] = "TIFFWriteDirectoryTagSubifd";
1725 : uint64 m;
1726 : int n;
1727 0 : if (tif->tif_dir.td_nsubifd==0)
1728 0 : return(1);
1729 0 : if (dir==NULL)
1730 : {
1731 0 : (*ndir)++;
1732 0 : return(1);
1733 : }
1734 0 : m=tif->tif_dataoff;
1735 0 : if (!(tif->tif_flags&TIFF_BIGTIFF))
1736 : {
1737 : uint32* o;
1738 : uint64* pa;
1739 : uint32* pb;
1740 : uint16 p;
1741 0 : o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
1742 0 : if (o==NULL)
1743 : {
1744 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
1745 0 : return(0);
1746 : }
1747 0 : pa=tif->tif_dir.td_subifd;
1748 0 : pb=o;
1749 0 : for (p=0; p < tif->tif_dir.td_nsubifd; p++)
1750 : {
1751 0 : assert(pa != 0);
1752 0 : assert(*pa <= 0xFFFFFFFFUL);
1753 0 : *pb++=(uint32)(*pa++);
1754 : }
1755 0 : n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
1756 0 : _TIFFfree(o);
1757 : }
1758 : else
1759 0 : n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
1760 0 : if (!n)
1761 0 : return(0);
1762 : /*
1763 : * Total hack: if this directory includes a SubIFD
1764 : * tag then force the next <n> directories to be
1765 : * written as ``sub directories'' of this one. This
1766 : * is used to write things like thumbnails and
1767 : * image masks that one wants to keep out of the
1768 : * normal directory linkage access mechanism.
1769 : */
1770 0 : tif->tif_flags|=TIFF_INSUBIFD;
1771 0 : tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
1772 0 : if (tif->tif_dir.td_nsubifd==1)
1773 0 : tif->tif_subifdoff=0;
1774 : else
1775 0 : tif->tif_subifdoff=m;
1776 0 : return(1);
1777 : }
1778 :
1779 : static int
1780 : TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
1781 859 : {
1782 : assert(sizeof(char)==1);
1783 859 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
1784 : }
1785 :
1786 : static int
1787 : TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1788 14 : {
1789 : assert(sizeof(uint8)==1);
1790 14 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
1791 : }
1792 :
1793 : #ifdef notdef
1794 : static int
1795 : TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
1796 : {
1797 : assert(sizeof(uint8)==1);
1798 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
1799 : }
1800 : #endif
1801 :
1802 : static int
1803 : TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
1804 0 : {
1805 : assert(sizeof(uint8)==1);
1806 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
1807 : }
1808 :
1809 : #ifdef notdef
1810 : static int
1811 : TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
1812 : {
1813 : assert(sizeof(int8)==1);
1814 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
1815 : }
1816 : #endif
1817 :
1818 : static int
1819 : TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
1820 0 : {
1821 : assert(sizeof(int8)==1);
1822 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
1823 : }
1824 :
1825 : static int
1826 : TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
1827 8625 : {
1828 : uint16 m;
1829 : assert(sizeof(uint16)==2);
1830 8625 : m=value;
1831 8625 : if (tif->tif_flags&TIFF_SWAB)
1832 429 : TIFFSwabShort(&m);
1833 8625 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
1834 : }
1835 :
1836 : static int
1837 : TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
1838 3250 : {
1839 3250 : assert(count<0x80000000);
1840 : assert(sizeof(uint16)==2);
1841 3250 : if (tif->tif_flags&TIFF_SWAB)
1842 134 : TIFFSwabArrayOfShort(value,count);
1843 3250 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
1844 : }
1845 :
1846 : #ifdef notdef
1847 : static int
1848 : TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
1849 : {
1850 : int16 m;
1851 : assert(sizeof(int16)==2);
1852 : m=value;
1853 : if (tif->tif_flags&TIFF_SWAB)
1854 : TIFFSwabShort((uint16*)(&m));
1855 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
1856 : }
1857 : #endif
1858 :
1859 : static int
1860 : TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
1861 0 : {
1862 0 : assert(count<0x80000000);
1863 : assert(sizeof(int16)==2);
1864 0 : if (tif->tif_flags&TIFF_SWAB)
1865 0 : TIFFSwabArrayOfShort((uint16*)value,count);
1866 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
1867 : }
1868 :
1869 : static int
1870 : TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
1871 218 : {
1872 : uint32 m;
1873 : assert(sizeof(uint32)==4);
1874 218 : m=value;
1875 218 : if (tif->tif_flags&TIFF_SWAB)
1876 35 : TIFFSwabLong(&m);
1877 218 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
1878 : }
1879 :
1880 : static int
1881 : TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
1882 2356 : {
1883 2356 : assert(count<0x40000000);
1884 : assert(sizeof(uint32)==4);
1885 2356 : if (tif->tif_flags&TIFF_SWAB)
1886 106 : TIFFSwabArrayOfLong(value,count);
1887 2356 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
1888 : }
1889 :
1890 : #ifdef notdef
1891 : static int
1892 : TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
1893 : {
1894 : int32 m;
1895 : assert(sizeof(int32)==4);
1896 : m=value;
1897 : if (tif->tif_flags&TIFF_SWAB)
1898 : TIFFSwabLong((uint32*)(&m));
1899 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
1900 : }
1901 : #endif
1902 :
1903 : static int
1904 : TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
1905 0 : {
1906 0 : assert(count<0x40000000);
1907 : assert(sizeof(int32)==4);
1908 0 : if (tif->tif_flags&TIFF_SWAB)
1909 0 : TIFFSwabArrayOfLong((uint32*)value,count);
1910 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
1911 : }
1912 :
1913 : #ifdef notdef
1914 : static int
1915 : TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
1916 : {
1917 : uint64 m;
1918 : assert(sizeof(uint64)==8);
1919 : assert(tif->tif_flags&TIFF_BIGTIFF);
1920 : m=value;
1921 : if (tif->tif_flags&TIFF_SWAB)
1922 : TIFFSwabLong8(&m);
1923 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
1924 : }
1925 : #endif
1926 :
1927 : static int
1928 : TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
1929 38 : {
1930 38 : assert(count<0x20000000);
1931 : assert(sizeof(uint64)==8);
1932 38 : assert(tif->tif_flags&TIFF_BIGTIFF);
1933 38 : if (tif->tif_flags&TIFF_SWAB)
1934 8 : TIFFSwabArrayOfLong8(value,count);
1935 38 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
1936 : }
1937 :
1938 : #ifdef notdef
1939 : static int
1940 : TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
1941 : {
1942 : int64 m;
1943 : assert(sizeof(int64)==8);
1944 : assert(tif->tif_flags&TIFF_BIGTIFF);
1945 : m=value;
1946 : if (tif->tif_flags&TIFF_SWAB)
1947 : TIFFSwabLong8((uint64*)(&m));
1948 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
1949 : }
1950 : #endif
1951 :
1952 : static int
1953 : TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
1954 0 : {
1955 0 : assert(count<0x20000000);
1956 : assert(sizeof(int64)==8);
1957 0 : assert(tif->tif_flags&TIFF_BIGTIFF);
1958 0 : if (tif->tif_flags&TIFF_SWAB)
1959 0 : TIFFSwabArrayOfLong8((uint64*)value,count);
1960 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
1961 : }
1962 :
1963 : static int
1964 : TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
1965 14 : {
1966 : uint32 m[2];
1967 14 : assert(value>=0.0);
1968 : assert(sizeof(uint32)==4);
1969 14 : if (value<=0.0)
1970 : {
1971 4 : m[0]=0;
1972 4 : m[1]=1;
1973 : }
1974 10 : else if (value==(double)(uint32)value)
1975 : {
1976 10 : m[0]=(uint32)value;
1977 10 : m[1]=1;
1978 : }
1979 0 : else if (value<1.0)
1980 : {
1981 0 : m[0]=(uint32)(value*0xFFFFFFFF);
1982 0 : m[1]=0xFFFFFFFF;
1983 : }
1984 : else
1985 : {
1986 0 : m[0]=0xFFFFFFFF;
1987 0 : m[1]=(uint32)(0xFFFFFFFF/value);
1988 : }
1989 14 : if (tif->tif_flags&TIFF_SWAB)
1990 : {
1991 0 : TIFFSwabLong(&m[0]);
1992 0 : TIFFSwabLong(&m[1]);
1993 : }
1994 14 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
1995 : }
1996 :
1997 : static int
1998 : TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
1999 0 : {
2000 : static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2001 : uint32* m;
2002 : float* na;
2003 : uint32* nb;
2004 : uint32 nc;
2005 : int o;
2006 : assert(sizeof(uint32)==4);
2007 0 : m=_TIFFmalloc(count*2*sizeof(uint32));
2008 0 : if (m==NULL)
2009 : {
2010 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
2011 0 : return(0);
2012 : }
2013 0 : for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
2014 : {
2015 0 : if (*na<=0.0)
2016 : {
2017 0 : nb[0]=0;
2018 0 : nb[1]=1;
2019 : }
2020 0 : else if (*na==(float)(uint32)(*na))
2021 : {
2022 0 : nb[0]=(uint32)(*na);
2023 0 : nb[1]=1;
2024 : }
2025 0 : else if (*na<1.0)
2026 : {
2027 0 : nb[0]=(uint32)((*na)*0xFFFFFFFF);
2028 0 : nb[1]=0xFFFFFFFF;
2029 : }
2030 : else
2031 : {
2032 0 : nb[0]=0xFFFFFFFF;
2033 0 : nb[1]=(uint32)(0xFFFFFFFF/(*na));
2034 : }
2035 : }
2036 0 : if (tif->tif_flags&TIFF_SWAB)
2037 0 : TIFFSwabArrayOfLong(m,count*2);
2038 0 : o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
2039 0 : _TIFFfree(m);
2040 0 : return(o);
2041 : }
2042 :
2043 : static int
2044 : TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2045 0 : {
2046 : static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2047 : int32* m;
2048 : float* na;
2049 : int32* nb;
2050 : uint32 nc;
2051 : int o;
2052 : assert(sizeof(int32)==4);
2053 0 : m=_TIFFmalloc(count*2*sizeof(int32));
2054 0 : if (m==NULL)
2055 : {
2056 0 : TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
2057 0 : return(0);
2058 : }
2059 0 : for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
2060 : {
2061 0 : if (*na<0.0)
2062 : {
2063 0 : if (*na==(int32)(*na))
2064 : {
2065 0 : nb[0]=(int32)(*na);
2066 0 : nb[1]=1;
2067 : }
2068 0 : else if (*na>-1.0)
2069 : {
2070 0 : nb[0]=-(int32)((-*na)*0x7FFFFFFF);
2071 0 : nb[1]=0x7FFFFFFF;
2072 : }
2073 : else
2074 : {
2075 0 : nb[0]=-0x7FFFFFFF;
2076 0 : nb[1]=(int32)(0x7FFFFFFF/(-*na));
2077 : }
2078 : }
2079 : else
2080 : {
2081 0 : if (*na==(int32)(*na))
2082 : {
2083 0 : nb[0]=(int32)(*na);
2084 0 : nb[1]=1;
2085 : }
2086 0 : else if (*na<1.0)
2087 : {
2088 0 : nb[0]=(int32)((*na)*0x7FFFFFFF);
2089 0 : nb[1]=0x7FFFFFFF;
2090 : }
2091 : else
2092 : {
2093 0 : nb[0]=0x7FFFFFFF;
2094 0 : nb[1]=(int32)(0x7FFFFFFF/(*na));
2095 : }
2096 : }
2097 : }
2098 0 : if (tif->tif_flags&TIFF_SWAB)
2099 0 : TIFFSwabArrayOfLong((uint32*)m,count*2);
2100 0 : o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
2101 0 : _TIFFfree(m);
2102 0 : return(o);
2103 : }
2104 :
2105 : #ifdef notdef
2106 : static int
2107 : TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
2108 : {
2109 : float m;
2110 : assert(sizeof(float)==4);
2111 : m=value;
2112 : TIFFCvtNativeToIEEEFloat(tif,1,&m);
2113 : if (tif->tif_flags&TIFF_SWAB)
2114 : TIFFSwabFloat(&m);
2115 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
2116 : }
2117 : #endif
2118 :
2119 : static int
2120 : TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
2121 0 : {
2122 0 : assert(count<0x40000000);
2123 : assert(sizeof(float)==4);
2124 : TIFFCvtNativeToIEEEFloat(tif,count,&value);
2125 0 : if (tif->tif_flags&TIFF_SWAB)
2126 0 : TIFFSwabArrayOfFloat(value,count);
2127 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
2128 : }
2129 :
2130 : #ifdef notdef
2131 : static int
2132 : TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
2133 : {
2134 : double m;
2135 : assert(sizeof(double)==8);
2136 : m=value;
2137 : TIFFCvtNativeToIEEEDouble(tif,1,&m);
2138 : if (tif->tif_flags&TIFF_SWAB)
2139 : TIFFSwabDouble(&m);
2140 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
2141 : }
2142 : #endif
2143 :
2144 : static int
2145 : TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
2146 2001 : {
2147 2001 : assert(count<0x20000000);
2148 : assert(sizeof(double)==8);
2149 : TIFFCvtNativeToIEEEDouble(tif,count,&value);
2150 2001 : if (tif->tif_flags&TIFF_SWAB)
2151 23 : TIFFSwabArrayOfDouble(value,count);
2152 2001 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
2153 : }
2154 :
2155 : static int
2156 : TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
2157 0 : {
2158 0 : assert(count<0x40000000);
2159 : assert(sizeof(uint32)==4);
2160 0 : if (tif->tif_flags&TIFF_SWAB)
2161 0 : TIFFSwabArrayOfLong(value,count);
2162 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
2163 : }
2164 :
2165 : static int
2166 : TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
2167 0 : {
2168 0 : assert(count<0x20000000);
2169 : assert(sizeof(uint64)==8);
2170 0 : assert(tif->tif_flags&TIFF_BIGTIFF);
2171 0 : if (tif->tif_flags&TIFF_SWAB)
2172 0 : TIFFSwabArrayOfLong8(value,count);
2173 0 : return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
2174 : }
2175 :
2176 : static int
2177 : TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
2178 17375 : {
2179 : static const char module[] = "TIFFWriteDirectoryTagData";
2180 : uint32 m;
2181 17375 : m=0;
2182 145949 : while (m<(*ndir))
2183 : {
2184 114812 : assert(dir[m].tdir_tag!=tag);
2185 114812 : if (dir[m].tdir_tag>tag)
2186 3613 : break;
2187 111199 : m++;
2188 : }
2189 17375 : if (m<(*ndir))
2190 : {
2191 : uint32 n;
2192 12142 : for (n=*ndir; n>m; n--)
2193 8529 : dir[n]=dir[n-1];
2194 : }
2195 17375 : dir[m].tdir_tag=tag;
2196 17375 : dir[m].tdir_type=datatype;
2197 17375 : dir[m].tdir_count=count;
2198 17375 : dir[m].tdir_offset.toff_long8 = 0;
2199 17375 : if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
2200 13059 : _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
2201 : else
2202 : {
2203 : uint64 na,nb;
2204 4316 : na=tif->tif_dataoff;
2205 4316 : nb=na+datalength;
2206 4316 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2207 4288 : nb=(uint32)nb;
2208 4316 : if ((nb<na)||(nb<datalength))
2209 : {
2210 0 : TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
2211 0 : return(0);
2212 : }
2213 4316 : if (!SeekOK(tif,na))
2214 : {
2215 0 : TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
2216 0 : return(0);
2217 : }
2218 4316 : assert(datalength<0x80000000UL);
2219 4316 : if (!WriteOK(tif,data,(tmsize_t)datalength))
2220 : {
2221 0 : TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
2222 0 : return(0);
2223 : }
2224 4316 : tif->tif_dataoff=nb;
2225 4316 : if (tif->tif_dataoff&1)
2226 86 : tif->tif_dataoff++;
2227 4316 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2228 : {
2229 : uint32 o;
2230 4288 : o=(uint32)na;
2231 4288 : if (tif->tif_flags&TIFF_SWAB)
2232 118 : TIFFSwabLong(&o);
2233 4288 : _TIFFmemcpy(&dir[m].tdir_offset,&o,4);
2234 : }
2235 : else
2236 : {
2237 28 : dir[m].tdir_offset.toff_long8 = na;
2238 28 : if (tif->tif_flags&TIFF_SWAB)
2239 8 : TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
2240 : }
2241 : }
2242 17375 : (*ndir)++;
2243 17375 : return(1);
2244 : }
2245 :
2246 : /*
2247 : * Link the current directory into the directory chain for the file.
2248 : */
2249 : static int
2250 : TIFFLinkDirectory(TIFF* tif)
2251 1197 : {
2252 : static const char module[] = "TIFFLinkDirectory";
2253 :
2254 1197 : tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
2255 :
2256 : /*
2257 : * Handle SubIFDs
2258 : */
2259 1197 : if (tif->tif_flags & TIFF_INSUBIFD)
2260 : {
2261 0 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2262 : {
2263 : uint32 m;
2264 0 : m = (uint32)tif->tif_diroff;
2265 0 : if (tif->tif_flags & TIFF_SWAB)
2266 0 : TIFFSwabLong(&m);
2267 0 : (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2268 0 : if (!WriteOK(tif, &m, 4)) {
2269 0 : TIFFErrorExt(tif->tif_clientdata, module,
2270 : "Error writing SubIFD directory link");
2271 0 : return (0);
2272 : }
2273 : /*
2274 : * Advance to the next SubIFD or, if this is
2275 : * the last one configured, revert back to the
2276 : * normal directory linkage.
2277 : */
2278 0 : if (--tif->tif_nsubifd)
2279 0 : tif->tif_subifdoff += 4;
2280 : else
2281 0 : tif->tif_flags &= ~TIFF_INSUBIFD;
2282 0 : return (1);
2283 : }
2284 : else
2285 : {
2286 : uint64 m;
2287 0 : m = tif->tif_diroff;
2288 0 : if (tif->tif_flags & TIFF_SWAB)
2289 0 : TIFFSwabLong8(&m);
2290 0 : (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2291 0 : if (!WriteOK(tif, &m, 8)) {
2292 0 : TIFFErrorExt(tif->tif_clientdata, module,
2293 : "Error writing SubIFD directory link");
2294 0 : return (0);
2295 : }
2296 : /*
2297 : * Advance to the next SubIFD or, if this is
2298 : * the last one configured, revert back to the
2299 : * normal directory linkage.
2300 : */
2301 0 : if (--tif->tif_nsubifd)
2302 0 : tif->tif_subifdoff += 8;
2303 : else
2304 0 : tif->tif_flags &= ~TIFF_INSUBIFD;
2305 0 : return (1);
2306 : }
2307 : }
2308 :
2309 1197 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2310 : {
2311 : uint32 m;
2312 : uint32 nextdir;
2313 1178 : m = (uint32)(tif->tif_diroff);
2314 1178 : if (tif->tif_flags & TIFF_SWAB)
2315 53 : TIFFSwabLong(&m);
2316 1178 : if (tif->tif_header.classic.tiff_diroff == 0) {
2317 : /*
2318 : * First directory, overwrite offset in header.
2319 : */
2320 1064 : tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
2321 1064 : (void) TIFFSeekFile(tif,4, SEEK_SET);
2322 1064 : if (!WriteOK(tif, &m, 4)) {
2323 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
2324 : "Error writing TIFF header");
2325 0 : return (0);
2326 : }
2327 1064 : return (1);
2328 : }
2329 : /*
2330 : * Not the first directory, search to the last and append.
2331 : */
2332 114 : nextdir = tif->tif_header.classic.tiff_diroff;
2333 : while(1) {
2334 : uint16 dircount;
2335 : uint32 nextnextdir;
2336 :
2337 171 : if (!SeekOK(tif, nextdir) ||
2338 : !ReadOK(tif, &dircount, 2)) {
2339 0 : TIFFErrorExt(tif->tif_clientdata, module,
2340 : "Error fetching directory count");
2341 0 : return (0);
2342 : }
2343 171 : if (tif->tif_flags & TIFF_SWAB)
2344 33 : TIFFSwabShort(&dircount);
2345 171 : (void) TIFFSeekFile(tif,
2346 : nextdir+2+dircount*12, SEEK_SET);
2347 171 : if (!ReadOK(tif, &nextnextdir, 4)) {
2348 0 : TIFFErrorExt(tif->tif_clientdata, module,
2349 : "Error fetching directory link");
2350 0 : return (0);
2351 : }
2352 171 : if (tif->tif_flags & TIFF_SWAB)
2353 33 : TIFFSwabLong(&nextnextdir);
2354 171 : if (nextnextdir==0)
2355 : {
2356 114 : (void) TIFFSeekFile(tif,
2357 : nextdir+2+dircount*12, SEEK_SET);
2358 114 : if (!WriteOK(tif, &m, 4)) {
2359 0 : TIFFErrorExt(tif->tif_clientdata, module,
2360 : "Error writing directory link");
2361 0 : return (0);
2362 : }
2363 : break;
2364 : }
2365 57 : nextdir=nextnextdir;
2366 57 : }
2367 : }
2368 : else
2369 : {
2370 : uint64 m;
2371 : uint64 nextdir;
2372 19 : m = tif->tif_diroff;
2373 19 : if (tif->tif_flags & TIFF_SWAB)
2374 4 : TIFFSwabLong8(&m);
2375 19 : if (tif->tif_header.big.tiff_diroff == 0) {
2376 : /*
2377 : * First directory, overwrite offset in header.
2378 : */
2379 17 : tif->tif_header.big.tiff_diroff = tif->tif_diroff;
2380 17 : (void) TIFFSeekFile(tif,8, SEEK_SET);
2381 17 : if (!WriteOK(tif, &m, 8)) {
2382 0 : TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
2383 : "Error writing TIFF header");
2384 0 : return (0);
2385 : }
2386 17 : return (1);
2387 : }
2388 : /*
2389 : * Not the first directory, search to the last and append.
2390 : */
2391 2 : nextdir = tif->tif_header.big.tiff_diroff;
2392 : while(1) {
2393 : uint64 dircount64;
2394 : uint16 dircount;
2395 : uint64 nextnextdir;
2396 :
2397 2 : if (!SeekOK(tif, nextdir) ||
2398 : !ReadOK(tif, &dircount64, 8)) {
2399 0 : TIFFErrorExt(tif->tif_clientdata, module,
2400 : "Error fetching directory count");
2401 0 : return (0);
2402 : }
2403 2 : if (tif->tif_flags & TIFF_SWAB)
2404 0 : TIFFSwabLong8(&dircount64);
2405 2 : if (dircount64>0xFFFF)
2406 : {
2407 0 : TIFFErrorExt(tif->tif_clientdata, module,
2408 : "Sanity check on tag count failed, likely corrupt TIFF");
2409 0 : return (0);
2410 : }
2411 2 : dircount=(uint16)dircount64;
2412 2 : (void) TIFFSeekFile(tif,
2413 : nextdir+8+dircount*20, SEEK_SET);
2414 2 : if (!ReadOK(tif, &nextnextdir, 8)) {
2415 0 : TIFFErrorExt(tif->tif_clientdata, module,
2416 : "Error fetching directory link");
2417 0 : return (0);
2418 : }
2419 2 : if (tif->tif_flags & TIFF_SWAB)
2420 0 : TIFFSwabLong8(&nextnextdir);
2421 2 : if (nextnextdir==0)
2422 : {
2423 2 : (void) TIFFSeekFile(tif,
2424 : nextdir+8+dircount*20, SEEK_SET);
2425 2 : if (!WriteOK(tif, &m, 8)) {
2426 0 : TIFFErrorExt(tif->tif_clientdata, module,
2427 : "Error writing directory link");
2428 0 : return (0);
2429 : }
2430 2 : break;
2431 : }
2432 0 : nextdir=nextnextdir;
2433 0 : }
2434 : }
2435 116 : return (1);
2436 : }
2437 :
2438 : /************************************************************************/
2439 : /* TIFFRewriteField() */
2440 : /* */
2441 : /* Rewrite a field in the directory on disk without regard to */
2442 : /* updating the TIFF directory structure in memory. Currently */
2443 : /* only supported for field that already exist in the on-disk */
2444 : /* directory. Mainly used for updating stripoffset / */
2445 : /* stripbytecount values after the directory is already on */
2446 : /* disk. */
2447 : /* */
2448 : /* Returns zero on failure, and one on success. */
2449 : /************************************************************************/
2450 :
2451 : int
2452 : _TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
2453 : tmsize_t count, void* data)
2454 2156 : {
2455 : static const char module[] = "TIFFResetField";
2456 2156 : const TIFFField* fip = NULL;
2457 : uint16 dircount;
2458 : tmsize_t dirsize;
2459 : uint8 direntry_raw[20];
2460 2156 : uint16 entry_tag = 0;
2461 2156 : uint16 entry_type = 0;
2462 2156 : uint64 entry_count = 0;
2463 2156 : uint64 entry_offset = 0;
2464 2156 : int value_in_entry = 0;
2465 : uint64 read_offset;
2466 2156 : uint8 *buf_to_write = NULL;
2467 : TIFFDataType datatype;
2468 :
2469 : /* -------------------------------------------------------------------- */
2470 : /* Find field definition. */
2471 : /* -------------------------------------------------------------------- */
2472 2156 : fip = TIFFFindField(tif, tag, TIFF_ANY);
2473 :
2474 : /* -------------------------------------------------------------------- */
2475 : /* Do some checking this is a straight forward case. */
2476 : /* -------------------------------------------------------------------- */
2477 2156 : if( isMapped(tif) )
2478 : {
2479 0 : TIFFErrorExt( tif->tif_clientdata, module,
2480 : "Memory mapped files not currently supported for this operation." );
2481 0 : return 0;
2482 : }
2483 :
2484 2156 : if( tif->tif_diroff == 0 )
2485 : {
2486 0 : TIFFErrorExt( tif->tif_clientdata, module,
2487 : "Attempt to reset field on directory not already on disk." );
2488 0 : return 0;
2489 : }
2490 :
2491 : /* -------------------------------------------------------------------- */
2492 : /* Read the directory entry count. */
2493 : /* -------------------------------------------------------------------- */
2494 2156 : if (!SeekOK(tif, tif->tif_diroff)) {
2495 0 : TIFFErrorExt(tif->tif_clientdata, module,
2496 : "%s: Seek error accessing TIFF directory",
2497 : tif->tif_name);
2498 0 : return 0;
2499 : }
2500 :
2501 2156 : read_offset = tif->tif_diroff;
2502 :
2503 2156 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2504 : {
2505 2146 : if (!ReadOK(tif, &dircount, sizeof (uint16))) {
2506 0 : TIFFErrorExt(tif->tif_clientdata, module,
2507 : "%s: Can not read TIFF directory count",
2508 : tif->tif_name);
2509 0 : return 0;
2510 : }
2511 2146 : if (tif->tif_flags & TIFF_SWAB)
2512 76 : TIFFSwabShort(&dircount);
2513 2146 : dirsize = 12;
2514 2146 : read_offset += 2;
2515 : } else {
2516 : uint64 dircount64;
2517 10 : if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
2518 0 : TIFFErrorExt(tif->tif_clientdata, module,
2519 : "%s: Can not read TIFF directory count",
2520 : tif->tif_name);
2521 0 : return 0;
2522 : }
2523 10 : if (tif->tif_flags & TIFF_SWAB)
2524 0 : TIFFSwabLong8(&dircount64);
2525 10 : dircount = (uint16)dircount64;
2526 10 : dirsize = 20;
2527 10 : read_offset += 8;
2528 : }
2529 :
2530 : /* -------------------------------------------------------------------- */
2531 : /* Read through directory to find target tag. */
2532 : /* -------------------------------------------------------------------- */
2533 20006 : while( dircount > 0 )
2534 : {
2535 17850 : if (!ReadOK(tif, direntry_raw, dirsize)) {
2536 0 : TIFFErrorExt(tif->tif_clientdata, module,
2537 : "%s: Can not read TIFF directory entry.",
2538 : tif->tif_name);
2539 0 : return 0;
2540 : }
2541 :
2542 17850 : memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
2543 17850 : if (tif->tif_flags&TIFF_SWAB)
2544 710 : TIFFSwabShort( &entry_tag );
2545 :
2546 17850 : if( entry_tag == tag )
2547 2156 : break;
2548 :
2549 15694 : read_offset += dirsize;
2550 : }
2551 :
2552 2156 : if( entry_tag != tag )
2553 : {
2554 0 : TIFFErrorExt(tif->tif_clientdata, module,
2555 : "%s: Could not find tag %d.",
2556 : tif->tif_name, tag );
2557 0 : return 0;
2558 : }
2559 :
2560 : /* -------------------------------------------------------------------- */
2561 : /* Extract the type, count and offset for this entry. */
2562 : /* -------------------------------------------------------------------- */
2563 2156 : memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
2564 2156 : if (tif->tif_flags&TIFF_SWAB)
2565 76 : TIFFSwabShort( &entry_type );
2566 :
2567 2156 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2568 : {
2569 : uint32 value;
2570 :
2571 2146 : memcpy( &value, direntry_raw + 4, sizeof(uint32) );
2572 2146 : if (tif->tif_flags&TIFF_SWAB)
2573 76 : TIFFSwabLong( &value );
2574 2146 : entry_count = value;
2575 :
2576 2146 : memcpy( &value, direntry_raw + 8, sizeof(uint32) );
2577 2146 : if (tif->tif_flags&TIFF_SWAB)
2578 76 : TIFFSwabLong( &value );
2579 2146 : entry_offset = value;
2580 : }
2581 : else
2582 : {
2583 10 : memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
2584 10 : if (tif->tif_flags&TIFF_SWAB)
2585 0 : TIFFSwabLong8( &entry_count );
2586 :
2587 10 : memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
2588 10 : if (tif->tif_flags&TIFF_SWAB)
2589 0 : TIFFSwabLong8( &entry_offset );
2590 : }
2591 :
2592 : /* -------------------------------------------------------------------- */
2593 : /* What data type do we want to write this as? */
2594 : /* -------------------------------------------------------------------- */
2595 4302 : if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
2596 : {
2597 2146 : if( in_datatype == TIFF_LONG8 )
2598 2146 : datatype = TIFF_LONG;
2599 0 : else if( in_datatype == TIFF_SLONG8 )
2600 0 : datatype = TIFF_SLONG;
2601 0 : else if( in_datatype == TIFF_IFD8 )
2602 0 : datatype = TIFF_IFD;
2603 : else
2604 0 : datatype = in_datatype;
2605 : }
2606 : else
2607 10 : datatype = in_datatype;
2608 :
2609 : /* -------------------------------------------------------------------- */
2610 : /* Prepare buffer of actual data to write. This includes */
2611 : /* swabbing as needed. */
2612 : /* -------------------------------------------------------------------- */
2613 2156 : buf_to_write =
2614 : (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
2615 : "for field buffer.");
2616 2156 : if (!buf_to_write)
2617 0 : return 0;
2618 :
2619 2156 : if( datatype == in_datatype )
2620 10 : memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
2621 2146 : else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
2622 : {
2623 : tmsize_t i;
2624 :
2625 0 : for( i = 0; i < count; i++ )
2626 : {
2627 0 : ((int32 *) buf_to_write)[i] =
2628 : (int32) ((int64 *) data)[i];
2629 0 : if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
2630 : {
2631 0 : _TIFFfree( buf_to_write );
2632 0 : TIFFErrorExt( tif->tif_clientdata, module,
2633 : "Value exceeds 32bit range of output type." );
2634 0 : return 0;
2635 : }
2636 : }
2637 : }
2638 2146 : else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
2639 : || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
2640 : {
2641 : tmsize_t i;
2642 :
2643 170174 : for( i = 0; i < count; i++ )
2644 : {
2645 168028 : ((uint32 *) buf_to_write)[i] =
2646 : (uint32) ((uint64 *) data)[i];
2647 168028 : if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
2648 : {
2649 0 : _TIFFfree( buf_to_write );
2650 0 : TIFFErrorExt( tif->tif_clientdata, module,
2651 : "Value exceeds 32bit range of output type." );
2652 0 : return 0;
2653 : }
2654 : }
2655 : }
2656 :
2657 2156 : if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
2658 : {
2659 76 : if( TIFFDataWidth(datatype) == 2 )
2660 0 : TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
2661 76 : else if( TIFFDataWidth(datatype) == 4 )
2662 76 : TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
2663 0 : else if( TIFFDataWidth(datatype) == 8 )
2664 0 : TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
2665 : }
2666 :
2667 : /* -------------------------------------------------------------------- */
2668 : /* Is this a value that fits into the directory entry? */
2669 : /* -------------------------------------------------------------------- */
2670 2156 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2671 : {
2672 2146 : if( TIFFDataWidth(datatype) * count <= 4 )
2673 : {
2674 1770 : entry_offset = read_offset + 8;
2675 1770 : value_in_entry = 1;
2676 : }
2677 : }
2678 : else
2679 : {
2680 10 : if( TIFFDataWidth(datatype) * count <= 8 )
2681 : {
2682 10 : entry_offset = read_offset + 12;
2683 10 : value_in_entry = 1;
2684 : }
2685 : }
2686 :
2687 : /* -------------------------------------------------------------------- */
2688 : /* If the tag type, and count match, then we just write it out */
2689 : /* over the old values without altering the directory entry at */
2690 : /* all. */
2691 : /* -------------------------------------------------------------------- */
2692 2156 : if( entry_count == (uint64)count && entry_type == (uint16) datatype )
2693 : {
2694 2156 : if (!SeekOK(tif, entry_offset)) {
2695 0 : _TIFFfree( buf_to_write );
2696 0 : TIFFErrorExt(tif->tif_clientdata, module,
2697 : "%s: Seek error accessing TIFF directory",
2698 : tif->tif_name);
2699 0 : return 0;
2700 : }
2701 2156 : if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
2702 0 : _TIFFfree( buf_to_write );
2703 0 : TIFFErrorExt(tif->tif_clientdata, module,
2704 : "Error writing directory link");
2705 0 : return (0);
2706 : }
2707 :
2708 2156 : _TIFFfree( buf_to_write );
2709 2156 : return 1;
2710 : }
2711 :
2712 : /* -------------------------------------------------------------------- */
2713 : /* Otherwise, we write the new tag data at the end of the file. */
2714 : /* -------------------------------------------------------------------- */
2715 0 : if( !value_in_entry )
2716 : {
2717 0 : entry_offset = TIFFSeekFile(tif,0,SEEK_END);
2718 :
2719 0 : if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
2720 0 : _TIFFfree( buf_to_write );
2721 0 : TIFFErrorExt(tif->tif_clientdata, module,
2722 : "Error writing directory link");
2723 0 : return (0);
2724 : }
2725 :
2726 0 : _TIFFfree( buf_to_write );
2727 : }
2728 : else
2729 : {
2730 0 : memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
2731 : }
2732 :
2733 : /* -------------------------------------------------------------------- */
2734 : /* Adjust the directory entry. */
2735 : /* -------------------------------------------------------------------- */
2736 0 : entry_type = datatype;
2737 0 : memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
2738 0 : if (tif->tif_flags&TIFF_SWAB)
2739 0 : TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
2740 :
2741 0 : if (!(tif->tif_flags&TIFF_BIGTIFF))
2742 : {
2743 : uint32 value;
2744 :
2745 0 : value = (uint32) entry_count;
2746 0 : memcpy( direntry_raw + 4, &value, sizeof(uint32) );
2747 0 : if (tif->tif_flags&TIFF_SWAB)
2748 0 : TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
2749 :
2750 0 : value = (uint32) entry_offset;
2751 0 : memcpy( direntry_raw + 8, &value, sizeof(uint32) );
2752 0 : if (tif->tif_flags&TIFF_SWAB)
2753 0 : TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
2754 : }
2755 : else
2756 : {
2757 0 : memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
2758 0 : if (tif->tif_flags&TIFF_SWAB)
2759 0 : TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
2760 :
2761 0 : memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
2762 0 : if (tif->tif_flags&TIFF_SWAB)
2763 0 : TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
2764 : }
2765 :
2766 : /* -------------------------------------------------------------------- */
2767 : /* Write the directory entry out to disk. */
2768 : /* -------------------------------------------------------------------- */
2769 0 : if (!SeekOK(tif, read_offset )) {
2770 0 : TIFFErrorExt(tif->tif_clientdata, module,
2771 : "%s: Seek error accessing TIFF directory",
2772 : tif->tif_name);
2773 0 : return 0;
2774 : }
2775 :
2776 0 : if (!WriteOK(tif, direntry_raw,dirsize))
2777 : {
2778 0 : TIFFErrorExt(tif->tif_clientdata, module,
2779 : "%s: Can not write TIFF directory entry.",
2780 : tif->tif_name);
2781 0 : return 0;
2782 : }
2783 :
2784 0 : return 1;
2785 : }
2786 : /* vim: set ts=8 sts=8 sw=8 noet: */
2787 : /*
2788 : * Local Variables:
2789 : * mode: c
2790 : * c-basic-offset: 8
2791 : * fill-column: 78
2792 : * End:
2793 : */
|