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