Coverage Report

Created: 2026-08-19 06:52

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