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