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