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 Tag Get & Set Routines.
29 : * (and also some miscellaneous stuff)
30 : */
31 : #include "tiffiop.h"
32 : #include <float.h> /*--: for Rational2Double */
33 : #include <limits.h>
34 :
35 : /*
36 : * These are used in the backwards compatibility code...
37 : */
38 : #define DATATYPE_VOID 0 /* !untyped data */
39 : #define DATATYPE_INT 1 /* !signed integer data */
40 : #define DATATYPE_UINT 2 /* !unsigned integer data */
41 : #define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
42 :
43 50590 : static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
44 : size_t elem_size)
45 : {
46 50590 : if (*vpp)
47 : {
48 1407 : _TIFFfreeExt(tif, *vpp);
49 1407 : *vpp = 0;
50 : }
51 50590 : if (vp)
52 : {
53 50541 : tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
54 50559 : if (bytes)
55 50549 : *vpp = (void *)_TIFFmallocExt(tif, bytes);
56 50556 : if (*vpp)
57 50527 : _TIFFmemcpy(*vpp, vp, bytes);
58 : }
59 50627 : }
60 0 : void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
61 : {
62 0 : setByteArray(NULL, vpp, vp, n, 1);
63 0 : }
64 3107 : void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
65 : {
66 3107 : setByteArray(tif, vpp, vp, n, 1);
67 3107 : }
68 :
69 0 : static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n)
70 : {
71 0 : setByteArray(tif, (void **)cpp, cp, n, 1);
72 0 : }
73 :
74 0 : void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n)
75 : {
76 0 : setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t));
77 0 : }
78 8590 : void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp,
79 : uint32_t n)
80 : {
81 8590 : setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
82 8590 : }
83 :
84 0 : void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n)
85 : {
86 0 : setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t));
87 0 : }
88 0 : void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp,
89 : uint32_t n)
90 : {
91 0 : setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t));
92 0 : }
93 :
94 60 : static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp,
95 : uint32_t n)
96 : {
97 60 : setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
98 60 : }
99 :
100 0 : void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n)
101 : {
102 0 : setByteArray(NULL, (void **)fpp, fp, n, sizeof(float));
103 0 : }
104 1851 : void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n)
105 : {
106 1851 : setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
107 1851 : }
108 :
109 0 : void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n)
110 : {
111 0 : setByteArray(NULL, (void **)dpp, dp, n, sizeof(double));
112 0 : }
113 0 : void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp,
114 : uint32_t n)
115 : {
116 0 : setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
117 0 : }
118 :
119 0 : static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
120 : size_t nmemb)
121 : {
122 0 : if (*vpp)
123 0 : _TIFFfreeExt(tif, *vpp);
124 0 : *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
125 0 : if (*vpp)
126 : {
127 0 : while (nmemb--)
128 0 : ((double *)*vpp)[nmemb] = value;
129 : }
130 0 : }
131 :
132 : /*
133 : * Install extra samples information.
134 : */
135 7362 : static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v)
136 : {
137 : /* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
138 : #define EXTRASAMPLE_COREL_UNASSALPHA 999
139 :
140 : uint16_t *va;
141 : uint32_t i;
142 7362 : TIFFDirectory *td = &tif->tif_dir;
143 : static const char module[] = "setExtraSamples";
144 :
145 7362 : *v = (uint16_t)va_arg(ap, uint16_vap);
146 7362 : if ((uint16_t)*v > td->td_samplesperpixel)
147 0 : return 0;
148 7362 : va = va_arg(ap, uint16_t *);
149 7362 : if (*v > 0 && va == NULL) /* typically missing param */
150 0 : return 0;
151 805169 : for (i = 0; i < *v; i++)
152 : {
153 797807 : if (va[i] > EXTRASAMPLE_UNASSALPHA)
154 : {
155 : /*
156 : * XXX: Corel Draw is known to produce incorrect
157 : * ExtraSamples tags which must be patched here if we
158 : * want to be able to open some of the damaged TIFF
159 : * files:
160 : */
161 0 : if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
162 0 : va[i] = EXTRASAMPLE_UNASSALPHA;
163 : else
164 0 : return 0;
165 : }
166 : }
167 :
168 7362 : if (td->td_transferfunction[0] != NULL &&
169 0 : (td->td_samplesperpixel - *v > 1) &&
170 0 : !(td->td_samplesperpixel - td->td_extrasamples > 1))
171 : {
172 0 : TIFFWarningExtR(tif, module,
173 : "ExtraSamples tag value is changing, "
174 : "but TransferFunction was read with a different value. "
175 : "Canceling it");
176 0 : TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
177 0 : _TIFFfreeExt(tif, td->td_transferfunction[0]);
178 0 : td->td_transferfunction[0] = NULL;
179 : }
180 :
181 7362 : td->td_extrasamples = (uint16_t)*v;
182 7362 : _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
183 7362 : return 1;
184 :
185 : #undef EXTRASAMPLE_COREL_UNASSALPHA
186 : }
187 :
188 : /*
189 : * Count ink names separated by \0. Returns
190 : * zero if the ink names are not as expected.
191 : */
192 0 : static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
193 : {
194 0 : uint16_t i = 0;
195 :
196 0 : if (slen > 0)
197 : {
198 0 : const char *ep = s + slen;
199 0 : const char *cp = s;
200 : do
201 : {
202 0 : for (; cp < ep && *cp != '\0'; cp++)
203 : {
204 : }
205 0 : if (cp >= ep)
206 0 : goto bad;
207 0 : cp++; /* skip \0 */
208 0 : i++;
209 0 : } while (cp < ep);
210 0 : return (i);
211 : }
212 0 : bad:
213 0 : TIFFErrorExtR(tif, "TIFFSetField",
214 : "%s: Invalid InkNames value; no null at given buffer end "
215 : "location %" PRIu32 ", after %" PRIu16 " ink",
216 : tif->tif_name, slen, i);
217 0 : return (0);
218 : }
219 :
220 1050540 : static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
221 : {
222 : static const char module[] = "_TIFFVSetField";
223 :
224 1050540 : TIFFDirectory *td = &tif->tif_dir;
225 1050540 : int status = 1;
226 : uint32_t v32, v;
227 : double dblval;
228 : char *s;
229 1050540 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
230 1050310 : uint32_t standard_tag = tag;
231 1050310 : if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */
232 0 : return 0;
233 : /*
234 : * We want to force the custom code to be used for custom
235 : * fields even if the tag happens to match a well known
236 : * one - important for reinterpreted handling of standard
237 : * tag values in custom directories (i.e. EXIF)
238 : */
239 1050310 : if (fip->field_bit == FIELD_CUSTOM)
240 : {
241 136827 : standard_tag = 0;
242 : }
243 :
244 1050310 : switch (standard_tag)
245 : {
246 6055 : case TIFFTAG_SUBFILETYPE:
247 6055 : td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
248 6055 : break;
249 80402 : case TIFFTAG_IMAGEWIDTH:
250 80402 : td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
251 80404 : break;
252 80394 : case TIFFTAG_IMAGELENGTH:
253 80394 : td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
254 80405 : break;
255 80387 : case TIFFTAG_BITSPERSAMPLE:
256 80387 : td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap);
257 : /*
258 : * If the data require post-decoding processing to byte-swap
259 : * samples, set it up here. Note that since tags are required
260 : * to be ordered, compression code can override this behavior
261 : * in the setup method if it wants to roll the post decoding
262 : * work in with its normal work.
263 : */
264 80379 : if (tif->tif_flags & TIFF_SWAB)
265 : {
266 690 : if (td->td_bitspersample == 8)
267 386 : tif->tif_postdecode = _TIFFNoPostDecode;
268 304 : else if (td->td_bitspersample == 16)
269 126 : tif->tif_postdecode = _TIFFSwab16BitData;
270 178 : else if (td->td_bitspersample == 24)
271 0 : tif->tif_postdecode = _TIFFSwab24BitData;
272 178 : else if (td->td_bitspersample == 32)
273 132 : tif->tif_postdecode = _TIFFSwab32BitData;
274 46 : else if (td->td_bitspersample == 64)
275 21 : tif->tif_postdecode = _TIFFSwab64BitData;
276 25 : else if (td->td_bitspersample == 128) /* two 64's */
277 7 : tif->tif_postdecode = _TIFFSwab64BitData;
278 : }
279 80379 : break;
280 199515 : case TIFFTAG_COMPRESSION:
281 199515 : v = (uint16_t)va_arg(ap, uint16_vap);
282 : /*
283 : * If we're changing the compression scheme, notify the
284 : * previous module so that it can cleanup any state it's
285 : * setup.
286 : */
287 199528 : if (TIFFFieldSet(tif, FIELD_COMPRESSION))
288 : {
289 81065 : if ((uint32_t)td->td_compression == v)
290 46742 : break;
291 34323 : (*tif->tif_cleanup)(tif);
292 34323 : tif->tif_flags &= ~TIFF_CODERSETUP;
293 : }
294 : /*
295 : * Setup new compression routine state.
296 : */
297 152786 : if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
298 152755 : td->td_compression = (uint16_t)v;
299 : else
300 0 : status = 0;
301 152735 : break;
302 80425 : case TIFFTAG_PHOTOMETRIC:
303 80425 : td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
304 80414 : break;
305 0 : case TIFFTAG_THRESHHOLDING:
306 0 : td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
307 0 : break;
308 2 : case TIFFTAG_FILLORDER:
309 2 : v = (uint16_t)va_arg(ap, uint16_vap);
310 2 : if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
311 0 : goto badvalue;
312 2 : td->td_fillorder = (uint16_t)v;
313 2 : break;
314 91 : case TIFFTAG_ORIENTATION:
315 91 : v = (uint16_t)va_arg(ap, uint16_vap);
316 91 : if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
317 0 : goto badvalue;
318 : else
319 91 : td->td_orientation = (uint16_t)v;
320 91 : break;
321 80357 : case TIFFTAG_SAMPLESPERPIXEL:
322 80357 : v = (uint16_t)va_arg(ap, uint16_vap);
323 80354 : if (v == 0)
324 0 : goto badvalue;
325 80354 : if (v != td->td_samplesperpixel)
326 : {
327 : /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
328 19869 : if (td->td_sminsamplevalue != NULL)
329 : {
330 0 : TIFFWarningExtR(tif, module,
331 : "SamplesPerPixel tag value is changing, "
332 : "but SMinSampleValue tag was read with a "
333 : "different value. Canceling it");
334 0 : TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE);
335 0 : _TIFFfreeExt(tif, td->td_sminsamplevalue);
336 0 : td->td_sminsamplevalue = NULL;
337 : }
338 19869 : if (td->td_smaxsamplevalue != NULL)
339 : {
340 0 : TIFFWarningExtR(tif, module,
341 : "SamplesPerPixel tag value is changing, "
342 : "but SMaxSampleValue tag was read with a "
343 : "different value. Canceling it");
344 0 : TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE);
345 0 : _TIFFfreeExt(tif, td->td_smaxsamplevalue);
346 0 : td->td_smaxsamplevalue = NULL;
347 : }
348 : /* Test if 3 transfer functions instead of just one are now
349 : needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820
350 : */
351 19869 : if (td->td_transferfunction[0] != NULL &&
352 0 : (v - td->td_extrasamples > 1) &&
353 0 : !(td->td_samplesperpixel - td->td_extrasamples > 1))
354 : {
355 0 : TIFFWarningExtR(tif, module,
356 : "SamplesPerPixel tag value is changing, "
357 : "but TransferFunction was read with a "
358 : "different value. Canceling it");
359 0 : TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
360 0 : _TIFFfreeExt(tif, td->td_transferfunction[0]);
361 0 : td->td_transferfunction[0] = NULL;
362 : }
363 : }
364 80323 : td->td_samplesperpixel = (uint16_t)v;
365 80323 : break;
366 71118 : case TIFFTAG_ROWSPERSTRIP:
367 71118 : v32 = (uint32_t)va_arg(ap, uint32_t);
368 71110 : if (v32 == 0)
369 0 : goto badvalue32;
370 71110 : td->td_rowsperstrip = v32;
371 71110 : if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
372 : {
373 71079 : td->td_tilelength = v32;
374 71079 : td->td_tilewidth = td->td_imagewidth;
375 : }
376 71110 : break;
377 8 : case TIFFTAG_MINSAMPLEVALUE:
378 8 : td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
379 8 : break;
380 8 : case TIFFTAG_MAXSAMPLEVALUE:
381 8 : td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
382 8 : break;
383 0 : case TIFFTAG_SMINSAMPLEVALUE:
384 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
385 0 : _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
386 0 : va_arg(ap, double *),
387 0 : td->td_samplesperpixel);
388 : else
389 0 : setDoubleArrayOneValue(tif, &td->td_sminsamplevalue,
390 : va_arg(ap, double),
391 0 : td->td_samplesperpixel);
392 0 : break;
393 0 : case TIFFTAG_SMAXSAMPLEVALUE:
394 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
395 0 : _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
396 0 : va_arg(ap, double *),
397 0 : td->td_samplesperpixel);
398 : else
399 0 : setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue,
400 : va_arg(ap, double),
401 0 : td->td_samplesperpixel);
402 0 : break;
403 129 : case TIFFTAG_XRESOLUTION:
404 129 : dblval = va_arg(ap, double);
405 129 : if (dblval != dblval || dblval < 0)
406 0 : goto badvaluedouble;
407 129 : td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
408 129 : break;
409 129 : case TIFFTAG_YRESOLUTION:
410 129 : dblval = va_arg(ap, double);
411 129 : if (dblval != dblval || dblval < 0)
412 0 : goto badvaluedouble;
413 129 : td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
414 129 : break;
415 124225 : case TIFFTAG_PLANARCONFIG:
416 124225 : v = (uint16_t)va_arg(ap, uint16_vap);
417 124262 : if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
418 0 : goto badvalue;
419 124262 : td->td_planarconfig = (uint16_t)v;
420 124262 : break;
421 2 : case TIFFTAG_XPOSITION:
422 2 : td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
423 2 : break;
424 2 : case TIFFTAG_YPOSITION:
425 2 : td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
426 2 : break;
427 133 : case TIFFTAG_RESOLUTIONUNIT:
428 133 : v = (uint16_t)va_arg(ap, uint16_vap);
429 133 : if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
430 0 : goto badvalue;
431 133 : td->td_resolutionunit = (uint16_t)v;
432 133 : break;
433 0 : case TIFFTAG_PAGENUMBER:
434 0 : td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
435 0 : td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
436 0 : break;
437 0 : case TIFFTAG_HALFTONEHINTS:
438 0 : td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
439 0 : td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
440 0 : break;
441 389 : case TIFFTAG_COLORMAP:
442 389 : v32 = (uint32_t)(1L << td->td_bitspersample);
443 389 : _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
444 389 : va_arg(ap, uint16_t *), v32);
445 389 : _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
446 389 : va_arg(ap, uint16_t *), v32);
447 389 : _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
448 389 : va_arg(ap, uint16_t *), v32);
449 389 : break;
450 7362 : case TIFFTAG_EXTRASAMPLES:
451 7362 : if (!setExtraSamples(tif, ap, &v))
452 0 : goto badvalue;
453 7362 : break;
454 2 : case TIFFTAG_MATTEING:
455 2 : td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
456 2 : if (td->td_extrasamples)
457 : {
458 0 : uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
459 0 : _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
460 : }
461 2 : break;
462 9402 : case TIFFTAG_TILEWIDTH:
463 9402 : v32 = (uint32_t)va_arg(ap, uint32_t);
464 9402 : if (v32 % 16)
465 : {
466 2 : if (tif->tif_mode != O_RDONLY)
467 0 : goto badvalue32;
468 2 : TIFFWarningExtR(
469 2 : tif, tif->tif_name,
470 : "Nonstandard tile width %" PRIu32 ", convert file", v32);
471 : }
472 9402 : td->td_tilewidth = v32;
473 9402 : tif->tif_flags |= TIFF_ISTILED;
474 9402 : break;
475 9402 : case TIFFTAG_TILELENGTH:
476 9402 : v32 = (uint32_t)va_arg(ap, uint32_t);
477 9402 : if (v32 % 16)
478 : {
479 4 : if (tif->tif_mode != O_RDONLY)
480 1 : goto badvalue32;
481 3 : TIFFWarningExtR(
482 3 : tif, tif->tif_name,
483 : "Nonstandard tile length %" PRIu32 ", convert file", v32);
484 : }
485 9401 : td->td_tilelength = v32;
486 9401 : tif->tif_flags |= TIFF_ISTILED;
487 9401 : break;
488 0 : case TIFFTAG_TILEDEPTH:
489 0 : v32 = (uint32_t)va_arg(ap, uint32_t);
490 0 : if (v32 == 0)
491 0 : goto badvalue32;
492 0 : td->td_tiledepth = v32;
493 0 : break;
494 0 : case TIFFTAG_DATATYPE:
495 0 : v = (uint16_t)va_arg(ap, uint16_vap);
496 0 : switch (v)
497 : {
498 0 : case DATATYPE_VOID:
499 0 : v = SAMPLEFORMAT_VOID;
500 0 : break;
501 0 : case DATATYPE_INT:
502 0 : v = SAMPLEFORMAT_INT;
503 0 : break;
504 0 : case DATATYPE_UINT:
505 0 : v = SAMPLEFORMAT_UINT;
506 0 : break;
507 0 : case DATATYPE_IEEEFP:
508 0 : v = SAMPLEFORMAT_IEEEFP;
509 0 : break;
510 0 : default:
511 0 : goto badvalue;
512 : }
513 0 : td->td_sampleformat = (uint16_t)v;
514 0 : break;
515 79402 : case TIFFTAG_SAMPLEFORMAT:
516 79402 : v = (uint16_t)va_arg(ap, uint16_vap);
517 79422 : if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
518 71 : goto badvalue;
519 79351 : td->td_sampleformat = (uint16_t)v;
520 :
521 : /* Try to fix up the SWAB function for complex data. */
522 79351 : if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
523 802 : td->td_bitspersample == 32 &&
524 482 : tif->tif_postdecode == _TIFFSwab32BitData)
525 81 : tif->tif_postdecode = _TIFFSwab16BitData;
526 79270 : else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
527 78586 : td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
528 1405 : td->td_bitspersample == 64 &&
529 669 : tif->tif_postdecode == _TIFFSwab64BitData)
530 14 : tif->tif_postdecode = _TIFFSwab32BitData;
531 79351 : break;
532 0 : case TIFFTAG_IMAGEDEPTH:
533 0 : td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
534 0 : break;
535 60 : case TIFFTAG_SUBIFD:
536 60 : if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
537 : {
538 60 : td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
539 60 : _TIFFsetLong8Array(tif, &td->td_subifd,
540 60 : (uint64_t *)va_arg(ap, uint64_t *),
541 60 : (uint32_t)td->td_nsubifd);
542 : }
543 : else
544 : {
545 0 : TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs",
546 : tif->tif_name);
547 0 : status = 0;
548 : }
549 60 : break;
550 11 : case TIFFTAG_YCBCRPOSITIONING:
551 11 : td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
552 11 : break;
553 2171 : case TIFFTAG_YCBCRSUBSAMPLING:
554 2171 : td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
555 2171 : td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
556 2171 : break;
557 19 : case TIFFTAG_TRANSFERFUNCTION:
558 : {
559 : uint32_t i;
560 19 : v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
561 76 : for (i = 0; i < v; i++)
562 57 : _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
563 57 : va_arg(ap, uint16_t *),
564 57 : 1U << td->td_bitspersample);
565 19 : break;
566 : }
567 1851 : case TIFFTAG_REFERENCEBLACKWHITE:
568 : /* XXX should check for null range */
569 1851 : _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
570 1851 : va_arg(ap, float *), 6);
571 1851 : break;
572 0 : case TIFFTAG_INKNAMES:
573 : {
574 0 : v = (uint16_t)va_arg(ap, uint16_vap);
575 0 : s = va_arg(ap, char *);
576 : uint16_t ninksinstring;
577 0 : ninksinstring = countInkNamesString(tif, v, s);
578 0 : status = ninksinstring > 0;
579 0 : if (ninksinstring > 0)
580 : {
581 0 : _TIFFsetNString(tif, &td->td_inknames, s, v);
582 0 : td->td_inknameslen = v;
583 : /* Set NumberOfInks to the value ninksinstring */
584 0 : if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
585 : {
586 0 : if (td->td_numberofinks != ninksinstring)
587 : {
588 0 : TIFFErrorExtR(
589 : tif, module,
590 : "Warning %s; Tag %s:\n Value %" PRIu16
591 : " of NumberOfInks is different from the number of "
592 : "inks %" PRIu16
593 : ".\n -> NumberOfInks value adapted to %" PRIu16 "",
594 0 : tif->tif_name, fip->field_name, td->td_numberofinks,
595 : ninksinstring, ninksinstring);
596 0 : td->td_numberofinks = ninksinstring;
597 : }
598 : }
599 : else
600 : {
601 0 : td->td_numberofinks = ninksinstring;
602 0 : TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
603 : }
604 0 : if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
605 : {
606 0 : if (td->td_numberofinks != td->td_samplesperpixel)
607 : {
608 0 : TIFFErrorExtR(tif, module,
609 : "Warning %s; Tag %s:\n Value %" PRIu16
610 : " of NumberOfInks is different from the "
611 : "SamplesPerPixel value %" PRIu16 "",
612 : tif->tif_name, fip->field_name,
613 0 : td->td_numberofinks,
614 0 : td->td_samplesperpixel);
615 : }
616 : }
617 : }
618 : }
619 0 : break;
620 0 : case TIFFTAG_NUMBEROFINKS:
621 0 : v = (uint16_t)va_arg(ap, uint16_vap);
622 : /* If InkNames already set also NumberOfInks is set accordingly and
623 : * should be equal */
624 0 : if (TIFFFieldSet(tif, FIELD_INKNAMES))
625 : {
626 0 : if (v != td->td_numberofinks)
627 : {
628 0 : TIFFErrorExtR(
629 : tif, module,
630 : "Error %s; Tag %s:\n It is not possible to set the "
631 : "value %" PRIu32
632 : " for NumberOfInks\n which is different from the "
633 : "number of inks in the InkNames tag (%" PRIu16 ")",
634 0 : tif->tif_name, fip->field_name, v, td->td_numberofinks);
635 : /* Do not set / overwrite number of inks already set by
636 : * InkNames case accordingly. */
637 0 : status = 0;
638 : }
639 : }
640 : else
641 : {
642 0 : td->td_numberofinks = (uint16_t)v;
643 0 : if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
644 : {
645 0 : if (td->td_numberofinks != td->td_samplesperpixel)
646 : {
647 0 : TIFFErrorExtR(tif, module,
648 : "Warning %s; Tag %s:\n Value %" PRIu32
649 : " of NumberOfInks is different from the "
650 : "SamplesPerPixel value %" PRIu16 "",
651 : tif->tif_name, fip->field_name, v,
652 0 : td->td_samplesperpixel);
653 : }
654 : }
655 : }
656 0 : break;
657 0 : case TIFFTAG_PERSAMPLE:
658 0 : v = (uint16_t)va_arg(ap, uint16_vap);
659 0 : if (v == PERSAMPLE_MULTI)
660 0 : tif->tif_flags |= TIFF_PERSAMPLE;
661 : else
662 0 : tif->tif_flags &= ~TIFF_PERSAMPLE;
663 0 : break;
664 136854 : default:
665 : {
666 : TIFFTagValue *tv;
667 : int tv_size, iCustom;
668 :
669 : /*
670 : * This can happen if multiple images are open with different
671 : * codecs which have private tags. The global tag information
672 : * table may then have tags that are valid for one file but not
673 : * the other. If the client tries to set a tag that is not valid
674 : * for the image's codec then we'll arrive here. This
675 : * happens, for example, when tiffcp is used to convert between
676 : * compression schemes and codec-specific tags are blindly copied.
677 : *
678 : * This also happens when a FIELD_IGNORE tag is written.
679 : */
680 136854 : if (fip->field_bit == FIELD_IGNORE)
681 : {
682 0 : TIFFErrorExtR(
683 : tif, module,
684 : "%s: Ignored %stag \"%s\" (not supported by libtiff)",
685 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
686 : fip->field_name);
687 0 : status = 0;
688 0 : break;
689 : }
690 136854 : if (fip->field_bit != FIELD_CUSTOM)
691 : {
692 0 : TIFFErrorExtR(
693 : tif, module,
694 : "%s: Invalid %stag \"%s\" (not supported by codec)",
695 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
696 : fip->field_name);
697 0 : status = 0;
698 0 : break;
699 : }
700 :
701 : /*
702 : * Find the existing entry for this custom value.
703 : */
704 136854 : tv = NULL;
705 356719 : for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
706 : {
707 221909 : if (td->td_customValues[iCustom].info->field_tag == tag)
708 : {
709 2044 : tv = td->td_customValues + iCustom;
710 2044 : if (tv->value != NULL)
711 : {
712 2044 : _TIFFfreeExt(tif, tv->value);
713 2044 : tv->value = NULL;
714 : }
715 2044 : break;
716 : }
717 : }
718 :
719 : /*
720 : * Grow the custom list if the entry was not found.
721 : */
722 136854 : if (tv == NULL)
723 : {
724 : TIFFTagValue *new_customValues;
725 :
726 134826 : td->td_customValueCount++;
727 134826 : new_customValues = (TIFFTagValue *)_TIFFreallocExt(
728 134826 : tif, td->td_customValues,
729 134826 : sizeof(TIFFTagValue) * td->td_customValueCount);
730 134862 : if (!new_customValues)
731 : {
732 72 : TIFFErrorExtR(tif, module,
733 : "%s: Failed to allocate space for list of "
734 : "custom values",
735 : tif->tif_name);
736 0 : status = 0;
737 0 : goto end;
738 : }
739 :
740 134790 : td->td_customValues = new_customValues;
741 :
742 134790 : tv = td->td_customValues + (td->td_customValueCount - 1);
743 134790 : tv->info = fip;
744 134790 : tv->value = NULL;
745 134790 : tv->count = 0;
746 : }
747 :
748 : /*
749 : * Set custom value ... save a copy of the custom tag value.
750 : */
751 : /*--: Rational2Double: For Rationals evaluate "set_field_type" to
752 : * determine internal storage size. */
753 136818 : tv_size = TIFFFieldSetGetSize(fip);
754 136765 : if (tv_size == 0)
755 : {
756 0 : status = 0;
757 0 : TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
758 0 : tif->tif_name, fip->field_type, fip->field_name);
759 0 : goto end;
760 : }
761 :
762 136784 : if (fip->field_type == TIFF_ASCII)
763 : {
764 : uint32_t ma;
765 : const char *mb;
766 36923 : if (fip->field_passcount)
767 : {
768 0 : assert(fip->field_writecount == TIFF_VARIABLE2);
769 0 : ma = (uint32_t)va_arg(ap, uint32_t);
770 0 : mb = (const char *)va_arg(ap, const char *);
771 : }
772 : else
773 : {
774 36923 : mb = (const char *)va_arg(ap, const char *);
775 36903 : size_t len = strlen(mb) + 1;
776 36903 : if (len >= 0x80000000U)
777 : {
778 0 : status = 0;
779 0 : TIFFErrorExtR(tif, module,
780 : "%s: Too long string value for \"%s\". "
781 : "Maximum supported is 2147483647 bytes",
782 : tif->tif_name, fip->field_name);
783 0 : goto end;
784 : }
785 36925 : ma = (uint32_t)len;
786 : }
787 36925 : tv->count = ma;
788 36925 : setByteArray(tif, &tv->value, mb, ma, 1);
789 : }
790 : else
791 : {
792 99861 : if (fip->field_passcount)
793 : {
794 99761 : if (fip->field_writecount == TIFF_VARIABLE2)
795 3002 : tv->count = (uint32_t)va_arg(ap, uint32_t);
796 : else
797 96759 : tv->count = (int)va_arg(ap, int);
798 : }
799 100 : else if (fip->field_writecount == TIFF_VARIABLE ||
800 71 : fip->field_writecount == TIFF_VARIABLE2)
801 29 : tv->count = 1;
802 71 : else if (fip->field_writecount == TIFF_SPP)
803 0 : tv->count = td->td_samplesperpixel;
804 : else
805 71 : tv->count = fip->field_writecount;
806 :
807 99826 : if (tv->count == 0)
808 : {
809 0 : TIFFWarningExtR(tif, module,
810 : "%s: Null count for \"%s\" (type "
811 : "%d, writecount %d, passcount %d)",
812 : tif->tif_name, fip->field_name,
813 0 : fip->field_type, fip->field_writecount,
814 0 : fip->field_passcount);
815 0 : break;
816 : }
817 :
818 99826 : tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
819 : "custom tag binary object");
820 99917 : if (!tv->value)
821 : {
822 0 : status = 0;
823 0 : goto end;
824 : }
825 :
826 99917 : if (fip->field_tag == TIFFTAG_DOTRANGE &&
827 0 : strcmp(fip->field_name, "DotRange") == 0)
828 0 : {
829 : /* TODO: This is an evil exception and should not have been
830 : handled this way ... likely best if we move it into
831 : the directory structure with an explicit field in
832 : libtiff 4.1 and assign it a FIELD_ value */
833 : uint16_t v2[2];
834 0 : v2[0] = (uint16_t)va_arg(ap, int);
835 0 : v2[1] = (uint16_t)va_arg(ap, int);
836 0 : _TIFFmemcpy(tv->value, &v2, 4);
837 : }
838 :
839 99917 : else if (fip->field_passcount ||
840 71 : fip->field_writecount == TIFF_VARIABLE ||
841 71 : fip->field_writecount == TIFF_VARIABLE2 ||
842 71 : fip->field_writecount == TIFF_SPP || tv->count > 1)
843 : {
844 : /*--: Rational2Double: For Rationals tv_size is set above to
845 : * 4 or 8 according to fip->set_field_type! */
846 99858 : _TIFFmemcpy(tv->value, va_arg(ap, void *),
847 99909 : tv->count * tv_size);
848 : /* Test here for too big values for LONG8, SLONG8 in
849 : * ClassicTIFF and delete custom field from custom list */
850 99884 : if (!(tif->tif_flags & TIFF_BIGTIFF))
851 : {
852 99734 : if (tv->info->field_type == TIFF_LONG8)
853 : {
854 0 : uint64_t *pui64 = (uint64_t *)tv->value;
855 0 : for (int i = 0; i < tv->count; i++)
856 : {
857 0 : if (pui64[i] > 0xffffffffu)
858 : {
859 0 : TIFFErrorExtR(
860 : tif, module,
861 : "%s: Bad LONG8 value %" PRIu64
862 : " at %d. array position for \"%s\" tag "
863 : "%d in ClassicTIFF. Tag won't be "
864 : "written to file",
865 0 : tif->tif_name, pui64[i], i,
866 : fip->field_name, tag);
867 0 : goto badvalueifd8long8;
868 : }
869 : }
870 : }
871 99734 : else if (tv->info->field_type == TIFF_SLONG8)
872 : {
873 0 : int64_t *pi64 = (int64_t *)tv->value;
874 0 : for (int i = 0; i < tv->count; i++)
875 : {
876 0 : if (pi64[i] > 2147483647 ||
877 0 : pi64[i] < (-2147483647 - 1))
878 : {
879 0 : TIFFErrorExtR(
880 : tif, module,
881 : "%s: Bad SLONG8 value %" PRIi64
882 : " at %d. array position for \"%s\" tag "
883 : "%d in ClassicTIFF. Tag won't be "
884 : "written to file",
885 0 : tif->tif_name, pi64[i], i,
886 : fip->field_name, tag);
887 0 : goto badvalueifd8long8;
888 : }
889 : }
890 : }
891 : }
892 : }
893 : else
894 : {
895 8 : char *val = (char *)tv->value;
896 8 : assert(tv->count == 1);
897 :
898 8 : switch (fip->field_type)
899 : {
900 0 : case TIFF_BYTE:
901 : case TIFF_UNDEFINED:
902 : {
903 0 : uint8_t v2 = (uint8_t)va_arg(ap, int);
904 0 : _TIFFmemcpy(val, &v2, tv_size);
905 : }
906 0 : break;
907 0 : case TIFF_SBYTE:
908 : {
909 0 : int8_t v2 = (int8_t)va_arg(ap, int);
910 0 : _TIFFmemcpy(val, &v2, tv_size);
911 : }
912 0 : break;
913 0 : case TIFF_SHORT:
914 : {
915 0 : uint16_t v2 = (uint16_t)va_arg(ap, int);
916 0 : _TIFFmemcpy(val, &v2, tv_size);
917 : }
918 0 : break;
919 0 : case TIFF_SSHORT:
920 : {
921 0 : int16_t v2 = (int16_t)va_arg(ap, int);
922 0 : _TIFFmemcpy(val, &v2, tv_size);
923 : }
924 0 : break;
925 0 : case TIFF_LONG:
926 : case TIFF_IFD:
927 : {
928 0 : uint32_t v2 = va_arg(ap, uint32_t);
929 0 : _TIFFmemcpy(val, &v2, tv_size);
930 : }
931 0 : break;
932 0 : case TIFF_SLONG:
933 : {
934 0 : int32_t v2 = va_arg(ap, int32_t);
935 0 : _TIFFmemcpy(val, &v2, tv_size);
936 : }
937 0 : break;
938 8 : case TIFF_LONG8:
939 : case TIFF_IFD8:
940 : {
941 8 : uint64_t v2 = va_arg(ap, uint64_t);
942 8 : _TIFFmemcpy(val, &v2, tv_size);
943 : /* Test here for too big values for ClassicTIFF and
944 : * delete custom field from custom list */
945 8 : if (!(tif->tif_flags & TIFF_BIGTIFF) &&
946 8 : (v2 > 0xffffffffu))
947 : {
948 0 : TIFFErrorExtR(
949 : tif, module,
950 : "%s: Bad LONG8 or IFD8 value %" PRIu64
951 : " for \"%s\" tag %d in ClassicTIFF. Tag "
952 : "won't be written to file",
953 : tif->tif_name, v2, fip->field_name, tag);
954 0 : goto badvalueifd8long8;
955 : }
956 : }
957 8 : break;
958 0 : case TIFF_SLONG8:
959 : {
960 0 : int64_t v2 = va_arg(ap, int64_t);
961 0 : _TIFFmemcpy(val, &v2, tv_size);
962 : /* Test here for too big values for ClassicTIFF and
963 : * delete custom field from custom list */
964 0 : if (!(tif->tif_flags & TIFF_BIGTIFF) &&
965 0 : ((v2 > 2147483647) || (v2 < (-2147483647 - 1))))
966 : {
967 0 : TIFFErrorExtR(
968 : tif, module,
969 : "%s: Bad SLONG8 value %" PRIi64
970 : " for \"%s\" tag %d in ClassicTIFF. Tag "
971 : "won't be written to file",
972 : tif->tif_name, v2, fip->field_name, tag);
973 0 : goto badvalueifd8long8;
974 : }
975 : }
976 0 : break;
977 0 : case TIFF_RATIONAL:
978 : case TIFF_SRATIONAL:
979 : /*-- Rational2Double: For Rationals tv_size is set
980 : * above to 4 or 8 according to fip->set_field_type!
981 : */
982 : {
983 0 : if (tv_size == 8)
984 : {
985 0 : double v2 = va_arg(ap, double);
986 0 : _TIFFmemcpy(val, &v2, tv_size);
987 : }
988 : else
989 : {
990 : /*-- default should be tv_size == 4 */
991 0 : float v3 = (float)va_arg(ap, double);
992 0 : _TIFFmemcpy(val, &v3, tv_size);
993 : /*-- ToDo: After Testing, this should be
994 : * removed and tv_size==4 should be set as
995 : * default. */
996 0 : if (tv_size != 4)
997 : {
998 0 : TIFFErrorExtR(
999 : tif, module,
1000 : "Rational2Double: .set_field_type "
1001 : "in not 4 but %d",
1002 : tv_size);
1003 : }
1004 : }
1005 : }
1006 0 : break;
1007 0 : case TIFF_FLOAT:
1008 : {
1009 0 : float v2 =
1010 0 : _TIFFClampDoubleToFloat(va_arg(ap, double));
1011 0 : _TIFFmemcpy(val, &v2, tv_size);
1012 : }
1013 0 : break;
1014 0 : case TIFF_DOUBLE:
1015 : {
1016 0 : double v2 = va_arg(ap, double);
1017 0 : _TIFFmemcpy(val, &v2, tv_size);
1018 : }
1019 0 : break;
1020 0 : default:
1021 0 : _TIFFmemset(val, 0, tv_size);
1022 0 : status = 0;
1023 0 : break;
1024 : }
1025 : }
1026 : }
1027 : }
1028 : }
1029 1049980 : if (status)
1030 : {
1031 1049980 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1032 1050110 : if (fip2)
1033 1050090 : TIFFSetFieldBit(tif, fip2->field_bit);
1034 1050110 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1035 : }
1036 :
1037 0 : end:
1038 1050110 : va_end(ap);
1039 1050110 : return (status);
1040 71 : badvalue:
1041 : {
1042 71 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1043 0 : TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1044 : tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
1045 0 : va_end(ap);
1046 : }
1047 0 : return (0);
1048 1 : badvalue32:
1049 : {
1050 1 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1051 1 : TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1052 : tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
1053 1 : va_end(ap);
1054 : }
1055 1 : return (0);
1056 0 : badvaluedouble:
1057 : {
1058 0 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1059 0 : TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
1060 : dblval, fip2 ? fip2->field_name : "Unknown");
1061 0 : va_end(ap);
1062 : }
1063 0 : return (0);
1064 0 : badvalueifd8long8:
1065 : {
1066 : /* Error message issued already above. */
1067 0 : TIFFTagValue *tv2 = NULL;
1068 : int iCustom2, iC2;
1069 : /* Find the existing entry for this custom value. */
1070 0 : for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
1071 : {
1072 0 : if (td->td_customValues[iCustom2].info->field_tag == tag)
1073 : {
1074 0 : tv2 = td->td_customValues + (iCustom2);
1075 0 : break;
1076 : }
1077 : }
1078 0 : if (tv2 != NULL)
1079 : {
1080 : /* Remove custom field from custom list */
1081 0 : if (tv2->value != NULL)
1082 : {
1083 0 : _TIFFfreeExt(tif, tv2->value);
1084 0 : tv2->value = NULL;
1085 : }
1086 : /* Shorten list and close gap in customValues list.
1087 : * Re-allocation of td_customValues not necessary here. */
1088 0 : td->td_customValueCount--;
1089 0 : for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
1090 : {
1091 0 : td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
1092 : }
1093 : }
1094 : else
1095 : {
1096 0 : assert(0);
1097 : }
1098 0 : va_end(ap);
1099 : }
1100 0 : return (0);
1101 : } /*-- _TIFFVSetField() --*/
1102 :
1103 : /*
1104 : * Return 1/0 according to whether or not
1105 : * it is permissible to set the tag's value.
1106 : * Note that we allow ImageLength to be changed
1107 : * so that we can append and extend to images.
1108 : * Any other tag may not be altered once writing
1109 : * has commenced, unless its value has no effect
1110 : * on the format of the data that is written.
1111 : */
1112 1072830 : static int OkToChangeTag(TIFF *tif, uint32_t tag)
1113 : {
1114 1072830 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1115 1073580 : if (!fip)
1116 : { /* unknown tag */
1117 0 : TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
1118 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
1119 0 : return (0);
1120 : }
1121 1073580 : if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
1122 742 : !fip->field_oktochange)
1123 : {
1124 : /*
1125 : * Consult info table to see if tag can be changed
1126 : * after we've started writing. We only allow changes
1127 : * to those tags that don't/shouldn't affect the
1128 : * compression and/or format of the data.
1129 : */
1130 2 : TIFFErrorExtR(tif, "TIFFSetField",
1131 : "%s: Cannot modify tag \"%s\" while writing",
1132 : tif->tif_name, fip->field_name);
1133 2 : return (0);
1134 : }
1135 1073580 : return (1);
1136 : }
1137 :
1138 : /*
1139 : * Record the value of a field in the
1140 : * internal directory structure. The
1141 : * field will be written to the file
1142 : * when/if the directory structure is
1143 : * updated.
1144 : */
1145 1073320 : int TIFFSetField(TIFF *tif, uint32_t tag, ...)
1146 : {
1147 : va_list ap;
1148 : int status;
1149 :
1150 1073320 : va_start(ap, tag);
1151 1073320 : status = TIFFVSetField(tif, tag, ap);
1152 1073170 : va_end(ap);
1153 1073170 : return (status);
1154 : }
1155 :
1156 : /*
1157 : * Clear the contents of the field in the internal structure.
1158 : */
1159 4624 : int TIFFUnsetField(TIFF *tif, uint32_t tag)
1160 : {
1161 4624 : const TIFFField *fip = TIFFFieldWithTag(tif, tag);
1162 4624 : TIFFDirectory *td = &tif->tif_dir;
1163 :
1164 4624 : if (!fip)
1165 0 : return 0;
1166 :
1167 4624 : if (fip->field_bit != FIELD_CUSTOM)
1168 5 : TIFFClrFieldBit(tif, fip->field_bit);
1169 : else
1170 : {
1171 4619 : TIFFTagValue *tv = NULL;
1172 : int i;
1173 :
1174 4950 : for (i = 0; i < td->td_customValueCount; i++)
1175 : {
1176 :
1177 414 : tv = td->td_customValues + i;
1178 414 : if (tv->info->field_tag == tag)
1179 83 : break;
1180 : }
1181 :
1182 4619 : if (i < td->td_customValueCount)
1183 : {
1184 83 : _TIFFfreeExt(tif, tv->value);
1185 198 : for (; i < td->td_customValueCount - 1; i++)
1186 : {
1187 115 : td->td_customValues[i] = td->td_customValues[i + 1];
1188 : }
1189 83 : td->td_customValueCount--;
1190 : }
1191 : }
1192 :
1193 4624 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1194 :
1195 4624 : return (1);
1196 : }
1197 :
1198 : /*
1199 : * Like TIFFSetField, but taking a varargs
1200 : * parameter list. This routine is useful
1201 : * for building higher-level interfaces on
1202 : * top of the library.
1203 : */
1204 1073240 : int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
1205 : {
1206 1073240 : return OkToChangeTag(tif, tag)
1207 1073450 : ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1208 2146610 : : 0;
1209 : }
1210 :
1211 1512460 : static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1212 : {
1213 1512460 : TIFFDirectory *td = &tif->tif_dir;
1214 1512460 : int ret_val = 1;
1215 1512460 : uint32_t standard_tag = tag;
1216 1512460 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1217 1512220 : if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */
1218 0 : return 0;
1219 :
1220 : /*
1221 : * We want to force the custom code to be used for custom
1222 : * fields even if the tag happens to match a well known
1223 : * one - important for reinterpreted handling of standard
1224 : * tag values in custom directories (i.e. EXIF)
1225 : */
1226 1512220 : if (fip->field_bit == FIELD_CUSTOM)
1227 : {
1228 348977 : standard_tag = 0;
1229 : }
1230 :
1231 1512220 : switch (standard_tag)
1232 : {
1233 1245 : case TIFFTAG_SUBFILETYPE:
1234 1245 : *va_arg(ap, uint32_t *) = td->td_subfiletype;
1235 1245 : break;
1236 42795 : case TIFFTAG_IMAGEWIDTH:
1237 42795 : *va_arg(ap, uint32_t *) = td->td_imagewidth;
1238 42818 : break;
1239 42910 : case TIFFTAG_IMAGELENGTH:
1240 42910 : *va_arg(ap, uint32_t *) = td->td_imagelength;
1241 42912 : break;
1242 27271 : case TIFFTAG_BITSPERSAMPLE:
1243 27271 : *va_arg(ap, uint16_t *) = td->td_bitspersample;
1244 27254 : break;
1245 47475 : case TIFFTAG_COMPRESSION:
1246 47475 : *va_arg(ap, uint16_t *) = td->td_compression;
1247 47464 : break;
1248 32624 : case TIFFTAG_PHOTOMETRIC:
1249 32624 : *va_arg(ap, uint16_t *) = td->td_photometric;
1250 32613 : break;
1251 0 : case TIFFTAG_THRESHHOLDING:
1252 0 : *va_arg(ap, uint16_t *) = td->td_threshholding;
1253 0 : break;
1254 0 : case TIFFTAG_FILLORDER:
1255 0 : *va_arg(ap, uint16_t *) = td->td_fillorder;
1256 0 : break;
1257 16 : case TIFFTAG_ORIENTATION:
1258 16 : *va_arg(ap, uint16_t *) = td->td_orientation;
1259 16 : break;
1260 24512 : case TIFFTAG_SAMPLESPERPIXEL:
1261 24512 : *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
1262 24480 : break;
1263 22465 : case TIFFTAG_ROWSPERSTRIP:
1264 22465 : *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
1265 22453 : break;
1266 5 : case TIFFTAG_MINSAMPLEVALUE:
1267 5 : *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
1268 5 : break;
1269 5 : case TIFFTAG_MAXSAMPLEVALUE:
1270 5 : *va_arg(ap, uint16_t *) = td->td_maxsamplevalue;
1271 5 : break;
1272 0 : case TIFFTAG_SMINSAMPLEVALUE:
1273 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
1274 0 : *va_arg(ap, double **) = td->td_sminsamplevalue;
1275 : else
1276 : {
1277 : /* libtiff historically treats this as a single value. */
1278 : uint16_t i;
1279 0 : double v = td->td_sminsamplevalue[0];
1280 0 : for (i = 1; i < td->td_samplesperpixel; ++i)
1281 0 : if (td->td_sminsamplevalue[i] < v)
1282 0 : v = td->td_sminsamplevalue[i];
1283 0 : *va_arg(ap, double *) = v;
1284 : }
1285 0 : break;
1286 0 : case TIFFTAG_SMAXSAMPLEVALUE:
1287 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
1288 0 : *va_arg(ap, double **) = td->td_smaxsamplevalue;
1289 : else
1290 : {
1291 : /* libtiff historically treats this as a single value. */
1292 : uint16_t i;
1293 0 : double v = td->td_smaxsamplevalue[0];
1294 0 : for (i = 1; i < td->td_samplesperpixel; ++i)
1295 0 : if (td->td_smaxsamplevalue[i] > v)
1296 0 : v = td->td_smaxsamplevalue[i];
1297 0 : *va_arg(ap, double *) = v;
1298 : }
1299 0 : break;
1300 86 : case TIFFTAG_XRESOLUTION:
1301 86 : *va_arg(ap, float *) = td->td_xresolution;
1302 86 : break;
1303 85 : case TIFFTAG_YRESOLUTION:
1304 85 : *va_arg(ap, float *) = td->td_yresolution;
1305 85 : break;
1306 27876 : case TIFFTAG_PLANARCONFIG:
1307 27876 : *va_arg(ap, uint16_t *) = td->td_planarconfig;
1308 27864 : break;
1309 0 : case TIFFTAG_XPOSITION:
1310 0 : *va_arg(ap, float *) = td->td_xposition;
1311 0 : break;
1312 0 : case TIFFTAG_YPOSITION:
1313 0 : *va_arg(ap, float *) = td->td_yposition;
1314 0 : break;
1315 88 : case TIFFTAG_RESOLUTIONUNIT:
1316 88 : *va_arg(ap, uint16_t *) = td->td_resolutionunit;
1317 88 : break;
1318 0 : case TIFFTAG_PAGENUMBER:
1319 0 : *va_arg(ap, uint16_t *) = td->td_pagenumber[0];
1320 0 : *va_arg(ap, uint16_t *) = td->td_pagenumber[1];
1321 0 : break;
1322 0 : case TIFFTAG_HALFTONEHINTS:
1323 0 : *va_arg(ap, uint16_t *) = td->td_halftonehints[0];
1324 0 : *va_arg(ap, uint16_t *) = td->td_halftonehints[1];
1325 0 : break;
1326 149 : case TIFFTAG_COLORMAP:
1327 149 : *va_arg(ap, const uint16_t **) = td->td_colormap[0];
1328 149 : *va_arg(ap, const uint16_t **) = td->td_colormap[1];
1329 149 : *va_arg(ap, const uint16_t **) = td->td_colormap[2];
1330 149 : break;
1331 124063 : case TIFFTAG_STRIPOFFSETS:
1332 : case TIFFTAG_TILEOFFSETS:
1333 124063 : _TIFFFillStriles(tif);
1334 124064 : *va_arg(ap, const uint64_t **) = td->td_stripoffset_p;
1335 124064 : if (td->td_stripoffset_p == NULL)
1336 0 : ret_val = 0;
1337 124064 : break;
1338 131973 : case TIFFTAG_STRIPBYTECOUNTS:
1339 : case TIFFTAG_TILEBYTECOUNTS:
1340 131973 : _TIFFFillStriles(tif);
1341 131973 : *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p;
1342 131972 : if (td->td_stripbytecount_p == NULL)
1343 0 : ret_val = 0;
1344 131972 : break;
1345 0 : case TIFFTAG_MATTEING:
1346 0 : *va_arg(ap, uint16_t *) =
1347 0 : (td->td_extrasamples == 1 &&
1348 0 : td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
1349 0 : break;
1350 599513 : case TIFFTAG_EXTRASAMPLES:
1351 599513 : *va_arg(ap, uint16_t *) = td->td_extrasamples;
1352 599513 : *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
1353 599513 : break;
1354 3687 : case TIFFTAG_TILEWIDTH:
1355 3687 : *va_arg(ap, uint32_t *) = td->td_tilewidth;
1356 3687 : break;
1357 3687 : case TIFFTAG_TILELENGTH:
1358 3687 : *va_arg(ap, uint32_t *) = td->td_tilelength;
1359 3687 : break;
1360 0 : case TIFFTAG_TILEDEPTH:
1361 0 : *va_arg(ap, uint32_t *) = td->td_tiledepth;
1362 0 : break;
1363 0 : case TIFFTAG_DATATYPE:
1364 0 : switch (td->td_sampleformat)
1365 : {
1366 0 : case SAMPLEFORMAT_UINT:
1367 0 : *va_arg(ap, uint16_t *) = DATATYPE_UINT;
1368 0 : break;
1369 0 : case SAMPLEFORMAT_INT:
1370 0 : *va_arg(ap, uint16_t *) = DATATYPE_INT;
1371 0 : break;
1372 0 : case SAMPLEFORMAT_IEEEFP:
1373 0 : *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP;
1374 0 : break;
1375 0 : case SAMPLEFORMAT_VOID:
1376 0 : *va_arg(ap, uint16_t *) = DATATYPE_VOID;
1377 0 : break;
1378 : }
1379 0 : break;
1380 25971 : case TIFFTAG_SAMPLEFORMAT:
1381 25971 : *va_arg(ap, uint16_t *) = td->td_sampleformat;
1382 25924 : break;
1383 0 : case TIFFTAG_IMAGEDEPTH:
1384 0 : *va_arg(ap, uint32_t *) = td->td_imagedepth;
1385 0 : break;
1386 16 : case TIFFTAG_SUBIFD:
1387 16 : *va_arg(ap, uint16_t *) = td->td_nsubifd;
1388 16 : *va_arg(ap, const uint64_t **) = td->td_subifd;
1389 16 : break;
1390 0 : case TIFFTAG_YCBCRPOSITIONING:
1391 0 : *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
1392 0 : break;
1393 3671 : case TIFFTAG_YCBCRSUBSAMPLING:
1394 3671 : *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
1395 3671 : *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
1396 3513 : break;
1397 6 : case TIFFTAG_TRANSFERFUNCTION:
1398 6 : *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
1399 6 : if (td->td_samplesperpixel - td->td_extrasamples > 1)
1400 : {
1401 6 : *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
1402 6 : *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
1403 : }
1404 : else
1405 : {
1406 0 : *va_arg(ap, const uint16_t **) = NULL;
1407 0 : *va_arg(ap, const uint16_t **) = NULL;
1408 : }
1409 6 : break;
1410 771 : case TIFFTAG_REFERENCEBLACKWHITE:
1411 771 : *va_arg(ap, const float **) = td->td_refblackwhite;
1412 771 : break;
1413 0 : case TIFFTAG_INKNAMES:
1414 0 : *va_arg(ap, const char **) = td->td_inknames;
1415 0 : break;
1416 0 : case TIFFTAG_NUMBEROFINKS:
1417 0 : *va_arg(ap, uint16_t *) = td->td_numberofinks;
1418 0 : break;
1419 349258 : default:
1420 : {
1421 : int i;
1422 :
1423 : /*
1424 : * This can happen if multiple images are open
1425 : * with different codecs which have private
1426 : * tags. The global tag information table may
1427 : * then have tags that are valid for one file
1428 : * but not the other. If the client tries to
1429 : * get a tag that is not valid for the image's
1430 : * codec then we'll arrive here.
1431 : */
1432 349258 : if (fip->field_bit != FIELD_CUSTOM)
1433 : {
1434 0 : TIFFErrorExtR(tif, "_TIFFVGetField",
1435 : "%s: Invalid %stag \"%s\" "
1436 : "(not supported by codec)",
1437 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
1438 : fip->field_name);
1439 0 : ret_val = 0;
1440 0 : break;
1441 : }
1442 :
1443 : /*
1444 : * Do we have a custom value?
1445 : */
1446 349258 : ret_val = 0;
1447 1485440 : for (i = 0; i < td->td_customValueCount; i++)
1448 : {
1449 1209860 : TIFFTagValue *tv = td->td_customValues + i;
1450 :
1451 1209860 : if (tv->info->field_tag != tag)
1452 1136180 : continue;
1453 :
1454 73675 : if (fip->field_passcount)
1455 : {
1456 53601 : if (fip->field_readcount == TIFF_VARIABLE2)
1457 392 : *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
1458 : else /* Assume TIFF_VARIABLE */
1459 53209 : *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
1460 53602 : *va_arg(ap, const void **) = tv->value;
1461 53602 : ret_val = 1;
1462 : }
1463 20074 : else if (fip->field_tag == TIFFTAG_DOTRANGE &&
1464 0 : strcmp(fip->field_name, "DotRange") == 0)
1465 : {
1466 : /* TODO: This is an evil exception and should not have been
1467 : handled this way ... likely best if we move it into
1468 : the directory structure with an explicit field in
1469 : libtiff 4.1 and assign it a FIELD_ value */
1470 0 : *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0];
1471 0 : *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1];
1472 0 : ret_val = 1;
1473 : }
1474 : else
1475 : {
1476 20074 : if (fip->field_type == TIFF_ASCII ||
1477 39 : fip->field_readcount == TIFF_VARIABLE ||
1478 39 : fip->field_readcount == TIFF_VARIABLE2 ||
1479 39 : fip->field_readcount == TIFF_SPP || tv->count > 1)
1480 : {
1481 20068 : *va_arg(ap, void **) = tv->value;
1482 20067 : ret_val = 1;
1483 : }
1484 : else
1485 : {
1486 6 : char *val = (char *)tv->value;
1487 6 : assert(tv->count == 1);
1488 6 : switch (fip->field_type)
1489 : {
1490 0 : case TIFF_BYTE:
1491 : case TIFF_UNDEFINED:
1492 0 : *va_arg(ap, uint8_t *) = *(uint8_t *)val;
1493 0 : ret_val = 1;
1494 0 : break;
1495 0 : case TIFF_SBYTE:
1496 0 : *va_arg(ap, int8_t *) = *(int8_t *)val;
1497 0 : ret_val = 1;
1498 0 : break;
1499 0 : case TIFF_SHORT:
1500 0 : *va_arg(ap, uint16_t *) = *(uint16_t *)val;
1501 0 : ret_val = 1;
1502 0 : break;
1503 0 : case TIFF_SSHORT:
1504 0 : *va_arg(ap, int16_t *) = *(int16_t *)val;
1505 0 : ret_val = 1;
1506 0 : break;
1507 0 : case TIFF_LONG:
1508 : case TIFF_IFD:
1509 0 : *va_arg(ap, uint32_t *) = *(uint32_t *)val;
1510 0 : ret_val = 1;
1511 0 : break;
1512 0 : case TIFF_SLONG:
1513 0 : *va_arg(ap, int32_t *) = *(int32_t *)val;
1514 0 : ret_val = 1;
1515 0 : break;
1516 6 : case TIFF_LONG8:
1517 : case TIFF_IFD8:
1518 6 : *va_arg(ap, uint64_t *) = *(uint64_t *)val;
1519 6 : ret_val = 1;
1520 6 : break;
1521 0 : case TIFF_SLONG8:
1522 0 : *va_arg(ap, int64_t *) = *(int64_t *)val;
1523 0 : ret_val = 1;
1524 0 : break;
1525 0 : case TIFF_RATIONAL:
1526 : case TIFF_SRATIONAL:
1527 : {
1528 : /*-- Rational2Double: For Rationals evaluate
1529 : * "set_field_type" to determine internal
1530 : * storage size and return value size. */
1531 0 : int tv_size = TIFFFieldSetGetSize(fip);
1532 0 : if (tv_size == 8)
1533 : {
1534 0 : *va_arg(ap, double *) = *(double *)val;
1535 0 : ret_val = 1;
1536 : }
1537 : else
1538 : {
1539 : /*-- default should be tv_size == 4 */
1540 0 : *va_arg(ap, float *) = *(float *)val;
1541 0 : ret_val = 1;
1542 : /*-- ToDo: After Testing, this should be
1543 : * removed and tv_size==4 should be set as
1544 : * default. */
1545 0 : if (tv_size != 4)
1546 : {
1547 0 : TIFFErrorExtR(
1548 : tif, "_TIFFVGetField",
1549 : "Rational2Double: .set_field_type "
1550 : "in not 4 but %d",
1551 : tv_size);
1552 : }
1553 : }
1554 : }
1555 0 : break;
1556 0 : case TIFF_FLOAT:
1557 0 : *va_arg(ap, float *) = *(float *)val;
1558 0 : ret_val = 1;
1559 0 : break;
1560 0 : case TIFF_DOUBLE:
1561 0 : *va_arg(ap, double *) = *(double *)val;
1562 0 : ret_val = 1;
1563 0 : break;
1564 0 : default:
1565 0 : ret_val = 0;
1566 0 : break;
1567 : }
1568 : }
1569 : }
1570 73673 : break;
1571 : }
1572 : }
1573 : }
1574 1511950 : return (ret_val);
1575 : }
1576 :
1577 : /*
1578 : * Return the value of a field in the
1579 : * internal directory structure.
1580 : */
1581 1854470 : int TIFFGetField(TIFF *tif, uint32_t tag, ...)
1582 : {
1583 : int status;
1584 : va_list ap;
1585 :
1586 1854470 : va_start(ap, tag);
1587 1854470 : status = TIFFVGetField(tif, tag, ap);
1588 1854340 : va_end(ap);
1589 1854340 : return (status);
1590 : }
1591 :
1592 : /*
1593 : * Like TIFFGetField, but taking a varargs
1594 : * parameter list. This routine is useful
1595 : * for building higher-level interfaces on
1596 : * top of the library.
1597 : */
1598 1866200 : int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1599 : {
1600 1866200 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1601 1866810 : return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
1602 1542610 : ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
1603 3733050 : : 0);
1604 : }
1605 :
1606 : #define CleanupField(member) \
1607 : { \
1608 : if (td->member) \
1609 : { \
1610 : _TIFFfreeExt(tif, td->member); \
1611 : td->member = 0; \
1612 : } \
1613 : }
1614 :
1615 : /*
1616 : * Release storage associated with a directory.
1617 : */
1618 183338 : void TIFFFreeDirectory(TIFF *tif)
1619 : {
1620 183338 : TIFFDirectory *td = &tif->tif_dir;
1621 : int i;
1622 :
1623 183338 : _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1624 183310 : CleanupField(td_sminsamplevalue);
1625 183282 : CleanupField(td_smaxsamplevalue);
1626 183282 : CleanupField(td_colormap[0]);
1627 183282 : CleanupField(td_colormap[1]);
1628 183282 : CleanupField(td_colormap[2]);
1629 183282 : CleanupField(td_sampleinfo);
1630 183282 : CleanupField(td_subifd);
1631 183282 : CleanupField(td_inknames);
1632 183282 : CleanupField(td_refblackwhite);
1633 183282 : CleanupField(td_transferfunction[0]);
1634 183282 : CleanupField(td_transferfunction[1]);
1635 183282 : CleanupField(td_transferfunction[2]);
1636 183282 : CleanupField(td_stripoffset_p);
1637 183283 : CleanupField(td_stripbytecount_p);
1638 183285 : td->td_stripoffsetbyteallocsize = 0;
1639 183285 : TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1640 183285 : TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1641 :
1642 : /* Cleanup custom tag values */
1643 318179 : for (i = 0; i < td->td_customValueCount; i++)
1644 : {
1645 134896 : if (td->td_customValues[i].value)
1646 134896 : _TIFFfreeExt(tif, td->td_customValues[i].value);
1647 : }
1648 :
1649 183283 : td->td_customValueCount = 0;
1650 183283 : CleanupField(td_customValues);
1651 :
1652 183283 : _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1653 183266 : _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1654 :
1655 : /* Reset some internal parameters for IFD data size checking. */
1656 183254 : tif->tif_dir.td_dirdatasize_read = 0;
1657 183254 : tif->tif_dir.td_dirdatasize_write = 0;
1658 183254 : if (tif->tif_dir.td_dirdatasize_offsets != NULL)
1659 : {
1660 43895 : _TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
1661 43894 : tif->tif_dir.td_dirdatasize_offsets = NULL;
1662 43894 : tif->tif_dir.td_dirdatasize_Noffsets = 0;
1663 : }
1664 183253 : tif->tif_dir.td_iswrittentofile = FALSE;
1665 183253 : }
1666 : #undef CleanupField
1667 :
1668 : /*
1669 : * Client Tag extension support (from Niles Ritter).
1670 : */
1671 : static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1672 :
1673 1216 : TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1674 : {
1675 1216 : TIFFExtendProc prev = _TIFFextender;
1676 1216 : _TIFFextender = extender;
1677 1216 : return (prev);
1678 : }
1679 :
1680 : /*
1681 : * Setup for a new directory. Should we automatically call
1682 : * TIFFWriteDirectory() if the current one is dirty?
1683 : *
1684 : * The newly created directory will not exist on the file till
1685 : * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1686 : */
1687 38729 : int TIFFCreateDirectory(TIFF *tif)
1688 : {
1689 : /* Free previously allocated memory and setup default values. */
1690 38729 : TIFFFreeDirectory(tif);
1691 38729 : TIFFDefaultDirectory(tif);
1692 38732 : tif->tif_diroff = 0;
1693 38732 : tif->tif_nextdiroff = 0;
1694 38732 : tif->tif_curoff = 0;
1695 38732 : tif->tif_row = (uint32_t)-1;
1696 38732 : tif->tif_curstrip = (uint32_t)-1;
1697 38732 : tif->tif_dir.td_iswrittentofile = FALSE;
1698 :
1699 38732 : return 0;
1700 : }
1701 :
1702 0 : int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
1703 : {
1704 : /* Free previously allocated memory and setup default values. */
1705 0 : TIFFFreeDirectory(tif);
1706 0 : TIFFDefaultDirectory(tif);
1707 :
1708 : /*
1709 : * Reset the field definitions to match the application provided list.
1710 : * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1711 : * based on it's assumption this is an image directory.
1712 : */
1713 0 : _TIFFSetupFields(tif, infoarray);
1714 :
1715 0 : tif->tif_diroff = 0;
1716 0 : tif->tif_nextdiroff = 0;
1717 0 : tif->tif_curoff = 0;
1718 0 : tif->tif_row = (uint32_t)-1;
1719 0 : tif->tif_curstrip = (uint32_t)-1;
1720 : /* invalidate directory index */
1721 0 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
1722 : /* invalidate IFD loop lists */
1723 0 : _TIFFCleanupIFDOffsetAndNumberMaps(tif);
1724 : /* To be able to return from SubIFD or custom-IFD to main-IFD */
1725 0 : tif->tif_setdirectory_force_absolute = TRUE;
1726 :
1727 0 : return 0;
1728 : }
1729 :
1730 0 : int TIFFCreateEXIFDirectory(TIFF *tif)
1731 : {
1732 : const TIFFFieldArray *exifFieldArray;
1733 0 : exifFieldArray = _TIFFGetExifFields();
1734 0 : return TIFFCreateCustomDirectory(tif, exifFieldArray);
1735 : }
1736 :
1737 : /*
1738 : * Creates the EXIF GPS custom directory
1739 : */
1740 0 : int TIFFCreateGPSDirectory(TIFF *tif)
1741 : {
1742 : const TIFFFieldArray *gpsFieldArray;
1743 0 : gpsFieldArray = _TIFFGetGpsFields();
1744 0 : return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1745 : }
1746 :
1747 : /*
1748 : * Setup a default directory structure.
1749 : */
1750 118478 : int TIFFDefaultDirectory(TIFF *tif)
1751 : {
1752 118478 : register TIFFDirectory *td = &tif->tif_dir;
1753 : const TIFFFieldArray *tiffFieldArray;
1754 :
1755 118478 : tiffFieldArray = _TIFFGetFields();
1756 118418 : _TIFFSetupFields(tif, tiffFieldArray);
1757 :
1758 118471 : _TIFFmemset(td, 0, sizeof(*td));
1759 118467 : td->td_fillorder = FILLORDER_MSB2LSB;
1760 118467 : td->td_bitspersample = 1;
1761 118467 : td->td_threshholding = THRESHHOLD_BILEVEL;
1762 118467 : td->td_orientation = ORIENTATION_TOPLEFT;
1763 118467 : td->td_samplesperpixel = 1;
1764 118467 : td->td_rowsperstrip = (uint32_t)-1;
1765 118467 : td->td_tilewidth = 0;
1766 118467 : td->td_tilelength = 0;
1767 118467 : td->td_tiledepth = 1;
1768 : #ifdef STRIPBYTECOUNTSORTED_UNUSED
1769 : td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1770 : #endif
1771 118467 : td->td_resolutionunit = RESUNIT_INCH;
1772 118467 : td->td_sampleformat = SAMPLEFORMAT_UINT;
1773 118467 : td->td_imagedepth = 1;
1774 118467 : td->td_ycbcrsubsampling[0] = 2;
1775 118467 : td->td_ycbcrsubsampling[1] = 2;
1776 118467 : td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1777 118467 : tif->tif_postdecode = _TIFFNoPostDecode;
1778 118467 : tif->tif_foundfield = NULL;
1779 118467 : tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1780 118467 : tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1781 118467 : tif->tif_tagmethods.printdir = NULL;
1782 : /* additional default values */
1783 118467 : td->td_planarconfig = PLANARCONFIG_CONTIG;
1784 118467 : td->td_compression = COMPRESSION_NONE;
1785 118467 : td->td_subfiletype = 0;
1786 118467 : td->td_minsamplevalue = 0;
1787 : /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1788 : * Therefore, td_maxsamplevalue has to be re-calculated in
1789 : * TIFFGetFieldDefaulted(). */
1790 118467 : td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1791 118467 : td->td_extrasamples = 0;
1792 118467 : td->td_sampleinfo = NULL;
1793 :
1794 : /*
1795 : * Give client code a chance to install their own
1796 : * tag extensions & methods, prior to compression overloads,
1797 : * but do some prior cleanup first.
1798 : * (http://trac.osgeo.org/gdal/ticket/5054)
1799 : */
1800 118467 : if (tif->tif_nfieldscompat > 0)
1801 : {
1802 : uint32_t i;
1803 :
1804 169520 : for (i = 0; i < tif->tif_nfieldscompat; i++)
1805 : {
1806 113011 : if (tif->tif_fieldscompat[i].allocated_size)
1807 113013 : _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1808 : }
1809 56509 : _TIFFfreeExt(tif, tif->tif_fieldscompat);
1810 56504 : tif->tif_nfieldscompat = 0;
1811 56504 : tif->tif_fieldscompat = NULL;
1812 : }
1813 118465 : if (_TIFFextender)
1814 118466 : (*_TIFFextender)(tif);
1815 118479 : (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1816 : /*
1817 : * NB: The directory is marked dirty as a result of setting
1818 : * up the default compression scheme. However, this really
1819 : * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1820 : * if the user does something. We could just do the setup
1821 : * by hand, but it seems better to use the normal mechanism
1822 : * (i.e. TIFFSetField).
1823 : */
1824 118420 : tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1825 :
1826 : /*
1827 : * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1828 : * we clear the ISTILED flag when setting up a new directory.
1829 : * Should we also be clearing stuff like INSUBIFD?
1830 : */
1831 118420 : tif->tif_flags &= ~TIFF_ISTILED;
1832 :
1833 118420 : return (1);
1834 : }
1835 :
1836 12585 : static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1837 : tdir_t *nextdirnum)
1838 : {
1839 : static const char module[] = "TIFFAdvanceDirectory";
1840 :
1841 : /* Add this directory to the directory list, if not already in. */
1842 12585 : if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1843 : {
1844 0 : TIFFErrorExtR(tif, module,
1845 : "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1846 : ") might cause an IFD loop",
1847 : *nextdirnum, *nextdiroff, *nextdiroff);
1848 0 : *nextdiroff = 0;
1849 0 : *nextdirnum = 0;
1850 0 : return (0);
1851 : }
1852 :
1853 12585 : if (isMapped(tif))
1854 : {
1855 0 : uint64_t poff = *nextdiroff;
1856 0 : if (!(tif->tif_flags & TIFF_BIGTIFF))
1857 : {
1858 : tmsize_t poffa, poffb, poffc, poffd;
1859 : uint16_t dircount;
1860 : uint32_t nextdir32;
1861 0 : poffa = (tmsize_t)poff;
1862 0 : poffb = poffa + sizeof(uint16_t);
1863 0 : if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1864 0 : (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1865 : {
1866 0 : TIFFErrorExtR(tif, module,
1867 : "%s:%d: %s: Error fetching directory count",
1868 : __FILE__, __LINE__, tif->tif_name);
1869 0 : *nextdiroff = 0;
1870 0 : return (0);
1871 : }
1872 0 : _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1873 0 : if (tif->tif_flags & TIFF_SWAB)
1874 0 : TIFFSwabShort(&dircount);
1875 0 : poffc = poffb + dircount * 12;
1876 0 : poffd = poffc + sizeof(uint32_t);
1877 0 : if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1878 0 : (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1879 : {
1880 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1881 0 : return (0);
1882 : }
1883 0 : if (off != NULL)
1884 0 : *off = (uint64_t)poffc;
1885 0 : _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1886 0 : if (tif->tif_flags & TIFF_SWAB)
1887 0 : TIFFSwabLong(&nextdir32);
1888 0 : *nextdiroff = nextdir32;
1889 : }
1890 : else
1891 : {
1892 : tmsize_t poffa, poffb, poffc, poffd;
1893 : uint64_t dircount64;
1894 : uint16_t dircount16;
1895 0 : if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1896 : {
1897 0 : TIFFErrorExtR(tif, module,
1898 : "%s:%d: %s: Error fetching directory count",
1899 : __FILE__, __LINE__, tif->tif_name);
1900 0 : return (0);
1901 : }
1902 0 : poffa = (tmsize_t)poff;
1903 0 : poffb = poffa + sizeof(uint64_t);
1904 0 : if (poffb > tif->tif_size)
1905 : {
1906 0 : TIFFErrorExtR(tif, module,
1907 : "%s:%d: %s: Error fetching directory count",
1908 : __FILE__, __LINE__, tif->tif_name);
1909 0 : return (0);
1910 : }
1911 0 : _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1912 0 : if (tif->tif_flags & TIFF_SWAB)
1913 0 : TIFFSwabLong8(&dircount64);
1914 0 : if (dircount64 > 0xFFFF)
1915 : {
1916 0 : TIFFErrorExtR(tif, module,
1917 : "Sanity check on directory count failed");
1918 0 : return (0);
1919 : }
1920 0 : dircount16 = (uint16_t)dircount64;
1921 0 : if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1922 : (tmsize_t)sizeof(uint64_t))
1923 : {
1924 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1925 0 : return (0);
1926 : }
1927 0 : poffc = poffb + dircount16 * 20;
1928 0 : poffd = poffc + sizeof(uint64_t);
1929 0 : if (poffd > tif->tif_size)
1930 : {
1931 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1932 0 : return (0);
1933 : }
1934 0 : if (off != NULL)
1935 0 : *off = (uint64_t)poffc;
1936 0 : _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1937 0 : if (tif->tif_flags & TIFF_SWAB)
1938 0 : TIFFSwabLong8(nextdiroff);
1939 : }
1940 : }
1941 : else
1942 : {
1943 12585 : if (!(tif->tif_flags & TIFF_BIGTIFF))
1944 : {
1945 : uint16_t dircount;
1946 : uint32_t nextdir32;
1947 23512 : if (!SeekOK(tif, *nextdiroff) ||
1948 11756 : !ReadOK(tif, &dircount, sizeof(uint16_t)))
1949 : {
1950 6 : TIFFErrorExtR(tif, module,
1951 : "%s:%d: %s: Error fetching directory count",
1952 : __FILE__, __LINE__, tif->tif_name);
1953 6 : return (0);
1954 : }
1955 11750 : if (tif->tif_flags & TIFF_SWAB)
1956 271 : TIFFSwabShort(&dircount);
1957 11750 : if (off != NULL)
1958 7 : *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1959 : else
1960 11743 : (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1961 11750 : if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1962 : {
1963 0 : TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1964 : tif->tif_name);
1965 0 : return (0);
1966 : }
1967 11750 : if (tif->tif_flags & TIFF_SWAB)
1968 271 : TIFFSwabLong(&nextdir32);
1969 11750 : *nextdiroff = nextdir32;
1970 : }
1971 : else
1972 : {
1973 : uint64_t dircount64;
1974 : uint16_t dircount16;
1975 1658 : if (!SeekOK(tif, *nextdiroff) ||
1976 829 : !ReadOK(tif, &dircount64, sizeof(uint64_t)))
1977 : {
1978 0 : TIFFErrorExtR(tif, module,
1979 : "%s:%d: %s: Error fetching directory count",
1980 : __FILE__, __LINE__, tif->tif_name);
1981 0 : return (0);
1982 : }
1983 829 : if (tif->tif_flags & TIFF_SWAB)
1984 4 : TIFFSwabLong8(&dircount64);
1985 829 : if (dircount64 > 0xFFFF)
1986 : {
1987 0 : TIFFErrorExtR(tif, module,
1988 : "%s:%d: %s: Error fetching directory count",
1989 : __FILE__, __LINE__, tif->tif_name);
1990 0 : return (0);
1991 : }
1992 829 : dircount16 = (uint16_t)dircount64;
1993 829 : if (off != NULL)
1994 0 : *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1995 : else
1996 829 : (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1997 829 : if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1998 : {
1999 0 : TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
2000 : tif->tif_name);
2001 0 : return (0);
2002 : }
2003 829 : if (tif->tif_flags & TIFF_SWAB)
2004 4 : TIFFSwabLong8(nextdiroff);
2005 : }
2006 : }
2007 12579 : if (*nextdiroff != 0)
2008 : {
2009 5172 : (*nextdirnum)++;
2010 : /* Check next directory for IFD looping and if so, set it as last
2011 : * directory. */
2012 5172 : if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
2013 : {
2014 0 : TIFFWarningExtR(
2015 : tif, module,
2016 : "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
2017 : ") might be an IFD loop. Treating directory %d as "
2018 : "last directory",
2019 0 : *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
2020 0 : *nextdiroff = 0;
2021 0 : (*nextdirnum)--;
2022 : }
2023 : }
2024 12579 : return (1);
2025 : }
2026 :
2027 : /*
2028 : * Count the number of directories in a file.
2029 : */
2030 7409 : tdir_t TIFFNumberOfDirectories(TIFF *tif)
2031 : {
2032 : uint64_t nextdiroff;
2033 : tdir_t nextdirnum;
2034 : tdir_t n;
2035 7409 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2036 7132 : nextdiroff = tif->tif_header.classic.tiff_diroff;
2037 : else
2038 277 : nextdiroff = tif->tif_header.big.tiff_diroff;
2039 7409 : nextdirnum = 0;
2040 7409 : n = 0;
2041 32551 : while (nextdiroff != 0 &&
2042 12574 : TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2043 : {
2044 12568 : ++n;
2045 : }
2046 : /* Update number of main-IFDs in file. */
2047 7409 : tif->tif_curdircount = n;
2048 7409 : return (n);
2049 : }
2050 :
2051 : /*
2052 : * Set the n-th directory as the current directory.
2053 : * NB: Directories are numbered starting at 0.
2054 : */
2055 7803 : int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2056 : {
2057 : uint64_t nextdiroff;
2058 7803 : tdir_t nextdirnum = 0;
2059 : tdir_t n;
2060 :
2061 7803 : if (tif->tif_setdirectory_force_absolute)
2062 : {
2063 : /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2064 : * chain from the beginning, thus IFD directory list needs to be cleared
2065 : * from possible SubIFD offsets.
2066 : */
2067 0 : _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2068 : }
2069 :
2070 : /* Even faster path, if offset is available within IFD loop hash list. */
2071 15606 : if (!tif->tif_setdirectory_force_absolute &&
2072 7803 : _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
2073 : {
2074 : /* Set parameters for following TIFFReadDirectory() below. */
2075 7803 : tif->tif_nextdiroff = nextdiroff;
2076 7803 : tif->tif_curdir = dirn;
2077 : /* Reset to relative stepping */
2078 7803 : tif->tif_setdirectory_force_absolute = FALSE;
2079 : }
2080 : else
2081 : {
2082 :
2083 : /* Fast path when we just advance relative to the current directory:
2084 : * start at the current dir offset and continue to seek from there.
2085 : * Check special cases when relative is not allowed:
2086 : * - jump back from SubIFD or custom directory
2087 : * - right after TIFFWriteDirectory() jump back to that directory
2088 : * using TIFFSetDirectory() */
2089 0 : const int relative = (dirn >= tif->tif_curdir) &&
2090 0 : (tif->tif_diroff != 0) &&
2091 0 : !tif->tif_setdirectory_force_absolute;
2092 :
2093 0 : if (relative)
2094 : {
2095 0 : nextdiroff = tif->tif_diroff;
2096 0 : dirn -= tif->tif_curdir;
2097 0 : nextdirnum = tif->tif_curdir;
2098 : }
2099 0 : else if (!(tif->tif_flags & TIFF_BIGTIFF))
2100 0 : nextdiroff = tif->tif_header.classic.tiff_diroff;
2101 : else
2102 0 : nextdiroff = tif->tif_header.big.tiff_diroff;
2103 :
2104 : /* Reset to relative stepping */
2105 0 : tif->tif_setdirectory_force_absolute = FALSE;
2106 :
2107 0 : for (n = dirn; n > 0 && nextdiroff != 0; n--)
2108 0 : if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2109 0 : return (0);
2110 : /* If the n-th directory could not be reached (does not exist),
2111 : * return here without touching anything further. */
2112 0 : if (nextdiroff == 0 || n > 0)
2113 0 : return (0);
2114 :
2115 0 : tif->tif_nextdiroff = nextdiroff;
2116 :
2117 : /* Set curdir to the actual directory index. */
2118 0 : if (relative)
2119 0 : tif->tif_curdir += dirn - n;
2120 : else
2121 0 : tif->tif_curdir = dirn - n;
2122 : }
2123 :
2124 : /* The -1 decrement is because TIFFReadDirectory will increment
2125 : * tif_curdir after successfully reading the directory. */
2126 7803 : if (tif->tif_curdir == 0)
2127 7112 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2128 : else
2129 691 : tif->tif_curdir--;
2130 :
2131 7803 : tdir_t curdir = tif->tif_curdir;
2132 :
2133 7803 : int retval = TIFFReadDirectory(tif);
2134 :
2135 7803 : if (!retval && tif->tif_curdir == curdir)
2136 : {
2137 : /* If tif_curdir has not be incremented, TIFFFetchDirectory() in
2138 : * TIFFReadDirectory() has failed and tif_curdir shall be set
2139 : * specifically. */
2140 4 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2141 : }
2142 7803 : return (retval);
2143 : }
2144 :
2145 : /*
2146 : * Set the current directory to be the directory
2147 : * located at the specified file offset. This interface
2148 : * is used mainly to access directories linked with
2149 : * the SubIFD tag (e.g. thumbnail images).
2150 : */
2151 15877 : int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2152 : {
2153 : /* Match nextdiroff and curdir for consistent IFD-loop checking.
2154 : * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2155 : * invalid offsets within the main IFD tree. In the case of several subIFDs
2156 : * of a main image, there are two possibilities that are not even mutually
2157 : * exclusive. a.) The subIFD tag contains an array with all offsets of the
2158 : * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2159 : * (refer to
2160 : * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2161 : */
2162 : int retval;
2163 15877 : uint32_t curdir = 0;
2164 15877 : int8_t probablySubIFD = 0;
2165 15877 : if (diroff == 0)
2166 : {
2167 : /* Special case to set tif_diroff=0, which is done in
2168 : * TIFFReadDirectory() below to indicate that the currently read IFD is
2169 : * treated as a new, fresh IFD. */
2170 6902 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2171 6902 : tif->tif_dir.td_iswrittentofile = FALSE;
2172 : }
2173 : else
2174 : {
2175 8975 : if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2176 : {
2177 : /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2178 43 : probablySubIFD = 1;
2179 : }
2180 : /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2181 8975 : if (curdir >= 1)
2182 1573 : tif->tif_curdir = curdir - 1;
2183 : else
2184 7402 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2185 : }
2186 15877 : curdir = tif->tif_curdir;
2187 :
2188 15877 : tif->tif_nextdiroff = diroff;
2189 15877 : retval = TIFFReadDirectory(tif);
2190 :
2191 : /* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
2192 : * incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
2193 : * be set specifically. */
2194 15877 : if (!retval && diroff != 0 && tif->tif_curdir == curdir)
2195 : {
2196 0 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2197 : }
2198 :
2199 15877 : if (probablySubIFD)
2200 : {
2201 43 : if (retval)
2202 : {
2203 : /* Reset IFD list to start new one for SubIFD chain and also start
2204 : * SubIFD chain with tif_curdir=0 for IFD loop checking. */
2205 : /* invalidate IFD loop lists */
2206 43 : _TIFFCleanupIFDOffsetAndNumberMaps(tif);
2207 43 : tif->tif_curdir = 0; /* first directory of new chain */
2208 : /* add this offset to new IFD list */
2209 43 : _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2210 : }
2211 : /* To be able to return from SubIFD or custom-IFD to main-IFD */
2212 43 : tif->tif_setdirectory_force_absolute = TRUE;
2213 : }
2214 :
2215 15877 : return (retval);
2216 : }
2217 :
2218 : /*
2219 : * Return file offset of the current directory.
2220 : */
2221 106396 : uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2222 :
2223 : /*
2224 : * Return an indication of whether or not we are
2225 : * at the last directory in the file.
2226 : */
2227 7564 : int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2228 :
2229 : /*
2230 : * Unlink the specified directory from the directory chain.
2231 : * Note: First directory starts with number dirn=1.
2232 : * This is different to TIFFSetDirectory() where the first directory starts with
2233 : * zero.
2234 : */
2235 4 : int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2236 : {
2237 : static const char module[] = "TIFFUnlinkDirectory";
2238 : uint64_t nextdir;
2239 : tdir_t nextdirnum;
2240 : uint64_t off;
2241 : tdir_t n;
2242 :
2243 4 : if (tif->tif_mode == O_RDONLY)
2244 : {
2245 0 : TIFFErrorExtR(tif, module,
2246 : "Can not unlink directory in read-only file");
2247 0 : return (0);
2248 : }
2249 4 : if (dirn == 0)
2250 : {
2251 0 : TIFFErrorExtR(tif, module,
2252 : "For TIFFUnlinkDirectory() first directory starts with "
2253 : "number 1 and not 0");
2254 0 : return (0);
2255 : }
2256 : /*
2257 : * Go to the directory before the one we want
2258 : * to unlink and nab the offset of the link
2259 : * field we'll need to patch.
2260 : */
2261 4 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2262 : {
2263 4 : nextdir = tif->tif_header.classic.tiff_diroff;
2264 4 : off = 4;
2265 : }
2266 : else
2267 : {
2268 0 : nextdir = tif->tif_header.big.tiff_diroff;
2269 0 : off = 8;
2270 : }
2271 4 : nextdirnum = 0; /* First directory is dirn=0 */
2272 :
2273 11 : for (n = dirn - 1; n > 0; n--)
2274 : {
2275 7 : if (nextdir == 0)
2276 : {
2277 0 : TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2278 0 : return (0);
2279 : }
2280 7 : if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2281 0 : return (0);
2282 : }
2283 : /*
2284 : * Advance to the directory to be unlinked and fetch
2285 : * the offset of the directory that follows.
2286 : */
2287 4 : if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2288 0 : return (0);
2289 : /*
2290 : * Go back and patch the link field of the preceding
2291 : * directory to point to the offset of the directory
2292 : * that follows.
2293 : */
2294 4 : (void)TIFFSeekFile(tif, off, SEEK_SET);
2295 4 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2296 : {
2297 : uint32_t nextdir32;
2298 4 : nextdir32 = (uint32_t)nextdir;
2299 4 : assert((uint64_t)nextdir32 == nextdir);
2300 4 : if (tif->tif_flags & TIFF_SWAB)
2301 0 : TIFFSwabLong(&nextdir32);
2302 4 : if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2303 : {
2304 0 : TIFFErrorExtR(tif, module, "Error writing directory link");
2305 0 : return (0);
2306 : }
2307 : }
2308 : else
2309 : {
2310 : /* Need local swap because nextdir has to be used unswapped below. */
2311 0 : uint64_t nextdir64 = nextdir;
2312 0 : if (tif->tif_flags & TIFF_SWAB)
2313 0 : TIFFSwabLong8(&nextdir64);
2314 0 : if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
2315 : {
2316 0 : TIFFErrorExtR(tif, module, "Error writing directory link");
2317 0 : return (0);
2318 : }
2319 : }
2320 :
2321 : /* For dirn=1 (first directory) also update the libtiff internal
2322 : * base offset variables. */
2323 4 : if (dirn == 1)
2324 : {
2325 0 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2326 0 : tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
2327 : else
2328 0 : tif->tif_header.big.tiff_diroff = nextdir;
2329 : }
2330 :
2331 : /*
2332 : * Leave directory state setup safely. We don't have
2333 : * facilities for doing inserting and removing directories,
2334 : * so it's safest to just invalidate everything. This
2335 : * means that the caller can only append to the directory
2336 : * chain.
2337 : */
2338 4 : (*tif->tif_cleanup)(tif);
2339 4 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2340 : {
2341 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
2342 0 : tif->tif_rawdata = NULL;
2343 0 : tif->tif_rawcc = 0;
2344 0 : tif->tif_rawdataoff = 0;
2345 0 : tif->tif_rawdataloaded = 0;
2346 : }
2347 4 : tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2348 : TIFF_BUF4WRITE);
2349 4 : TIFFFreeDirectory(tif);
2350 4 : TIFFDefaultDirectory(tif);
2351 4 : tif->tif_diroff = 0; /* force link on next write */
2352 4 : tif->tif_nextdiroff = 0; /* next write must be at end */
2353 4 : tif->tif_lastdiroff = 0; /* will be updated on next link */
2354 4 : tif->tif_curoff = 0;
2355 4 : tif->tif_row = (uint32_t)-1;
2356 4 : tif->tif_curstrip = (uint32_t)-1;
2357 4 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2358 4 : if (tif->tif_curdircount > 0)
2359 4 : tif->tif_curdircount--;
2360 : else
2361 0 : tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
2362 4 : _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2363 4 : return (1);
2364 : }
|