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