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