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