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 58655 : static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
44 : size_t elem_size)
45 : {
46 58655 : if (*vpp)
47 : {
48 1443 : _TIFFfreeExt(tif, *vpp);
49 1443 : *vpp = 0;
50 : }
51 58655 : if (vp)
52 : {
53 58649 : tmsize_t bytes = _TIFFMultiplySSize(NULL, (tmsize_t)nmemb,
54 : (tmsize_t)elem_size, NULL);
55 58656 : if (bytes)
56 58651 : *vpp = (void *)_TIFFmallocExt(tif, bytes);
57 58668 : if (*vpp)
58 58658 : _TIFFmemcpy(*vpp, vp, bytes);
59 : }
60 58674 : }
61 0 : void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
62 : {
63 0 : setByteArray(NULL, vpp, vp, n, 1);
64 0 : }
65 3086 : void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
66 : {
67 3086 : 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 10006 : }
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 8638 : 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 1228670 : static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
223 : {
224 : static const char module[] = "_TIFFVSetField";
225 :
226 1228670 : TIFFDirectory *td = &tif->tif_dir;
227 1228670 : int status = 1;
228 : uint32_t v32, v;
229 : double dblval;
230 : char *s;
231 1228670 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
232 1228590 : uint32_t standard_tag = tag;
233 1228590 : 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 1228590 : if (fip->field_bit == FIELD_CUSTOM)
242 : {
243 158734 : standard_tag = 0;
244 : }
245 :
246 1228590 : switch (standard_tag)
247 : {
248 6684 : case TIFFTAG_SUBFILETYPE:
249 6684 : td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
250 6684 : break;
251 94372 : case TIFFTAG_IMAGEWIDTH:
252 94372 : td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
253 94374 : break;
254 94374 : case TIFFTAG_IMAGELENGTH:
255 94374 : td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
256 94377 : break;
257 94357 : case TIFFTAG_BITSPERSAMPLE:
258 94357 : td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap);
259 94356 : _TIFFSetDefaultPostDecode(tif);
260 94354 : break;
261 230375 : case TIFFTAG_COMPRESSION:
262 230375 : 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 230376 : if (TIFFFieldSet(tif, FIELD_COMPRESSION))
269 : {
270 94137 : if ((uint32_t)td->td_compression == v)
271 57799 : break;
272 36338 : (*tif->tif_cleanup)(tif);
273 36338 : tif->tif_flags &= ~TIFF_CODERSETUP;
274 : }
275 : /*
276 : * Setup new compression routine state.
277 : */
278 172577 : if ((status = TIFFSetCompressionScheme(tif, (int)v)) != 0)
279 172576 : td->td_compression = (uint16_t)v;
280 : else
281 1 : status = 0;
282 172577 : break;
283 94400 : case TIFFTAG_PHOTOMETRIC:
284 94400 : td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
285 94395 : 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 94355 : case TIFFTAG_SAMPLESPERPIXEL:
303 94355 : v = (uint16_t)va_arg(ap, uint16_vap);
304 94352 : if (v == 0)
305 0 : goto badvalue;
306 94352 : if (v != td->td_samplesperpixel)
307 : {
308 : /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
309 23009 : 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 23009 : 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 23009 : 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 94352 : td->td_samplesperpixel = (uint16_t)v;
346 94352 : break;
347 83449 : case TIFFTAG_ROWSPERSTRIP:
348 83449 : v32 = (uint32_t)va_arg(ap, uint32_t);
349 83446 : if (v32 == 0)
350 0 : goto badvalue32;
351 83446 : td->td_rowsperstrip = v32;
352 83446 : if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
353 : {
354 83443 : td->td_tilelength = v32;
355 83443 : td->td_tilewidth = td->td_imagewidth;
356 : }
357 83446 : 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 148493 : case TIFFTAG_PLANARCONFIG:
397 148493 : v = (uint16_t)va_arg(ap, uint16_vap);
398 148498 : if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
399 0 : goto badvalue;
400 148498 : td->td_planarconfig = (uint16_t)v;
401 148498 : 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 8638 : case TIFFTAG_EXTRASAMPLES:
432 8638 : if (!setExtraSamples(tif, ap, &v))
433 0 : goto badvalue;
434 8638 : 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 11034 : case TIFFTAG_TILEWIDTH:
444 11034 : v32 = (uint32_t)va_arg(ap, uint32_t);
445 11034 : 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 11034 : td->td_tilewidth = v32;
454 11034 : tif->tif_flags |= TIFF_ISTILED;
455 11034 : break;
456 11034 : case TIFFTAG_TILELENGTH:
457 11034 : v32 = (uint32_t)va_arg(ap, uint32_t);
458 11034 : 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 11034 : td->td_tilelength = v32;
467 11034 : tif->tif_flags |= TIFF_ISTILED;
468 11034 : 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 93358 : case TIFFTAG_SAMPLEFORMAT:
497 93358 : v = (uint16_t)va_arg(ap, uint16_vap);
498 93342 : if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
499 0 : goto badvalue;
500 93356 : td->td_sampleformat = (uint16_t)v;
501 :
502 : /* Try to fix up the SWAB function for complex data. */
503 93356 : 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 93275 : else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
508 91855 : td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
509 3210 : td->td_bitspersample == 64 &&
510 1402 : tif->tif_postdecode == _TIFFSwab64BitData)
511 14 : tif->tif_postdecode = _TIFFSwab32BitData;
512 93356 : 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 158675 : 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 158675 : 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 158675 : 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 158675 : tv = NULL;
686 415912 : for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
687 : {
688 259317 : 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 158675 : if (tv == NULL)
704 : {
705 : TIFFTagValue *new_customValues;
706 :
707 156650 : new_customValues = (TIFFTagValue *)_TIFFreallocExt(
708 156650 : tif, td->td_customValues,
709 156650 : (tmsize_t)(sizeof(TIFFTagValue) *
710 156650 : (size_t)(td->td_customValueCount + 1)));
711 156678 : if (!new_customValues)
712 : {
713 0 : 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 156683 : td->td_customValueCount++;
722 156683 : td->td_customValues = new_customValues;
723 :
724 156683 : tv = td->td_customValues + (td->td_customValueCount - 1);
725 156683 : tv->info = fip;
726 156683 : tv->value = NULL;
727 156683 : 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 158708 : tv_size = TIFFFieldSetGetSize(fip);
736 158749 : if (tv_size == 0)
737 : {
738 5 : status = 0;
739 5 : TIFFErrorExtR(tif, module, "%s: Bad field type %u for \"%s\"",
740 5 : tif->tif_name, fip->field_type, fip->field_name);
741 0 : goto end;
742 : }
743 :
744 158744 : if (fip->field_type == TIFF_ASCII)
745 : {
746 : uint32_t ma;
747 : const char *mb;
748 43694 : 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 43694 : mb = (const char *)va_arg(ap, const char *);
757 43690 : size_t len = strlen(mb) + 1;
758 43690 : if (len >= 0x80000000U)
759 : {
760 5 : status = 0;
761 5 : 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 43685 : ma = (uint32_t)len;
768 : }
769 43685 : tv->count = (int)ma;
770 43685 : setByteArray(tif, &tv->value, mb, ma, 1);
771 : }
772 : else
773 : {
774 115050 : if (fip->field_passcount)
775 : {
776 114981 : if (fip->field_writecount == TIFF_VARIABLE2)
777 3017 : tv->count = (int)va_arg(ap, uint32_t);
778 : else
779 111964 : tv->count = va_arg(ap, int);
780 : }
781 69 : 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 115040 : 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 115040 : tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
801 : "custom tag binary object");
802 115064 : if (!tv->value)
803 : {
804 0 : status = 0;
805 0 : goto end;
806 : }
807 :
808 115064 : 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 115064 : 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 115048 : _TIFFmemcpy(tv->value, va_arg(ap, void *),
829 115056 : 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 115050 : if (!(tif->tif_flags & TIFF_BIGTIFF))
833 : {
834 114885 : if (tv->info->field_type == TIFF_LONG8 ||
835 114887 : 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 114885 : 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 1228580 : if (status)
1019 : {
1020 1228580 : const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1021 1228560 : if (fip2)
1022 1228560 : TIFFSetFieldBit(tif, fip2->field_bit);
1023 1228560 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1024 : }
1025 :
1026 0 : end:
1027 1228560 : va_end(ap);
1028 1228560 : return (status);
1029 0 : badvalue:
1030 : {
1031 0 : 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 1253170 : static int OkToChangeTag(TIFF *tif, uint32_t tag)
1102 : {
1103 1253170 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1104 1253300 : 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 1253300 : 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 1253300 : 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 1253270 : int TIFFSetField(TIFF *tif, uint32_t tag, ...)
1135 : {
1136 : va_list ap;
1137 : int status;
1138 :
1139 1253270 : va_start(ap, tag);
1140 1253270 : status = TIFFVSetField(tif, tag, ap);
1141 1253160 : va_end(ap);
1142 1253160 : return (status);
1143 : }
1144 :
1145 : /*
1146 : * Clear the contents of the field in the internal structure.
1147 : */
1148 5534 : int TIFFUnsetField(TIFF *tif, uint32_t tag)
1149 : {
1150 5534 : const TIFFField *fip = TIFFFieldWithTag(tif, tag);
1151 5534 : TIFFDirectory *td = &tif->tif_dir;
1152 :
1153 5534 : if (!fip)
1154 0 : return 0;
1155 :
1156 5534 : if (fip->field_bit != FIELD_CUSTOM)
1157 5 : TIFFClrFieldBit(tif, fip->field_bit);
1158 : else
1159 : {
1160 5529 : TIFFTagValue *tv = NULL;
1161 : int i;
1162 :
1163 6111 : 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 5529 : 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 5534 : tif->tif_flags |= TIFF_DIRTYDIRECT;
1183 :
1184 5534 : 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 1253250 : int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
1194 : {
1195 1253250 : return OkToChangeTag(tif, tag)
1196 1253280 : ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1197 2506270 : : 0;
1198 : }
1199 :
1200 2026890 : static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1201 : {
1202 2026890 : TIFFDirectory *td = &tif->tif_dir;
1203 2026890 : int ret_val = 1;
1204 2026890 : uint32_t standard_tag = tag;
1205 2026890 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1206 2026790 : 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 2026790 : if (fip->field_bit == FIELD_CUSTOM)
1216 : {
1217 400555 : standard_tag = 0;
1218 : }
1219 :
1220 2026790 : switch (standard_tag)
1221 : {
1222 1383 : case TIFFTAG_SUBFILETYPE:
1223 1383 : *va_arg(ap, uint32_t *) = td->td_subfiletype;
1224 1384 : break;
1225 52515 : case TIFFTAG_IMAGEWIDTH:
1226 52515 : *va_arg(ap, uint32_t *) = td->td_imagewidth;
1227 52521 : break;
1228 52533 : case TIFFTAG_IMAGELENGTH:
1229 52533 : *va_arg(ap, uint32_t *) = td->td_imagelength;
1230 52533 : break;
1231 34949 : case TIFFTAG_BITSPERSAMPLE:
1232 34949 : *va_arg(ap, uint16_t *) = td->td_bitspersample;
1233 34946 : break;
1234 59935 : case TIFFTAG_COMPRESSION:
1235 59935 : *va_arg(ap, uint16_t *) = td->td_compression;
1236 59933 : break;
1237 43241 : case TIFFTAG_PHOTOMETRIC:
1238 43241 : *va_arg(ap, uint16_t *) = td->td_photometric;
1239 43242 : 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 29636 : break;
1252 29525 : case TIFFTAG_ROWSPERSTRIP:
1253 29525 : *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
1254 29523 : 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 35873 : case TIFFTAG_PLANARCONFIG:
1296 35873 : *va_arg(ap, uint16_t *) = td->td_planarconfig;
1297 35871 : 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 140870 : case TIFFTAG_STRIPOFFSETS:
1321 : case TIFFTAG_TILEOFFSETS:
1322 140870 : _TIFFFillStriles(tif);
1323 140869 : *va_arg(ap, const uint64_t **) = td->td_stripoffset_p;
1324 140869 : if (td->td_stripoffset_p == NULL)
1325 0 : ret_val = 0;
1326 140869 : break;
1327 169359 : case TIFFTAG_STRIPBYTECOUNTS:
1328 : case TIFFTAG_TILEBYTECOUNTS:
1329 169359 : _TIFFFillStriles(tif);
1330 169359 : *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p;
1331 169359 : if (td->td_stripbytecount_p == NULL)
1332 0 : ret_val = 0;
1333 169359 : 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 929433 : case TIFFTAG_EXTRASAMPLES:
1340 929433 : *va_arg(ap, uint16_t *) = td->td_extrasamples;
1341 929433 : *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
1342 929433 : break;
1343 4290 : case TIFFTAG_TILEWIDTH:
1344 4290 : *va_arg(ap, uint32_t *) = td->td_tilewidth;
1345 4290 : break;
1346 4290 : case TIFFTAG_TILELENGTH:
1347 4290 : *va_arg(ap, uint32_t *) = td->td_tilelength;
1348 4290 : 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 33660 : case TIFFTAG_SAMPLEFORMAT:
1372 33660 : *va_arg(ap, uint16_t *) = td->td_sampleformat;
1373 33653 : 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 3545 : 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 400474 : 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 400474 : 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 400474 : ret_val = 0;
1438 1704460 : for (i = 0; i < td->td_customValueCount; i++)
1439 : {
1440 1391900 : TIFFTagValue *tv = td->td_customValues + i;
1441 :
1442 1391900 : if (tv->info->field_tag != tag)
1443 1303990 : continue;
1444 :
1445 87910 : if (fip->field_passcount)
1446 : {
1447 63498 : if (fip->field_readcount == TIFF_VARIABLE2)
1448 392 : *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
1449 : else /* Assume TIFF_VARIABLE */
1450 63106 : *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
1451 63497 : *va_arg(ap, const void **) = tv->value;
1452 63497 : ret_val = 1;
1453 : }
1454 24412 : 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 24412 : 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 24406 : *va_arg(ap, void **) = tv->value;
1473 24404 : 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 87906 : break;
1564 : }
1565 : }
1566 : }
1567 2026750 : return (ret_val);
1568 : }
1569 :
1570 : /*
1571 : * Return the value of a field in the
1572 : * internal directory structure.
1573 : */
1574 2455860 : int TIFFGetField(TIFF *tif, uint32_t tag, ...)
1575 : {
1576 : int status;
1577 : va_list ap;
1578 :
1579 2455860 : va_start(ap, tag);
1580 2455860 : status = TIFFVGetField(tif, tag, ap);
1581 2455750 : va_end(ap);
1582 2455750 : 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 2468140 : int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1592 : {
1593 2468140 : const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1594 2468250 : return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
1595 2058630 : ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
1596 4936380 : : 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 : * Release storage associated with a directory.
1610 : */
1611 209093 : void TIFFFreeDirectory(TIFF *tif)
1612 : {
1613 209093 : TIFFDirectory *td = &tif->tif_dir;
1614 : int i;
1615 :
1616 209093 : (*tif->tif_cleanup)(tif);
1617 209088 : _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1618 209084 : CleanupField(td_sminsamplevalue);
1619 209084 : CleanupField(td_smaxsamplevalue);
1620 209084 : CleanupField(td_colormap[0]);
1621 209084 : CleanupField(td_colormap[1]);
1622 209084 : CleanupField(td_colormap[2]);
1623 209084 : CleanupField(td_sampleinfo);
1624 209083 : CleanupField(td_subifd);
1625 209083 : CleanupField(td_inknames);
1626 209083 : CleanupField(td_refblackwhite);
1627 209083 : CleanupField(td_transferfunction[0]);
1628 209083 : CleanupField(td_transferfunction[1]);
1629 209083 : CleanupField(td_transferfunction[2]);
1630 209083 : CleanupField(td_stripoffset_p);
1631 209085 : CleanupField(td_stripbytecount_p);
1632 209086 : td->td_stripoffsetbyteallocsize = 0;
1633 209086 : TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1634 209086 : TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1635 :
1636 : /* Cleanup custom tag values */
1637 365661 : for (i = 0; i < td->td_customValueCount; i++)
1638 : {
1639 156573 : if (td->td_customValues[i].value)
1640 156575 : _TIFFfreeExt(tif, td->td_customValues[i].value);
1641 : }
1642 :
1643 209088 : td->td_customValueCount = 0;
1644 209088 : CleanupField(td_customValues);
1645 :
1646 209089 : _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1647 209086 : _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1648 :
1649 : /* Reset some internal parameters for IFD data size checking. */
1650 209083 : tif->tif_dir.td_dirdatasize_read = 0;
1651 209083 : tif->tif_dir.td_dirdatasize_write = 0;
1652 209083 : if (tif->tif_dir.td_dirdatasize_offsets != NULL)
1653 : {
1654 54148 : _TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
1655 54150 : tif->tif_dir.td_dirdatasize_offsets = NULL;
1656 54150 : tif->tif_dir.td_dirdatasize_Noffsets = 0;
1657 : }
1658 209085 : tif->tif_dir.td_iswrittentofile = FALSE;
1659 209085 : }
1660 : #undef CleanupField
1661 :
1662 : /*
1663 : * Client Tag extension support (from Niles Ritter).
1664 : */
1665 : static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1666 :
1667 1398 : TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1668 : {
1669 1398 : TIFFExtendProc prev = _TIFFextender;
1670 1398 : _TIFFextender = extender;
1671 1398 : return (prev);
1672 : }
1673 :
1674 : /*
1675 : * Setup for a new directory. Should we automatically call
1676 : * TIFFWriteDirectory() if the current one is dirty?
1677 : *
1678 : * The newly created directory will not exist on the file till
1679 : * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1680 : */
1681 42636 : int TIFFCreateDirectory(TIFF *tif)
1682 : {
1683 : /* Free previously allocated memory and setup default values. */
1684 42636 : TIFFFreeDirectory(tif);
1685 42637 : TIFFDefaultDirectory(tif);
1686 42637 : tif->tif_diroff = 0;
1687 42637 : tif->tif_nextdiroff = 0;
1688 42637 : tif->tif_curoff = 0;
1689 42637 : tif->tif_row = (uint32_t)-1;
1690 42637 : tif->tif_curstrip = (uint32_t)-1;
1691 42637 : tif->tif_dir.td_iswrittentofile = FALSE;
1692 :
1693 42637 : return 0;
1694 : }
1695 :
1696 0 : int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
1697 : {
1698 : /* Free previously allocated memory and setup default values. */
1699 0 : TIFFFreeDirectory(tif);
1700 0 : TIFFDefaultDirectory(tif);
1701 :
1702 : /*
1703 : * Reset the field definitions to match the application provided list.
1704 : * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1705 : * based on it's assumption this is an image directory.
1706 : */
1707 0 : _TIFFSetupFields(tif, infoarray);
1708 :
1709 0 : tif->tif_diroff = 0;
1710 0 : tif->tif_nextdiroff = 0;
1711 0 : tif->tif_curoff = 0;
1712 0 : tif->tif_row = (uint32_t)-1;
1713 0 : tif->tif_curstrip = (uint32_t)-1;
1714 : /* invalidate directory index */
1715 0 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
1716 : /* invalidate IFD loop lists */
1717 0 : _TIFFCleanupIFDOffsetAndNumberMaps(tif);
1718 : /* To be able to return from SubIFD or custom-IFD to main-IFD */
1719 0 : tif->tif_setdirectory_force_absolute = TRUE;
1720 :
1721 0 : return 0;
1722 : }
1723 :
1724 0 : int TIFFCreateEXIFDirectory(TIFF *tif)
1725 : {
1726 : const TIFFFieldArray *exifFieldArray;
1727 0 : exifFieldArray = _TIFFGetExifFields();
1728 0 : return TIFFCreateCustomDirectory(tif, exifFieldArray);
1729 : }
1730 :
1731 : /*
1732 : * Creates the EXIF GPS custom directory
1733 : */
1734 0 : int TIFFCreateGPSDirectory(TIFF *tif)
1735 : {
1736 : const TIFFFieldArray *gpsFieldArray;
1737 0 : gpsFieldArray = _TIFFGetGpsFields();
1738 0 : return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1739 : }
1740 :
1741 : /*
1742 : * Setup a default directory structure.
1743 : */
1744 136251 : int TIFFDefaultDirectory(TIFF *tif)
1745 : {
1746 136251 : TIFFDirectory *td = &tif->tif_dir;
1747 : const TIFFFieldArray *tiffFieldArray;
1748 :
1749 136251 : tiffFieldArray = _TIFFGetFields();
1750 136245 : _TIFFSetupFields(tif, tiffFieldArray);
1751 :
1752 136248 : _TIFFmemset(td, 0, sizeof(*td));
1753 136250 : td->td_fillorder = FILLORDER_MSB2LSB;
1754 136250 : td->td_bitspersample = 1;
1755 136250 : td->td_threshholding = THRESHHOLD_BILEVEL;
1756 136250 : td->td_orientation = ORIENTATION_TOPLEFT;
1757 136250 : td->td_samplesperpixel = 1;
1758 136250 : td->td_rowsperstrip = (uint32_t)-1;
1759 136250 : td->td_tilewidth = 0;
1760 136250 : td->td_tilelength = 0;
1761 136250 : td->td_tiledepth = 1;
1762 : #ifdef STRIPBYTECOUNTSORTED_UNUSED
1763 : td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1764 : #endif
1765 136250 : td->td_resolutionunit = RESUNIT_INCH;
1766 136250 : td->td_sampleformat = SAMPLEFORMAT_UINT;
1767 136250 : td->td_imagedepth = 1;
1768 136250 : td->td_ycbcrsubsampling[0] = 2;
1769 136250 : td->td_ycbcrsubsampling[1] = 2;
1770 136250 : td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1771 136250 : tif->tif_postdecode = _TIFFNoPostDecode;
1772 136250 : tif->tif_foundfield = NULL;
1773 136250 : tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1774 136250 : tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1775 136250 : tif->tif_tagmethods.printdir = NULL;
1776 : /* additional default values */
1777 136250 : td->td_planarconfig = PLANARCONFIG_CONTIG;
1778 136250 : td->td_compression = COMPRESSION_NONE;
1779 136250 : td->td_subfiletype = 0;
1780 136250 : td->td_minsamplevalue = 0;
1781 : /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1782 : * Therefore, td_maxsamplevalue has to be re-calculated in
1783 : * TIFFGetFieldDefaulted(). */
1784 136250 : td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1785 136250 : td->td_extrasamples = 0;
1786 136250 : td->td_sampleinfo = NULL;
1787 :
1788 : /*
1789 : * Give client code a chance to install their own
1790 : * tag extensions & methods, prior to compression overloads,
1791 : * but do some prior cleanup first.
1792 : * (http://trac.osgeo.org/gdal/ticket/5054)
1793 : */
1794 136250 : if (tif->tif_nfieldscompat > 0)
1795 : {
1796 : uint32_t i;
1797 :
1798 196814 : for (i = 0; i < tif->tif_nfieldscompat; i++)
1799 : {
1800 131208 : if (tif->tif_fieldscompat[i].allocated_size)
1801 131210 : _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1802 : }
1803 65606 : _TIFFfreeExt(tif, tif->tif_fieldscompat);
1804 65606 : tif->tif_nfieldscompat = 0;
1805 65606 : tif->tif_fieldscompat = NULL;
1806 : }
1807 136251 : if (_TIFFextender)
1808 136247 : (*_TIFFextender)(tif);
1809 136255 : (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1810 : /*
1811 : * NB: The directory is marked dirty as a result of setting
1812 : * up the default compression scheme. However, this really
1813 : * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1814 : * if the user does something. We could just do the setup
1815 : * by hand, but it seems better to use the normal mechanism
1816 : * (i.e. TIFFSetField).
1817 : */
1818 136235 : tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1819 :
1820 : /*
1821 : * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1822 : * we clear the ISTILED flag when setting up a new directory.
1823 : * Should we also be clearing stuff like INSUBIFD?
1824 : */
1825 136235 : tif->tif_flags &= ~TIFF_ISTILED;
1826 :
1827 136235 : return (1);
1828 : }
1829 :
1830 16496 : static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1831 : tdir_t *nextdirnum)
1832 : {
1833 : static const char module[] = "TIFFAdvanceDirectory";
1834 :
1835 : /* Add this directory to the directory list, if not already in. */
1836 16496 : if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1837 : {
1838 0 : TIFFErrorExtR(tif, module,
1839 : "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1840 : ") might cause an IFD loop",
1841 : *nextdirnum, *nextdiroff, *nextdiroff);
1842 0 : *nextdiroff = 0;
1843 0 : *nextdirnum = 0;
1844 0 : return (0);
1845 : }
1846 :
1847 16495 : if (isMapped(tif))
1848 : {
1849 0 : uint64_t poff = *nextdiroff;
1850 0 : if (!(tif->tif_flags & TIFF_BIGTIFF))
1851 : {
1852 : tmsize_t poffa, poffb, poffc, poffd;
1853 : uint16_t dircount;
1854 : uint32_t nextdir32;
1855 0 : poffa = (tmsize_t)poff;
1856 0 : poffb = poffa + (tmsize_t)sizeof(uint16_t);
1857 0 : if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1858 0 : (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1859 : {
1860 0 : TIFFErrorExtR(tif, module,
1861 : "%s:%d: %s: Error fetching directory count",
1862 : __FILE__, __LINE__, tif->tif_name);
1863 0 : *nextdiroff = 0;
1864 0 : return (0);
1865 : }
1866 0 : _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1867 0 : if (tif->tif_flags & TIFF_SWAB)
1868 0 : TIFFSwabShort(&dircount);
1869 0 : poffc = poffb + dircount * 12;
1870 0 : poffd = poffc + (tmsize_t)sizeof(uint32_t);
1871 0 : if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1872 0 : (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1873 : {
1874 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1875 0 : return (0);
1876 : }
1877 0 : if (off != NULL)
1878 0 : *off = (uint64_t)poffc;
1879 0 : _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1880 0 : if (tif->tif_flags & TIFF_SWAB)
1881 0 : TIFFSwabLong(&nextdir32);
1882 0 : *nextdiroff = nextdir32;
1883 : }
1884 : else
1885 : {
1886 : tmsize_t poffa, poffb, poffc, poffd;
1887 : uint64_t dircount64;
1888 : uint16_t dircount16;
1889 0 : if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1890 : {
1891 0 : TIFFErrorExtR(tif, module,
1892 : "%s:%d: %s: Error fetching directory count",
1893 : __FILE__, __LINE__, tif->tif_name);
1894 0 : return (0);
1895 : }
1896 0 : poffa = (tmsize_t)poff;
1897 0 : poffb = poffa + (tmsize_t)sizeof(uint64_t);
1898 0 : if (poffb > tif->tif_size)
1899 : {
1900 0 : TIFFErrorExtR(tif, module,
1901 : "%s:%d: %s: Error fetching directory count",
1902 : __FILE__, __LINE__, tif->tif_name);
1903 0 : return (0);
1904 : }
1905 0 : _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1906 0 : if (tif->tif_flags & TIFF_SWAB)
1907 0 : TIFFSwabLong8(&dircount64);
1908 0 : if (dircount64 > 0xFFFF)
1909 : {
1910 0 : TIFFErrorExtR(tif, module,
1911 : "Sanity check on directory count failed");
1912 0 : return (0);
1913 : }
1914 0 : dircount16 = (uint16_t)dircount64;
1915 0 : if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1916 : (tmsize_t)sizeof(uint64_t))
1917 : {
1918 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1919 0 : return (0);
1920 : }
1921 0 : poffc = poffb + dircount16 * 20;
1922 0 : poffd = poffc + (tmsize_t)sizeof(uint64_t);
1923 0 : if (poffd > tif->tif_size)
1924 : {
1925 0 : TIFFErrorExtR(tif, module, "Error fetching directory link");
1926 0 : return (0);
1927 : }
1928 0 : if (off != NULL)
1929 0 : *off = (uint64_t)poffc;
1930 0 : _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1931 0 : if (tif->tif_flags & TIFF_SWAB)
1932 0 : TIFFSwabLong8(nextdiroff);
1933 : }
1934 : }
1935 : else
1936 : {
1937 16495 : if (!(tif->tif_flags & TIFF_BIGTIFF))
1938 : {
1939 : uint16_t dircount;
1940 : uint32_t nextdir32;
1941 31316 : if (!SeekOK(tif, *nextdiroff) ||
1942 15658 : !ReadOK(tif, &dircount, sizeof(uint16_t)))
1943 : {
1944 7 : TIFFErrorExtR(tif, module,
1945 : "%s:%d: %s: Error fetching directory count",
1946 : __FILE__, __LINE__, tif->tif_name);
1947 10 : return (0);
1948 : }
1949 15651 : if (tif->tif_flags & TIFF_SWAB)
1950 272 : TIFFSwabShort(&dircount);
1951 15652 : if (off != NULL)
1952 9 : *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1953 : else
1954 15643 : (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1955 15652 : if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1956 : {
1957 3 : TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1958 : tif->tif_name);
1959 3 : return (0);
1960 : }
1961 15648 : if (tif->tif_flags & TIFF_SWAB)
1962 272 : TIFFSwabLong(&nextdir32);
1963 15647 : *nextdiroff = nextdir32;
1964 : }
1965 : else
1966 : {
1967 : uint64_t dircount64;
1968 : uint16_t dircount16;
1969 1674 : if (!SeekOK(tif, *nextdiroff) ||
1970 837 : !ReadOK(tif, &dircount64, sizeof(uint64_t)))
1971 : {
1972 0 : TIFFErrorExtR(tif, module,
1973 : "%s:%d: %s: Error fetching directory count",
1974 : __FILE__, __LINE__, tif->tif_name);
1975 0 : return (0);
1976 : }
1977 837 : if (tif->tif_flags & TIFF_SWAB)
1978 4 : TIFFSwabLong8(&dircount64);
1979 837 : if (dircount64 > 0xFFFF)
1980 : {
1981 0 : TIFFErrorExtR(tif, module,
1982 : "%s:%d: %s: Error fetching directory count",
1983 : __FILE__, __LINE__, tif->tif_name);
1984 0 : return (0);
1985 : }
1986 837 : dircount16 = (uint16_t)dircount64;
1987 837 : if (off != NULL)
1988 0 : *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1989 : else
1990 837 : (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1991 837 : if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1992 : {
1993 0 : TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1994 : tif->tif_name);
1995 0 : return (0);
1996 : }
1997 837 : if (tif->tif_flags & TIFF_SWAB)
1998 4 : TIFFSwabLong8(nextdiroff);
1999 : }
2000 : }
2001 16484 : if (*nextdiroff != 0)
2002 : {
2003 5831 : (*nextdirnum)++;
2004 : /* Check next directory for IFD looping and if so, set it as last
2005 : * directory. */
2006 5831 : if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
2007 : {
2008 0 : TIFFWarningExtR(
2009 : tif, module,
2010 : "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
2011 : ") might be an IFD loop. Treating directory %d as "
2012 : "last directory",
2013 0 : *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
2014 0 : *nextdiroff = 0;
2015 0 : (*nextdirnum)--;
2016 : }
2017 : }
2018 16486 : return (1);
2019 : }
2020 :
2021 : /*
2022 : * Count the number of directories in a file.
2023 : */
2024 10659 : tdir_t TIFFNumberOfDirectories(TIFF *tif)
2025 : {
2026 : uint64_t nextdiroff;
2027 : tdir_t nextdirnum;
2028 : tdir_t n;
2029 10659 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2030 10382 : nextdiroff = tif->tif_header.classic.tiff_diroff;
2031 : else
2032 277 : nextdiroff = tif->tif_header.big.tiff_diroff;
2033 10659 : nextdirnum = 0;
2034 10659 : n = 0;
2035 43611 : while (nextdiroff != 0 &&
2036 16480 : TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2037 : {
2038 16471 : ++n;
2039 : }
2040 : /* Update number of main-IFDs in file. */
2041 10660 : tif->tif_curdircount = n;
2042 10660 : return (n);
2043 : }
2044 :
2045 : /*
2046 : * Set the n-th directory as the current directory.
2047 : * NB: Directories are numbered starting at 0.
2048 : */
2049 10824 : int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2050 : {
2051 : uint64_t nextdiroff;
2052 10824 : tdir_t nextdirnum = 0;
2053 : tdir_t n;
2054 :
2055 10824 : if (tif->tif_setdirectory_force_absolute)
2056 : {
2057 : /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2058 : * chain from the beginning, thus IFD directory list needs to be cleared
2059 : * from possible SubIFD offsets.
2060 : */
2061 0 : _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2062 : }
2063 :
2064 : /* Even faster path, if offset is available within IFD loop hash list. */
2065 21648 : if (!tif->tif_setdirectory_force_absolute &&
2066 10824 : _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
2067 : {
2068 : /* Set parameters for following TIFFReadDirectory() below. */
2069 10824 : tif->tif_nextdiroff = nextdiroff;
2070 10824 : tif->tif_curdir = dirn;
2071 : /* Reset to relative stepping */
2072 10824 : tif->tif_setdirectory_force_absolute = FALSE;
2073 : }
2074 : else
2075 : {
2076 :
2077 : /* Fast path when we just advance relative to the current directory:
2078 : * start at the current dir offset and continue to seek from there.
2079 : * Check special cases when relative is not allowed:
2080 : * - jump back from SubIFD or custom directory
2081 : * - right after TIFFWriteDirectory() jump back to that directory
2082 : * using TIFFSetDirectory() */
2083 0 : const int relative = (dirn >= tif->tif_curdir) &&
2084 0 : (tif->tif_diroff != 0) &&
2085 0 : !tif->tif_setdirectory_force_absolute;
2086 :
2087 0 : if (relative)
2088 : {
2089 0 : nextdiroff = tif->tif_diroff;
2090 0 : dirn -= tif->tif_curdir;
2091 0 : nextdirnum = tif->tif_curdir;
2092 : }
2093 0 : else if (!(tif->tif_flags & TIFF_BIGTIFF))
2094 0 : nextdiroff = tif->tif_header.classic.tiff_diroff;
2095 : else
2096 0 : nextdiroff = tif->tif_header.big.tiff_diroff;
2097 :
2098 : /* Reset to relative stepping */
2099 0 : tif->tif_setdirectory_force_absolute = FALSE;
2100 :
2101 0 : for (n = dirn; n > 0 && nextdiroff != 0; n--)
2102 0 : if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2103 0 : return (0);
2104 : /* If the n-th directory could not be reached (does not exist),
2105 : * return here without touching anything further. */
2106 0 : if (nextdiroff == 0 || n > 0)
2107 0 : return (0);
2108 :
2109 0 : tif->tif_nextdiroff = nextdiroff;
2110 :
2111 : /* Set curdir to the actual directory index. */
2112 0 : if (relative)
2113 0 : tif->tif_curdir += dirn - n;
2114 : else
2115 0 : tif->tif_curdir = dirn - n;
2116 : }
2117 :
2118 : /* The -1 decrement is because TIFFReadDirectory will increment
2119 : * tif_curdir after successfully reading the directory. */
2120 10824 : if (tif->tif_curdir == 0)
2121 10050 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2122 : else
2123 774 : tif->tif_curdir--;
2124 :
2125 10824 : tdir_t curdir = tif->tif_curdir;
2126 :
2127 10824 : int retval = TIFFReadDirectory(tif);
2128 :
2129 10824 : if (!retval && tif->tif_curdir == curdir)
2130 : {
2131 : /* If tif_curdir has not be incremented, TIFFFetchDirectory() in
2132 : * TIFFReadDirectory() has failed and tif_curdir shall be set
2133 : * specifically. */
2134 4 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2135 : }
2136 10824 : return (retval);
2137 : }
2138 :
2139 : /*
2140 : * Set the current directory to be the directory
2141 : * located at the specified file offset. This interface
2142 : * is used mainly to access directories linked with
2143 : * the SubIFD tag (e.g. thumbnail images).
2144 : */
2145 19508 : int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2146 : {
2147 : /* Match nextdiroff and curdir for consistent IFD-loop checking.
2148 : * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2149 : * invalid offsets within the main IFD tree. In the case of several subIFDs
2150 : * of a main image, there are two possibilities that are not even mutually
2151 : * exclusive. a.) The subIFD tag contains an array with all offsets of the
2152 : * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2153 : * (refer to
2154 : * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2155 : */
2156 : int retval;
2157 19508 : uint32_t curdir = 0;
2158 19508 : int8_t probablySubIFD = 0;
2159 19508 : if (diroff == 0)
2160 : {
2161 : /* Special case to set tif_diroff=0, which is done in
2162 : * TIFFReadDirectory() below to indicate that the currently read IFD is
2163 : * treated as a new, fresh IFD. */
2164 8507 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2165 8507 : tif->tif_dir.td_iswrittentofile = FALSE;
2166 : }
2167 : else
2168 : {
2169 11001 : if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2170 : {
2171 : /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2172 59 : probablySubIFD = 1;
2173 : }
2174 : /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2175 11003 : if (curdir >= 1)
2176 1787 : tif->tif_curdir = curdir - 1;
2177 : else
2178 9216 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2179 : }
2180 19510 : curdir = tif->tif_curdir;
2181 :
2182 19510 : tif->tif_nextdiroff = diroff;
2183 19510 : retval = TIFFReadDirectory(tif);
2184 :
2185 : /* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
2186 : * incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
2187 : * be set specifically. */
2188 19511 : if (!retval && diroff != 0 && tif->tif_curdir == curdir)
2189 : {
2190 1 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2191 : }
2192 :
2193 19511 : if (probablySubIFD)
2194 : {
2195 59 : if (retval)
2196 : {
2197 : /* Reset IFD list to start new one for SubIFD chain and also start
2198 : * SubIFD chain with tif_curdir=0 for IFD loop checking. */
2199 : /* invalidate IFD loop lists */
2200 58 : _TIFFCleanupIFDOffsetAndNumberMaps(tif);
2201 58 : tif->tif_curdir = 0; /* first directory of new chain */
2202 : /* add this offset to new IFD list */
2203 58 : retval = _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2204 : }
2205 : /* To be able to return from SubIFD or custom-IFD to main-IFD */
2206 59 : tif->tif_setdirectory_force_absolute = TRUE;
2207 : }
2208 :
2209 19511 : return (retval);
2210 : }
2211 :
2212 : /*
2213 : * Return file offset of the current directory.
2214 : */
2215 135437 : uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2216 :
2217 : /*
2218 : * Return an indication of whether or not we are
2219 : * at the last directory in the file.
2220 : */
2221 9272 : int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2222 :
2223 : /*
2224 : * Unlink the specified directory from the directory chain.
2225 : * Note: First directory starts with number dirn=1.
2226 : * This is different to TIFFSetDirectory() where the first directory starts with
2227 : * zero.
2228 : */
2229 6 : int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2230 : {
2231 : static const char module[] = "TIFFUnlinkDirectory";
2232 : uint64_t nextdir;
2233 : tdir_t nextdirnum;
2234 : uint64_t off;
2235 : tdir_t n;
2236 :
2237 6 : if (tif->tif_mode == O_RDONLY)
2238 : {
2239 0 : TIFFErrorExtR(tif, module,
2240 : "Can not unlink directory in read-only file");
2241 0 : return (0);
2242 : }
2243 6 : if (dirn == 0)
2244 : {
2245 0 : TIFFErrorExtR(tif, module,
2246 : "For TIFFUnlinkDirectory() first directory starts with "
2247 : "number 1 and not 0");
2248 0 : return (0);
2249 : }
2250 : /*
2251 : * Go to the directory before the one we want
2252 : * to unlink and nab the offset of the link
2253 : * field we'll need to patch.
2254 : */
2255 6 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2256 : {
2257 6 : nextdir = tif->tif_header.classic.tiff_diroff;
2258 6 : off = 4;
2259 : }
2260 : else
2261 : {
2262 0 : nextdir = tif->tif_header.big.tiff_diroff;
2263 0 : off = 8;
2264 : }
2265 6 : nextdirnum = 0; /* First directory is dirn=0 */
2266 :
2267 15 : for (n = dirn - 1; n > 0; n--)
2268 : {
2269 9 : if (nextdir == 0)
2270 : {
2271 0 : TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2272 0 : return (0);
2273 : }
2274 9 : if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2275 0 : return (0);
2276 : }
2277 : /*
2278 : * Advance to the directory to be unlinked and fetch
2279 : * the offset of the directory that follows.
2280 : */
2281 6 : if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2282 0 : return (0);
2283 : /*
2284 : * Go back and patch the link field of the preceding
2285 : * directory to point to the offset of the directory
2286 : * that follows.
2287 : */
2288 6 : (void)TIFFSeekFile(tif, off, SEEK_SET);
2289 6 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2290 : {
2291 : uint32_t nextdir32;
2292 6 : nextdir32 = (uint32_t)nextdir;
2293 6 : assert((uint64_t)nextdir32 == nextdir);
2294 6 : if (tif->tif_flags & TIFF_SWAB)
2295 0 : TIFFSwabLong(&nextdir32);
2296 6 : if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2297 : {
2298 0 : TIFFErrorExtR(tif, module, "Error writing directory link");
2299 0 : return (0);
2300 : }
2301 : }
2302 : else
2303 : {
2304 : /* Need local swap because nextdir has to be used unswapped below. */
2305 0 : uint64_t nextdir64 = nextdir;
2306 0 : if (tif->tif_flags & TIFF_SWAB)
2307 0 : TIFFSwabLong8(&nextdir64);
2308 0 : if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
2309 : {
2310 0 : TIFFErrorExtR(tif, module, "Error writing directory link");
2311 0 : return (0);
2312 : }
2313 : }
2314 :
2315 : /* For dirn=1 (first directory) also update the libtiff internal
2316 : * base offset variables. */
2317 6 : if (dirn == 1)
2318 : {
2319 0 : if (!(tif->tif_flags & TIFF_BIGTIFF))
2320 0 : tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
2321 : else
2322 0 : tif->tif_header.big.tiff_diroff = nextdir;
2323 : }
2324 :
2325 : /*
2326 : * Leave directory state setup safely. We don't have
2327 : * facilities for doing inserting and removing directories,
2328 : * so it's safest to just invalidate everything. This
2329 : * means that the caller can only append to the directory
2330 : * chain.
2331 : */
2332 6 : if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2333 : {
2334 0 : _TIFFfreeExt(tif, tif->tif_rawdata);
2335 0 : tif->tif_rawdata = NULL;
2336 0 : tif->tif_rawcc = 0;
2337 0 : tif->tif_rawcp = NULL;
2338 0 : tif->tif_rawdataoff = 0;
2339 0 : tif->tif_rawdataloaded = 0;
2340 : }
2341 6 : tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2342 : TIFF_BUF4WRITE);
2343 6 : TIFFFreeDirectory(tif);
2344 6 : TIFFDefaultDirectory(tif);
2345 6 : tif->tif_diroff = 0; /* force link on next write */
2346 6 : tif->tif_nextdiroff = 0; /* next write must be at end */
2347 6 : tif->tif_lastdiroff = 0; /* will be updated on next link */
2348 6 : tif->tif_curoff = 0;
2349 6 : tif->tif_row = (uint32_t)-1;
2350 6 : tif->tif_curstrip = (uint32_t)-1;
2351 6 : tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2352 6 : if (tif->tif_curdircount > 0)
2353 6 : tif->tif_curdircount--;
2354 : else
2355 0 : tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
2356 6 : _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2357 6 : return (1);
2358 : }
|