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