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