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