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