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