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