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