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