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