Release 9.12.
[wine.git] / libs / tiff / libtiff / tif_dirwrite.c
blobd8844bbd8a36a0dfc902f811bc8dee7ab59ea325
1 /*
2 * Copyright (c) 1988-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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.
26 * TIFF Library.
28 * Directory Write Support Routines.
30 #include "tiffiop.h"
31 #include <float.h> /*--: for Rational2Double */
32 #include <math.h> /*--: for Rational2Double */
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
42 static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
43 uint64_t *pdiroff);
45 static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
46 TIFFDirEntry *dir,
47 uint16_t tag, uint32_t count,
48 double *value);
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);
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);
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);
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);
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);
227 static int TIFFLinkDirectory(TIFF *);
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.
235 int TIFFWriteDirectory(TIFF *tif)
237 return TIFFWriteDirectorySec(tif, TRUE, TRUE, NULL);
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.
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.
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
263 * Returns 1 in case of success, 0 otherwise.
265 int TIFFDeferStrileArrayWriting(TIFF *tif)
267 static const char module[] = "TIFFDeferStrileArrayWriting";
268 if (tif->tif_mode == O_RDONLY)
270 TIFFErrorExtR(tif, tif->tif_name, "File opened in read-only mode");
271 return 0;
273 if (tif->tif_diroff != 0)
275 TIFFErrorExtR(tif, module, "Directory has already been written");
276 return 0;
279 tif->tif_dir.td_deferstrilearraywriting = TRUE;
280 return 1;
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.
289 int TIFFCheckpointDirectory(TIFF *tif)
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;
300 int TIFFWriteCustomDirectory(TIFF *tif, uint64_t *pdiroff)
302 return TIFFWriteDirectorySec(tif, FALSE, FALSE, pdiroff);
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.
311 int TIFFRewriteDirectory(TIFF *tif)
313 static const char module[] = "TIFFRewriteDirectory";
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);
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.
323 uint64_t torewritediroff = tif->tif_diroff;
325 if (!(tif->tif_flags & TIFF_BIGTIFF))
327 if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
329 tif->tif_header.classic.tiff_diroff = 0;
330 tif->tif_diroff = 0;
332 TIFFSeekFile(tif, 4, SEEK_SET);
333 if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff), 4))
335 TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
336 return (0);
339 else if (tif->tif_diroff > 0xFFFFFFFFU)
341 TIFFErrorExtR(tif, module,
342 "tif->tif_diroff exceeds 32 bit range allowed for "
343 "Classic TIFF");
344 return (0);
346 else
348 uint32_t nextdir;
349 nextdir = tif->tif_header.classic.tiff_diroff;
350 while (1)
352 uint16_t dircount;
353 uint32_t nextnextdir;
355 if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
357 TIFFErrorExtR(tif, module,
358 "Error fetching directory count");
359 return (0);
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))
366 TIFFErrorExtR(tif, module, "Error fetching directory link");
367 return (0);
369 if (tif->tif_flags & TIFF_SWAB)
370 TIFFSwabLong(&nextnextdir);
371 if (nextnextdir == tif->tif_diroff)
373 uint32_t m;
374 m = 0;
375 (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12,
376 SEEK_SET);
377 if (!WriteOK(tif, &m, 4))
379 TIFFErrorExtR(tif, module,
380 "Error writing directory link");
381 return (0);
383 tif->tif_diroff = 0;
384 /* Force a full-traversal to reach the zeroed pointer */
385 tif->tif_lastdiroff = 0;
386 break;
388 nextdir = nextnextdir;
391 /* Remove skipped offset from IFD loop directory list. */
392 _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
394 else
396 if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
398 tif->tif_header.big.tiff_diroff = 0;
399 tif->tif_diroff = 0;
401 TIFFSeekFile(tif, 8, SEEK_SET);
402 if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff), 8))
404 TIFFErrorExtR(tif, tif->tif_name, "Error updating TIFF header");
405 return (0);
408 else
410 uint64_t nextdir;
411 nextdir = tif->tif_header.big.tiff_diroff;
412 while (1)
414 uint64_t dircount64;
415 uint16_t dircount;
416 uint64_t nextnextdir;
418 if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
420 TIFFErrorExtR(tif, module,
421 "Error fetching directory count");
422 return (0);
424 if (tif->tif_flags & TIFF_SWAB)
425 TIFFSwabLong8(&dircount64);
426 if (dircount64 > 0xFFFF)
428 TIFFErrorExtR(tif, module,
429 "Sanity check on tag count failed, likely "
430 "corrupt TIFF");
431 return (0);
433 dircount = (uint16_t)dircount64;
434 (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
435 if (!ReadOK(tif, &nextnextdir, 8))
437 TIFFErrorExtR(tif, module, "Error fetching directory link");
438 return (0);
440 if (tif->tif_flags & TIFF_SWAB)
441 TIFFSwabLong8(&nextnextdir);
442 if (nextnextdir == tif->tif_diroff)
444 uint64_t m;
445 m = 0;
446 (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20,
447 SEEK_SET);
448 if (!WriteOK(tif, &m, 8))
450 TIFFErrorExtR(tif, module,
451 "Error writing directory link");
452 return (0);
454 tif->tif_diroff = 0;
455 /* Force a full-traversal to reach the zeroed pointer */
456 tif->tif_lastdiroff = 0;
457 break;
459 nextdir = nextnextdir;
462 /* Remove skipped offset from IFD loop directory list. */
463 _TIFFRemoveEntryFromDirectoryListByOffset(tif, torewritediroff);
467 * Now use TIFFWriteDirectory() normally.
470 return TIFFWriteDirectory(tif);
473 static int TIFFWriteDirectorySec(TIFF *tif, int isimage, int imagedone,
474 uint64_t *pdiroff)
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);
485 _TIFFFillStriles(tif);
488 * Clear write state so that subsequent images with
489 * different characteristics get the right buffers
490 * setup for them.
492 if (imagedone)
494 if (tif->tif_flags & TIFF_POSTENCODE)
496 tif->tif_flags &= ~TIFF_POSTENCODE;
497 if (!(*tif->tif_postencode)(tif))
499 TIFFErrorExtR(tif, module,
500 "Error post-encoding before directory write");
501 return (0);
504 (*tif->tif_close)(tif); /* shutdown encoder */
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.
512 if (tif->tif_rawcc > 0 && (tif->tif_flags & TIFF_BEENWRITING) != 0)
514 if (!TIFFFlushData1(tif))
516 TIFFErrorExtR(tif, module,
517 "Error flushing data before directory write");
518 return (0);
521 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
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;
530 tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP);
533 if (TIFFFieldSet(tif, FIELD_COMPRESSION) &&
534 (tif->tif_dir.td_compression == COMPRESSION_DEFLATE))
536 TIFFWarningExtR(tif, module,
537 "Creating TIFF with legacy Deflate codec identifier, "
538 "COMPRESSION_ADOBE_DEFLATE is more widely supported");
540 dir = NULL;
541 dirmem = NULL;
542 dirsize = 0;
543 while (1)
545 ndir = 0;
546 if (isimage)
548 if (TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
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;
559 if (TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
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;
570 if (TIFFFieldSet(tif, FIELD_RESOLUTION))
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;
581 if (TIFFFieldSet(tif, FIELD_POSITION))
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;
592 if (TIFFFieldSet(tif, FIELD_SUBFILETYPE))
594 if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
595 TIFFTAG_SUBFILETYPE,
596 tif->tif_dir.td_subfiletype))
597 goto bad;
599 if (TIFFFieldSet(tif, FIELD_BITSPERSAMPLE))
601 if (!TIFFWriteDirectoryTagShortPerSample(
602 tif, &ndir, dir, TIFFTAG_BITSPERSAMPLE,
603 tif->tif_dir.td_bitspersample))
604 goto bad;
606 if (TIFFFieldSet(tif, FIELD_COMPRESSION))
608 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
609 TIFFTAG_COMPRESSION,
610 tif->tif_dir.td_compression))
611 goto bad;
613 if (TIFFFieldSet(tif, FIELD_PHOTOMETRIC))
615 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
616 TIFFTAG_PHOTOMETRIC,
617 tif->tif_dir.td_photometric))
618 goto bad;
620 if (TIFFFieldSet(tif, FIELD_THRESHHOLDING))
622 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
623 TIFFTAG_THRESHHOLDING,
624 tif->tif_dir.td_threshholding))
625 goto bad;
627 if (TIFFFieldSet(tif, FIELD_FILLORDER))
629 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
630 TIFFTAG_FILLORDER,
631 tif->tif_dir.td_fillorder))
632 goto bad;
634 if (TIFFFieldSet(tif, FIELD_ORIENTATION))
636 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
637 TIFFTAG_ORIENTATION,
638 tif->tif_dir.td_orientation))
639 goto bad;
641 if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
643 if (!TIFFWriteDirectoryTagShort(
644 tif, &ndir, dir, TIFFTAG_SAMPLESPERPIXEL,
645 tif->tif_dir.td_samplesperpixel))
646 goto bad;
648 if (TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
650 if (!TIFFWriteDirectoryTagShortLong(
651 tif, &ndir, dir, TIFFTAG_ROWSPERSTRIP,
652 tif->tif_dir.td_rowsperstrip))
653 goto bad;
655 if (TIFFFieldSet(tif, FIELD_MINSAMPLEVALUE))
657 if (!TIFFWriteDirectoryTagShortPerSample(
658 tif, &ndir, dir, TIFFTAG_MINSAMPLEVALUE,
659 tif->tif_dir.td_minsamplevalue))
660 goto bad;
662 if (TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
664 if (!TIFFWriteDirectoryTagShortPerSample(
665 tif, &ndir, dir, TIFFTAG_MAXSAMPLEVALUE,
666 tif->tif_dir.td_maxsamplevalue))
667 goto bad;
669 if (TIFFFieldSet(tif, FIELD_PLANARCONFIG))
671 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
672 TIFFTAG_PLANARCONFIG,
673 tif->tif_dir.td_planarconfig))
674 goto bad;
676 if (TIFFFieldSet(tif, FIELD_RESOLUTIONUNIT))
678 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
679 TIFFTAG_RESOLUTIONUNIT,
680 tif->tif_dir.td_resolutionunit))
681 goto bad;
683 if (TIFFFieldSet(tif, FIELD_PAGENUMBER))
685 if (!TIFFWriteDirectoryTagShortArray(
686 tif, &ndir, dir, TIFFTAG_PAGENUMBER, 2,
687 &tif->tif_dir.td_pagenumber[0]))
688 goto bad;
690 if (TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS))
692 if (!isTiled(tif))
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;
700 else
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;
709 if (TIFFFieldSet(tif, FIELD_STRIPOFFSETS))
711 if (!isTiled(tif))
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
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;
731 else
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;
740 if (TIFFFieldSet(tif, FIELD_COLORMAP))
742 if (!TIFFWriteDirectoryTagColormap(tif, &ndir, dir))
743 goto bad;
745 if (TIFFFieldSet(tif, FIELD_EXTRASAMPLES))
747 if (tif->tif_dir.td_extrasamples)
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;
757 if (TIFFFieldSet(tif, FIELD_SAMPLEFORMAT))
759 if (!TIFFWriteDirectoryTagShortPerSample(
760 tif, &ndir, dir, TIFFTAG_SAMPLEFORMAT,
761 tif->tif_dir.td_sampleformat))
762 goto bad;
764 if (TIFFFieldSet(tif, FIELD_SMINSAMPLEVALUE))
766 if (!TIFFWriteDirectoryTagSampleformatArray(
767 tif, &ndir, dir, TIFFTAG_SMINSAMPLEVALUE,
768 tif->tif_dir.td_samplesperpixel,
769 tif->tif_dir.td_sminsamplevalue))
770 goto bad;
772 if (TIFFFieldSet(tif, FIELD_SMAXSAMPLEVALUE))
774 if (!TIFFWriteDirectoryTagSampleformatArray(
775 tif, &ndir, dir, TIFFTAG_SMAXSAMPLEVALUE,
776 tif->tif_dir.td_samplesperpixel,
777 tif->tif_dir.td_smaxsamplevalue))
778 goto bad;
780 if (TIFFFieldSet(tif, FIELD_IMAGEDEPTH))
782 if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
783 TIFFTAG_IMAGEDEPTH,
784 tif->tif_dir.td_imagedepth))
785 goto bad;
787 if (TIFFFieldSet(tif, FIELD_TILEDEPTH))
789 if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir,
790 TIFFTAG_TILEDEPTH,
791 tif->tif_dir.td_tiledepth))
792 goto bad;
794 if (TIFFFieldSet(tif, FIELD_HALFTONEHINTS))
796 if (!TIFFWriteDirectoryTagShortArray(
797 tif, &ndir, dir, TIFFTAG_HALFTONEHINTS, 2,
798 &tif->tif_dir.td_halftonehints[0]))
799 goto bad;
801 if (TIFFFieldSet(tif, FIELD_YCBCRSUBSAMPLING))
803 if (!TIFFWriteDirectoryTagShortArray(
804 tif, &ndir, dir, TIFFTAG_YCBCRSUBSAMPLING, 2,
805 &tif->tif_dir.td_ycbcrsubsampling[0]))
806 goto bad;
808 if (TIFFFieldSet(tif, FIELD_YCBCRPOSITIONING))
810 if (!TIFFWriteDirectoryTagShort(
811 tif, &ndir, dir, TIFFTAG_YCBCRPOSITIONING,
812 tif->tif_dir.td_ycbcrpositioning))
813 goto bad;
815 if (TIFFFieldSet(tif, FIELD_REFBLACKWHITE))
817 if (!TIFFWriteDirectoryTagRationalArray(
818 tif, &ndir, dir, TIFFTAG_REFERENCEBLACKWHITE, 6,
819 tif->tif_dir.td_refblackwhite))
820 goto bad;
822 if (TIFFFieldSet(tif, FIELD_TRANSFERFUNCTION))
824 if (!TIFFWriteDirectoryTagTransferfunction(tif, &ndir, dir))
825 goto bad;
827 if (TIFFFieldSet(tif, FIELD_INKNAMES))
829 if (!TIFFWriteDirectoryTagAscii(
830 tif, &ndir, dir, TIFFTAG_INKNAMES,
831 tif->tif_dir.td_inknameslen, tif->tif_dir.td_inknames))
832 goto bad;
834 if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
836 if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir,
837 TIFFTAG_NUMBEROFINKS,
838 tif->tif_dir.td_numberofinks))
839 goto bad;
841 if (TIFFFieldSet(tif, FIELD_SUBIFD))
843 if (!TIFFWriteDirectoryTagSubifd(tif, &ndir, dir))
844 goto bad;
847 uint32_t n;
848 for (n = 0; n < tif->tif_nfields; n++)
850 const TIFFField *o;
851 o = tif->tif_fields[n];
852 if ((o->field_bit >= FIELD_CODEC) &&
853 (TIFFFieldSet(tif, o->field_bit)))
855 switch (o->get_field_type)
857 case TIFF_SETGET_ASCII:
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;
871 break;
872 case TIFF_SETGET_UINT16:
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,
882 goto bad;
884 break;
885 case TIFF_SETGET_UINT32:
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,
895 goto bad;
897 break;
898 case TIFF_SETGET_C32_UINT8:
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;
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;
924 for (m = 0; m < (uint32_t)(tif->tif_dir.td_customValueCount); m++)
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)
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:
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)
1000 if (!TIFFWriteDirectoryTagRationalDoubleArray(
1001 tif, &ndir, dir, tag, count,
1002 tif->tif_dir.td_customValues[m].value))
1003 goto bad;
1005 else
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)
1016 TIFFErrorExtR(tif,
1017 "TIFFLib: _TIFFWriteDirectorySec()",
1018 "Rational2Double: .set_field_type is "
1019 "not 4 but %d",
1020 tv_size);
1024 break;
1025 case TIFF_SRATIONAL:
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)
1034 if (!TIFFWriteDirectoryTagSrationalDoubleArray(
1035 tif, &ndir, dir, tag, count,
1036 tif->tif_dir.td_customValues[m].value))
1037 goto bad;
1039 else
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)
1050 TIFFErrorExtR(tif,
1051 "TIFFLib: _TIFFWriteDirectorySec()",
1052 "Rational2Double: .set_field_type is "
1053 "not 4 but %d",
1054 tv_size);
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;
1088 if (dir != NULL)
1089 break;
1090 dir = _TIFFmallocExt(tif, ndir * sizeof(TIFFDirEntry));
1091 if (dir == NULL)
1093 TIFFErrorExtR(tif, module, "Out of memory");
1094 goto bad;
1096 if (isimage)
1098 if ((tif->tif_diroff == 0) && (!TIFFLinkDirectory(tif)))
1099 goto bad;
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))
1116 TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
1117 goto bad;
1119 if (tif->tif_dataoff & 1)
1120 tif->tif_dataoff++;
1121 if (isimage)
1123 if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
1124 tif->tif_curdir = 0;
1125 else
1126 tif->tif_curdir++;
1129 if (isimage)
1131 if (TIFFFieldSet(tif, FIELD_SUBIFD) && (tif->tif_subifdoff == 0))
1133 uint32_t na;
1134 TIFFDirEntry *nb;
1135 for (na = 0, nb = dir;; na++, nb++)
1137 if (na == ndir)
1139 TIFFErrorExtR(tif, module, "Cannot find SubIFD tag");
1140 goto bad;
1142 if (nb->tdir_tag == TIFFTAG_SUBIFD)
1143 break;
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;
1151 dirmem = _TIFFmallocExt(tif, dirsize);
1152 if (dirmem == NULL)
1154 TIFFErrorExtR(tif, module, "Out of memory");
1155 goto bad;
1157 if (!(tif->tif_flags & TIFF_BIGTIFF))
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++)
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++;
1189 nTmp = (uint32_t)tif->tif_nextdiroff;
1190 if (tif->tif_flags & TIFF_SWAB)
1191 TIFFSwabLong(&nTmp);
1192 _TIFFmemcpy(n, &nTmp, 4);
1194 else
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++)
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++;
1222 _TIFFmemcpy(n, &tif->tif_nextdiroff, 8);
1223 if (tif->tif_flags & TIFF_SWAB)
1224 TIFFSwabLong8((uint64_t *)n);
1226 _TIFFfreeExt(tif, dir);
1227 dir = NULL;
1228 if (!SeekOK(tif, tif->tif_diroff))
1230 TIFFErrorExtR(tif, module, "IO error writing directory");
1231 goto bad;
1233 if (!WriteOK(tif, dirmem, (tmsize_t)dirsize))
1235 TIFFErrorExtR(tif, module, "IO error writing directory");
1236 goto bad;
1238 _TIFFfreeExt(tif, dirmem);
1239 if (imagedone)
1241 TIFFFreeDirectory(tif);
1242 tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1243 tif->tif_flags &= ~TIFF_DIRTYSTRIP;
1244 (*tif->tif_cleanup)(tif);
1246 * Reset directory-related state for subsequent
1247 * directories.
1249 TIFFCreateDirectory(tif);
1251 return (1);
1252 bad:
1253 if (dir != NULL)
1254 _TIFFfreeExt(tif, dir);
1255 if (dirmem != NULL)
1256 _TIFFfreeExt(tif, dirmem);
1257 return (0);
1260 static int8_t TIFFClampDoubleToInt8(double val)
1262 if (val > 127)
1263 return 127;
1264 if (val < -128 || val != val)
1265 return -128;
1266 return (int8_t)val;
1269 static int16_t TIFFClampDoubleToInt16(double val)
1271 if (val > 32767)
1272 return 32767;
1273 if (val < -32768 || val != val)
1274 return -32768;
1275 return (int16_t)val;
1278 static int32_t TIFFClampDoubleToInt32(double val)
1280 if (val > 0x7FFFFFFF)
1281 return 0x7FFFFFFF;
1282 if (val < -0x7FFFFFFF - 1 || val != val)
1283 return -0x7FFFFFFF - 1;
1284 return (int32_t)val;
1287 static uint8_t TIFFClampDoubleToUInt8(double val)
1289 if (val < 0)
1290 return 0;
1291 if (val > 255 || val != val)
1292 return 255;
1293 return (uint8_t)val;
1296 static uint16_t TIFFClampDoubleToUInt16(double val)
1298 if (val < 0)
1299 return 0;
1300 if (val > 65535 || val != val)
1301 return 65535;
1302 return (uint16_t)val;
1305 static uint32_t TIFFClampDoubleToUInt32(double val)
1307 if (val < 0)
1308 return 0;
1309 if (val > 0xFFFFFFFFU || val != val)
1310 return 0xFFFFFFFFU;
1311 return (uint32_t)val;
1314 static int TIFFWriteDirectoryTagSampleformatArray(TIFF *tif, uint32_t *ndir,
1315 TIFFDirEntry *dir,
1316 uint16_t tag, uint32_t count,
1317 double *value)
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)
1326 TIFFErrorExtR(tif, module, "Out of memory");
1327 return (0);
1330 switch (tif->tif_dir.td_sampleformat)
1332 case SAMPLEFORMAT_IEEEFP:
1333 if (tif->tif_dir.td_bitspersample <= 32)
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);
1340 else
1342 ok = TIFFWriteDirectoryTagDoubleArray(tif, ndir, dir, tag,
1343 count, value);
1345 break;
1346 case SAMPLEFORMAT_INT:
1347 if (tif->tif_dir.td_bitspersample <= 8)
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);
1354 else if (tif->tif_dir.td_bitspersample <= 16)
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);
1361 else
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);
1368 break;
1369 case SAMPLEFORMAT_UINT:
1370 if (tif->tif_dir.td_bitspersample <= 8)
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);
1377 else if (tif->tif_dir.td_bitspersample <= 16)
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);
1384 else
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);
1391 break;
1392 default:
1393 ok = 0;
1396 _TIFFfreeExt(tif, conv);
1397 return (ok);
1400 static int TIFFWriteDirectoryTagAscii(TIFF *tif, uint32_t *ndir,
1401 TIFFDirEntry *dir, uint16_t tag,
1402 uint32_t count, char *value)
1404 if (dir == NULL)
1406 (*ndir)++;
1407 return (1);
1409 return (
1410 TIFFWriteDirectoryTagCheckedAscii(tif, ndir, dir, tag, count, value));
1413 static int TIFFWriteDirectoryTagUndefinedArray(TIFF *tif, uint32_t *ndir,
1414 TIFFDirEntry *dir, uint16_t tag,
1415 uint32_t count, uint8_t *value)
1417 if (dir == NULL)
1419 (*ndir)++;
1420 return (1);
1422 return (TIFFWriteDirectoryTagCheckedUndefinedArray(tif, ndir, dir, tag,
1423 count, value));
1426 static int TIFFWriteDirectoryTagByteArray(TIFF *tif, uint32_t *ndir,
1427 TIFFDirEntry *dir, uint16_t tag,
1428 uint32_t count, uint8_t *value)
1430 if (dir == NULL)
1432 (*ndir)++;
1433 return (1);
1435 return (TIFFWriteDirectoryTagCheckedByteArray(tif, ndir, dir, tag, count,
1436 value));
1439 static int TIFFWriteDirectoryTagSbyteArray(TIFF *tif, uint32_t *ndir,
1440 TIFFDirEntry *dir, uint16_t tag,
1441 uint32_t count, int8_t *value)
1443 if (dir == NULL)
1445 (*ndir)++;
1446 return (1);
1448 return (TIFFWriteDirectoryTagCheckedSbyteArray(tif, ndir, dir, tag, count,
1449 value));
1452 static int TIFFWriteDirectoryTagShort(TIFF *tif, uint32_t *ndir,
1453 TIFFDirEntry *dir, uint16_t tag,
1454 uint16_t value)
1456 if (dir == NULL)
1458 (*ndir)++;
1459 return (1);
1461 return (TIFFWriteDirectoryTagCheckedShort(tif, ndir, dir, tag, value));
1464 static int TIFFWriteDirectoryTagShortArray(TIFF *tif, uint32_t *ndir,
1465 TIFFDirEntry *dir, uint16_t tag,
1466 uint32_t count, uint16_t *value)
1468 if (dir == NULL)
1470 (*ndir)++;
1471 return (1);
1473 return (TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1474 value));
1477 static int TIFFWriteDirectoryTagShortPerSample(TIFF *tif, uint32_t *ndir,
1478 TIFFDirEntry *dir, uint16_t tag,
1479 uint16_t value)
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)
1488 (*ndir)++;
1489 return (1);
1491 m = _TIFFmallocExt(tif, tif->tif_dir.td_samplesperpixel * sizeof(uint16_t));
1492 if (m == NULL)
1494 TIFFErrorExtR(tif, module, "Out of memory");
1495 return (0);
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);
1505 static int TIFFWriteDirectoryTagSshortArray(TIFF *tif, uint32_t *ndir,
1506 TIFFDirEntry *dir, uint16_t tag,
1507 uint32_t count, int16_t *value)
1509 if (dir == NULL)
1511 (*ndir)++;
1512 return (1);
1514 return (TIFFWriteDirectoryTagCheckedSshortArray(tif, ndir, dir, tag, count,
1515 value));
1518 static int TIFFWriteDirectoryTagLong(TIFF *tif, uint32_t *ndir,
1519 TIFFDirEntry *dir, uint16_t tag,
1520 uint32_t value)
1522 if (dir == NULL)
1524 (*ndir)++;
1525 return (1);
1527 return (TIFFWriteDirectoryTagCheckedLong(tif, ndir, dir, tag, value));
1530 static int TIFFWriteDirectoryTagLongArray(TIFF *tif, uint32_t *ndir,
1531 TIFFDirEntry *dir, uint16_t tag,
1532 uint32_t count, uint32_t *value)
1534 if (dir == NULL)
1536 (*ndir)++;
1537 return (1);
1539 return (TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1540 value));
1543 static int TIFFWriteDirectoryTagSlongArray(TIFF *tif, uint32_t *ndir,
1544 TIFFDirEntry *dir, uint16_t tag,
1545 uint32_t count, int32_t *value)
1547 if (dir == NULL)
1549 (*ndir)++;
1550 return (1);
1552 return (TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count,
1553 value));
1556 /************************************************************************/
1557 /* TIFFWriteDirectoryTagLong8Array() */
1558 /* */
1559 /* Write either Long8 or Long array depending on file type. */
1560 /************************************************************************/
1561 static int TIFFWriteDirectoryTagLong8Array(TIFF *tif, uint32_t *ndir,
1562 TIFFDirEntry *dir, uint16_t tag,
1563 uint32_t count, uint64_t *value)
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;
1572 /* is this just a counting pass? */
1573 if (dir == NULL)
1575 (*ndir)++;
1576 return (1);
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));
1585 ** For classic tiff we want to verify everything is in range for long
1586 ** and convert to long format.
1588 p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1589 if (p == NULL)
1591 TIFFErrorExtR(tif, module, "Out of memory");
1592 return (0);
1595 for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1597 if (*ma > 0xFFFFFFFF)
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);
1607 *q = (uint32_t)(*ma);
1610 o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count, p);
1611 _TIFFfreeExt(tif, p);
1613 return (o);
1616 /************************************************************************/
1617 /* TIFFWriteDirectoryTagSlong8Array() */
1618 /* */
1619 /* Write either SLong8 or SLong array depending on file type. */
1620 /************************************************************************/
1621 static int TIFFWriteDirectoryTagSlong8Array(TIFF *tif, uint32_t *ndir,
1622 TIFFDirEntry *dir, uint16_t tag,
1623 uint32_t count, int64_t *value)
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;
1632 /* is this just a counting pass? */
1633 if (dir == NULL)
1635 (*ndir)++;
1636 return (1);
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));
1644 ** For classic tiff we want to verify everything is in range for signed-long
1645 ** and convert to signed-long format.
1647 p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1648 if (p == NULL)
1650 TIFFErrorExtR(tif, module, "Out of memory");
1651 return (0);
1654 for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1656 if (*ma > (2147483647))
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);
1666 else if (*ma < (-2147483647 - 1))
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);
1676 *q = (int32_t)(*ma);
1679 o = TIFFWriteDirectoryTagCheckedSlongArray(tif, ndir, dir, tag, count, p);
1680 _TIFFfreeExt(tif, p);
1682 return (o);
1685 static int TIFFWriteDirectoryTagRational(TIFF *tif, uint32_t *ndir,
1686 TIFFDirEntry *dir, uint16_t tag,
1687 double value)
1689 if (dir == NULL)
1691 (*ndir)++;
1692 return (1);
1694 return (TIFFWriteDirectoryTagCheckedRational(tif, ndir, dir, tag, value));
1697 static int TIFFWriteDirectoryTagRationalArray(TIFF *tif, uint32_t *ndir,
1698 TIFFDirEntry *dir, uint16_t tag,
1699 uint32_t count, float *value)
1701 if (dir == NULL)
1703 (*ndir)++;
1704 return (1);
1706 return (TIFFWriteDirectoryTagCheckedRationalArray(tif, ndir, dir, tag,
1707 count, value));
1710 static int TIFFWriteDirectoryTagSrationalArray(TIFF *tif, uint32_t *ndir,
1711 TIFFDirEntry *dir, uint16_t tag,
1712 uint32_t count, float *value)
1714 if (dir == NULL)
1716 (*ndir)++;
1717 return (1);
1719 return (TIFFWriteDirectoryTagCheckedSrationalArray(tif, ndir, dir, tag,
1720 count, value));
1723 /*-- Rational2Double: additional write functions */
1724 static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF *tif, uint32_t *ndir,
1725 TIFFDirEntry *dir,
1726 uint16_t tag,
1727 uint32_t count,
1728 double *value)
1730 if (dir == NULL)
1732 (*ndir)++;
1733 return (1);
1735 return (TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif, ndir, dir, tag,
1736 count, value));
1739 static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF *tif, uint32_t *ndir,
1740 TIFFDirEntry *dir,
1741 uint16_t tag,
1742 uint32_t count,
1743 double *value)
1745 if (dir == NULL)
1747 (*ndir)++;
1748 return (1);
1750 return (TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
1751 tif, ndir, dir, tag, count, value));
1754 static int TIFFWriteDirectoryTagFloatArray(TIFF *tif, uint32_t *ndir,
1755 TIFFDirEntry *dir, uint16_t tag,
1756 uint32_t count, float *value)
1758 if (dir == NULL)
1760 (*ndir)++;
1761 return (1);
1763 return (TIFFWriteDirectoryTagCheckedFloatArray(tif, ndir, dir, tag, count,
1764 value));
1767 static int TIFFWriteDirectoryTagDoubleArray(TIFF *tif, uint32_t *ndir,
1768 TIFFDirEntry *dir, uint16_t tag,
1769 uint32_t count, double *value)
1771 if (dir == NULL)
1773 (*ndir)++;
1774 return (1);
1776 return (TIFFWriteDirectoryTagCheckedDoubleArray(tif, ndir, dir, tag, count,
1777 value));
1780 static int TIFFWriteDirectoryTagIfdArray(TIFF *tif, uint32_t *ndir,
1781 TIFFDirEntry *dir, uint16_t tag,
1782 uint32_t count, uint32_t *value)
1784 if (dir == NULL)
1786 (*ndir)++;
1787 return (1);
1789 return (TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count,
1790 value));
1793 static int TIFFWriteDirectoryTagShortLong(TIFF *tif, uint32_t *ndir,
1794 TIFFDirEntry *dir, uint16_t tag,
1795 uint32_t value)
1797 if (dir == NULL)
1799 (*ndir)++;
1800 return (1);
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));
1809 static int _WriteAsType(TIFF *tif, uint64_t strile_size,
1810 uint64_t uncompressed_threshold)
1812 const uint16_t compression = tif->tif_dir.td_compression;
1813 if (compression == COMPRESSION_NONE)
1815 return strile_size > uncompressed_threshold;
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)
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;
1831 return 1;
1834 static int WriteAsLong8(TIFF *tif, uint64_t strile_size)
1836 return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
1839 static int WriteAsLong4(TIFF *tif, uint64_t strile_size)
1841 return _WriteAsType(tif, strile_size, 0xFFFFU);
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 /************************************************************************/
1851 static int TIFFWriteDirectoryTagLongLong8Array(TIFF *tif, uint32_t *ndir,
1852 TIFFDirEntry *dir, uint16_t tag,
1853 uint32_t count, uint64_t *value)
1855 static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
1856 int o;
1857 int write_aslong4;
1859 /* is this just a counting pass? */
1860 if (dir == NULL)
1862 (*ndir)++;
1863 return (1);
1866 if (tif->tif_dir.td_deferstrilearraywriting)
1868 return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0,
1869 NULL);
1872 if (tif->tif_flags & TIFF_BIGTIFF)
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
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)
1883 write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
1885 else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1887 write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
1889 if (write_aslong8)
1891 return TIFFWriteDirectoryTagCheckedLong8Array(tif, ndir, dir, tag,
1892 count, value);
1896 write_aslong4 = 1;
1897 if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
1899 write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
1901 else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
1903 write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
1905 if (write_aslong4)
1908 ** For classic tiff we want to verify everything is in range for LONG
1909 ** and convert to long format.
1912 uint32_t *p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
1913 uint32_t *q;
1914 uint64_t *ma;
1915 uint32_t mb;
1917 if (p == NULL)
1919 TIFFErrorExtR(tif, module, "Out of memory");
1920 return (0);
1923 for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1925 if (*ma > 0xFFFFFFFF)
1927 TIFFErrorExtR(tif, module,
1928 "Attempt to write value larger than 0xFFFFFFFF "
1929 "in LONG array.");
1930 _TIFFfreeExt(tif, p);
1931 return (0);
1933 *q = (uint32_t)(*ma);
1936 o = TIFFWriteDirectoryTagCheckedLongArray(tif, ndir, dir, tag, count,
1938 _TIFFfreeExt(tif, p);
1940 else
1942 uint16_t *p = _TIFFmallocExt(tif, count * sizeof(uint16_t));
1943 uint16_t *q;
1944 uint64_t *ma;
1945 uint32_t mb;
1947 if (p == NULL)
1949 TIFFErrorExtR(tif, module, "Out of memory");
1950 return (0);
1953 for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
1955 if (*ma > 0xFFFF)
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);
1964 *q = (uint16_t)(*ma);
1967 o = TIFFWriteDirectoryTagCheckedShortArray(tif, ndir, dir, tag, count,
1969 _TIFFfreeExt(tif, p);
1972 return (o);
1975 /************************************************************************/
1976 /* TIFFWriteDirectoryTagIfdIfd8Array() */
1977 /* */
1978 /* Write either IFD8 or IFD array depending on file type. */
1979 /************************************************************************/
1981 static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF *tif, uint32_t *ndir,
1982 TIFFDirEntry *dir, uint16_t tag,
1983 uint32_t count, uint64_t *value)
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;
1992 /* is this just a counting pass? */
1993 if (dir == NULL)
1995 (*ndir)++;
1996 return (1);
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);
2005 ** For classic tiff we want to verify everything is in range for IFD
2006 ** and convert to long format.
2009 p = _TIFFmallocExt(tif, count * sizeof(uint32_t));
2010 if (p == NULL)
2012 TIFFErrorExtR(tif, module, "Out of memory");
2013 return (0);
2016 for (q = p, ma = value, mb = 0; mb < count; ma++, mb++, q++)
2018 if (*ma > 0xFFFFFFFF)
2020 TIFFErrorExtR(tif, module,
2021 "Attempt to write value larger than 0xFFFFFFFF in "
2022 "Classic TIFF file.");
2023 _TIFFfreeExt(tif, p);
2024 return (0);
2026 *q = (uint32_t)(*ma);
2029 o = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, tag, count, p);
2030 _TIFFfreeExt(tif, p);
2032 return (o);
2035 static int TIFFWriteDirectoryTagColormap(TIFF *tif, uint32_t *ndir,
2036 TIFFDirEntry *dir)
2038 static const char module[] = "TIFFWriteDirectoryTagColormap";
2039 uint32_t m;
2040 uint16_t *n;
2041 int o;
2042 if (dir == NULL)
2044 (*ndir)++;
2045 return (1);
2047 m = (1 << tif->tif_dir.td_bitspersample);
2048 n = _TIFFmallocExt(tif, 3 * m * sizeof(uint16_t));
2049 if (n == NULL)
2051 TIFFErrorExtR(tif, module, "Out of memory");
2052 return (0);
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);
2063 static int TIFFWriteDirectoryTagTransferfunction(TIFF *tif, uint32_t *ndir,
2064 TIFFDirEntry *dir)
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)
2073 (*ndir)++;
2074 return (1);
2076 /* TIFFTAG_TRANSFERFUNCTION expects (1 or 3) pointer to arrays with
2077 * (1 << BitsPerSample) * uint16_t values.
2079 m = (1 << tif->tif_dir.td_bitspersample);
2080 /* clang-format off */
2081 n = (tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples) > 1 ? 3 : 1;
2082 /* clang-format on */
2084 /* Check for proper number of transferfunctions */
2085 for (int i = 0; i < n; i++)
2087 if (tif->tif_dir.td_transferfunction[i] == NULL)
2089 TIFFWarningExtR(
2090 tif, module,
2091 "Too few TransferFunctions provided. Tag not written to file");
2092 return (1); /* Not an error; only tag is not written. */
2096 * Check if the table can be written as a single column,
2097 * or if it must be written as 3 columns. Note that we
2098 * write a 3-column tag if there are 2 samples/pixel and
2099 * a single column of data won't suffice--hmm.
2101 if (n == 3)
2103 if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2104 tif->tif_dir.td_transferfunction[2],
2105 m * sizeof(uint16_t)) &&
2106 !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],
2107 tif->tif_dir.td_transferfunction[1],
2108 m * sizeof(uint16_t)))
2109 n = 1;
2111 o = _TIFFmallocExt(tif, n * m * sizeof(uint16_t));
2112 if (o == NULL)
2114 TIFFErrorExtR(tif, module, "Out of memory");
2115 return (0);
2117 _TIFFmemcpy(&o[0], tif->tif_dir.td_transferfunction[0],
2118 m * sizeof(uint16_t));
2119 if (n > 1)
2120 _TIFFmemcpy(&o[m], tif->tif_dir.td_transferfunction[1],
2121 m * sizeof(uint16_t));
2122 if (n > 2)
2123 _TIFFmemcpy(&o[2 * m], tif->tif_dir.td_transferfunction[2],
2124 m * sizeof(uint16_t));
2125 p = TIFFWriteDirectoryTagCheckedShortArray(
2126 tif, ndir, dir, TIFFTAG_TRANSFERFUNCTION, n * m, o);
2127 _TIFFfreeExt(tif, o);
2128 return (p);
2131 static int TIFFWriteDirectoryTagSubifd(TIFF *tif, uint32_t *ndir,
2132 TIFFDirEntry *dir)
2134 static const char module[] = "TIFFWriteDirectoryTagSubifd";
2135 uint64_t m;
2136 int n;
2137 if (tif->tif_dir.td_nsubifd == 0)
2138 return (1);
2139 if (dir == NULL)
2141 (*ndir)++;
2142 return (1);
2144 m = tif->tif_dataoff;
2145 if (!(tif->tif_flags & TIFF_BIGTIFF))
2147 uint32_t *o;
2148 uint64_t *pa;
2149 uint32_t *pb;
2150 uint16_t p;
2151 o = _TIFFmallocExt(tif, tif->tif_dir.td_nsubifd * sizeof(uint32_t));
2152 if (o == NULL)
2154 TIFFErrorExtR(tif, module, "Out of memory");
2155 return (0);
2157 pa = tif->tif_dir.td_subifd;
2158 pb = o;
2159 for (p = 0; p < tif->tif_dir.td_nsubifd; p++)
2161 assert(pa != 0);
2163 /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which
2164 * is illegal) */
2165 if (*pa > 0xFFFFFFFFUL)
2167 TIFFErrorExtR(tif, module, "Illegal value for SubIFD tag");
2168 _TIFFfreeExt(tif, o);
2169 return (0);
2171 *pb++ = (uint32_t)(*pa++);
2173 n = TIFFWriteDirectoryTagCheckedIfdArray(tif, ndir, dir, TIFFTAG_SUBIFD,
2174 tif->tif_dir.td_nsubifd, o);
2175 _TIFFfreeExt(tif, o);
2177 else
2178 n = TIFFWriteDirectoryTagCheckedIfd8Array(
2179 tif, ndir, dir, TIFFTAG_SUBIFD, tif->tif_dir.td_nsubifd,
2180 tif->tif_dir.td_subifd);
2181 if (!n)
2182 return (0);
2184 * Total hack: if this directory includes a SubIFD
2185 * tag then force the next <n> directories to be
2186 * written as ``sub directories'' of this one. This
2187 * is used to write things like thumbnails and
2188 * image masks that one wants to keep out of the
2189 * normal directory linkage access mechanism.
2191 tif->tif_flags |= TIFF_INSUBIFD;
2192 tif->tif_nsubifd = tif->tif_dir.td_nsubifd;
2193 if (tif->tif_dir.td_nsubifd == 1)
2194 tif->tif_subifdoff = 0;
2195 else
2196 tif->tif_subifdoff = m;
2197 return (1);
2200 static int TIFFWriteDirectoryTagCheckedAscii(TIFF *tif, uint32_t *ndir,
2201 TIFFDirEntry *dir, uint16_t tag,
2202 uint32_t count, char *value)
2204 assert(sizeof(char) == 1);
2205 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_ASCII, count,
2206 count, value));
2209 static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF *tif, uint32_t *ndir,
2210 TIFFDirEntry *dir,
2211 uint16_t tag,
2212 uint32_t count,
2213 uint8_t *value)
2215 assert(sizeof(uint8_t) == 1);
2216 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_UNDEFINED,
2217 count, count, value));
2220 static int TIFFWriteDirectoryTagCheckedByteArray(TIFF *tif, uint32_t *ndir,
2221 TIFFDirEntry *dir,
2222 uint16_t tag, uint32_t count,
2223 uint8_t *value)
2225 assert(sizeof(uint8_t) == 1);
2226 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_BYTE, count,
2227 count, value));
2230 static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF *tif, uint32_t *ndir,
2231 TIFFDirEntry *dir,
2232 uint16_t tag, uint32_t count,
2233 int8_t *value)
2235 assert(sizeof(int8_t) == 1);
2236 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SBYTE, count,
2237 count, value));
2240 static int TIFFWriteDirectoryTagCheckedShort(TIFF *tif, uint32_t *ndir,
2241 TIFFDirEntry *dir, uint16_t tag,
2242 uint16_t value)
2244 uint16_t m;
2245 assert(sizeof(uint16_t) == 2);
2246 m = value;
2247 if (tif->tif_flags & TIFF_SWAB)
2248 TIFFSwabShort(&m);
2249 return (
2250 TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, 1, 2, &m));
2253 static int TIFFWriteDirectoryTagCheckedShortArray(TIFF *tif, uint32_t *ndir,
2254 TIFFDirEntry *dir,
2255 uint16_t tag, uint32_t count,
2256 uint16_t *value)
2258 assert(count < 0x80000000);
2259 assert(sizeof(uint16_t) == 2);
2260 if (tif->tif_flags & TIFF_SWAB)
2261 TIFFSwabArrayOfShort(value, count);
2262 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SHORT, count,
2263 count * 2, value));
2266 static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF *tif, uint32_t *ndir,
2267 TIFFDirEntry *dir,
2268 uint16_t tag, uint32_t count,
2269 int16_t *value)
2271 assert(count < 0x80000000);
2272 assert(sizeof(int16_t) == 2);
2273 if (tif->tif_flags & TIFF_SWAB)
2274 TIFFSwabArrayOfShort((uint16_t *)value, count);
2275 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SSHORT, count,
2276 count * 2, value));
2279 static int TIFFWriteDirectoryTagCheckedLong(TIFF *tif, uint32_t *ndir,
2280 TIFFDirEntry *dir, uint16_t tag,
2281 uint32_t value)
2283 uint32_t m;
2284 assert(sizeof(uint32_t) == 4);
2285 m = value;
2286 if (tif->tif_flags & TIFF_SWAB)
2287 TIFFSwabLong(&m);
2288 return (
2289 TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, 1, 4, &m));
2292 static int TIFFWriteDirectoryTagCheckedLongArray(TIFF *tif, uint32_t *ndir,
2293 TIFFDirEntry *dir,
2294 uint16_t tag, uint32_t count,
2295 uint32_t *value)
2297 assert(count < 0x40000000);
2298 assert(sizeof(uint32_t) == 4);
2299 if (tif->tif_flags & TIFF_SWAB)
2300 TIFFSwabArrayOfLong(value, count);
2301 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG, count,
2302 count * 4, value));
2305 static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF *tif, uint32_t *ndir,
2306 TIFFDirEntry *dir,
2307 uint16_t tag, uint32_t count,
2308 int32_t *value)
2310 assert(count < 0x40000000);
2311 assert(sizeof(int32_t) == 4);
2312 if (tif->tif_flags & TIFF_SWAB)
2313 TIFFSwabArrayOfLong((uint32_t *)value, count);
2314 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG, count,
2315 count * 4, value));
2318 static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF *tif, uint32_t *ndir,
2319 TIFFDirEntry *dir,
2320 uint16_t tag, uint32_t count,
2321 uint64_t *value)
2323 assert(count < 0x20000000);
2324 assert(sizeof(uint64_t) == 8);
2325 if (!(tif->tif_flags & TIFF_BIGTIFF))
2327 TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedLong8Array",
2328 "LONG8 not allowed for ClassicTIFF");
2329 return (0);
2331 if (tif->tif_flags & TIFF_SWAB)
2332 TIFFSwabArrayOfLong8(value, count);
2333 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_LONG8, count,
2334 count * 8, value));
2337 static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF *tif, uint32_t *ndir,
2338 TIFFDirEntry *dir,
2339 uint16_t tag, uint32_t count,
2340 int64_t *value)
2342 assert(count < 0x20000000);
2343 assert(sizeof(int64_t) == 8);
2344 if (!(tif->tif_flags & TIFF_BIGTIFF))
2346 TIFFErrorExtR(tif, "TIFFWriteDirectoryTagCheckedSlong8Array",
2347 "SLONG8 not allowed for ClassicTIFF");
2348 return (0);
2350 if (tif->tif_flags & TIFF_SWAB)
2351 TIFFSwabArrayOfLong8((uint64_t *)value, count);
2352 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SLONG8, count,
2353 count * 8, value));
2356 static int TIFFWriteDirectoryTagCheckedRational(TIFF *tif, uint32_t *ndir,
2357 TIFFDirEntry *dir, uint16_t tag,
2358 double value)
2360 static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
2361 uint32_t m[2];
2362 assert(sizeof(uint32_t) == 4);
2363 if (value < 0)
2365 TIFFErrorExtR(tif, module, "Negative value is illegal");
2366 return 0;
2368 else if (value != value)
2370 TIFFErrorExtR(tif, module, "Not-a-number value is illegal");
2371 return 0;
2373 /*--Rational2Double: New function also used for non-custom rational tags.
2374 * However, could be omitted here, because
2375 * TIFFWriteDirectoryTagCheckedRational() is not used by code for custom
2376 * tags, only by code for named-tiff-tags like FIELD_RESOLUTION and
2377 * FIELD_POSITION */
2378 else
2380 DoubleToRational(value, &m[0], &m[1]);
2383 if (tif->tif_flags & TIFF_SWAB)
2385 TIFFSwabLong(&m[0]);
2386 TIFFSwabLong(&m[1]);
2388 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, 1, 8,
2389 &m[0]));
2392 static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF *tif, uint32_t *ndir,
2393 TIFFDirEntry *dir,
2394 uint16_t tag,
2395 uint32_t count,
2396 float *value)
2398 static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
2399 uint32_t *m;
2400 float *na;
2401 uint32_t *nb;
2402 uint32_t nc;
2403 int o;
2404 assert(sizeof(uint32_t) == 4);
2405 m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2406 if (m == NULL)
2408 TIFFErrorExtR(tif, module, "Out of memory");
2409 return (0);
2411 for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2413 DoubleToRational(*na, &nb[0], &nb[1]);
2415 if (tif->tif_flags & TIFF_SWAB)
2416 TIFFSwabArrayOfLong(m, count * 2);
2417 o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2418 count * 8, &m[0]);
2419 _TIFFfreeExt(tif, m);
2420 return (o);
2423 static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF *tif, uint32_t *ndir,
2424 TIFFDirEntry *dir,
2425 uint16_t tag,
2426 uint32_t count,
2427 float *value)
2429 static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
2430 int32_t *m;
2431 float *na;
2432 int32_t *nb;
2433 uint32_t nc;
2434 int o;
2435 assert(sizeof(int32_t) == 4);
2436 m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2437 if (m == NULL)
2439 TIFFErrorExtR(tif, module, "Out of memory");
2440 return (0);
2442 for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2444 DoubleToSrational(*na, &nb[0], &nb[1]);
2446 if (tif->tif_flags & TIFF_SWAB)
2447 TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2448 o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2449 count * 8, &m[0]);
2450 _TIFFfreeExt(tif, m);
2451 return (o);
2454 /*-- Rational2Double: additional write functions for double arrays */
2455 static int
2456 TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF *tif, uint32_t *ndir,
2457 TIFFDirEntry *dir, uint16_t tag,
2458 uint32_t count, double *value)
2460 static const char module[] =
2461 "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
2462 uint32_t *m;
2463 double *na;
2464 uint32_t *nb;
2465 uint32_t nc;
2466 int o;
2467 assert(sizeof(uint32_t) == 4);
2468 m = _TIFFmallocExt(tif, count * 2 * sizeof(uint32_t));
2469 if (m == NULL)
2471 TIFFErrorExtR(tif, module, "Out of memory");
2472 return (0);
2474 for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2476 DoubleToRational(*na, &nb[0], &nb[1]);
2478 if (tif->tif_flags & TIFF_SWAB)
2479 TIFFSwabArrayOfLong(m, count * 2);
2480 o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_RATIONAL, count,
2481 count * 8, &m[0]);
2482 _TIFFfreeExt(tif, m);
2483 return (o);
2484 } /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
2486 static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(
2487 TIFF *tif, uint32_t *ndir, TIFFDirEntry *dir, uint16_t tag, uint32_t count,
2488 double *value)
2490 static const char module[] =
2491 "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
2492 int32_t *m;
2493 double *na;
2494 int32_t *nb;
2495 uint32_t nc;
2496 int o;
2497 assert(sizeof(int32_t) == 4);
2498 m = _TIFFmallocExt(tif, count * 2 * sizeof(int32_t));
2499 if (m == NULL)
2501 TIFFErrorExtR(tif, module, "Out of memory");
2502 return (0);
2504 for (na = value, nb = m, nc = 0; nc < count; na++, nb += 2, nc++)
2506 DoubleToSrational(*na, &nb[0], &nb[1]);
2508 if (tif->tif_flags & TIFF_SWAB)
2509 TIFFSwabArrayOfLong((uint32_t *)m, count * 2);
2510 o = TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_SRATIONAL, count,
2511 count * 8, &m[0]);
2512 _TIFFfreeExt(tif, m);
2513 return (o);
2514 } /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
2516 /** ----- Rational2Double: Double To Rational Conversion
2517 ----------------------------------------------------------
2518 * There is a mathematical theorem to convert real numbers into a rational
2519 (integer fraction) number.
2520 * This is called "continuous fraction" which uses the Euclidean algorithm to
2521 find the greatest common divisor (GCD).
2522 * (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or
2523 https://en.wikipedia.org/wiki/Continued_fraction
2524 * https://en.wikipedia.org/wiki/Euclidean_algorithm)
2525 * The following functions implement the
2526 * - ToRationalEuclideanGCD() auxiliary function which mainly
2527 implements euclidean GCD
2528 * - DoubleToRational() conversion function for un-signed
2529 rationals
2530 * - DoubleToSrational() conversion function for signed rationals
2531 ------------------------------------------------------------------------------------------------------------------*/
2533 /**---- ToRationalEuclideanGCD() -----------------------------------------
2534 * Calculates the rational fractional of a double input value
2535 * using the Euclidean algorithm to find the greatest common divisor (GCD)
2536 ------------------------------------------------------------------------*/
2537 static void ToRationalEuclideanGCD(double value, int blnUseSignedRange,
2538 int blnUseSmallRange, uint64_t *ullNum,
2539 uint64_t *ullDenom)
2541 /* Internally, the integer variables can be bigger than the external ones,
2542 * as long as the result will fit into the external variable size.
2544 uint64_t numSum[3] = {0, 1, 0}, denomSum[3] = {1, 0, 0};
2545 uint64_t aux, bigNum, bigDenom;
2546 uint64_t returnLimit;
2547 int i;
2548 uint64_t nMax;
2549 double fMax;
2550 unsigned long maxDenom;
2551 /*-- nMax and fMax defines the initial accuracy of the starting fractional,
2552 * or better, the highest used integer numbers used within the starting
2553 * fractional (bigNum/bigDenom). There are two approaches, which can
2554 * accidentally lead to different accuracies just depending on the value.
2555 * Therefore, blnUseSmallRange steers this behavior.
2556 * For long long nMax = ((9223372036854775807-1)/2); for long nMax =
2557 * ((2147483647-1)/2);
2559 if (blnUseSmallRange)
2561 nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
2563 else
2565 nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
2567 fMax = (double)nMax;
2569 /*-- For the Euclidean GCD define the denominator range, so that it stays
2570 * within size of unsigned long variables. maxDenom should be LONG_MAX for
2571 * negative values and ULONG_MAX for positive ones. Also the final returned
2572 * value of ullNum and ullDenom is limited according to signed- or
2573 * unsigned-range.
2575 if (blnUseSignedRange)
2577 maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
2578 returnLimit = maxDenom;
2580 else
2582 maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
2583 returnLimit = maxDenom;
2586 /*-- First generate a rational fraction (bigNum/bigDenom) which represents
2587 *the value as a rational number with the highest accuracy. Therefore,
2588 *uint64_t (uint64_t) is needed. This rational fraction is then reduced
2589 *using the Euclidean algorithm to find the greatest common divisor (GCD).
2590 * bigNum = big numinator of value without fraction (or cut residual
2591 *fraction) bigDenom = big denominator of value
2592 *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error
2593 *and bigDenom has no overflow, and stop with enlargement of fraction when
2594 *the double-value of it reaches an integer number without fractional part.
2596 bigDenom = 1;
2597 while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax))
2599 bigDenom <<= 1;
2600 value *= 2;
2602 bigNum = (uint64_t)value;
2604 /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) --
2606 #define MAX_ITERATIONS 64
2607 for (i = 0; i < MAX_ITERATIONS; i++)
2609 uint64_t val;
2610 /* if bigDenom is not zero, calculate integer part of fraction. */
2611 if (bigDenom == 0)
2613 break;
2615 val = bigNum / bigDenom;
2617 /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous
2618 * denominator bigDenom. */
2619 aux = bigNum;
2620 bigNum = bigDenom;
2621 bigDenom = aux % bigDenom;
2623 /* calculate next denominator and check for its given maximum */
2624 aux = val;
2625 if (denomSum[1] * val + denomSum[0] >= maxDenom)
2627 aux = (maxDenom - denomSum[0]) / denomSum[1];
2628 if (aux * 2 >= val || denomSum[1] >= maxDenom)
2629 i = (MAX_ITERATIONS +
2630 1); /* exit but execute rest of for-loop */
2631 else
2632 break;
2634 /* calculate next numerator to numSum2 and save previous one to numSum0;
2635 * numSum1 just copy of numSum2. */
2636 numSum[2] = aux * numSum[1] + numSum[0];
2637 numSum[0] = numSum[1];
2638 numSum[1] = numSum[2];
2639 /* calculate next denominator to denomSum2 and save previous one to
2640 * denomSum0; denomSum1 just copy of denomSum2. */
2641 denomSum[2] = aux * denomSum[1] + denomSum[0];
2642 denomSum[0] = denomSum[1];
2643 denomSum[1] = denomSum[2];
2646 /*-- Check and adapt for final variable size and return values; reduces
2647 * internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
2648 while (numSum[1] > returnLimit || denomSum[1] > returnLimit)
2650 numSum[1] = numSum[1] / 2;
2651 denomSum[1] = denomSum[1] / 2;
2654 /* return values */
2655 *ullNum = numSum[1];
2656 *ullDenom = denomSum[1];
2658 } /*-- ToRationalEuclideanGCD() -------------- */
2660 /**---- DoubleToRational() -----------------------------------------------
2661 * Calculates the rational fractional of a double input value
2662 * for UN-SIGNED rationals,
2663 * using the Euclidean algorithm to find the greatest common divisor (GCD)
2664 ------------------------------------------------------------------------*/
2665 static void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
2667 /*---- UN-SIGNED RATIONAL ---- */
2668 double dblDiff, dblDiff2;
2669 uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2671 /*-- Check for negative values. If so it is an error. */
2672 /* Test written that way to catch NaN */
2673 if (!(value >= 0))
2675 *num = *denom = 0;
2676 TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2677 " Negative Value for Unsigned Rational given.");
2678 return;
2681 /*-- Check for too big numbers (> ULONG_MAX) -- */
2682 if (value > 0xFFFFFFFFUL)
2684 *num = 0xFFFFFFFFU;
2685 *denom = 0;
2686 return;
2688 /*-- Check for easy integer numbers -- */
2689 if (value == (uint32_t)(value))
2691 *num = (uint32_t)value;
2692 *denom = 1;
2693 return;
2695 /*-- Check for too small numbers for "unsigned long" type rationals -- */
2696 if (value < 1.0 / (double)0xFFFFFFFFUL)
2698 *num = 0;
2699 *denom = 0xFFFFFFFFU;
2700 return;
2703 /*-- There are two approaches using the Euclidean algorithm,
2704 * which can accidentally lead to different accuracies just depending on
2705 * the value. Try both and define which one was better.
2707 ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
2708 ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
2709 /*-- Double-Check, that returned values fit into ULONG :*/
2710 if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL ||
2711 ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL)
2713 TIFFErrorExt(0, "TIFFLib: DoubleToRational()",
2714 " Num or Denom exceeds ULONG: val=%14.6f, num=%12" PRIu64
2715 ", denom=%12" PRIu64 " | num2=%12" PRIu64
2716 ", denom2=%12" PRIu64 "",
2717 value, ullNum, ullDenom, ullNum2, ullDenom2);
2718 assert(0);
2721 /* Check, which one has higher accuracy and take that. */
2722 dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2723 dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2724 if (dblDiff < dblDiff2)
2726 *num = (uint32_t)ullNum;
2727 *denom = (uint32_t)ullDenom;
2729 else
2731 *num = (uint32_t)ullNum2;
2732 *denom = (uint32_t)ullDenom2;
2734 } /*-- DoubleToRational() -------------- */
2736 /**---- DoubleToSrational() -----------------------------------------------
2737 * Calculates the rational fractional of a double input value
2738 * for SIGNED rationals,
2739 * using the Euclidean algorithm to find the greatest common divisor (GCD)
2740 ------------------------------------------------------------------------*/
2741 static void DoubleToSrational(double value, int32_t *num, int32_t *denom)
2743 /*---- SIGNED RATIONAL ----*/
2744 int neg = 1;
2745 double dblDiff, dblDiff2;
2746 uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
2748 /*-- Check for negative values and use then the positive one for internal
2749 * calculations, but take the sign into account before returning. */
2750 if (value < 0)
2752 neg = -1;
2753 value = -value;
2756 /*-- Check for too big numbers (> LONG_MAX) -- */
2757 if (value > 0x7FFFFFFFL)
2759 *num = 0x7FFFFFFFL;
2760 *denom = 0;
2761 return;
2763 /*-- Check for easy numbers -- */
2764 if (value == (int32_t)(value))
2766 *num = (int32_t)(neg * value);
2767 *denom = 1;
2768 return;
2770 /*-- Check for too small numbers for "long" type rationals -- */
2771 if (value < 1.0 / (double)0x7FFFFFFFL)
2773 *num = 0;
2774 *denom = 0x7FFFFFFFL;
2775 return;
2778 /*-- There are two approaches using the Euclidean algorithm,
2779 * which can accidentally lead to different accuracies just depending on
2780 * the value. Try both and define which one was better. Furthermore, set
2781 * behavior of ToRationalEuclideanGCD() to the range of signed-long.
2783 ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
2784 ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
2785 /*-- Double-Check, that returned values fit into LONG :*/
2786 if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL ||
2787 ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL)
2789 TIFFErrorExt(0, "TIFFLib: DoubleToSrational()",
2790 " Num or Denom exceeds LONG: val=%14.6f, num=%12" PRIu64
2791 ", denom=%12" PRIu64 " | num2=%12" PRIu64
2792 ", denom2=%12" PRIu64 "",
2793 neg * value, ullNum, ullDenom, ullNum2, ullDenom2);
2794 assert(0);
2797 /* Check, which one has higher accuracy and take that. */
2798 dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
2799 dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
2800 if (dblDiff < dblDiff2)
2802 *num = (int32_t)(neg * (long)ullNum);
2803 *denom = (int32_t)ullDenom;
2805 else
2807 *num = (int32_t)(neg * (long)ullNum2);
2808 *denom = (int32_t)ullDenom2;
2810 } /*-- DoubleToSrational() --------------*/
2812 static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF *tif, uint32_t *ndir,
2813 TIFFDirEntry *dir,
2814 uint16_t tag, uint32_t count,
2815 float *value)
2817 assert(count < 0x40000000);
2818 assert(sizeof(float) == 4);
2819 TIFFCvtNativeToIEEEFloat(tif, count, &value);
2820 if (tif->tif_flags & TIFF_SWAB)
2821 TIFFSwabArrayOfFloat(value, count);
2822 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_FLOAT, count,
2823 count * 4, value));
2826 static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF *tif, uint32_t *ndir,
2827 TIFFDirEntry *dir,
2828 uint16_t tag, uint32_t count,
2829 double *value)
2831 assert(count < 0x20000000);
2832 assert(sizeof(double) == 8);
2833 TIFFCvtNativeToIEEEDouble(tif, count, &value);
2834 if (tif->tif_flags & TIFF_SWAB)
2835 TIFFSwabArrayOfDouble(value, count);
2836 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_DOUBLE, count,
2837 count * 8, value));
2840 static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF *tif, uint32_t *ndir,
2841 TIFFDirEntry *dir, uint16_t tag,
2842 uint32_t count, uint32_t *value)
2844 assert(count < 0x40000000);
2845 assert(sizeof(uint32_t) == 4);
2846 if (tif->tif_flags & TIFF_SWAB)
2847 TIFFSwabArrayOfLong(value, count);
2848 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD, count,
2849 count * 4, value));
2852 static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF *tif, uint32_t *ndir,
2853 TIFFDirEntry *dir,
2854 uint16_t tag, uint32_t count,
2855 uint64_t *value)
2857 assert(count < 0x20000000);
2858 assert(sizeof(uint64_t) == 8);
2859 assert(tif->tif_flags & TIFF_BIGTIFF);
2860 if (tif->tif_flags & TIFF_SWAB)
2861 TIFFSwabArrayOfLong8(value, count);
2862 return (TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_IFD8, count,
2863 count * 8, value));
2866 static int TIFFWriteDirectoryTagData(TIFF *tif, uint32_t *ndir,
2867 TIFFDirEntry *dir, uint16_t tag,
2868 uint16_t datatype, uint32_t count,
2869 uint32_t datalength, void *data)
2871 static const char module[] = "TIFFWriteDirectoryTagData";
2872 uint32_t m;
2873 m = 0;
2874 while (m < (*ndir))
2876 assert(dir[m].tdir_tag != tag);
2877 if (dir[m].tdir_tag > tag)
2878 break;
2879 m++;
2881 if (m < (*ndir))
2883 uint32_t n;
2884 for (n = *ndir; n > m; n--)
2885 dir[n] = dir[n - 1];
2887 dir[m].tdir_tag = tag;
2888 dir[m].tdir_type = datatype;
2889 dir[m].tdir_count = count;
2890 dir[m].tdir_offset.toff_long8 = 0;
2891 if (datalength <= ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
2893 if (data && datalength)
2895 _TIFFmemcpy(&dir[m].tdir_offset, data, datalength);
2898 else
2900 uint64_t na, nb;
2901 na = tif->tif_dataoff;
2902 nb = na + datalength;
2903 if (!(tif->tif_flags & TIFF_BIGTIFF))
2904 nb = (uint32_t)nb;
2905 if ((nb < na) || (nb < datalength))
2907 TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
2908 return (0);
2910 if (!SeekOK(tif, na))
2912 TIFFErrorExtR(tif, module, "IO error writing tag data");
2913 return (0);
2915 if (datalength >= 0x80000000UL)
2917 TIFFErrorExtR(tif, module,
2918 "libtiff does not allow writing more than 2147483647 "
2919 "bytes in a tag");
2920 return (0);
2922 if (!WriteOK(tif, data, (tmsize_t)datalength))
2924 TIFFErrorExtR(tif, module, "IO error writing tag data");
2925 return (0);
2927 tif->tif_dataoff = nb;
2928 if (tif->tif_dataoff & 1)
2929 tif->tif_dataoff++;
2930 if (!(tif->tif_flags & TIFF_BIGTIFF))
2932 uint32_t o;
2933 o = (uint32_t)na;
2934 if (tif->tif_flags & TIFF_SWAB)
2935 TIFFSwabLong(&o);
2936 _TIFFmemcpy(&dir[m].tdir_offset, &o, 4);
2938 else
2940 dir[m].tdir_offset.toff_long8 = na;
2941 if (tif->tif_flags & TIFF_SWAB)
2942 TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
2945 (*ndir)++;
2946 return (1);
2950 * Link the current directory into the directory chain for the file.
2952 static int TIFFLinkDirectory(TIFF *tif)
2954 static const char module[] = "TIFFLinkDirectory";
2956 tif->tif_diroff = (TIFFSeekFile(tif, 0, SEEK_END) + 1) & (~((toff_t)1));
2959 * Handle SubIFDs
2961 if (tif->tif_flags & TIFF_INSUBIFD)
2963 if (!(tif->tif_flags & TIFF_BIGTIFF))
2965 uint32_t m;
2966 m = (uint32_t)tif->tif_diroff;
2967 if (tif->tif_flags & TIFF_SWAB)
2968 TIFFSwabLong(&m);
2969 (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2970 if (!WriteOK(tif, &m, 4))
2972 TIFFErrorExtR(tif, module,
2973 "Error writing SubIFD directory link");
2974 return (0);
2977 * Advance to the next SubIFD or, if this is
2978 * the last one configured, revert back to the
2979 * normal directory linkage.
2981 if (--tif->tif_nsubifd)
2982 tif->tif_subifdoff += 4;
2983 else
2984 tif->tif_flags &= ~TIFF_INSUBIFD;
2985 return (1);
2987 else
2989 uint64_t m;
2990 m = tif->tif_diroff;
2991 if (tif->tif_flags & TIFF_SWAB)
2992 TIFFSwabLong8(&m);
2993 (void)TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
2994 if (!WriteOK(tif, &m, 8))
2996 TIFFErrorExtR(tif, module,
2997 "Error writing SubIFD directory link");
2998 return (0);
3001 * Advance to the next SubIFD or, if this is
3002 * the last one configured, revert back to the
3003 * normal directory linkage.
3005 if (--tif->tif_nsubifd)
3006 tif->tif_subifdoff += 8;
3007 else
3008 tif->tif_flags &= ~TIFF_INSUBIFD;
3009 return (1);
3013 if (!(tif->tif_flags & TIFF_BIGTIFF))
3015 uint32_t m;
3016 uint32_t nextdir;
3017 m = (uint32_t)(tif->tif_diroff);
3018 if (tif->tif_flags & TIFF_SWAB)
3019 TIFFSwabLong(&m);
3020 if (tif->tif_header.classic.tiff_diroff == 0)
3023 * First directory, overwrite offset in header.
3025 tif->tif_header.classic.tiff_diroff = (uint32_t)tif->tif_diroff;
3026 tif->tif_lastdiroff = tif->tif_diroff;
3027 (void)TIFFSeekFile(tif, 4, SEEK_SET);
3028 if (!WriteOK(tif, &m, 4))
3030 TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3031 return (0);
3033 return (1);
3036 * Not the first directory, search to the last and append.
3038 if (tif->tif_lastdiroff != 0)
3040 nextdir = (uint32_t)tif->tif_lastdiroff;
3042 else
3044 nextdir = tif->tif_header.classic.tiff_diroff;
3047 while (1)
3049 uint16_t dircount;
3050 uint32_t nextnextdir;
3052 if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount, 2))
3054 TIFFErrorExtR(tif, module, "Error fetching directory count");
3055 return (0);
3057 if (tif->tif_flags & TIFF_SWAB)
3058 TIFFSwabShort(&dircount);
3059 (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3060 if (!ReadOK(tif, &nextnextdir, 4))
3062 TIFFErrorExtR(tif, module, "Error fetching directory link");
3063 return (0);
3065 if (tif->tif_flags & TIFF_SWAB)
3066 TIFFSwabLong(&nextnextdir);
3067 if (nextnextdir == 0)
3069 (void)TIFFSeekFile(tif, nextdir + 2 + dircount * 12, SEEK_SET);
3070 if (!WriteOK(tif, &m, 4))
3072 TIFFErrorExtR(tif, module, "Error writing directory link");
3073 return (0);
3075 tif->tif_lastdiroff = tif->tif_diroff;
3076 break;
3078 nextdir = nextnextdir;
3081 else
3083 uint64_t m;
3084 uint64_t nextdir;
3085 m = tif->tif_diroff;
3086 if (tif->tif_flags & TIFF_SWAB)
3087 TIFFSwabLong8(&m);
3088 if (tif->tif_header.big.tiff_diroff == 0)
3091 * First directory, overwrite offset in header.
3093 tif->tif_header.big.tiff_diroff = tif->tif_diroff;
3094 tif->tif_lastdiroff = tif->tif_diroff;
3095 (void)TIFFSeekFile(tif, 8, SEEK_SET);
3096 if (!WriteOK(tif, &m, 8))
3098 TIFFErrorExtR(tif, tif->tif_name, "Error writing TIFF header");
3099 return (0);
3101 return (1);
3104 * Not the first directory, search to the last and append.
3106 if (tif->tif_lastdiroff != 0)
3108 nextdir = tif->tif_lastdiroff;
3110 else
3112 nextdir = tif->tif_header.big.tiff_diroff;
3114 while (1)
3116 uint64_t dircount64;
3117 uint16_t dircount;
3118 uint64_t nextnextdir;
3120 if (!SeekOK(tif, nextdir) || !ReadOK(tif, &dircount64, 8))
3122 TIFFErrorExtR(tif, module, "Error fetching directory count");
3123 return (0);
3125 if (tif->tif_flags & TIFF_SWAB)
3126 TIFFSwabLong8(&dircount64);
3127 if (dircount64 > 0xFFFF)
3129 TIFFErrorExtR(
3130 tif, module,
3131 "Sanity check on tag count failed, likely corrupt TIFF");
3132 return (0);
3134 dircount = (uint16_t)dircount64;
3135 (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3136 if (!ReadOK(tif, &nextnextdir, 8))
3138 TIFFErrorExtR(tif, module, "Error fetching directory link");
3139 return (0);
3141 if (tif->tif_flags & TIFF_SWAB)
3142 TIFFSwabLong8(&nextnextdir);
3143 if (nextnextdir == 0)
3145 (void)TIFFSeekFile(tif, nextdir + 8 + dircount * 20, SEEK_SET);
3146 if (!WriteOK(tif, &m, 8))
3148 TIFFErrorExtR(tif, module, "Error writing directory link");
3149 return (0);
3151 tif->tif_lastdiroff = tif->tif_diroff;
3152 break;
3154 nextdir = nextnextdir;
3157 return (1);
3160 /************************************************************************/
3161 /* TIFFRewriteField() */
3162 /* */
3163 /* Rewrite a field in the directory on disk without regard to */
3164 /* updating the TIFF directory structure in memory. Currently */
3165 /* only supported for field that already exist in the on-disk */
3166 /* directory. Mainly used for updating stripoffset / */
3167 /* stripbytecount values after the directory is already on */
3168 /* disk. */
3169 /* */
3170 /* Returns zero on failure, and one on success. */
3171 /************************************************************************/
3173 int _TIFFRewriteField(TIFF *tif, uint16_t tag, TIFFDataType in_datatype,
3174 tmsize_t count, void *data)
3176 static const char module[] = "TIFFResetField";
3177 /* const TIFFField* fip = NULL; */
3178 uint16_t dircount;
3179 tmsize_t dirsize;
3180 uint8_t direntry_raw[20];
3181 uint16_t entry_tag = 0;
3182 uint16_t entry_type = 0;
3183 uint64_t entry_count = 0;
3184 uint64_t entry_offset = 0;
3185 int value_in_entry = 0;
3186 uint64_t read_offset;
3187 uint8_t *buf_to_write = NULL;
3188 TIFFDataType datatype;
3190 /* -------------------------------------------------------------------- */
3191 /* Find field definition. */
3192 /* -------------------------------------------------------------------- */
3193 /*fip =*/TIFFFindField(tif, tag, TIFF_ANY);
3195 /* -------------------------------------------------------------------- */
3196 /* Do some checking this is a straight forward case. */
3197 /* -------------------------------------------------------------------- */
3198 if (isMapped(tif))
3200 TIFFErrorExtR(
3201 tif, module,
3202 "Memory mapped files not currently supported for this operation.");
3203 return 0;
3206 if (tif->tif_diroff == 0)
3208 TIFFErrorExtR(
3209 tif, module,
3210 "Attempt to reset field on directory not already on disk.");
3211 return 0;
3214 /* -------------------------------------------------------------------- */
3215 /* Read the directory entry count. */
3216 /* -------------------------------------------------------------------- */
3217 if (!SeekOK(tif, tif->tif_diroff))
3219 TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3220 tif->tif_name);
3221 return 0;
3224 read_offset = tif->tif_diroff;
3226 if (!(tif->tif_flags & TIFF_BIGTIFF))
3228 if (!ReadOK(tif, &dircount, sizeof(uint16_t)))
3230 TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3231 tif->tif_name);
3232 return 0;
3234 if (tif->tif_flags & TIFF_SWAB)
3235 TIFFSwabShort(&dircount);
3236 dirsize = 12;
3237 read_offset += 2;
3239 else
3241 uint64_t dircount64;
3242 if (!ReadOK(tif, &dircount64, sizeof(uint64_t)))
3244 TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory count",
3245 tif->tif_name);
3246 return 0;
3248 if (tif->tif_flags & TIFF_SWAB)
3249 TIFFSwabLong8(&dircount64);
3250 dircount = (uint16_t)dircount64;
3251 dirsize = 20;
3252 read_offset += 8;
3255 /* -------------------------------------------------------------------- */
3256 /* Read through directory to find target tag. */
3257 /* -------------------------------------------------------------------- */
3258 while (dircount > 0)
3260 if (!ReadOK(tif, direntry_raw, dirsize))
3262 TIFFErrorExtR(tif, module, "%s: Can not read TIFF directory entry.",
3263 tif->tif_name);
3264 return 0;
3267 memcpy(&entry_tag, direntry_raw + 0, sizeof(uint16_t));
3268 if (tif->tif_flags & TIFF_SWAB)
3269 TIFFSwabShort(&entry_tag);
3271 if (entry_tag == tag)
3272 break;
3274 read_offset += dirsize;
3277 if (entry_tag != tag)
3279 TIFFErrorExtR(tif, module, "%s: Could not find tag %" PRIu16 ".",
3280 tif->tif_name, tag);
3281 return 0;
3284 /* -------------------------------------------------------------------- */
3285 /* Extract the type, count and offset for this entry. */
3286 /* -------------------------------------------------------------------- */
3287 memcpy(&entry_type, direntry_raw + 2, sizeof(uint16_t));
3288 if (tif->tif_flags & TIFF_SWAB)
3289 TIFFSwabShort(&entry_type);
3291 if (!(tif->tif_flags & TIFF_BIGTIFF))
3293 uint32_t value;
3295 memcpy(&value, direntry_raw + 4, sizeof(uint32_t));
3296 if (tif->tif_flags & TIFF_SWAB)
3297 TIFFSwabLong(&value);
3298 entry_count = value;
3300 memcpy(&value, direntry_raw + 8, sizeof(uint32_t));
3301 if (tif->tif_flags & TIFF_SWAB)
3302 TIFFSwabLong(&value);
3303 entry_offset = value;
3305 else
3307 memcpy(&entry_count, direntry_raw + 4, sizeof(uint64_t));
3308 if (tif->tif_flags & TIFF_SWAB)
3309 TIFFSwabLong8(&entry_count);
3311 memcpy(&entry_offset, direntry_raw + 12, sizeof(uint64_t));
3312 if (tif->tif_flags & TIFF_SWAB)
3313 TIFFSwabLong8(&entry_offset);
3316 /* -------------------------------------------------------------------- */
3317 /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
3318 /* -------------------------------------------------------------------- */
3319 if (entry_offset == 0 && entry_count == 0 && entry_type == 0)
3321 if (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS)
3323 entry_type =
3324 (tif->tif_flags & TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
3326 else
3328 int write_aslong8 = 1;
3329 if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3331 write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
3333 else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3335 write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
3337 if (write_aslong8)
3339 entry_type = TIFF_LONG8;
3341 else
3343 int write_aslong4 = 1;
3344 if (count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS)
3346 write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
3348 else if (count > 1 && tag == TIFFTAG_TILEBYTECOUNTS)
3350 write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
3352 if (write_aslong4)
3354 entry_type = TIFF_LONG;
3356 else
3358 entry_type = TIFF_SHORT;
3364 /* -------------------------------------------------------------------- */
3365 /* What data type do we want to write this as? */
3366 /* -------------------------------------------------------------------- */
3367 if (TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags & TIFF_BIGTIFF))
3369 if (in_datatype == TIFF_LONG8)
3370 datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
3371 else if (in_datatype == TIFF_SLONG8)
3372 datatype = TIFF_SLONG;
3373 else if (in_datatype == TIFF_IFD8)
3374 datatype = TIFF_IFD;
3375 else
3376 datatype = in_datatype;
3378 else
3380 if (in_datatype == TIFF_LONG8 &&
3381 (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
3382 entry_type == TIFF_LONG8))
3383 datatype = entry_type;
3384 else if (in_datatype == TIFF_SLONG8 &&
3385 (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8))
3386 datatype = entry_type;
3387 else if (in_datatype == TIFF_IFD8 &&
3388 (entry_type == TIFF_IFD || entry_type == TIFF_IFD8))
3389 datatype = entry_type;
3390 else
3391 datatype = in_datatype;
3394 /* -------------------------------------------------------------------- */
3395 /* Prepare buffer of actual data to write. This includes */
3396 /* swabbing as needed. */
3397 /* -------------------------------------------------------------------- */
3398 buf_to_write = (uint8_t *)_TIFFCheckMalloc(
3399 tif, count, TIFFDataWidth(datatype), "for field buffer.");
3400 if (!buf_to_write)
3401 return 0;
3403 if (datatype == in_datatype)
3404 memcpy(buf_to_write, data, count * TIFFDataWidth(datatype));
3405 else if (datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8)
3407 tmsize_t i;
3409 for (i = 0; i < count; i++)
3411 ((int32_t *)buf_to_write)[i] = (int32_t)((int64_t *)data)[i];
3412 if ((int64_t)((int32_t *)buf_to_write)[i] != ((int64_t *)data)[i])
3414 _TIFFfreeExt(tif, buf_to_write);
3415 TIFFErrorExtR(tif, module,
3416 "Value exceeds 32bit range of output type.");
3417 return 0;
3421 else if ((datatype == TIFF_LONG && in_datatype == TIFF_LONG8) ||
3422 (datatype == TIFF_IFD && in_datatype == TIFF_IFD8))
3424 tmsize_t i;
3426 for (i = 0; i < count; i++)
3428 ((uint32_t *)buf_to_write)[i] = (uint32_t)((uint64_t *)data)[i];
3429 if ((uint64_t)((uint32_t *)buf_to_write)[i] !=
3430 ((uint64_t *)data)[i])
3432 _TIFFfreeExt(tif, buf_to_write);
3433 TIFFErrorExtR(tif, module,
3434 "Value exceeds 32bit range of output type.");
3435 return 0;
3439 else if (datatype == TIFF_SHORT && in_datatype == TIFF_LONG8)
3441 tmsize_t i;
3443 for (i = 0; i < count; i++)
3445 ((uint16_t *)buf_to_write)[i] = (uint16_t)((uint64_t *)data)[i];
3446 if ((uint64_t)((uint16_t *)buf_to_write)[i] !=
3447 ((uint64_t *)data)[i])
3449 _TIFFfreeExt(tif, buf_to_write);
3450 TIFFErrorExtR(tif, module,
3451 "Value exceeds 16bit range of output type.");
3452 return 0;
3456 else
3458 TIFFErrorExtR(tif, module, "Unhandled type conversion.");
3459 return 0;
3462 if (TIFFDataWidth(datatype) > 1 && (tif->tif_flags & TIFF_SWAB))
3464 if (TIFFDataWidth(datatype) == 2)
3465 TIFFSwabArrayOfShort((uint16_t *)buf_to_write, count);
3466 else if (TIFFDataWidth(datatype) == 4)
3467 TIFFSwabArrayOfLong((uint32_t *)buf_to_write, count);
3468 else if (TIFFDataWidth(datatype) == 8)
3469 TIFFSwabArrayOfLong8((uint64_t *)buf_to_write, count);
3472 /* -------------------------------------------------------------------- */
3473 /* Is this a value that fits into the directory entry? */
3474 /* -------------------------------------------------------------------- */
3475 if (!(tif->tif_flags & TIFF_BIGTIFF))
3477 if (TIFFDataWidth(datatype) * count <= 4)
3479 entry_offset = read_offset + 8;
3480 value_in_entry = 1;
3483 else
3485 if (TIFFDataWidth(datatype) * count <= 8)
3487 entry_offset = read_offset + 12;
3488 value_in_entry = 1;
3492 if ((tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
3493 tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
3494 tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
3495 tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0)
3497 tif->tif_dir.td_stripoffset_entry.tdir_type = datatype;
3498 tif->tif_dir.td_stripoffset_entry.tdir_count = count;
3500 else if ((tag == TIFFTAG_TILEBYTECOUNTS ||
3501 tag == TIFFTAG_STRIPBYTECOUNTS) &&
3502 tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
3503 tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
3504 tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0)
3506 tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
3507 tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
3510 /* -------------------------------------------------------------------- */
3511 /* If the tag type, and count match, then we just write it out */
3512 /* over the old values without altering the directory entry at */
3513 /* all. */
3514 /* -------------------------------------------------------------------- */
3515 if (entry_count == (uint64_t)count && entry_type == (uint16_t)datatype)
3517 if (!SeekOK(tif, entry_offset))
3519 _TIFFfreeExt(tif, buf_to_write);
3520 TIFFErrorExtR(tif, module,
3521 "%s: Seek error accessing TIFF directory",
3522 tif->tif_name);
3523 return 0;
3525 if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3527 _TIFFfreeExt(tif, buf_to_write);
3528 TIFFErrorExtR(tif, module, "Error writing directory link");
3529 return (0);
3532 _TIFFfreeExt(tif, buf_to_write);
3533 return 1;
3536 /* -------------------------------------------------------------------- */
3537 /* Otherwise, we write the new tag data at the end of the file. */
3538 /* -------------------------------------------------------------------- */
3539 if (!value_in_entry)
3541 entry_offset = TIFFSeekFile(tif, 0, SEEK_END);
3543 if (!WriteOK(tif, buf_to_write, count * TIFFDataWidth(datatype)))
3545 _TIFFfreeExt(tif, buf_to_write);
3546 TIFFErrorExtR(tif, module, "Error writing directory link");
3547 return (0);
3550 else
3552 if (count * TIFFDataWidth(datatype) == 4)
3554 uint32_t value;
3555 memcpy(&value, buf_to_write, count * TIFFDataWidth(datatype));
3556 entry_offset = value;
3558 else
3560 memcpy(&entry_offset, buf_to_write,
3561 count * TIFFDataWidth(datatype));
3565 _TIFFfreeExt(tif, buf_to_write);
3566 buf_to_write = 0;
3568 /* -------------------------------------------------------------------- */
3569 /* Adjust the directory entry. */
3570 /* -------------------------------------------------------------------- */
3571 entry_type = datatype;
3572 entry_count = (uint64_t)count;
3573 memcpy(direntry_raw + 2, &entry_type, sizeof(uint16_t));
3574 if (tif->tif_flags & TIFF_SWAB)
3575 TIFFSwabShort((uint16_t *)(direntry_raw + 2));
3577 if (!(tif->tif_flags & TIFF_BIGTIFF))
3579 uint32_t value;
3581 value = (uint32_t)entry_count;
3582 memcpy(direntry_raw + 4, &value, sizeof(uint32_t));
3583 if (tif->tif_flags & TIFF_SWAB)
3584 TIFFSwabLong((uint32_t *)(direntry_raw + 4));
3586 value = (uint32_t)entry_offset;
3587 memcpy(direntry_raw + 8, &value, sizeof(uint32_t));
3588 if (tif->tif_flags & TIFF_SWAB)
3589 TIFFSwabLong((uint32_t *)(direntry_raw + 8));
3591 else
3593 memcpy(direntry_raw + 4, &entry_count, sizeof(uint64_t));
3594 if (tif->tif_flags & TIFF_SWAB)
3595 TIFFSwabLong8((uint64_t *)(direntry_raw + 4));
3597 memcpy(direntry_raw + 12, &entry_offset, sizeof(uint64_t));
3598 if (tif->tif_flags & TIFF_SWAB)
3599 TIFFSwabLong8((uint64_t *)(direntry_raw + 12));
3602 /* -------------------------------------------------------------------- */
3603 /* Write the directory entry out to disk. */
3604 /* -------------------------------------------------------------------- */
3605 if (!SeekOK(tif, read_offset))
3607 TIFFErrorExtR(tif, module, "%s: Seek error accessing TIFF directory",
3608 tif->tif_name);
3609 return 0;
3612 if (!WriteOK(tif, direntry_raw, dirsize))
3614 TIFFErrorExtR(tif, module, "%s: Can not write TIFF directory entry.",
3615 tif->tif_name);
3616 return 0;
3619 return 1;