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