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 51639 : static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
44 : size_t elem_size)
45 : {
46 51639 : if (*vpp)
47 : {
48 1410 : _TIFFfreeExt(tif, *vpp);
49 1410 : *vpp = 0;
50 : }
51 51639 : if (vp)
52 : {
53 51520 : tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
54 51559 : if (bytes)
55 51536 : *vpp = (void *)_TIFFmallocExt(tif, bytes);
56 51603 : if (*vpp)
57 51570 : _TIFFmemcpy(*vpp, vp, bytes);
58 : }
59 51740 : }
60 0 : void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
61 : {
62 0 : setByteArray(NULL, vpp, vp, n, 1);
63 0 : }
64 3137 : void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
65 : {
66 3137 : setByteArray(tif, vpp, vp, n, 1);
67 3137 : }
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 8810 : void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp,
79 : uint32_t n)
80 : {
81 8810 : setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
82 8810 : }
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 78 : static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp,
95 : uint32_t n)
96 : {
97 78 : setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
98 78 : }
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 1866 : void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n)
105 : {
106 1866 : setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
107 1866 : }
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 7582 : 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 7582 : TIFFDirectory *td = &tif->tif_dir;
143 : static const char module[] = "setExtraSamples";
144 :
145 7582 : *v = (uint16_t)va_arg(ap, uint16_vap);
146 7582 : if ((uint16_t)*v > td->td_samplesperpixel)
147 0 : return 0;
148 7582 : va = va_arg(ap, uint16_t *);
149 7582 : if (*v > 0 && va == NULL) /* typically missing param */
150 0 : return 0;
151 805809 : for (i = 0; i < *v; i++)
152 : {
153 798227 : 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 7582 : 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 7582 : td->td_extrasamples = (uint16_t)*v;
182 7582 : _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
183 7582 : 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 1066010 : static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
221 : {
222 : static const char module[] = "_TIFFVSetField";
223 :
224 1066010 : TIFFDirectory *td = &tif->tif_dir;
225 1066010 : int status = 1;
226 : uint32_t v32, v;
227 : double dblval;
228 : char *s;
229 1066010 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
230 1065820 : uint32_t standard_tag = tag;
231 1065820 : 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 1065820 : if (fip->field_bit == FIELD_CUSTOM)
240 : {
241 139430 : standard_tag = 0;
242 : }
243 :
244 1065820 : switch (standard_tag)
245 : {
246 6238 : case TIFFTAG_SUBFILETYPE:
247 6238 : td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
248 6238 : break;
249 81493 : case TIFFTAG_IMAGEWIDTH:
250 81493 : td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
251 81497 : break;
252 81486 : case TIFFTAG_IMAGELENGTH:
253 81486 : td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
254 81504 : break;
255 81481 : case TIFFTAG_BITSPERSAMPLE:
256 81481 : 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 81480 : if (tif->tif_flags & TIFF_SWAB)
265 : {
266 696 : if (td->td_bitspersample == 8)
267 386 : tif->tif_postdecode = _TIFFNoPostDecode;
268 310 : else if (td->td_bitspersample == 16)
269 126 : tif->tif_postdecode = _TIFFSwab16BitData;
270 184 : else if (td->td_bitspersample == 24)
271 0 : tif->tif_postdecode = _TIFFSwab24BitData;
272 184 : else if (td->td_bitspersample == 32)
273 138 : 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 81480 : break;
280 201856 : case TIFFTAG_COMPRESSION:
281 201856 : 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 201901 : if (TIFFFieldSet(tif, FIELD_COMPRESSION))
288 : {
289 82186 : if ((uint32_t)td->td_compression == v)
290 47668 : break;
291 34518 : (*tif->tif_cleanup)(tif);
292 34516 : tif->tif_flags &= ~TIFF_CODERSETUP;
293 : }
294 : /*
295 : * Setup new compression routine state.
296 : */
297 154231 : if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
298 154194 : td->td_compression = (uint16_t)v;
299 : else
300 0 : status = 0;
301 154160 : break;
302 81511 : case TIFFTAG_PHOTOMETRIC:
303 81511 : td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
304 81495 : 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 92 : case TIFFTAG_ORIENTATION:
315 92 : v = (uint16_t)va_arg(ap, uint16_vap);
316 92 : if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
317 0 : goto badvalue;
318 : else
319 92 : td->td_orientation = (uint16_t)v;
320 92 : break;
321 81459 : case TIFFTAG_SAMPLESPERPIXEL:
322 81459 : v = (uint16_t)va_arg(ap, uint16_vap);
323 81451 : if (v == 0)
324 0 : goto badvalue;
325 81451 : if (v != td->td_samplesperpixel)
326 : {
327 : /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
328 20162 : 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 20162 : 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 20162 : 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 81440 : td->td_samplesperpixel = (uint16_t)v;
365 81440 : break;
366 71993 : case TIFFTAG_ROWSPERSTRIP:
367 71993 : v32 = (uint32_t)va_arg(ap, uint32_t);
368 71988 : if (v32 == 0)
369 0 : goto badvalue32;
370 71988 : td->td_rowsperstrip = v32;
371 71988 : if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
372 : {
373 71955 : td->td_tilelength = v32;
374 71955 : td->td_tilewidth = td->td_imagewidth;
375 : }
376 71988 : 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 130 : case TIFFTAG_XRESOLUTION:
404 130 : dblval = va_arg(ap, double);
405 130 : if (dblval != dblval || dblval < 0)
406 0 : goto badvaluedouble;
407 130 : td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
408 130 : break;
409 130 : case TIFFTAG_YRESOLUTION:
410 130 : dblval = va_arg(ap, double);
411 130 : if (dblval != dblval || dblval < 0)
412 0 : goto badvaluedouble;
413 130 : td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
414 130 : break;
415 126329 : case TIFFTAG_PLANARCONFIG:
416 126329 : v = (uint16_t)va_arg(ap, uint16_vap);
417 126329 : if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
418 0 : goto badvalue;
419 126329 : td->td_planarconfig = (uint16_t)v;
420 126329 : 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 134 : case TIFFTAG_RESOLUTIONUNIT:
428 134 : v = (uint16_t)va_arg(ap, uint16_vap);
429 134 : if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
430 0 : goto badvalue;
431 134 : td->td_resolutionunit = (uint16_t)v;
432 134 : 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 7582 : case TIFFTAG_EXTRASAMPLES:
451 7582 : if (!setExtraSamples(tif, ap, &v))
452 0 : goto badvalue;
453 7582 : 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 9635 : case TIFFTAG_TILEWIDTH:
463 9635 : v32 = (uint32_t)va_arg(ap, uint32_t);
464 9635 : 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 9635 : td->td_tilewidth = v32;
473 9635 : tif->tif_flags |= TIFF_ISTILED;
474 9635 : break;
475 9635 : case TIFFTAG_TILELENGTH:
476 9635 : v32 = (uint32_t)va_arg(ap, uint32_t);
477 9635 : 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 9634 : td->td_tilelength = v32;
486 9634 : tif->tif_flags |= TIFF_ISTILED;
487 9634 : 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 80441 : case TIFFTAG_SAMPLEFORMAT:
516 80441 : v = (uint16_t)va_arg(ap, uint16_vap);
517 80458 : if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
518 34 : goto badvalue;
519 80424 : td->td_sampleformat = (uint16_t)v;
520 :
521 : /* Try to fix up the SWAB function for complex data. */
522 80424 : 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 80343 : else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
527 79628 : td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
528 1436 : td->td_bitspersample == 64 &&
529 669 : tif->tif_postdecode == _TIFFSwab64BitData)
530 14 : tif->tif_postdecode = _TIFFSwab32BitData;
531 80424 : break;
532 0 : case TIFFTAG_IMAGEDEPTH:
533 0 : td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
534 0 : break;
535 78 : case TIFFTAG_SUBIFD:
536 78 : if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
537 : {
538 78 : td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
539 78 : _TIFFsetLong8Array(tif, &td->td_subifd,
540 78 : (uint64_t *)va_arg(ap, uint64_t *),
541 78 : (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 78 : break;
550 11 : case TIFFTAG_YCBCRPOSITIONING:
551 11 : td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
552 11 : break;
553 2187 : case TIFFTAG_YCBCRSUBSAMPLING:
554 2187 : td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
555 2187 : td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
556 2187 : 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 1866 : case TIFFTAG_REFERENCEBLACKWHITE:
568 : /* XXX should check for null range */
569 1866 : _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
570 1866 : va_arg(ap, float *), 6);
571 1866 : 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 139617 : 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 139617 : 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 139617 : 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 139617 : tv = NULL;
705 363020 : for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
706 : {
707 225453 : if (td->td_customValues[iCustom].info->field_tag == tag)
708 : {
709 2050 : tv = td->td_customValues + iCustom;
710 2050 : if (tv->value != NULL)
711 : {
712 2050 : _TIFFfreeExt(tif, tv->value);
713 2050 : tv->value = NULL;
714 : }
715 2050 : break;
716 : }
717 : }
718 :
719 : /*
720 : * Grow the custom list if the entry was not found.
721 : */
722 139617 : if (tv == NULL)
723 : {
724 : TIFFTagValue *new_customValues;
725 :
726 137257 : new_customValues = (TIFFTagValue *)_TIFFreallocExt(
727 137257 : tif, td->td_customValues,
728 137257 : sizeof(TIFFTagValue) * (td->td_customValueCount + 1));
729 137499 : if (!new_customValues)
730 : {
731 44 : TIFFErrorExtR(tif, module,
732 : "%s: Failed to allocate space for list of "
733 : "custom values",
734 : tif->tif_name);
735 0 : status = 0;
736 0 : goto end;
737 : }
738 :
739 137455 : td->td_customValueCount++;
740 137455 : td->td_customValues = new_customValues;
741 :
742 137455 : tv = td->td_customValues + (td->td_customValueCount - 1);
743 137455 : tv->info = fip;
744 137455 : tv->value = NULL;
745 137455 : 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_get_field_type"
752 : * to determine internal storage size. */
753 139815 : tv_size = TIFFFieldSetGetSize(fip);
754 139430 : if (tv_size == 0)
755 : {
756 46 : status = 0;
757 46 : TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
758 46 : tif->tif_name, fip->field_type, fip->field_name);
759 0 : goto end;
760 : }
761 :
762 139384 : if (fip->field_type == TIFF_ASCII)
763 : {
764 : uint32_t ma;
765 : const char *mb;
766 37692 : 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 37692 : mb = (const char *)va_arg(ap, const char *);
775 37654 : size_t len = strlen(mb) + 1;
776 37654 : 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 37706 : ma = (uint32_t)len;
786 : }
787 37706 : tv->count = ma;
788 37706 : setByteArray(tif, &tv->value, mb, ma, 1);
789 : }
790 : else
791 : {
792 101692 : if (fip->field_passcount)
793 : {
794 101623 : if (fip->field_writecount == TIFF_VARIABLE2)
795 3002 : tv->count = (uint32_t)va_arg(ap, uint32_t);
796 : else
797 98621 : tv->count = (int)va_arg(ap, int);
798 : }
799 69 : else if (fip->field_writecount == TIFF_VARIABLE ||
800 71 : fip->field_writecount == TIFF_VARIABLE2)
801 0 : 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 101661 : 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 101661 : tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
819 : "custom tag binary object");
820 101812 : if (!tv->value)
821 : {
822 0 : status = 0;
823 0 : goto end;
824 : }
825 :
826 101812 : 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 101812 : 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_get_field_type! */
846 101750 : _TIFFmemcpy(tv->value, va_arg(ap, void *),
847 101804 : 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 101756 : if (!(tif->tif_flags & TIFF_BIGTIFF))
851 : {
852 101634 : 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 101634 : 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
981 : * fip->set_get_field_type!
982 : */
983 : {
984 0 : if (tv_size == 8)
985 : {
986 0 : double v2 = va_arg(ap, double);
987 0 : _TIFFmemcpy(val, &v2, tv_size);
988 : }
989 : else
990 : {
991 : /*-- default should be tv_size == 4 */
992 0 : float v3 = (float)va_arg(ap, double);
993 0 : _TIFFmemcpy(val, &v3, tv_size);
994 : /*-- ToDo: After Testing, this should be
995 : * removed and tv_size==4 should be set as
996 : * default. */
997 0 : if (tv_size != 4)
998 : {
999 0 : TIFFErrorExtR(tif, module,
1000 : "Rational2Double: "
1001 : ".set_get_field_type "
1002 : "in not 4 but %d",
1003 : tv_size);
1004 : }
1005 : }
1006 : }
1007 0 : break;
1008 0 : case TIFF_FLOAT:
1009 : {
1010 0 : float v2 =
1011 0 : _TIFFClampDoubleToFloat(va_arg(ap, double));
1012 0 : _TIFFmemcpy(val, &v2, tv_size);
1013 : }
1014 0 : break;
1015 0 : case TIFF_DOUBLE:
1016 : {
1017 0 : double v2 = va_arg(ap, double);
1018 0 : _TIFFmemcpy(val, &v2, tv_size);
1019 : }
1020 0 : break;
1021 0 : default:
1022 0 : _TIFFmemset(val, 0, tv_size);
1023 0 : status = 0;
1024 0 : break;
1025 : }
1026 : }
1027 : }
1028 : }
1029 : }
1030 1065310 : if (status)
1031 : {
1032 1065310 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1033 1065380 : if (fip2)
1034 1065290 : TIFFSetFieldBit(tif, fip2->field_bit);
1035 1065380 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1036 : }
1037 :
1038 0 : end:
1039 1065380 : va_end(ap);
1040 1065380 : return (status);
1041 34 : badvalue:
1042 : {
1043 34 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1044 0 : TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1045 : tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
1046 0 : va_end(ap);
1047 : }
1048 0 : return (0);
1049 1 : badvalue32:
1050 : {
1051 1 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1052 1 : TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1053 : tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
1054 1 : va_end(ap);
1055 : }
1056 1 : return (0);
1057 0 : badvaluedouble:
1058 : {
1059 0 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1060 0 : TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
1061 : dblval, fip2 ? fip2->field_name : "Unknown");
1062 0 : va_end(ap);
1063 : }
1064 0 : return (0);
1065 0 : badvalueifd8long8:
1066 : {
1067 : /* Error message issued already above. */
1068 0 : TIFFTagValue *tv2 = NULL;
1069 : int iCustom2, iC2;
1070 : /* Find the existing entry for this custom value. */
1071 0 : for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
1072 : {
1073 0 : if (td->td_customValues[iCustom2].info->field_tag == tag)
1074 : {
1075 0 : tv2 = td->td_customValues + (iCustom2);
1076 0 : break;
1077 : }
1078 : }
1079 0 : if (tv2 != NULL)
1080 : {
1081 : /* Remove custom field from custom list */
1082 0 : if (tv2->value != NULL)
1083 : {
1084 0 : _TIFFfreeExt(tif, tv2->value);
1085 0 : tv2->value = NULL;
1086 : }
1087 : /* Shorten list and close gap in customValues list.
1088 : * Re-allocation of td_customValues not necessary here. */
1089 0 : td->td_customValueCount--;
1090 0 : for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
1091 : {
1092 0 : td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
1093 : }
1094 : }
1095 : else
1096 : {
1097 0 : assert(0);
1098 : }
1099 0 : va_end(ap);
1100 : }
1101 0 : return (0);
1102 : } /*-- _TIFFVSetField() --*/
1103 :
1104 : /*
1105 : * Return 1/0 according to whether or not
1106 : * it is permissible to set the tag's value.
1107 : * Note that we allow ImageLength to be changed
1108 : * so that we can append and extend to images.
1109 : * Any other tag may not be altered once writing
1110 : * has commenced, unless its value has no effect
1111 : * on the format of the data that is written.
1112 : */
1113 1088420 : static int OkToChangeTag(TIFF *tif, uint32_t tag)
1114 : {
1115 1088420 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1116 1089240 : if (!fip)
1117 : { /* unknown tag */
1118 0 : TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
1119 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
1120 0 : return (0);
1121 : }
1122 1089240 : if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
1123 769 : !fip->field_oktochange)
1124 : {
1125 : /*
1126 : * Consult info table to see if tag can be changed
1127 : * after we've started writing. We only allow changes
1128 : * to those tags that don't/shouldn't affect the
1129 : * compression and/or format of the data.
1130 : */
1131 2 : TIFFErrorExtR(tif, "TIFFSetField",
1132 : "%s: Cannot modify tag \"%s\" while writing",
1133 : tif->tif_name, fip->field_name);
1134 2 : return (0);
1135 : }
1136 1089240 : return (1);
1137 : }
1138 :
1139 : /*
1140 : * Record the value of a field in the
1141 : * internal directory structure. The
1142 : * field will be written to the file
1143 : * when/if the directory structure is
1144 : * updated.
1145 : */
1146 1088840 : int TIFFSetField(TIFF *tif, uint32_t tag, ...)
1147 : {
1148 : va_list ap;
1149 : int status;
1150 :
1151 1088840 : va_start(ap, tag);
1152 1088840 : status = TIFFVSetField(tif, tag, ap);
1153 1088610 : va_end(ap);
1154 1088610 : return (status);
1155 : }
1156 :
1157 : /*
1158 : * Clear the contents of the field in the internal structure.
1159 : */
1160 4741 : int TIFFUnsetField(TIFF *tif, uint32_t tag)
1161 : {
1162 4741 : const TIFFField *fip = TIFFFieldWithTag(tif, tag);
1163 4741 : TIFFDirectory *td = &tif->tif_dir;
1164 :
1165 4741 : if (!fip)
1166 0 : return 0;
1167 :
1168 4741 : if (fip->field_bit != FIELD_CUSTOM)
1169 5 : TIFFClrFieldBit(tif, fip->field_bit);
1170 : else
1171 : {
1172 4736 : TIFFTagValue *tv = NULL;
1173 : int i;
1174 :
1175 5078 : for (i = 0; i < td->td_customValueCount; i++)
1176 : {
1177 :
1178 433 : tv = td->td_customValues + i;
1179 433 : if (tv->info->field_tag == tag)
1180 91 : break;
1181 : }
1182 :
1183 4736 : if (i < td->td_customValueCount)
1184 : {
1185 91 : _TIFFfreeExt(tif, tv->value);
1186 218 : for (; i < td->td_customValueCount - 1; i++)
1187 : {
1188 127 : td->td_customValues[i] = td->td_customValues[i + 1];
1189 : }
1190 91 : td->td_customValueCount--;
1191 : }
1192 : }
1193 :
1194 4741 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1195 :
1196 4741 : return (1);
1197 : }
1198 :
1199 : /*
1200 : * Like TIFFSetField, but taking a varargs
1201 : * parameter list. This routine is useful
1202 : * for building higher-level interfaces on
1203 : * top of the library.
1204 : */
1205 1088850 : int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
1206 : {
1207 1088850 : return OkToChangeTag(tif, tag)
1208 1089220 : ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1209 2177810 : : 0;
1210 : }
1211 :
1212 1535720 : static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1213 : {
1214 1535720 : TIFFDirectory *td = &tif->tif_dir;
1215 1535720 : int ret_val = 1;
1216 1535720 : uint32_t standard_tag = tag;
1217 1535720 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1218 1535260 : if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */
1219 0 : return 0;
1220 :
1221 : /*
1222 : * We want to force the custom code to be used for custom
1223 : * fields even if the tag happens to match a well known
1224 : * one - important for reinterpreted handling of standard
1225 : * tag values in custom directories (i.e. EXIF)
1226 : */
1227 1535260 : if (fip->field_bit == FIELD_CUSTOM)
1228 : {
1229 355571 : standard_tag = 0;
1230 : }
1231 :
1232 1535260 : switch (standard_tag)
1233 : {
1234 1307 : case TIFFTAG_SUBFILETYPE:
1235 1307 : *va_arg(ap, uint32_t *) = td->td_subfiletype;
1236 1307 : break;
1237 43622 : case TIFFTAG_IMAGEWIDTH:
1238 43622 : *va_arg(ap, uint32_t *) = td->td_imagewidth;
1239 43596 : break;
1240 43665 : case TIFFTAG_IMAGELENGTH:
1241 43665 : *va_arg(ap, uint32_t *) = td->td_imagelength;
1242 43664 : break;
1243 27775 : case TIFFTAG_BITSPERSAMPLE:
1244 27775 : *va_arg(ap, uint16_t *) = td->td_bitspersample;
1245 27769 : break;
1246 48315 : case TIFFTAG_COMPRESSION:
1247 48315 : *va_arg(ap, uint16_t *) = td->td_compression;
1248 48306 : break;
1249 33208 : case TIFFTAG_PHOTOMETRIC:
1250 33208 : *va_arg(ap, uint16_t *) = td->td_photometric;
1251 33192 : break;
1252 0 : case TIFFTAG_THRESHHOLDING:
1253 0 : *va_arg(ap, uint16_t *) = td->td_threshholding;
1254 0 : break;
1255 0 : case TIFFTAG_FILLORDER:
1256 0 : *va_arg(ap, uint16_t *) = td->td_fillorder;
1257 0 : break;
1258 16 : case TIFFTAG_ORIENTATION:
1259 16 : *va_arg(ap, uint16_t *) = td->td_orientation;
1260 16 : break;
1261 24936 : case TIFFTAG_SAMPLESPERPIXEL:
1262 24936 : *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
1263 24937 : break;
1264 22867 : case TIFFTAG_ROWSPERSTRIP:
1265 22867 : *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
1266 22866 : break;
1267 5 : case TIFFTAG_MINSAMPLEVALUE:
1268 5 : *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
1269 5 : break;
1270 5 : case TIFFTAG_MAXSAMPLEVALUE:
1271 5 : *va_arg(ap, uint16_t *) = td->td_maxsamplevalue;
1272 5 : break;
1273 0 : case TIFFTAG_SMINSAMPLEVALUE:
1274 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
1275 0 : *va_arg(ap, double **) = td->td_sminsamplevalue;
1276 : else
1277 : {
1278 : /* libtiff historically treats this as a single value. */
1279 : uint16_t i;
1280 0 : double v = td->td_sminsamplevalue[0];
1281 0 : for (i = 1; i < td->td_samplesperpixel; ++i)
1282 0 : if (td->td_sminsamplevalue[i] < v)
1283 0 : v = td->td_sminsamplevalue[i];
1284 0 : *va_arg(ap, double *) = v;
1285 : }
1286 0 : break;
1287 0 : case TIFFTAG_SMAXSAMPLEVALUE:
1288 0 : if (tif->tif_flags & TIFF_PERSAMPLE)
1289 0 : *va_arg(ap, double **) = td->td_smaxsamplevalue;
1290 : else
1291 : {
1292 : /* libtiff historically treats this as a single value. */
1293 : uint16_t i;
1294 0 : double v = td->td_smaxsamplevalue[0];
1295 0 : for (i = 1; i < td->td_samplesperpixel; ++i)
1296 0 : if (td->td_smaxsamplevalue[i] > v)
1297 0 : v = td->td_smaxsamplevalue[i];
1298 0 : *va_arg(ap, double *) = v;
1299 : }
1300 0 : break;
1301 87 : case TIFFTAG_XRESOLUTION:
1302 87 : *va_arg(ap, float *) = td->td_xresolution;
1303 87 : break;
1304 86 : case TIFFTAG_YRESOLUTION:
1305 86 : *va_arg(ap, float *) = td->td_yresolution;
1306 86 : break;
1307 28475 : case TIFFTAG_PLANARCONFIG:
1308 28475 : *va_arg(ap, uint16_t *) = td->td_planarconfig;
1309 28416 : break;
1310 0 : case TIFFTAG_XPOSITION:
1311 0 : *va_arg(ap, float *) = td->td_xposition;
1312 0 : break;
1313 0 : case TIFFTAG_YPOSITION:
1314 0 : *va_arg(ap, float *) = td->td_yposition;
1315 0 : break;
1316 89 : case TIFFTAG_RESOLUTIONUNIT:
1317 89 : *va_arg(ap, uint16_t *) = td->td_resolutionunit;
1318 89 : break;
1319 0 : case TIFFTAG_PAGENUMBER:
1320 0 : *va_arg(ap, uint16_t *) = td->td_pagenumber[0];
1321 0 : *va_arg(ap, uint16_t *) = td->td_pagenumber[1];
1322 0 : break;
1323 0 : case TIFFTAG_HALFTONEHINTS:
1324 0 : *va_arg(ap, uint16_t *) = td->td_halftonehints[0];
1325 0 : *va_arg(ap, uint16_t *) = td->td_halftonehints[1];
1326 0 : break;
1327 149 : case TIFFTAG_COLORMAP:
1328 149 : *va_arg(ap, const uint16_t **) = td->td_colormap[0];
1329 149 : *va_arg(ap, const uint16_t **) = td->td_colormap[1];
1330 149 : *va_arg(ap, const uint16_t **) = td->td_colormap[2];
1331 149 : break;
1332 124208 : case TIFFTAG_STRIPOFFSETS:
1333 : case TIFFTAG_TILEOFFSETS:
1334 124208 : _TIFFFillStriles(tif);
1335 124211 : *va_arg(ap, const uint64_t **) = td->td_stripoffset_p;
1336 124208 : if (td->td_stripoffset_p == NULL)
1337 0 : ret_val = 0;
1338 124208 : break;
1339 142334 : case TIFFTAG_STRIPBYTECOUNTS:
1340 : case TIFFTAG_TILEBYTECOUNTS:
1341 142334 : _TIFFFillStriles(tif);
1342 142334 : *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p;
1343 142331 : if (td->td_stripbytecount_p == NULL)
1344 0 : ret_val = 0;
1345 142331 : break;
1346 0 : case TIFFTAG_MATTEING:
1347 0 : *va_arg(ap, uint16_t *) =
1348 0 : (td->td_extrasamples == 1 &&
1349 0 : td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
1350 0 : break;
1351 599773 : case TIFFTAG_EXTRASAMPLES:
1352 599773 : *va_arg(ap, uint16_t *) = td->td_extrasamples;
1353 599773 : *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
1354 599773 : break;
1355 3786 : case TIFFTAG_TILEWIDTH:
1356 3786 : *va_arg(ap, uint32_t *) = td->td_tilewidth;
1357 3786 : break;
1358 3786 : case TIFFTAG_TILELENGTH:
1359 3786 : *va_arg(ap, uint32_t *) = td->td_tilelength;
1360 3786 : break;
1361 0 : case TIFFTAG_TILEDEPTH:
1362 0 : *va_arg(ap, uint32_t *) = td->td_tiledepth;
1363 0 : break;
1364 0 : case TIFFTAG_DATATYPE:
1365 0 : switch (td->td_sampleformat)
1366 : {
1367 0 : case SAMPLEFORMAT_UINT:
1368 0 : *va_arg(ap, uint16_t *) = DATATYPE_UINT;
1369 0 : break;
1370 0 : case SAMPLEFORMAT_INT:
1371 0 : *va_arg(ap, uint16_t *) = DATATYPE_INT;
1372 0 : break;
1373 0 : case SAMPLEFORMAT_IEEEFP:
1374 0 : *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP;
1375 0 : break;
1376 0 : case SAMPLEFORMAT_VOID:
1377 0 : *va_arg(ap, uint16_t *) = DATATYPE_VOID;
1378 0 : break;
1379 : }
1380 0 : break;
1381 26457 : case TIFFTAG_SAMPLEFORMAT:
1382 26457 : *va_arg(ap, uint16_t *) = td->td_sampleformat;
1383 26530 : break;
1384 0 : case TIFFTAG_IMAGEDEPTH:
1385 0 : *va_arg(ap, uint32_t *) = td->td_imagedepth;
1386 0 : break;
1387 21 : case TIFFTAG_SUBIFD:
1388 21 : *va_arg(ap, uint16_t *) = td->td_nsubifd;
1389 21 : *va_arg(ap, const uint64_t **) = td->td_subifd;
1390 21 : break;
1391 0 : case TIFFTAG_YCBCRPOSITIONING:
1392 0 : *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
1393 0 : break;
1394 3701 : case TIFFTAG_YCBCRSUBSAMPLING:
1395 3701 : *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
1396 3701 : *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
1397 3512 : break;
1398 6 : case TIFFTAG_TRANSFERFUNCTION:
1399 6 : *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
1400 6 : if (td->td_samplesperpixel - td->td_extrasamples > 1)
1401 : {
1402 6 : *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
1403 6 : *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
1404 : }
1405 : else
1406 : {
1407 0 : *va_arg(ap, const uint16_t **) = NULL;
1408 0 : *va_arg(ap, const uint16_t **) = NULL;
1409 : }
1410 6 : break;
1411 773 : case TIFFTAG_REFERENCEBLACKWHITE:
1412 773 : *va_arg(ap, const float **) = td->td_refblackwhite;
1413 773 : break;
1414 0 : case TIFFTAG_INKNAMES:
1415 0 : *va_arg(ap, const char **) = td->td_inknames;
1416 0 : break;
1417 0 : case TIFFTAG_NUMBEROFINKS:
1418 0 : *va_arg(ap, uint16_t *) = td->td_numberofinks;
1419 0 : break;
1420 355806 : default:
1421 : {
1422 : int i;
1423 :
1424 : /*
1425 : * This can happen if multiple images are open
1426 : * with different codecs which have private
1427 : * tags. The global tag information table may
1428 : * then have tags that are valid for one file
1429 : * but not the other. If the client tries to
1430 : * get a tag that is not valid for the image's
1431 : * codec then we'll arrive here.
1432 : */
1433 355806 : if (fip->field_bit != FIELD_CUSTOM)
1434 : {
1435 0 : TIFFErrorExtR(tif, "_TIFFVGetField",
1436 : "%s: Invalid %stag \"%s\" "
1437 : "(not supported by codec)",
1438 : tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
1439 : fip->field_name);
1440 0 : ret_val = 0;
1441 0 : break;
1442 : }
1443 :
1444 : /*
1445 : * Do we have a custom value?
1446 : */
1447 355806 : ret_val = 0;
1448 1510180 : for (i = 0; i < td->td_customValueCount; i++)
1449 : {
1450 1229550 : TIFFTagValue *tv = td->td_customValues + i;
1451 :
1452 1229550 : if (tv->info->field_tag != tag)
1453 1154380 : continue;
1454 :
1455 75173 : if (fip->field_passcount)
1456 : {
1457 54650 : if (fip->field_readcount == TIFF_VARIABLE2)
1458 392 : *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
1459 : else /* Assume TIFF_VARIABLE */
1460 54258 : *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
1461 54650 : *va_arg(ap, const void **) = tv->value;
1462 54650 : ret_val = 1;
1463 : }
1464 20523 : else if (fip->field_tag == TIFFTAG_DOTRANGE &&
1465 0 : strcmp(fip->field_name, "DotRange") == 0)
1466 : {
1467 : /* TODO: This is an evil exception and should not have been
1468 : handled this way ... likely best if we move it into
1469 : the directory structure with an explicit field in
1470 : libtiff 4.1 and assign it a FIELD_ value */
1471 0 : *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0];
1472 0 : *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1];
1473 0 : ret_val = 1;
1474 : }
1475 : else
1476 : {
1477 20523 : if (fip->field_type == TIFF_ASCII ||
1478 39 : fip->field_readcount == TIFF_VARIABLE ||
1479 39 : fip->field_readcount == TIFF_VARIABLE2 ||
1480 39 : fip->field_readcount == TIFF_SPP || tv->count > 1)
1481 : {
1482 20517 : *va_arg(ap, void **) = tv->value;
1483 20516 : ret_val = 1;
1484 : }
1485 : else
1486 : {
1487 6 : char *val = (char *)tv->value;
1488 6 : assert(tv->count == 1);
1489 6 : switch (fip->field_type)
1490 : {
1491 0 : case TIFF_BYTE:
1492 : case TIFF_UNDEFINED:
1493 0 : *va_arg(ap, uint8_t *) = *(uint8_t *)val;
1494 0 : ret_val = 1;
1495 0 : break;
1496 0 : case TIFF_SBYTE:
1497 0 : *va_arg(ap, int8_t *) = *(int8_t *)val;
1498 0 : ret_val = 1;
1499 0 : break;
1500 0 : case TIFF_SHORT:
1501 0 : *va_arg(ap, uint16_t *) = *(uint16_t *)val;
1502 0 : ret_val = 1;
1503 0 : break;
1504 0 : case TIFF_SSHORT:
1505 0 : *va_arg(ap, int16_t *) = *(int16_t *)val;
1506 0 : ret_val = 1;
1507 0 : break;
1508 0 : case TIFF_LONG:
1509 : case TIFF_IFD:
1510 0 : *va_arg(ap, uint32_t *) = *(uint32_t *)val;
1511 0 : ret_val = 1;
1512 0 : break;
1513 0 : case TIFF_SLONG:
1514 0 : *va_arg(ap, int32_t *) = *(int32_t *)val;
1515 0 : ret_val = 1;
1516 0 : break;
1517 6 : case TIFF_LONG8:
1518 : case TIFF_IFD8:
1519 6 : *va_arg(ap, uint64_t *) = *(uint64_t *)val;
1520 6 : ret_val = 1;
1521 6 : break;
1522 0 : case TIFF_SLONG8:
1523 0 : *va_arg(ap, int64_t *) = *(int64_t *)val;
1524 0 : ret_val = 1;
1525 0 : break;
1526 0 : case TIFF_RATIONAL:
1527 : case TIFF_SRATIONAL:
1528 : {
1529 : /*-- Rational2Double: For Rationals evaluate
1530 : * "set_get_field_type" to determine internal
1531 : * storage size and return value size. */
1532 0 : int tv_size = TIFFFieldSetGetSize(fip);
1533 0 : if (tv_size == 8)
1534 : {
1535 0 : *va_arg(ap, double *) = *(double *)val;
1536 0 : ret_val = 1;
1537 : }
1538 : else
1539 : {
1540 : /*-- default should be tv_size == 4 */
1541 0 : *va_arg(ap, float *) = *(float *)val;
1542 0 : ret_val = 1;
1543 : /*-- ToDo: After Testing, this should be
1544 : * removed and tv_size==4 should be set as
1545 : * default. */
1546 0 : if (tv_size != 4)
1547 : {
1548 0 : TIFFErrorExtR(tif, "_TIFFVGetField",
1549 : "Rational2Double: "
1550 : ".set_get_field_type "
1551 : "in not 4 but %d",
1552 : tv_size);
1553 : }
1554 : }
1555 : }
1556 0 : break;
1557 0 : case TIFF_FLOAT:
1558 0 : *va_arg(ap, float *) = *(float *)val;
1559 0 : ret_val = 1;
1560 0 : break;
1561 0 : case TIFF_DOUBLE:
1562 0 : *va_arg(ap, double *) = *(double *)val;
1563 0 : ret_val = 1;
1564 0 : break;
1565 0 : default:
1566 0 : ret_val = 0;
1567 0 : break;
1568 : }
1569 : }
1570 : }
1571 75171 : break;
1572 : }
1573 : }
1574 : }
1575 1535020 : return (ret_val);
1576 : }
1577 :
1578 : /*
1579 : * Return the value of a field in the
1580 : * internal directory structure.
1581 : */
1582 1882060 : int TIFFGetField(TIFF *tif, uint32_t tag, ...)
1583 : {
1584 : int status;
1585 : va_list ap;
1586 :
1587 1882060 : va_start(ap, tag);
1588 1882060 : status = TIFFVGetField(tif, tag, ap);
1589 1882000 : va_end(ap);
1590 1882000 : return (status);
1591 : }
1592 :
1593 : /*
1594 : * Like TIFFGetField, but taking a varargs
1595 : * parameter list. This routine is useful
1596 : * for building higher-level interfaces on
1597 : * top of the library.
1598 : */
1599 1894060 : int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1600 : {
1601 1894060 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1602 1894940 : return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
1603 1566080 : ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
1604 3789120 : : 0);
1605 : }
1606 :
1607 : #define CleanupField(member) \
1608 : { \
1609 : if (td->member) \
1610 : { \
1611 : _TIFFfreeExt(tif, td->member); \
1612 : td->member = 0; \
1613 : } \
1614 : }
1615 :
1616 : /*
1617 : * Release storage associated with a directory.
1618 : */
1619 185225 : void TIFFFreeDirectory(TIFF *tif)
1620 : {
1621 185225 : TIFFDirectory *td = &tif->tif_dir;
1622 : int i;
1623 :
1624 185225 : _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1625 185187 : CleanupField(td_sminsamplevalue);
1626 185132 : CleanupField(td_smaxsamplevalue);
1627 185132 : CleanupField(td_colormap[0]);
1628 185132 : CleanupField(td_colormap[1]);
1629 185132 : CleanupField(td_colormap[2]);
1630 185132 : CleanupField(td_sampleinfo);
1631 185133 : CleanupField(td_subifd);
1632 185133 : CleanupField(td_inknames);
1633 185133 : CleanupField(td_refblackwhite);
1634 185133 : CleanupField(td_transferfunction[0]);
1635 185133 : CleanupField(td_transferfunction[1]);
1636 185133 : CleanupField(td_transferfunction[2]);
1637 185133 : CleanupField(td_stripoffset_p);
1638 185136 : CleanupField(td_stripbytecount_p);
1639 185137 : td->td_stripoffsetbyteallocsize = 0;
1640 185137 : TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1641 185137 : TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1642 :
1643 : /* Cleanup custom tag values */
1644 322670 : for (i = 0; i < td->td_customValueCount; i++)
1645 : {
1646 137533 : if (td->td_customValues[i].value)
1647 137532 : _TIFFfreeExt(tif, td->td_customValues[i].value);
1648 : }
1649 :
1650 185137 : td->td_customValueCount = 0;
1651 185137 : CleanupField(td_customValues);
1652 :
1653 185137 : _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1654 185126 : _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1655 :
1656 : /* Reset some internal parameters for IFD data size checking. */
1657 185127 : tif->tif_dir.td_dirdatasize_read = 0;
1658 185127 : tif->tif_dir.td_dirdatasize_write = 0;
1659 185127 : if (tif->tif_dir.td_dirdatasize_offsets != NULL)
1660 : {
1661 44860 : _TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
1662 44861 : tif->tif_dir.td_dirdatasize_offsets = NULL;
1663 44861 : tif->tif_dir.td_dirdatasize_Noffsets = 0;
1664 : }
1665 185128 : tif->tif_dir.td_iswrittentofile = FALSE;
1666 185128 : }
1667 : #undef CleanupField
1668 :
1669 : /*
1670 : * Client Tag extension support (from Niles Ritter).
1671 : */
1672 : static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1673 :
1674 1242 : TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1675 : {
1676 1242 : TIFFExtendProc prev = _TIFFextender;
1677 1242 : _TIFFextender = extender;
1678 1242 : return (prev);
1679 : }
1680 :
1681 : /*
1682 : * Setup for a new directory. Should we automatically call
1683 : * TIFFWriteDirectory() if the current one is dirty?
1684 : *
1685 : * The newly created directory will not exist on the file till
1686 : * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1687 : */
1688 38907 : int TIFFCreateDirectory(TIFF *tif)
1689 : {
1690 : /* Free previously allocated memory and setup default values. */
1691 38907 : TIFFFreeDirectory(tif);
1692 38908 : TIFFDefaultDirectory(tif);
1693 38910 : tif->tif_diroff = 0;
1694 38910 : tif->tif_nextdiroff = 0;
1695 38910 : tif->tif_curoff = 0;
1696 38910 : tif->tif_row = (uint32_t)-1;
1697 38910 : tif->tif_curstrip = (uint32_t)-1;
1698 38910 : tif->tif_dir.td_iswrittentofile = FALSE;
1699 :
1700 38910 : return 0;
1701 : }
1702 :
1703 0 : int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
1704 : {
1705 : /* Free previously allocated memory and setup default values. */
1706 0 : TIFFFreeDirectory(tif);
1707 0 : TIFFDefaultDirectory(tif);
1708 :
1709 : /*
1710 : * Reset the field definitions to match the application provided list.
1711 : * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1712 : * based on it's assumption this is an image directory.
1713 : */
1714 0 : _TIFFSetupFields(tif, infoarray);
1715 :
1716 0 : tif->tif_diroff = 0;
1717 0 : tif->tif_nextdiroff = 0;
1718 0 : tif->tif_curoff = 0;
1719 0 : tif->tif_row = (uint32_t)-1;
1720 0 : tif->tif_curstrip = (uint32_t)-1;
1721 : /* invalidate directory index */
1722 0 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
1723 : /* invalidate IFD loop lists */
1724 0 : _TIFFCleanupIFDOffsetAndNumberMaps(tif);
1725 : /* To be able to return from SubIFD or custom-IFD to main-IFD */
1726 0 : tif->tif_setdirectory_force_absolute = TRUE;
1727 :
1728 0 : return 0;
1729 : }
1730 :
1731 0 : int TIFFCreateEXIFDirectory(TIFF *tif)
1732 : {
1733 : const TIFFFieldArray *exifFieldArray;
1734 0 : exifFieldArray = _TIFFGetExifFields();
1735 0 : return TIFFCreateCustomDirectory(tif, exifFieldArray);
1736 : }
1737 :
1738 : /*
1739 : * Creates the EXIF GPS custom directory
1740 : */
1741 0 : int TIFFCreateGPSDirectory(TIFF *tif)
1742 : {
1743 : const TIFFFieldArray *gpsFieldArray;
1744 0 : gpsFieldArray = _TIFFGetGpsFields();
1745 0 : return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1746 : }
1747 :
1748 : /*
1749 : * Setup a default directory structure.
1750 : */
1751 119732 : int TIFFDefaultDirectory(TIFF *tif)
1752 : {
1753 119732 : register TIFFDirectory *td = &tif->tif_dir;
1754 : const TIFFFieldArray *tiffFieldArray;
1755 :
1756 119732 : tiffFieldArray = _TIFFGetFields();
1757 119691 : _TIFFSetupFields(tif, tiffFieldArray);
1758 :
1759 119732 : _TIFFmemset(td, 0, sizeof(*td));
1760 119715 : td->td_fillorder = FILLORDER_MSB2LSB;
1761 119715 : td->td_bitspersample = 1;
1762 119715 : td->td_threshholding = THRESHHOLD_BILEVEL;
1763 119715 : td->td_orientation = ORIENTATION_TOPLEFT;
1764 119715 : td->td_samplesperpixel = 1;
1765 119715 : td->td_rowsperstrip = (uint32_t)-1;
1766 119715 : td->td_tilewidth = 0;
1767 119715 : td->td_tilelength = 0;
1768 119715 : td->td_tiledepth = 1;
1769 : #ifdef STRIPBYTECOUNTSORTED_UNUSED
1770 : td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1771 : #endif
1772 119715 : td->td_resolutionunit = RESUNIT_INCH;
1773 119715 : td->td_sampleformat = SAMPLEFORMAT_UINT;
1774 119715 : td->td_imagedepth = 1;
1775 119715 : td->td_ycbcrsubsampling[0] = 2;
1776 119715 : td->td_ycbcrsubsampling[1] = 2;
1777 119715 : td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1778 119715 : tif->tif_postdecode = _TIFFNoPostDecode;
1779 119715 : tif->tif_foundfield = NULL;
1780 119715 : tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1781 119715 : tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1782 119715 : tif->tif_tagmethods.printdir = NULL;
1783 : /* additional default values */
1784 119715 : td->td_planarconfig = PLANARCONFIG_CONTIG;
1785 119715 : td->td_compression = COMPRESSION_NONE;
1786 119715 : td->td_subfiletype = 0;
1787 119715 : td->td_minsamplevalue = 0;
1788 : /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1789 : * Therefore, td_maxsamplevalue has to be re-calculated in
1790 : * TIFFGetFieldDefaulted(). */
1791 119715 : td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1792 119715 : td->td_extrasamples = 0;
1793 119715 : td->td_sampleinfo = NULL;
1794 :
1795 : /*
1796 : * Give client code a chance to install their own
1797 : * tag extensions & methods, prior to compression overloads,
1798 : * but do some prior cleanup first.
1799 : * (http://trac.osgeo.org/gdal/ticket/5054)
1800 : */
1801 119715 : if (tif->tif_nfieldscompat > 0)
1802 : {
1803 : uint32_t i;
1804 :
1805 171643 : for (i = 0; i < tif->tif_nfieldscompat; i++)
1806 : {
1807 114426 : if (tif->tif_fieldscompat[i].allocated_size)
1808 114429 : _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1809 : }
1810 57217 : _TIFFfreeExt(tif, tif->tif_fieldscompat);
1811 57216 : tif->tif_nfieldscompat = 0;
1812 57216 : tif->tif_fieldscompat = NULL;
1813 : }
1814 119719 : if (_TIFFextender)
1815 119709 : (*_TIFFextender)(tif);
1816 119767 : (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1817 : /*
1818 : * NB: The directory is marked dirty as a result of setting
1819 : * up the default compression scheme. However, this really
1820 : * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1821 : * if the user does something. We could just do the setup
1822 : * by hand, but it seems better to use the normal mechanism
1823 : * (i.e. TIFFSetField).
1824 : */
1825 119625 : tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1826 :
1827 : /*
1828 : * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1829 : * we clear the ISTILED flag when setting up a new directory.
1830 : * Should we also be clearing stuff like INSUBIFD?
1831 : */
1832 119625 : tif->tif_flags &= ~TIFF_ISTILED;
1833 :
1834 119625 : return (1);
1835 : }
1836 :
1837 13027 : static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1838 : tdir_t *nextdirnum)
1839 : {
1840 : static const char module[] = "TIFFAdvanceDirectory";
1841 :
1842 : /* Add this directory to the directory list, if not already in. */
1843 13027 : if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1844 : {
1845 0 : TIFFErrorExtR(tif, module,
1846 : "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1847 : ") might cause an IFD loop",
1848 : *nextdirnum, *nextdiroff, *nextdiroff);
1849 0 : *nextdiroff = 0;
1850 0 : *nextdirnum = 0;
1851 0 : return (0);
1852 : }
1853 :
1854 13027 : if (isMapped(tif))
1855 : {
1856 0 : uint64_t poff = *nextdiroff;
1857 0 : if (!(tif->tif_flags & TIFF_BIGTIFF))
1858 : {
1859 : tmsize_t poffa, poffb, poffc, poffd;
1860 : uint16_t dircount;
1861 : uint32_t nextdir32;
1862 0 : poffa = (tmsize_t)poff;
1863 0 : poffb = poffa + sizeof(uint16_t);
1864 0 : if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1865 0 : (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1866 : {
1867 0 : TIFFErrorExtR(tif, module,
1868 : "%s:%d: %s: Error fetching directory count",
1869 : __FILE__, __LINE__, tif->tif_name);
1870 0 : *nextdiroff = 0;
1871 0 : return (0);
1872 : }
1873 0 : _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1874 0 : if (tif->tif_flags & TIFF_SWAB)
1875 0 : TIFFSwabShort(&dircount);
1876 0 : poffc = poffb + dircount * 12;
1877 0 : poffd = poffc + sizeof(uint32_t);
1878 0 : if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1879 0 : (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1880 : {
1881 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1882 0 : return (0);
1883 : }
1884 0 : if (off != NULL)
1885 0 : *off = (uint64_t)poffc;
1886 0 : _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1887 0 : if (tif->tif_flags & TIFF_SWAB)
1888 0 : TIFFSwabLong(&nextdir32);
1889 0 : *nextdiroff = nextdir32;
1890 : }
1891 : else
1892 : {
1893 : tmsize_t poffa, poffb, poffc, poffd;
1894 : uint64_t dircount64;
1895 : uint16_t dircount16;
1896 0 : if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1897 : {
1898 0 : TIFFErrorExtR(tif, module,
1899 : "%s:%d: %s: Error fetching directory count",
1900 : __FILE__, __LINE__, tif->tif_name);
1901 0 : return (0);
1902 : }
1903 0 : poffa = (tmsize_t)poff;
1904 0 : poffb = poffa + sizeof(uint64_t);
1905 0 : if (poffb > tif->tif_size)
1906 : {
1907 0 : TIFFErrorExtR(tif, module,
1908 : "%s:%d: %s: Error fetching directory count",
1909 : __FILE__, __LINE__, tif->tif_name);
1910 0 : return (0);
1911 : }
1912 0 : _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1913 0 : if (tif->tif_flags & TIFF_SWAB)
1914 0 : TIFFSwabLong8(&dircount64);
1915 0 : if (dircount64 > 0xFFFF)
1916 : {
1917 0 : TIFFErrorExtR(tif, module,
1918 : "Sanity check on directory count failed");
1919 0 : return (0);
1920 : }
1921 0 : dircount16 = (uint16_t)dircount64;
1922 0 : if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1923 : (tmsize_t)sizeof(uint64_t))
1924 : {
1925 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1926 0 : return (0);
1927 : }
1928 0 : poffc = poffb + dircount16 * 20;
1929 0 : poffd = poffc + sizeof(uint64_t);
1930 0 : if (poffd > tif->tif_size)
1931 : {
1932 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1933 0 : return (0);
1934 : }
1935 0 : if (off != NULL)
1936 0 : *off = (uint64_t)poffc;
1937 0 : _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1938 0 : if (tif->tif_flags & TIFF_SWAB)
1939 0 : TIFFSwabLong8(nextdiroff);
1940 : }
1941 : }
1942 : else
1943 : {
1944 13027 : if (!(tif->tif_flags & TIFF_BIGTIFF))
1945 : {
1946 : uint16_t dircount;
1947 : uint32_t nextdir32;
1948 24396 : if (!SeekOK(tif, *nextdiroff) ||
1949 12198 : !ReadOK(tif, &dircount, sizeof(uint16_t)))
1950 : {
1951 7 : TIFFErrorExtR(tif, module,
1952 : "%s:%d: %s: Error fetching directory count",
1953 : __FILE__, __LINE__, tif->tif_name);
1954 7 : return (0);
1955 : }
1956 12191 : if (tif->tif_flags & TIFF_SWAB)
1957 272 : TIFFSwabShort(&dircount);
1958 12191 : if (off != NULL)
1959 7 : *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1960 : else
1961 12184 : (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1962 12191 : if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1963 : {
1964 0 : TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1965 : tif->tif_name);
1966 0 : return (0);
1967 : }
1968 12191 : if (tif->tif_flags & TIFF_SWAB)
1969 272 : TIFFSwabLong(&nextdir32);
1970 12191 : *nextdiroff = nextdir32;
1971 : }
1972 : else
1973 : {
1974 : uint64_t dircount64;
1975 : uint16_t dircount16;
1976 1658 : if (!SeekOK(tif, *nextdiroff) ||
1977 829 : !ReadOK(tif, &dircount64, sizeof(uint64_t)))
1978 : {
1979 0 : TIFFErrorExtR(tif, module,
1980 : "%s:%d: %s: Error fetching directory count",
1981 : __FILE__, __LINE__, tif->tif_name);
1982 0 : return (0);
1983 : }
1984 829 : if (tif->tif_flags & TIFF_SWAB)
1985 4 : TIFFSwabLong8(&dircount64);
1986 829 : if (dircount64 > 0xFFFF)
1987 : {
1988 0 : TIFFErrorExtR(tif, module,
1989 : "%s:%d: %s: Error fetching directory count",
1990 : __FILE__, __LINE__, tif->tif_name);
1991 0 : return (0);
1992 : }
1993 829 : dircount16 = (uint16_t)dircount64;
1994 829 : if (off != NULL)
1995 0 : *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1996 : else
1997 829 : (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1998 829 : if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1999 : {
2000 0 : TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
2001 : tif->tif_name);
2002 0 : return (0);
2003 : }
2004 829 : if (tif->tif_flags & TIFF_SWAB)
2005 4 : TIFFSwabLong8(nextdiroff);
2006 : }
2007 : }
2008 13020 : if (*nextdiroff != 0)
2009 : {
2010 5391 : (*nextdirnum)++;
2011 : /* Check next directory for IFD looping and if so, set it as last
2012 : * directory. */
2013 5391 : if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
2014 : {
2015 0 : TIFFWarningExtR(
2016 : tif, module,
2017 : "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
2018 : ") might be an IFD loop. Treating directory %d as "
2019 : "last directory",
2020 0 : *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
2021 0 : *nextdiroff = 0;
2022 0 : (*nextdirnum)--;
2023 : }
2024 : }
2025 13020 : return (1);
2026 : }
2027 :
2028 : /*
2029 : * Count the number of directories in a file.
2030 : */
2031 7632 : tdir_t TIFFNumberOfDirectories(TIFF *tif)
2032 : {
2033 : uint64_t nextdiroff;
2034 : tdir_t nextdirnum;
2035 : tdir_t n;
2036 7632 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2037 7355 : nextdiroff = tif->tif_header.classic.tiff_diroff;
2038 : else
2039 277 : nextdiroff = tif->tif_header.big.tiff_diroff;
2040 7632 : nextdirnum = 0;
2041 7632 : n = 0;
2042 33657 : while (nextdiroff != 0 &&
2043 13016 : TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2044 : {
2045 13009 : ++n;
2046 : }
2047 : /* Update number of main-IFDs in file. */
2048 7632 : tif->tif_curdircount = n;
2049 7632 : return (n);
2050 : }
2051 :
2052 : /*
2053 : * Set the n-th directory as the current directory.
2054 : * NB: Directories are numbered starting at 0.
2055 : */
2056 7939 : int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2057 : {
2058 : uint64_t nextdiroff;
2059 7939 : tdir_t nextdirnum = 0;
2060 : tdir_t n;
2061 :
2062 7939 : if (tif->tif_setdirectory_force_absolute)
2063 : {
2064 : /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2065 : * chain from the beginning, thus IFD directory list needs to be cleared
2066 : * from possible SubIFD offsets.
2067 : */
2068 0 : _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2069 : }
2070 :
2071 : /* Even faster path, if offset is available within IFD loop hash list. */
2072 15878 : if (!tif->tif_setdirectory_force_absolute &&
2073 7939 : _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
2074 : {
2075 : /* Set parameters for following TIFFReadDirectory() below. */
2076 7939 : tif->tif_nextdiroff = nextdiroff;
2077 7939 : tif->tif_curdir = dirn;
2078 : /* Reset to relative stepping */
2079 7939 : tif->tif_setdirectory_force_absolute = FALSE;
2080 : }
2081 : else
2082 : {
2083 :
2084 : /* Fast path when we just advance relative to the current directory:
2085 : * start at the current dir offset and continue to seek from there.
2086 : * Check special cases when relative is not allowed:
2087 : * - jump back from SubIFD or custom directory
2088 : * - right after TIFFWriteDirectory() jump back to that directory
2089 : * using TIFFSetDirectory() */
2090 0 : const int relative = (dirn >= tif->tif_curdir) &&
2091 0 : (tif->tif_diroff != 0) &&
2092 0 : !tif->tif_setdirectory_force_absolute;
2093 :
2094 0 : if (relative)
2095 : {
2096 0 : nextdiroff = tif->tif_diroff;
2097 0 : dirn -= tif->tif_curdir;
2098 0 : nextdirnum = tif->tif_curdir;
2099 : }
2100 0 : else if (!(tif->tif_flags & TIFF_BIGTIFF))
2101 0 : nextdiroff = tif->tif_header.classic.tiff_diroff;
2102 : else
2103 0 : nextdiroff = tif->tif_header.big.tiff_diroff;
2104 :
2105 : /* Reset to relative stepping */
2106 0 : tif->tif_setdirectory_force_absolute = FALSE;
2107 :
2108 0 : for (n = dirn; n > 0 && nextdiroff != 0; n--)
2109 0 : if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2110 0 : return (0);
2111 : /* If the n-th directory could not be reached (does not exist),
2112 : * return here without touching anything further. */
2113 0 : if (nextdiroff == 0 || n > 0)
2114 0 : return (0);
2115 :
2116 0 : tif->tif_nextdiroff = nextdiroff;
2117 :
2118 : /* Set curdir to the actual directory index. */
2119 0 : if (relative)
2120 0 : tif->tif_curdir += dirn - n;
2121 : else
2122 0 : tif->tif_curdir = dirn - n;
2123 : }
2124 :
2125 : /* The -1 decrement is because TIFFReadDirectory will increment
2126 : * tif_curdir after successfully reading the directory. */
2127 7939 : if (tif->tif_curdir == 0)
2128 7232 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2129 : else
2130 707 : tif->tif_curdir--;
2131 :
2132 7939 : tdir_t curdir = tif->tif_curdir;
2133 :
2134 7939 : int retval = TIFFReadDirectory(tif);
2135 :
2136 7939 : if (!retval && tif->tif_curdir == curdir)
2137 : {
2138 : /* If tif_curdir has not be incremented, TIFFFetchDirectory() in
2139 : * TIFFReadDirectory() has failed and tif_curdir shall be set
2140 : * specifically. */
2141 4 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2142 : }
2143 7939 : return (retval);
2144 : }
2145 :
2146 : /*
2147 : * Set the current directory to be the directory
2148 : * located at the specified file offset. This interface
2149 : * is used mainly to access directories linked with
2150 : * the SubIFD tag (e.g. thumbnail images).
2151 : */
2152 16420 : int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2153 : {
2154 : /* Match nextdiroff and curdir for consistent IFD-loop checking.
2155 : * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2156 : * invalid offsets within the main IFD tree. In the case of several subIFDs
2157 : * of a main image, there are two possibilities that are not even mutually
2158 : * exclusive. a.) The subIFD tag contains an array with all offsets of the
2159 : * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2160 : * (refer to
2161 : * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2162 : */
2163 : int retval;
2164 16420 : uint32_t curdir = 0;
2165 16420 : int8_t probablySubIFD = 0;
2166 16420 : if (diroff == 0)
2167 : {
2168 : /* Special case to set tif_diroff=0, which is done in
2169 : * TIFFReadDirectory() below to indicate that the currently read IFD is
2170 : * treated as a new, fresh IFD. */
2171 7110 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2172 7110 : tif->tif_dir.td_iswrittentofile = FALSE;
2173 : }
2174 : else
2175 : {
2176 9310 : if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2177 : {
2178 : /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2179 55 : probablySubIFD = 1;
2180 : }
2181 : /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2182 9310 : if (curdir >= 1)
2183 1647 : tif->tif_curdir = curdir - 1;
2184 : else
2185 7663 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2186 : }
2187 16420 : curdir = tif->tif_curdir;
2188 :
2189 16420 : tif->tif_nextdiroff = diroff;
2190 16420 : retval = TIFFReadDirectory(tif);
2191 :
2192 : /* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
2193 : * incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
2194 : * be set specifically. */
2195 16420 : if (!retval && diroff != 0 && tif->tif_curdir == curdir)
2196 : {
2197 0 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2198 : }
2199 :
2200 16420 : if (probablySubIFD)
2201 : {
2202 55 : if (retval)
2203 : {
2204 : /* Reset IFD list to start new one for SubIFD chain and also start
2205 : * SubIFD chain with tif_curdir=0 for IFD loop checking. */
2206 : /* invalidate IFD loop lists */
2207 55 : _TIFFCleanupIFDOffsetAndNumberMaps(tif);
2208 55 : tif->tif_curdir = 0; /* first directory of new chain */
2209 : /* add this offset to new IFD list */
2210 55 : retval = _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2211 : }
2212 : /* To be able to return from SubIFD or custom-IFD to main-IFD */
2213 55 : tif->tif_setdirectory_force_absolute = TRUE;
2214 : }
2215 :
2216 16420 : return (retval);
2217 : }
2218 :
2219 : /*
2220 : * Return file offset of the current directory.
2221 : */
2222 108578 : uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2223 :
2224 : /*
2225 : * Return an indication of whether or not we are
2226 : * at the last directory in the file.
2227 : */
2228 7830 : int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2229 :
2230 : /*
2231 : * Unlink the specified directory from the directory chain.
2232 : * Note: First directory starts with number dirn=1.
2233 : * This is different to TIFFSetDirectory() where the first directory starts with
2234 : * zero.
2235 : */
2236 4 : int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2237 : {
2238 : static const char module[] = "TIFFUnlinkDirectory";
2239 : uint64_t nextdir;
2240 : tdir_t nextdirnum;
2241 : uint64_t off;
2242 : tdir_t n;
2243 :
2244 4 : if (tif->tif_mode == O_RDONLY)
2245 : {
2246 0 : TIFFErrorExtR(tif, module,
2247 : "Can not unlink directory in read-only file");
2248 0 : return (0);
2249 : }
2250 4 : if (dirn == 0)
2251 : {
2252 0 : TIFFErrorExtR(tif, module,
2253 : "For TIFFUnlinkDirectory() first directory starts with "
2254 : "number 1 and not 0");
2255 0 : return (0);
2256 : }
2257 : /*
2258 : * Go to the directory before the one we want
2259 : * to unlink and nab the offset of the link
2260 : * field we'll need to patch.
2261 : */
2262 4 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2263 : {
2264 4 : nextdir = tif->tif_header.classic.tiff_diroff;
2265 4 : off = 4;
2266 : }
2267 : else
2268 : {
2269 0 : nextdir = tif->tif_header.big.tiff_diroff;
2270 0 : off = 8;
2271 : }
2272 4 : nextdirnum = 0; /* First directory is dirn=0 */
2273 :
2274 11 : for (n = dirn - 1; n > 0; n--)
2275 : {
2276 7 : if (nextdir == 0)
2277 : {
2278 0 : TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2279 0 : return (0);
2280 : }
2281 7 : if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2282 0 : return (0);
2283 : }
2284 : /*
2285 : * Advance to the directory to be unlinked and fetch
2286 : * the offset of the directory that follows.
2287 : */
2288 4 : if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2289 0 : return (0);
2290 : /*
2291 : * Go back and patch the link field of the preceding
2292 : * directory to point to the offset of the directory
2293 : * that follows.
2294 : */
2295 4 : (void)TIFFSeekFile(tif, off, SEEK_SET);
2296 4 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2297 : {
2298 : uint32_t nextdir32;
2299 4 : nextdir32 = (uint32_t)nextdir;
2300 4 : assert((uint64_t)nextdir32 == nextdir);
2301 4 : if (tif->tif_flags & TIFF_SWAB)
2302 0 : TIFFSwabLong(&nextdir32);
2303 4 : if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2304 : {
2305 0 : TIFFErrorExtR(tif, module, "Error writing directory link");
2306 0 : return (0);
2307 : }
2308 : }
2309 : else
2310 : {
2311 : /* Need local swap because nextdir has to be used unswapped below. */
2312 0 : uint64_t nextdir64 = nextdir;
2313 0 : if (tif->tif_flags & TIFF_SWAB)
2314 0 : TIFFSwabLong8(&nextdir64);
2315 0 : if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
2316 : {
2317 0 : TIFFErrorExtR(tif, module, "Error writing directory link");
2318 0 : return (0);
2319 : }
2320 : }
2321 :
2322 : /* For dirn=1 (first directory) also update the libtiff internal
2323 : * base offset variables. */
2324 4 : if (dirn == 1)
2325 : {
2326 0 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2327 0 : tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
2328 : else
2329 0 : tif->tif_header.big.tiff_diroff = nextdir;
2330 : }
2331 :
2332 : /*
2333 : * Leave directory state setup safely. We don't have
2334 : * facilities for doing inserting and removing directories,
2335 : * so it's safest to just invalidate everything. This
2336 : * means that the caller can only append to the directory
2337 : * chain.
2338 : */
2339 4 : (*tif->tif_cleanup)(tif);
2340 4 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2341 : {
2342 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
2343 0 : tif->tif_rawdata = NULL;
2344 0 : tif->tif_rawcc = 0;
2345 0 : tif->tif_rawdataoff = 0;
2346 0 : tif->tif_rawdataloaded = 0;
2347 : }
2348 4 : tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2349 : TIFF_BUF4WRITE);
2350 4 : TIFFFreeDirectory(tif);
2351 4 : TIFFDefaultDirectory(tif);
2352 4 : tif->tif_diroff = 0; /* force link on next write */
2353 4 : tif->tif_nextdiroff = 0; /* next write must be at end */
2354 4 : tif->tif_lastdiroff = 0; /* will be updated on next link */
2355 4 : tif->tif_curoff = 0;
2356 4 : tif->tif_row = (uint32_t)-1;
2357 4 : tif->tif_curstrip = (uint32_t)-1;
2358 4 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2359 4 : if (tif->tif_curdircount > 0)
2360 4 : tif->tif_curdircount--;
2361 : else
2362 0 : tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
2363 4 : _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2364 4 : return (1);
2365 : }
|