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