Coverage Report

Created: 2025-06-12 06:52

/src/opencv/3rdparty/libtiff/tif_dir.c
Line
Count
Source (jump to first uncovered line)
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
2
#define DATATYPE_INT 1    /* !signed integer data */
40
4
#define DATATYPE_UINT 2   /* !unsigned integer data */
41
0
#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
1.72k
{
46
1.72k
    if (*vpp)
47
15
    {
48
15
        _TIFFfreeExt(tif, *vpp);
49
15
        *vpp = 0;
50
15
    }
51
1.72k
    if (vp)
52
1.66k
    {
53
1.66k
        tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
54
1.66k
        if (bytes)
55
1.66k
            *vpp = (void *)_TIFFmallocExt(tif, bytes);
56
1.66k
        if (*vpp)
57
1.66k
            _TIFFmemcpy(*vpp, vp, bytes);
58
1.66k
    }
59
1.72k
}
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
0
{
66
0
    setByteArray(tif, vpp, vp, n, 1);
67
0
}
68
69
static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n)
70
10
{
71
10
    setByteArray(tif, (void **)cpp, cp, n, 1);
72
10
}
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
1.03k
{
81
1.03k
    setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
82
1.03k
}
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
3
{
97
3
    setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
98
3
}
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
20
{
106
20
    setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
107
20
}
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
40
{
116
40
    setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
117
40
}
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
147
{
137
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
138
147
#define EXTRASAMPLE_COREL_UNASSALPHA 999
139
140
147
    uint16_t *va;
141
147
    uint32_t i;
142
147
    TIFFDirectory *td = &tif->tif_dir;
143
147
    static const char module[] = "setExtraSamples";
144
145
147
    *v = (uint16_t)va_arg(ap, uint16_vap);
146
147
    if ((uint16_t)*v > td->td_samplesperpixel)
147
0
        return 0;
148
147
    va = va_arg(ap, uint16_t *);
149
147
    if (*v > 0 && va == NULL) /* typically missing param */
150
0
        return 0;
151
418
    for (i = 0; i < *v; i++)
152
272
    {
153
272
        if (va[i] > EXTRASAMPLE_UNASSALPHA)
154
1
        {
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
1
            if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
162
0
                va[i] = EXTRASAMPLE_UNASSALPHA;
163
1
            else
164
1
                return 0;
165
1
        }
166
272
    }
167
168
146
    if (td->td_transferfunction[0] != NULL &&
169
146
        (td->td_samplesperpixel - *v > 1) &&
170
146
        !(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
146
    td->td_extrasamples = (uint16_t)*v;
182
146
    _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
183
146
    return 1;
184
185
147
#undef EXTRASAMPLE_COREL_UNASSALPHA
186
147
}
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
10
{
194
10
    uint16_t i = 0;
195
196
10
    if (slen > 0)
197
10
    {
198
10
        const char *ep = s + slen;
199
10
        const char *cp = s;
200
10
        do
201
181
        {
202
277
            for (; cp < ep && *cp != '\0'; cp++)
203
96
            {
204
96
            }
205
181
            if (cp >= ep)
206
0
                goto bad;
207
181
            cp++; /* skip \0 */
208
181
            i++;
209
181
        } while (cp < ep);
210
10
        return (i);
211
10
    }
212
0
bad:
213
0
    TIFFErrorExtR(tif, "TIFFSetField",
214
0
                  "%s: Invalid InkNames value; no NUL at given buffer end "
215
0
                  "location %" PRIu32 ", after %" PRIu16 " ink",
216
0
                  tif->tif_name, slen, i);
217
0
    return (0);
218
10
}
219
220
static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
221
48.4k
{
222
48.4k
    static const char module[] = "_TIFFVSetField";
223
224
48.4k
    TIFFDirectory *td = &tif->tif_dir;
225
48.4k
    int status = 1;
226
48.4k
    uint32_t v32, v;
227
48.4k
    double dblval;
228
48.4k
    char *s;
229
48.4k
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
230
48.4k
    uint32_t standard_tag = tag;
231
48.4k
    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
48.4k
    if (fip->field_bit == FIELD_CUSTOM)
240
4.88k
    {
241
4.88k
        standard_tag = 0;
242
4.88k
    }
243
244
48.4k
    switch (standard_tag)
245
48.4k
    {
246
40
        case TIFFTAG_SUBFILETYPE:
247
40
            td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
248
40
            break;
249
3.55k
        case TIFFTAG_IMAGEWIDTH:
250
3.55k
            td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
251
3.55k
            break;
252
3.47k
        case TIFFTAG_IMAGELENGTH:
253
3.47k
            td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
254
3.47k
            break;
255
6.91k
        case TIFFTAG_BITSPERSAMPLE:
256
6.91k
            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
6.91k
            if (tif->tif_flags & TIFF_SWAB)
265
145
            {
266
145
                if (td->td_bitspersample == 8)
267
115
                    tif->tif_postdecode = _TIFFNoPostDecode;
268
30
                else if (td->td_bitspersample == 16)
269
3
                    tif->tif_postdecode = _TIFFSwab16BitData;
270
27
                else if (td->td_bitspersample == 24)
271
1
                    tif->tif_postdecode = _TIFFSwab24BitData;
272
26
                else if (td->td_bitspersample == 32)
273
1
                    tif->tif_postdecode = _TIFFSwab32BitData;
274
25
                else if (td->td_bitspersample == 64)
275
3
                    tif->tif_postdecode = _TIFFSwab64BitData;
276
22
                else if (td->td_bitspersample == 128) /* two 64's */
277
0
                    tif->tif_postdecode = _TIFFSwab64BitData;
278
145
            }
279
6.91k
            break;
280
7.39k
        case TIFFTAG_COMPRESSION:
281
7.39k
            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
7.39k
            if (TIFFFieldSet(tif, FIELD_COMPRESSION))
288
3.68k
            {
289
3.68k
                if ((uint32_t)td->td_compression == v)
290
719
                    break;
291
2.96k
                (*tif->tif_cleanup)(tif);
292
2.96k
                tif->tif_flags &= ~TIFF_CODERSETUP;
293
2.96k
            }
294
            /*
295
             * Setup new compression routine state.
296
             */
297
6.67k
            if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
298
6.67k
                td->td_compression = (uint16_t)v;
299
0
            else
300
0
                status = 0;
301
6.67k
            break;
302
3.39k
        case TIFFTAG_PHOTOMETRIC:
303
3.39k
            td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
304
3.39k
            break;
305
3
        case TIFFTAG_THRESHHOLDING:
306
3
            td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
307
3
            break;
308
56
        case TIFFTAG_FILLORDER:
309
56
            v = (uint16_t)va_arg(ap, uint16_vap);
310
56
            if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
311
3
                goto badvalue;
312
53
            td->td_fillorder = (uint16_t)v;
313
53
            break;
314
296
        case TIFFTAG_ORIENTATION:
315
296
            v = (uint16_t)va_arg(ap, uint16_vap);
316
296
            if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
317
15
                goto badvalue;
318
281
            else
319
281
                td->td_orientation = (uint16_t)v;
320
281
            break;
321
2.50k
        case TIFFTAG_SAMPLESPERPIXEL:
322
2.50k
            v = (uint16_t)va_arg(ap, uint16_vap);
323
2.50k
            if (v == 0)
324
0
                goto badvalue;
325
2.50k
            if (v != td->td_samplesperpixel)
326
2.45k
            {
327
                /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
328
2.45k
                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
2.45k
                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
2.45k
                if (td->td_transferfunction[0] != NULL &&
352
2.45k
                    (v - td->td_extrasamples > 1) &&
353
2.45k
                    !(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
2.45k
            }
364
2.50k
            td->td_samplesperpixel = (uint16_t)v;
365
2.50k
            break;
366
838
        case TIFFTAG_ROWSPERSTRIP:
367
838
            v32 = (uint32_t)va_arg(ap, uint32_t);
368
838
            if (v32 == 0)
369
1
                goto badvalue32;
370
837
            td->td_rowsperstrip = v32;
371
837
            if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
372
835
            {
373
835
                td->td_tilelength = v32;
374
835
                td->td_tilewidth = td->td_imagewidth;
375
835
            }
376
837
            break;
377
2
        case TIFFTAG_MINSAMPLEVALUE:
378
2
            td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
379
2
            break;
380
7
        case TIFFTAG_MAXSAMPLEVALUE:
381
7
            td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
382
7
            break;
383
12
        case TIFFTAG_SMINSAMPLEVALUE:
384
12
            if (tif->tif_flags & TIFF_PERSAMPLE)
385
12
                _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
386
12
                                       va_arg(ap, double *),
387
12
                                       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
12
            break;
393
28
        case TIFFTAG_SMAXSAMPLEVALUE:
394
28
            if (tif->tif_flags & TIFF_PERSAMPLE)
395
28
                _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
396
28
                                       va_arg(ap, double *),
397
28
                                       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
28
            break;
403
55
        case TIFFTAG_XRESOLUTION:
404
55
            dblval = va_arg(ap, double);
405
55
            if (dblval != dblval || dblval < 0)
406
0
                goto badvaluedouble;
407
55
            td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
408
55
            break;
409
50
        case TIFFTAG_YRESOLUTION:
410
50
            dblval = va_arg(ap, double);
411
50
            if (dblval != dblval || dblval < 0)
412
0
                goto badvaluedouble;
413
50
            td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
414
50
            break;
415
4.75k
        case TIFFTAG_PLANARCONFIG:
416
4.75k
            v = (uint16_t)va_arg(ap, uint16_vap);
417
4.75k
            if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
418
0
                goto badvalue;
419
4.75k
            td->td_planarconfig = (uint16_t)v;
420
4.75k
            break;
421
7
        case TIFFTAG_XPOSITION:
422
7
            td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
423
7
            break;
424
7
        case TIFFTAG_YPOSITION:
425
7
            td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
426
7
            break;
427
40
        case TIFFTAG_RESOLUTIONUNIT:
428
40
            v = (uint16_t)va_arg(ap, uint16_vap);
429
40
            if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
430
5
                goto badvalue;
431
35
            td->td_resolutionunit = (uint16_t)v;
432
35
            break;
433
12
        case TIFFTAG_PAGENUMBER:
434
12
            td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
435
12
            td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
436
12
            break;
437
1
        case TIFFTAG_HALFTONEHINTS:
438
1
            td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
439
1
            td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
440
1
            break;
441
43
        case TIFFTAG_COLORMAP:
442
43
            v32 = (uint32_t)(1L << td->td_bitspersample);
443
43
            _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
444
43
                                  va_arg(ap, uint16_t *), v32);
445
43
            _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
446
43
                                  va_arg(ap, uint16_t *), v32);
447
43
            _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
448
43
                                  va_arg(ap, uint16_t *), v32);
449
43
            break;
450
147
        case TIFFTAG_EXTRASAMPLES:
451
147
            if (!setExtraSamples(tif, ap, &v))
452
1
                goto badvalue;
453
146
            break;
454
146
        case TIFFTAG_MATTEING:
455
2
            td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
456
2
            if (td->td_extrasamples)
457
2
            {
458
2
                uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
459
2
                _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
460
2
            }
461
2
            break;
462
2.08k
        case TIFFTAG_TILEWIDTH:
463
2.08k
            v32 = (uint32_t)va_arg(ap, uint32_t);
464
2.08k
            if (v32 % 16)
465
1.81k
            {
466
1.81k
                if (tif->tif_mode != O_RDONLY)
467
0
                    goto badvalue32;
468
1.81k
                TIFFWarningExtR(
469
1.81k
                    tif, tif->tif_name,
470
1.81k
                    "Nonstandard tile width %" PRIu32 ", convert file", v32);
471
1.81k
            }
472
2.08k
            td->td_tilewidth = v32;
473
2.08k
            tif->tif_flags |= TIFF_ISTILED;
474
2.08k
            break;
475
2.13k
        case TIFFTAG_TILELENGTH:
476
2.13k
            v32 = (uint32_t)va_arg(ap, uint32_t);
477
2.13k
            if (v32 % 16)
478
1.16k
            {
479
1.16k
                if (tif->tif_mode != O_RDONLY)
480
0
                    goto badvalue32;
481
1.16k
                TIFFWarningExtR(
482
1.16k
                    tif, tif->tif_name,
483
1.16k
                    "Nonstandard tile length %" PRIu32 ", convert file", v32);
484
1.16k
            }
485
2.13k
            td->td_tilelength = v32;
486
2.13k
            tif->tif_flags |= TIFF_ISTILED;
487
2.13k
            break;
488
8
        case TIFFTAG_TILEDEPTH:
489
8
            v32 = (uint32_t)va_arg(ap, uint32_t);
490
8
            if (v32 == 0)
491
0
                goto badvalue32;
492
8
            td->td_tiledepth = v32;
493
8
            break;
494
6
        case TIFFTAG_DATATYPE:
495
6
            v = (uint16_t)va_arg(ap, uint16_vap);
496
6
            switch (v)
497
6
            {
498
0
                case DATATYPE_VOID:
499
0
                    v = SAMPLEFORMAT_VOID;
500
0
                    break;
501
2
                case DATATYPE_INT:
502
2
                    v = SAMPLEFORMAT_INT;
503
2
                    break;
504
4
                case DATATYPE_UINT:
505
4
                    v = SAMPLEFORMAT_UINT;
506
4
                    break;
507
0
                case DATATYPE_IEEEFP:
508
0
                    v = SAMPLEFORMAT_IEEEFP;
509
0
                    break;
510
0
                default:
511
0
                    goto badvalue;
512
6
            }
513
6
            td->td_sampleformat = (uint16_t)v;
514
6
            break;
515
5.43k
        case TIFFTAG_SAMPLEFORMAT:
516
5.43k
            v = (uint16_t)va_arg(ap, uint16_vap);
517
5.43k
            if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
518
0
                goto badvalue;
519
5.43k
            td->td_sampleformat = (uint16_t)v;
520
521
            /*  Try to fix up the SWAB function for complex data. */
522
5.43k
            if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
523
5.43k
                td->td_bitspersample == 32 &&
524
5.43k
                tif->tif_postdecode == _TIFFSwab32BitData)
525
0
                tif->tif_postdecode = _TIFFSwab16BitData;
526
5.43k
            else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
527
5.43k
                      td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
528
5.43k
                     td->td_bitspersample == 64 &&
529
5.43k
                     tif->tif_postdecode == _TIFFSwab64BitData)
530
0
                tif->tif_postdecode = _TIFFSwab32BitData;
531
5.43k
            break;
532
11
        case TIFFTAG_IMAGEDEPTH:
533
11
            td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
534
11
            break;
535
3
        case TIFFTAG_SUBIFD:
536
3
            if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
537
3
            {
538
3
                td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
539
3
                _TIFFsetLong8Array(tif, &td->td_subifd,
540
3
                                   (uint64_t *)va_arg(ap, uint64_t *),
541
3
                                   (uint32_t)td->td_nsubifd);
542
3
            }
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
3
            break;
550
14
        case TIFFTAG_YCBCRPOSITIONING:
551
14
            td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
552
14
            break;
553
186
        case TIFFTAG_YCBCRSUBSAMPLING:
554
186
            td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
555
186
            td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
556
186
            break;
557
0
        case TIFFTAG_TRANSFERFUNCTION:
558
0
        {
559
0
            uint32_t i;
560
0
            v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
561
0
            for (i = 0; i < v; i++)
562
0
                _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
563
0
                                      va_arg(ap, uint16_t *),
564
0
                                      1U << td->td_bitspersample);
565
0
            break;
566
5.43k
        }
567
20
        case TIFFTAG_REFERENCEBLACKWHITE:
568
            /* XXX should check for null range */
569
20
            _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
570
20
                                  va_arg(ap, float *), 6);
571
20
            break;
572
10
        case TIFFTAG_INKNAMES:
573
10
        {
574
10
            v = (uint16_t)va_arg(ap, uint16_vap);
575
10
            s = va_arg(ap, char *);
576
10
            uint16_t ninksinstring;
577
10
            ninksinstring = countInkNamesString(tif, v, s);
578
10
            status = ninksinstring > 0;
579
10
            if (ninksinstring > 0)
580
10
            {
581
10
                _TIFFsetNString(tif, &td->td_inknames, s, v);
582
10
                td->td_inknameslen = v;
583
                /* Set NumberOfInks to the value ninksinstring */
584
10
                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
10
                else
600
10
                {
601
10
                    td->td_numberofinks = ninksinstring;
602
10
                    TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
603
10
                }
604
10
                if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
605
8
                {
606
8
                    if (td->td_numberofinks != td->td_samplesperpixel)
607
8
                    {
608
8
                        TIFFErrorExtR(tif, module,
609
8
                                      "Warning %s; Tag %s:\n  Value %" PRIu16
610
8
                                      " of NumberOfInks is different from the "
611
8
                                      "SamplesPerPixel value %" PRIu16 "",
612
8
                                      tif->tif_name, fip->field_name,
613
8
                                      td->td_numberofinks,
614
8
                                      td->td_samplesperpixel);
615
8
                    }
616
8
                }
617
10
            }
618
10
        }
619
10
        break;
620
1
        case TIFFTAG_NUMBEROFINKS:
621
1
            v = (uint16_t)va_arg(ap, uint16_vap);
622
            /* If InkNames already set also NumberOfInks is set accordingly and
623
             * should be equal */
624
1
            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
1
            else
641
1
            {
642
1
                td->td_numberofinks = (uint16_t)v;
643
1
                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
1
            }
656
1
            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
4.88k
        default:
665
4.88k
        {
666
4.88k
            TIFFTagValue *tv;
667
4.88k
            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
4.88k
            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
4.88k
            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
4.88k
            tv = NULL;
705
36.0k
            for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
706
31.1k
            {
707
31.1k
                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
31.1k
            }
718
719
            /*
720
             * Grow the custom list if the entry was not found.
721
             */
722
4.88k
            if (tv == NULL)
723
4.88k
            {
724
4.88k
                TIFFTagValue *new_customValues;
725
726
4.88k
                td->td_customValueCount++;
727
4.88k
                new_customValues = (TIFFTagValue *)_TIFFreallocExt(
728
4.88k
                    tif, td->td_customValues,
729
4.88k
                    sizeof(TIFFTagValue) * td->td_customValueCount);
730
4.88k
                if (!new_customValues)
731
0
                {
732
0
                    TIFFErrorExtR(tif, module,
733
0
                                  "%s: Failed to allocate space for list of "
734
0
                                  "custom values",
735
0
                                  tif->tif_name);
736
0
                    status = 0;
737
0
                    goto end;
738
0
                }
739
740
4.88k
                td->td_customValues = new_customValues;
741
742
4.88k
                tv = td->td_customValues + (td->td_customValueCount - 1);
743
4.88k
                tv->info = fip;
744
4.88k
                tv->value = NULL;
745
4.88k
                tv->count = 0;
746
4.88k
            }
747
748
            /*
749
             * Set custom value ... save a copy of the custom tag value.
750
             */
751
            /*--: Rational2Double: For Rationals evaluate "set_field_type" to
752
             * determine internal storage size. */
753
4.88k
            tv_size = TIFFFieldSetGetSize(fip);
754
4.88k
            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
4.88k
            if (fip->field_type == TIFF_ASCII)
763
615
            {
764
615
                uint32_t ma;
765
615
                const char *mb;
766
615
                if (fip->field_passcount)
767
434
                {
768
434
                    assert(fip->field_writecount == TIFF_VARIABLE2);
769
434
                    ma = (uint32_t)va_arg(ap, uint32_t);
770
434
                    mb = (const char *)va_arg(ap, const char *);
771
434
                }
772
181
                else
773
181
                {
774
181
                    mb = (const char *)va_arg(ap, const char *);
775
181
                    size_t len = strlen(mb) + 1;
776
181
                    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
181
                    ma = (uint32_t)len;
786
181
                }
787
615
                tv->count = ma;
788
615
                setByteArray(tif, &tv->value, mb, ma, 1);
789
615
            }
790
4.27k
            else
791
4.27k
            {
792
4.27k
                if (fip->field_passcount)
793
3.97k
                {
794
3.97k
                    if (fip->field_writecount == TIFF_VARIABLE2)
795
3.77k
                        tv->count = (uint32_t)va_arg(ap, uint32_t);
796
198
                    else
797
198
                        tv->count = (int)va_arg(ap, int);
798
3.97k
                }
799
296
                else if (fip->field_writecount == TIFF_VARIABLE ||
800
296
                         fip->field_writecount == TIFF_VARIABLE2)
801
0
                    tv->count = 1;
802
296
                else if (fip->field_writecount == TIFF_SPP)
803
0
                    tv->count = td->td_samplesperpixel;
804
296
                else
805
296
                    tv->count = fip->field_writecount;
806
807
4.27k
                if (tv->count == 0)
808
576
                {
809
576
                    status = 0;
810
576
                    TIFFErrorExtR(tif, module,
811
576
                                  "%s: Null count for \"%s\" (type "
812
576
                                  "%d, writecount %d, passcount %d)",
813
576
                                  tif->tif_name, fip->field_name,
814
576
                                  fip->field_type, fip->field_writecount,
815
576
                                  fip->field_passcount);
816
576
                    goto end;
817
576
                }
818
819
3.69k
                tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
820
3.69k
                                             "custom tag binary object");
821
3.69k
                if (!tv->value)
822
0
                {
823
0
                    status = 0;
824
0
                    goto end;
825
0
                }
826
827
3.69k
                if (fip->field_tag == TIFFTAG_DOTRANGE &&
828
3.69k
                    strcmp(fip->field_name, "DotRange") == 0)
829
20
                {
830
                    /* TODO: This is an evil exception and should not have been
831
                       handled this way ... likely best if we move it into
832
                       the directory structure with an explicit field in
833
                       libtiff 4.1 and assign it a FIELD_ value */
834
20
                    uint16_t v2[2];
835
20
                    v2[0] = (uint16_t)va_arg(ap, int);
836
20
                    v2[1] = (uint16_t)va_arg(ap, int);
837
20
                    _TIFFmemcpy(tv->value, &v2, 4);
838
20
                }
839
840
3.67k
                else if (fip->field_passcount ||
841
3.67k
                         fip->field_writecount == TIFF_VARIABLE ||
842
3.67k
                         fip->field_writecount == TIFF_VARIABLE2 ||
843
3.67k
                         fip->field_writecount == TIFF_SPP || tv->count > 1)
844
3.46k
                {
845
                    /*--: Rational2Double: For Rationals tv_size is set above to
846
                     * 4 or 8 according to fip->set_field_type! */
847
3.46k
                    _TIFFmemcpy(tv->value, va_arg(ap, void *),
848
3.46k
                                tv->count * tv_size);
849
                    /* Test here for too big values for LONG8, SLONG8 in
850
                     * ClassicTIFF and delete custom field from custom list */
851
3.46k
                    if (!(tif->tif_flags & TIFF_BIGTIFF))
852
3.45k
                    {
853
3.45k
                        if (tv->info->field_type == TIFF_LONG8)
854
13
                        {
855
13
                            uint64_t *pui64 = (uint64_t *)tv->value;
856
68
                            for (int i = 0; i < tv->count; i++)
857
67
                            {
858
67
                                if (pui64[i] > 0xffffffffu)
859
12
                                {
860
12
                                    TIFFErrorExtR(
861
12
                                        tif, module,
862
12
                                        "%s: Bad LONG8 value %" PRIu64
863
12
                                        " at %d. array position for \"%s\" tag "
864
12
                                        "%d in ClassicTIFF. Tag won't be "
865
12
                                        "written to file",
866
12
                                        tif->tif_name, pui64[i], i,
867
12
                                        fip->field_name, tag);
868
12
                                    goto badvalueifd8long8;
869
12
                                }
870
67
                            }
871
13
                        }
872
3.44k
                        else if (tv->info->field_type == TIFF_SLONG8)
873
8
                        {
874
8
                            int64_t *pi64 = (int64_t *)tv->value;
875
69
                            for (int i = 0; i < tv->count; i++)
876
68
                            {
877
68
                                if (pi64[i] > 2147483647 ||
878
68
                                    pi64[i] < (-2147483647 - 1))
879
7
                                {
880
7
                                    TIFFErrorExtR(
881
7
                                        tif, module,
882
7
                                        "%s: Bad SLONG8 value %" PRIi64
883
7
                                        " at %d. array position for \"%s\" tag "
884
7
                                        "%d in ClassicTIFF. Tag won't be "
885
7
                                        "written to file",
886
7
                                        tif->tif_name, pi64[i], i,
887
7
                                        fip->field_name, tag);
888
7
                                    goto badvalueifd8long8;
889
7
                                }
890
68
                            }
891
8
                        }
892
3.45k
                    }
893
3.46k
                }
894
213
                else
895
213
                {
896
213
                    char *val = (char *)tv->value;
897
213
                    assert(tv->count == 1);
898
899
213
                    switch (fip->field_type)
900
213
                    {
901
8
                        case TIFF_BYTE:
902
8
                        case TIFF_UNDEFINED:
903
8
                        {
904
8
                            uint8_t v2 = (uint8_t)va_arg(ap, int);
905
8
                            _TIFFmemcpy(val, &v2, tv_size);
906
8
                        }
907
8
                        break;
908
0
                        case TIFF_SBYTE:
909
0
                        {
910
0
                            int8_t v2 = (int8_t)va_arg(ap, int);
911
0
                            _TIFFmemcpy(val, &v2, tv_size);
912
0
                        }
913
0
                        break;
914
36
                        case TIFF_SHORT:
915
36
                        {
916
36
                            uint16_t v2 = (uint16_t)va_arg(ap, int);
917
36
                            _TIFFmemcpy(val, &v2, tv_size);
918
36
                        }
919
36
                        break;
920
0
                        case TIFF_SSHORT:
921
0
                        {
922
0
                            int16_t v2 = (int16_t)va_arg(ap, int);
923
0
                            _TIFFmemcpy(val, &v2, tv_size);
924
0
                        }
925
0
                        break;
926
1
                        case TIFF_LONG:
927
1
                        case TIFF_IFD:
928
1
                        {
929
1
                            uint32_t v2 = va_arg(ap, uint32_t);
930
1
                            _TIFFmemcpy(val, &v2, tv_size);
931
1
                        }
932
1
                        break;
933
0
                        case TIFF_SLONG:
934
0
                        {
935
0
                            int32_t v2 = va_arg(ap, int32_t);
936
0
                            _TIFFmemcpy(val, &v2, tv_size);
937
0
                        }
938
0
                        break;
939
0
                        case TIFF_LONG8:
940
75
                        case TIFF_IFD8:
941
75
                        {
942
75
                            uint64_t v2 = va_arg(ap, uint64_t);
943
75
                            _TIFFmemcpy(val, &v2, tv_size);
944
                            /* Test here for too big values for ClassicTIFF and
945
                             * delete custom field from custom list */
946
75
                            if (!(tif->tif_flags & TIFF_BIGTIFF) &&
947
75
                                (v2 > 0xffffffffu))
948
0
                            {
949
0
                                TIFFErrorExtR(
950
0
                                    tif, module,
951
0
                                    "%s: Bad LONG8 or IFD8 value %" PRIu64
952
0
                                    " for \"%s\" tag %d in ClassicTIFF. Tag "
953
0
                                    "won't be written to file",
954
0
                                    tif->tif_name, v2, fip->field_name, tag);
955
0
                                goto badvalueifd8long8;
956
0
                            }
957
75
                        }
958
75
                        break;
959
75
                        case TIFF_SLONG8:
960
0
                        {
961
0
                            int64_t v2 = va_arg(ap, int64_t);
962
0
                            _TIFFmemcpy(val, &v2, tv_size);
963
                            /* Test here for too big values for ClassicTIFF and
964
                             * delete custom field from custom list */
965
0
                            if (!(tif->tif_flags & TIFF_BIGTIFF) &&
966
0
                                ((v2 > 2147483647) || (v2 < (-2147483647 - 1))))
967
0
                            {
968
0
                                TIFFErrorExtR(
969
0
                                    tif, module,
970
0
                                    "%s: Bad SLONG8 value %" PRIi64
971
0
                                    " for \"%s\" tag %d in ClassicTIFF. Tag "
972
0
                                    "won't be written to file",
973
0
                                    tif->tif_name, v2, fip->field_name, tag);
974
0
                                goto badvalueifd8long8;
975
0
                            }
976
0
                        }
977
0
                        break;
978
72
                        case TIFF_RATIONAL:
979
91
                        case TIFF_SRATIONAL:
980
                            /*-- Rational2Double: For Rationals tv_size is set
981
                             * above to 4 or 8 according to fip->set_field_type!
982
                             */
983
91
                            {
984
91
                                if (tv_size == 8)
985
0
                                {
986
0
                                    double v2 = va_arg(ap, double);
987
0
                                    _TIFFmemcpy(val, &v2, tv_size);
988
0
                                }
989
91
                                else
990
91
                                {
991
                                    /*-- default should be tv_size == 4 */
992
91
                                    float v3 = (float)va_arg(ap, double);
993
91
                                    _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
91
                                    if (tv_size != 4)
998
0
                                    {
999
0
                                        TIFFErrorExtR(
1000
0
                                            tif, module,
1001
0
                                            "Rational2Double: .set_field_type "
1002
0
                                            "in not 4 but %d",
1003
0
                                            tv_size);
1004
0
                                    }
1005
91
                                }
1006
91
                            }
1007
91
                            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
213
                    }
1026
213
                }
1027
3.69k
            }
1028
4.88k
        }
1029
48.4k
    }
1030
47.8k
    if (status)
1031
47.8k
    {
1032
47.8k
        const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1033
47.8k
        if (fip2)
1034
47.8k
            TIFFSetFieldBit(tif, fip2->field_bit);
1035
47.8k
        tif->tif_flags |= TIFF_DIRTYDIRECT;
1036
47.8k
    }
1037
1038
48.3k
end:
1039
48.3k
    va_end(ap);
1040
48.3k
    return (status);
1041
24
badvalue:
1042
24
{
1043
24
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1044
24
    TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1045
24
                  tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
1046
24
    va_end(ap);
1047
24
}
1048
24
    return (0);
1049
1
badvalue32:
1050
1
{
1051
1
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1052
1
    TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1053
1
                  tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
1054
1
    va_end(ap);
1055
1
}
1056
1
    return (0);
1057
0
badvaluedouble:
1058
0
{
1059
0
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1060
0
    TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
1061
0
                  dblval, fip2 ? fip2->field_name : "Unknown");
1062
0
    va_end(ap);
1063
0
}
1064
0
    return (0);
1065
19
badvalueifd8long8:
1066
19
{
1067
    /* Error message issued already above. */
1068
19
    TIFFTagValue *tv2 = NULL;
1069
19
    int iCustom2, iC2;
1070
    /* Find the existing entry for this custom value. */
1071
129
    for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
1072
129
    {
1073
129
        if (td->td_customValues[iCustom2].info->field_tag == tag)
1074
19
        {
1075
19
            tv2 = td->td_customValues + (iCustom2);
1076
19
            break;
1077
19
        }
1078
129
    }
1079
19
    if (tv2 != NULL)
1080
19
    {
1081
        /* Remove custom field from custom list */
1082
19
        if (tv2->value != NULL)
1083
19
        {
1084
19
            _TIFFfreeExt(tif, tv2->value);
1085
19
            tv2->value = NULL;
1086
19
        }
1087
        /* Shorten list and close gap in customValues list.
1088
         * Re-allocation of td_customValues not necessary here. */
1089
19
        td->td_customValueCount--;
1090
19
        for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
1091
0
        {
1092
0
            td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
1093
0
        }
1094
19
    }
1095
0
    else
1096
0
    {
1097
0
        assert(0);
1098
0
    }
1099
19
    va_end(ap);
1100
19
}
1101
19
    return (0);
1102
47.8k
} /*-- _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
54.9k
{
1115
54.9k
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1116
54.9k
    if (!fip)
1117
1
    { /* unknown tag */
1118
1
        TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
1119
1
                      tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
1120
1
        return (0);
1121
1
    }
1122
54.9k
    if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
1123
54.9k
        !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
54.9k
    return (1);
1137
54.9k
}
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
54.9k
{
1148
54.9k
    va_list ap;
1149
54.9k
    int status;
1150
1151
54.9k
    va_start(ap, tag);
1152
54.9k
    status = TIFFVSetField(tif, tag, ap);
1153
54.9k
    va_end(ap);
1154
54.9k
    return (status);
1155
54.9k
}
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
54.9k
{
1207
54.9k
    return OkToChangeTag(tif, tag)
1208
54.9k
               ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1209
54.9k
               : 0;
1210
54.9k
}
1211
1212
static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1213
890k
{
1214
890k
    TIFFDirectory *td = &tif->tif_dir;
1215
890k
    int ret_val = 1;
1216
890k
    uint32_t standard_tag = tag;
1217
890k
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1218
890k
    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
890k
    if (fip->field_bit == FIELD_CUSTOM)
1228
6.52k
    {
1229
6.52k
        standard_tag = 0;
1230
6.52k
    }
1231
1232
890k
    switch (standard_tag)
1233
890k
    {
1234
0
        case TIFFTAG_SUBFILETYPE:
1235
0
            *va_arg(ap, uint32_t *) = td->td_subfiletype;
1236
0
            break;
1237
69.5k
        case TIFFTAG_IMAGEWIDTH:
1238
69.5k
            *va_arg(ap, uint32_t *) = td->td_imagewidth;
1239
69.5k
            break;
1240
69.5k
        case TIFFTAG_IMAGELENGTH:
1241
69.5k
            *va_arg(ap, uint32_t *) = td->td_imagelength;
1242
69.5k
            break;
1243
39.6k
        case TIFFTAG_BITSPERSAMPLE:
1244
39.6k
            *va_arg(ap, uint16_t *) = td->td_bitspersample;
1245
39.6k
            break;
1246
66.4k
        case TIFFTAG_COMPRESSION:
1247
66.4k
            *va_arg(ap, uint16_t *) = td->td_compression;
1248
66.4k
            break;
1249
274k
        case TIFFTAG_PHOTOMETRIC:
1250
274k
            *va_arg(ap, uint16_t *) = td->td_photometric;
1251
274k
            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
4.18k
        case TIFFTAG_ORIENTATION:
1259
4.18k
            *va_arg(ap, uint16_t *) = td->td_orientation;
1260
4.18k
            break;
1261
33.4k
        case TIFFTAG_SAMPLESPERPIXEL:
1262
33.4k
            *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
1263
33.4k
            break;
1264
29.4k
        case TIFFTAG_ROWSPERSTRIP:
1265
29.4k
            *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
1266
29.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
66.4k
        case TIFFTAG_PLANARCONFIG:
1308
66.4k
            *va_arg(ap, uint16_t *) = td->td_planarconfig;
1309
66.4k
            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
1.42k
        case TIFFTAG_COLORMAP:
1328
1.42k
            *va_arg(ap, const uint16_t **) = td->td_colormap[0];
1329
1.42k
            *va_arg(ap, const uint16_t **) = td->td_colormap[1];
1330
1.42k
            *va_arg(ap, const uint16_t **) = td->td_colormap[2];
1331
1.42k
            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
998
        case TIFFTAG_EXTRASAMPLES:
1352
998
            *va_arg(ap, uint16_t *) = td->td_extrasamples;
1353
998
            *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
1354
998
            break;
1355
104k
        case TIFFTAG_TILEWIDTH:
1356
104k
            *va_arg(ap, uint32_t *) = td->td_tilewidth;
1357
104k
            break;
1358
104k
        case TIFFTAG_TILELENGTH:
1359
104k
            *va_arg(ap, uint32_t *) = td->td_tilelength;
1360
104k
            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
256
        case TIFFTAG_SAMPLEFORMAT:
1382
256
            *va_arg(ap, uint16_t *) = td->td_sampleformat;
1383
256
            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
18.4k
        case TIFFTAG_YCBCRSUBSAMPLING:
1395
18.4k
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
1396
18.4k
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
1397
18.4k
            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
103
        case TIFFTAG_REFERENCEBLACKWHITE:
1412
103
            *va_arg(ap, const float **) = td->td_refblackwhite;
1413
103
            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
6.52k
        default:
1421
6.52k
        {
1422
6.52k
            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
6.52k
            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
6.52k
            ret_val = 0;
1448
19.2k
            for (i = 0; i < td->td_customValueCount; i++)
1449
13.1k
            {
1450
13.1k
                TIFFTagValue *tv = td->td_customValues + i;
1451
1452
13.1k
                if (tv->info->field_tag != tag)
1453
12.7k
                    continue;
1454
1455
419
                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
419
                else if (fip->field_tag == TIFFTAG_DOTRANGE &&
1465
419
                         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
419
                else
1476
419
                {
1477
419
                    if (fip->field_type == TIFF_ASCII ||
1478
419
                        fip->field_readcount == TIFF_VARIABLE ||
1479
419
                        fip->field_readcount == TIFF_VARIABLE2 ||
1480
419
                        fip->field_readcount == TIFF_SPP || tv->count > 1)
1481
419
                    {
1482
419
                        *va_arg(ap, void **) = tv->value;
1483
419
                        ret_val = 1;
1484
419
                    }
1485
0
                    else
1486
0
                    {
1487
0
                        char *val = (char *)tv->value;
1488
0
                        assert(tv->count == 1);
1489
0
                        switch (fip->field_type)
1490
0
                        {
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
0
                            case TIFF_SHORT:
1501
0
                                *va_arg(ap, uint16_t *) = *(uint16_t *)val;
1502
0
                                ret_val = 1;
1503
0
                                break;
1504
0
                            case TIFF_SSHORT:
1505
0
                                *va_arg(ap, int16_t *) = *(int16_t *)val;
1506
0
                                ret_val = 1;
1507
0
                                break;
1508
0
                            case TIFF_LONG:
1509
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_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(
1549
0
                                            tif, "_TIFFVGetField",
1550
0
                                            "Rational2Double: .set_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
0
                        }
1569
0
                    }
1570
419
                }
1571
419
                break;
1572
419
            }
1573
6.52k
        }
1574
890k
    }
1575
890k
    return (ret_val);
1576
890k
}
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
540k
{
1584
540k
    int status;
1585
540k
    va_list ap;
1586
1587
540k
    va_start(ap, tag);
1588
540k
    status = TIFFVGetField(tif, tag, ap);
1589
540k
    va_end(ap);
1590
540k
    return (status);
1591
540k
}
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
1.12M
{
1601
1.12M
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1602
1.12M
    return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
1603
1.12M
                ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
1604
1.12M
                : 0);
1605
1.12M
}
1606
1607
#define CleanupField(member)                                                   \
1608
111k
    {                                                                          \
1609
111k
        if (td->member)                                                        \
1610
111k
        {                                                                      \
1611
9.73k
            _TIFFfreeExt(tif, td->member);                                     \
1612
9.73k
            td->member = 0;                                                    \
1613
9.73k
        }                                                                      \
1614
111k
    }
1615
1616
/*
1617
 * Release storage associated with a directory.
1618
 */
1619
void TIFFFreeDirectory(TIFF *tif)
1620
7.40k
{
1621
7.40k
    TIFFDirectory *td = &tif->tif_dir;
1622
7.40k
    int i;
1623
1624
7.40k
    _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1625
7.40k
    CleanupField(td_sminsamplevalue);
1626
7.40k
    CleanupField(td_smaxsamplevalue);
1627
7.40k
    CleanupField(td_colormap[0]);
1628
7.40k
    CleanupField(td_colormap[1]);
1629
7.40k
    CleanupField(td_colormap[2]);
1630
7.40k
    CleanupField(td_sampleinfo);
1631
7.40k
    CleanupField(td_subifd);
1632
7.40k
    CleanupField(td_inknames);
1633
7.40k
    CleanupField(td_refblackwhite);
1634
7.40k
    CleanupField(td_transferfunction[0]);
1635
7.40k
    CleanupField(td_transferfunction[1]);
1636
7.40k
    CleanupField(td_transferfunction[2]);
1637
7.40k
    CleanupField(td_stripoffset_p);
1638
7.40k
    CleanupField(td_stripbytecount_p);
1639
7.40k
    td->td_stripoffsetbyteallocsize = 0;
1640
7.40k
    TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1641
7.40k
    TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1642
1643
    /* Cleanup custom tag values */
1644
12.2k
    for (i = 0; i < td->td_customValueCount; i++)
1645
4.86k
    {
1646
4.86k
        if (td->td_customValues[i].value)
1647
4.23k
            _TIFFfreeExt(tif, td->td_customValues[i].value);
1648
4.86k
    }
1649
1650
7.40k
    td->td_customValueCount = 0;
1651
7.40k
    CleanupField(td_customValues);
1652
1653
7.40k
    _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1654
7.40k
    _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1655
7.40k
}
1656
#undef CleanupField
1657
1658
/*
1659
 * Client Tag extension support (from Niles Ritter).
1660
 */
1661
static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1662
1663
TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1664
0
{
1665
0
    TIFFExtendProc prev = _TIFFextender;
1666
0
    _TIFFextender = extender;
1667
0
    return (prev);
1668
0
}
1669
1670
/*
1671
 * Setup for a new directory.  Should we automatically call
1672
 * TIFFWriteDirectory() if the current one is dirty?
1673
 *
1674
 * The newly created directory will not exist on the file till
1675
 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1676
 */
1677
int TIFFCreateDirectory(TIFF *tif)
1678
0
{
1679
0
    TIFFDefaultDirectory(tif);
1680
0
    tif->tif_diroff = 0;
1681
0
    tif->tif_nextdiroff = 0;
1682
0
    tif->tif_curoff = 0;
1683
0
    tif->tif_row = (uint32_t)-1;
1684
0
    tif->tif_curstrip = (uint32_t)-1;
1685
1686
0
    return 0;
1687
0
}
1688
1689
int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
1690
0
{
1691
0
    TIFFDefaultDirectory(tif);
1692
1693
    /*
1694
     * Reset the field definitions to match the application provided list.
1695
     * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1696
     * based on it's assumption this is an image directory.
1697
     */
1698
0
    _TIFFSetupFields(tif, infoarray);
1699
1700
0
    tif->tif_diroff = 0;
1701
0
    tif->tif_nextdiroff = 0;
1702
0
    tif->tif_curoff = 0;
1703
0
    tif->tif_row = (uint32_t)-1;
1704
0
    tif->tif_curstrip = (uint32_t)-1;
1705
    /* invalidate directory index */
1706
0
    tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
1707
    /* invalidate IFD loop lists */
1708
0
    _TIFFCleanupIFDOffsetAndNumberMaps(tif);
1709
    /* To be able to return from SubIFD or custom-IFD to main-IFD */
1710
0
    tif->tif_setdirectory_force_absolute = TRUE;
1711
1712
0
    return 0;
1713
0
}
1714
1715
int TIFFCreateEXIFDirectory(TIFF *tif)
1716
0
{
1717
0
    const TIFFFieldArray *exifFieldArray;
1718
0
    exifFieldArray = _TIFFGetExifFields();
1719
0
    return TIFFCreateCustomDirectory(tif, exifFieldArray);
1720
0
}
1721
1722
/*
1723
 * Creates the EXIF GPS custom directory
1724
 */
1725
int TIFFCreateGPSDirectory(TIFF *tif)
1726
0
{
1727
0
    const TIFFFieldArray *gpsFieldArray;
1728
0
    gpsFieldArray = _TIFFGetGpsFields();
1729
0
    return TIFFCreateCustomDirectory(tif, gpsFieldArray);
1730
0
}
1731
1732
/*
1733
 * Setup a default directory structure.
1734
 */
1735
int TIFFDefaultDirectory(TIFF *tif)
1736
3.70k
{
1737
3.70k
    register TIFFDirectory *td = &tif->tif_dir;
1738
3.70k
    const TIFFFieldArray *tiffFieldArray;
1739
1740
3.70k
    tiffFieldArray = _TIFFGetFields();
1741
3.70k
    _TIFFSetupFields(tif, tiffFieldArray);
1742
1743
3.70k
    _TIFFmemset(td, 0, sizeof(*td));
1744
3.70k
    td->td_fillorder = FILLORDER_MSB2LSB;
1745
3.70k
    td->td_bitspersample = 1;
1746
3.70k
    td->td_threshholding = THRESHHOLD_BILEVEL;
1747
3.70k
    td->td_orientation = ORIENTATION_TOPLEFT;
1748
3.70k
    td->td_samplesperpixel = 1;
1749
3.70k
    td->td_rowsperstrip = (uint32_t)-1;
1750
3.70k
    td->td_tilewidth = 0;
1751
3.70k
    td->td_tilelength = 0;
1752
3.70k
    td->td_tiledepth = 1;
1753
#ifdef STRIPBYTECOUNTSORTED_UNUSED
1754
    td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1755
#endif
1756
3.70k
    td->td_resolutionunit = RESUNIT_INCH;
1757
3.70k
    td->td_sampleformat = SAMPLEFORMAT_UINT;
1758
3.70k
    td->td_imagedepth = 1;
1759
3.70k
    td->td_ycbcrsubsampling[0] = 2;
1760
3.70k
    td->td_ycbcrsubsampling[1] = 2;
1761
3.70k
    td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1762
3.70k
    tif->tif_postdecode = _TIFFNoPostDecode;
1763
3.70k
    tif->tif_foundfield = NULL;
1764
3.70k
    tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1765
3.70k
    tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1766
3.70k
    tif->tif_tagmethods.printdir = NULL;
1767
    /* additional default values */
1768
3.70k
    td->td_planarconfig = PLANARCONFIG_CONTIG;
1769
3.70k
    td->td_compression = COMPRESSION_NONE;
1770
3.70k
    td->td_subfiletype = 0;
1771
3.70k
    td->td_minsamplevalue = 0;
1772
    /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1773
     * Therefore, td_maxsamplevalue has to be re-calculated in
1774
     * TIFFGetFieldDefaulted(). */
1775
3.70k
    td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1776
3.70k
    td->td_extrasamples = 0;
1777
3.70k
    td->td_sampleinfo = NULL;
1778
1779
    /*
1780
     *  Give client code a chance to install their own
1781
     *  tag extensions & methods, prior to compression overloads,
1782
     *  but do some prior cleanup first.
1783
     * (http://trac.osgeo.org/gdal/ticket/5054)
1784
     */
1785
3.70k
    if (tif->tif_nfieldscompat > 0)
1786
0
    {
1787
0
        uint32_t i;
1788
1789
0
        for (i = 0; i < tif->tif_nfieldscompat; i++)
1790
0
        {
1791
0
            if (tif->tif_fieldscompat[i].allocated_size)
1792
0
                _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
1793
0
        }
1794
0
        _TIFFfreeExt(tif, tif->tif_fieldscompat);
1795
0
        tif->tif_nfieldscompat = 0;
1796
0
        tif->tif_fieldscompat = NULL;
1797
0
    }
1798
3.70k
    if (_TIFFextender)
1799
0
        (*_TIFFextender)(tif);
1800
3.70k
    (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
1801
    /*
1802
     * NB: The directory is marked dirty as a result of setting
1803
     * up the default compression scheme.  However, this really
1804
     * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1805
     * if the user does something.  We could just do the setup
1806
     * by hand, but it seems better to use the normal mechanism
1807
     * (i.e. TIFFSetField).
1808
     */
1809
3.70k
    tif->tif_flags &= ~TIFF_DIRTYDIRECT;
1810
1811
    /*
1812
     * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1813
     * we clear the ISTILED flag when setting up a new directory.
1814
     * Should we also be clearing stuff like INSUBIFD?
1815
     */
1816
3.70k
    tif->tif_flags &= ~TIFF_ISTILED;
1817
1818
3.70k
    return (1);
1819
3.70k
}
1820
1821
static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
1822
                                tdir_t *nextdirnum)
1823
5.93k
{
1824
5.93k
    static const char module[] = "TIFFAdvanceDirectory";
1825
1826
    /* Add this directory to the directory list, if not already in. */
1827
5.93k
    if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1828
0
    {
1829
0
        TIFFErrorExtR(tif, module,
1830
0
                      "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1831
0
                      ") might cause an IFD loop",
1832
0
                      *nextdirnum, *nextdiroff, *nextdiroff);
1833
0
        *nextdiroff = 0;
1834
0
        *nextdirnum = 0;
1835
0
        return (0);
1836
0
    }
1837
1838
5.93k
    if (isMapped(tif))
1839
0
    {
1840
0
        uint64_t poff = *nextdiroff;
1841
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
1842
0
        {
1843
0
            tmsize_t poffa, poffb, poffc, poffd;
1844
0
            uint16_t dircount;
1845
0
            uint32_t nextdir32;
1846
0
            poffa = (tmsize_t)poff;
1847
0
            poffb = poffa + sizeof(uint16_t);
1848
0
            if (((uint64_t)poffa != poff) || (poffb < poffa) ||
1849
0
                (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
1850
0
            {
1851
0
                TIFFErrorExtR(tif, module, "Error fetching directory count");
1852
0
                *nextdiroff = 0;
1853
0
                return (0);
1854
0
            }
1855
0
            _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
1856
0
            if (tif->tif_flags & TIFF_SWAB)
1857
0
                TIFFSwabShort(&dircount);
1858
0
            poffc = poffb + dircount * 12;
1859
0
            poffd = poffc + sizeof(uint32_t);
1860
0
            if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
1861
0
                (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
1862
0
            {
1863
0
                TIFFErrorExtR(tif, module, "Error fetching directory link");
1864
0
                return (0);
1865
0
            }
1866
0
            if (off != NULL)
1867
0
                *off = (uint64_t)poffc;
1868
0
            _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
1869
0
            if (tif->tif_flags & TIFF_SWAB)
1870
0
                TIFFSwabLong(&nextdir32);
1871
0
            *nextdiroff = nextdir32;
1872
0
        }
1873
0
        else
1874
0
        {
1875
0
            tmsize_t poffa, poffb, poffc, poffd;
1876
0
            uint64_t dircount64;
1877
0
            uint16_t dircount16;
1878
0
            if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
1879
0
            {
1880
0
                TIFFErrorExtR(tif, module, "Error fetching directory count");
1881
0
                return (0);
1882
0
            }
1883
0
            poffa = (tmsize_t)poff;
1884
0
            poffb = poffa + sizeof(uint64_t);
1885
0
            if (poffb > tif->tif_size)
1886
0
            {
1887
0
                TIFFErrorExtR(tif, module, "Error fetching directory count");
1888
0
                return (0);
1889
0
            }
1890
0
            _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
1891
0
            if (tif->tif_flags & TIFF_SWAB)
1892
0
                TIFFSwabLong8(&dircount64);
1893
0
            if (dircount64 > 0xFFFF)
1894
0
            {
1895
0
                TIFFErrorExtR(tif, module,
1896
0
                              "Sanity check on directory count failed");
1897
0
                return (0);
1898
0
            }
1899
0
            dircount16 = (uint16_t)dircount64;
1900
0
            if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
1901
0
                            (tmsize_t)sizeof(uint64_t))
1902
0
            {
1903
0
                TIFFErrorExtR(tif, module, "Error fetching directory link");
1904
0
                return (0);
1905
0
            }
1906
0
            poffc = poffb + dircount16 * 20;
1907
0
            poffd = poffc + sizeof(uint64_t);
1908
0
            if (poffd > tif->tif_size)
1909
0
            {
1910
0
                TIFFErrorExtR(tif, module, "Error fetching directory link");
1911
0
                return (0);
1912
0
            }
1913
0
            if (off != NULL)
1914
0
                *off = (uint64_t)poffc;
1915
0
            _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
1916
0
            if (tif->tif_flags & TIFF_SWAB)
1917
0
                TIFFSwabLong8(nextdiroff);
1918
0
        }
1919
0
    }
1920
5.93k
    else
1921
5.93k
    {
1922
5.93k
        if (!(tif->tif_flags & TIFF_BIGTIFF))
1923
5.81k
        {
1924
5.81k
            uint16_t dircount;
1925
5.81k
            uint32_t nextdir32;
1926
5.81k
            if (!SeekOK(tif, *nextdiroff) ||
1927
5.81k
                !ReadOK(tif, &dircount, sizeof(uint16_t)))
1928
2.69k
            {
1929
2.69k
                TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
1930
2.69k
                              tif->tif_name);
1931
2.69k
                return (0);
1932
2.69k
            }
1933
3.11k
            if (tif->tif_flags & TIFF_SWAB)
1934
127
                TIFFSwabShort(&dircount);
1935
3.11k
            if (off != NULL)
1936
0
                *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1937
3.11k
            else
1938
3.11k
                (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
1939
3.11k
            if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
1940
98
            {
1941
98
                TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1942
98
                              tif->tif_name);
1943
98
                return (0);
1944
98
            }
1945
3.02k
            if (tif->tif_flags & TIFF_SWAB)
1946
123
                TIFFSwabLong(&nextdir32);
1947
3.02k
            *nextdiroff = nextdir32;
1948
3.02k
        }
1949
117
        else
1950
117
        {
1951
117
            uint64_t dircount64;
1952
117
            uint16_t dircount16;
1953
117
            if (!SeekOK(tif, *nextdiroff) ||
1954
117
                !ReadOK(tif, &dircount64, sizeof(uint64_t)))
1955
8
            {
1956
8
                TIFFErrorExtR(tif, module, "%s: Error fetching directory count",
1957
8
                              tif->tif_name);
1958
8
                return (0);
1959
8
            }
1960
109
            if (tif->tif_flags & TIFF_SWAB)
1961
3
                TIFFSwabLong8(&dircount64);
1962
109
            if (dircount64 > 0xFFFF)
1963
47
            {
1964
47
                TIFFErrorExtR(tif, module, "Error fetching directory count");
1965
47
                return (0);
1966
47
            }
1967
62
            dircount16 = (uint16_t)dircount64;
1968
62
            if (off != NULL)
1969
0
                *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1970
62
            else
1971
62
                (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
1972
62
            if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
1973
1
            {
1974
1
                TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
1975
1
                              tif->tif_name);
1976
1
                return (0);
1977
1
            }
1978
61
            if (tif->tif_flags & TIFF_SWAB)
1979
3
                TIFFSwabLong8(nextdiroff);
1980
61
        }
1981
5.93k
    }
1982
3.08k
    if (*nextdiroff != 0)
1983
2.84k
    {
1984
2.84k
        (*nextdirnum)++;
1985
        /* Check next directory for IFD looping and if so, set it as last
1986
         * directory. */
1987
2.84k
        if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
1988
2
        {
1989
2
            TIFFWarningExtR(
1990
2
                tif, module,
1991
2
                "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
1992
2
                ") might be an IFD loop. Treating directory %d as "
1993
2
                "last directory",
1994
2
                *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
1995
2
            *nextdiroff = 0;
1996
2
            (*nextdirnum)--;
1997
2
        }
1998
2.84k
    }
1999
3.08k
    return (1);
2000
5.93k
}
2001
2002
/*
2003
 * Count the number of directories in a file.
2004
 */
2005
tdir_t TIFFNumberOfDirectories(TIFF *tif)
2006
3.08k
{
2007
3.08k
    uint64_t nextdiroff;
2008
3.08k
    tdir_t nextdirnum;
2009
3.08k
    tdir_t n;
2010
3.08k
    if (!(tif->tif_flags & TIFF_BIGTIFF))
2011
3.03k
        nextdiroff = tif->tif_header.classic.tiff_diroff;
2012
56
    else
2013
56
        nextdiroff = tif->tif_header.big.tiff_diroff;
2014
3.08k
    nextdirnum = 0;
2015
3.08k
    n = 0;
2016
6.16k
    while (nextdiroff != 0 &&
2017
6.16k
           TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2018
3.08k
    {
2019
3.08k
        ++n;
2020
3.08k
    }
2021
3.08k
    return (n);
2022
3.08k
}
2023
2024
/*
2025
 * Set the n-th directory as the current directory.
2026
 * NB: Directories are numbered starting at 0.
2027
 */
2028
int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
2029
0
{
2030
0
    uint64_t nextdiroff;
2031
0
    tdir_t nextdirnum = 0;
2032
0
    tdir_t n;
2033
2034
0
    if (tif->tif_setdirectory_force_absolute)
2035
0
    {
2036
        /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2037
         * chain from the beginning, thus IFD directory list needs to be cleared
2038
         * from possible SubIFD offsets.
2039
         */
2040
0
        _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2041
0
    }
2042
2043
    /* Even faster path, if offset is available within IFD loop hash list. */
2044
0
    if (!tif->tif_setdirectory_force_absolute &&
2045
0
        _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
2046
0
    {
2047
        /* Set parameters for following TIFFReadDirectory() below. */
2048
0
        tif->tif_nextdiroff = nextdiroff;
2049
0
        tif->tif_curdir = dirn;
2050
        /* Reset to relative stepping */
2051
0
        tif->tif_setdirectory_force_absolute = FALSE;
2052
0
    }
2053
0
    else
2054
0
    {
2055
2056
        /* Fast path when we just advance relative to the current directory:
2057
         * start at the current dir offset and continue to seek from there.
2058
         * Check special cases when relative is not allowed:
2059
         * - jump back from SubIFD or custom directory
2060
         * - right after TIFFWriteDirectory() jump back to that directory
2061
         *   using TIFFSetDirectory() */
2062
0
        const int relative = (dirn >= tif->tif_curdir) &&
2063
0
                             (tif->tif_diroff != 0) &&
2064
0
                             !tif->tif_setdirectory_force_absolute;
2065
2066
0
        if (relative)
2067
0
        {
2068
0
            nextdiroff = tif->tif_diroff;
2069
0
            dirn -= tif->tif_curdir;
2070
0
            nextdirnum = tif->tif_curdir;
2071
0
        }
2072
0
        else if (!(tif->tif_flags & TIFF_BIGTIFF))
2073
0
            nextdiroff = tif->tif_header.classic.tiff_diroff;
2074
0
        else
2075
0
            nextdiroff = tif->tif_header.big.tiff_diroff;
2076
2077
        /* Reset to relative stepping */
2078
0
        tif->tif_setdirectory_force_absolute = FALSE;
2079
2080
0
        for (n = dirn; n > 0 && nextdiroff != 0; n--)
2081
0
            if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
2082
0
                return (0);
2083
        /* If the n-th directory could not be reached (does not exist),
2084
         * return here without touching anything further. */
2085
0
        if (nextdiroff == 0 || n > 0)
2086
0
            return (0);
2087
2088
0
        tif->tif_nextdiroff = nextdiroff;
2089
2090
        /* Set curdir to the actual directory index. */
2091
0
        if (relative)
2092
0
            tif->tif_curdir += dirn - n;
2093
0
        else
2094
0
            tif->tif_curdir = dirn - n;
2095
0
    }
2096
2097
    /* The -1 decrement is because TIFFReadDirectory will increment
2098
     * tif_curdir after successfully reading the directory. */
2099
0
    if (tif->tif_curdir == 0)
2100
0
        tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2101
0
    else
2102
0
        tif->tif_curdir--;
2103
0
    return (TIFFReadDirectory(tif));
2104
0
}
2105
2106
/*
2107
 * Set the current directory to be the directory
2108
 * located at the specified file offset.  This interface
2109
 * is used mainly to access directories linked with
2110
 * the SubIFD tag (e.g. thumbnail images).
2111
 */
2112
int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
2113
0
{
2114
    /* Match nextdiroff and curdir for consistent IFD-loop checking.
2115
     * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2116
     * invalid offsets within the main IFD tree. In the case of several subIFDs
2117
     * of a main image, there are two possibilities that are not even mutually
2118
     * exclusive. a.) The subIFD tag contains an array with all offsets of the
2119
     * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2120
     * (refer to
2121
     * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2122
     */
2123
0
    int retval;
2124
0
    uint32_t curdir = 0;
2125
0
    int8_t probablySubIFD = 0;
2126
0
    if (diroff == 0)
2127
0
    {
2128
        /* Special case to invalidate the tif_lastdiroff member. */
2129
0
        tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2130
0
    }
2131
0
    else
2132
0
    {
2133
0
        if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
2134
0
        {
2135
            /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2136
0
            probablySubIFD = 1;
2137
0
        }
2138
        /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2139
0
        tif->tif_curdir =
2140
0
            curdir == 0 ? TIFF_NON_EXISTENT_DIR_NUMBER : curdir - 1;
2141
0
    }
2142
2143
0
    tif->tif_nextdiroff = diroff;
2144
0
    retval = TIFFReadDirectory(tif);
2145
    /* If failed, curdir was not incremented in TIFFReadDirectory(), so set it
2146
     * back, but leave it for diroff==0. */
2147
0
    if (!retval && diroff != 0)
2148
0
    {
2149
0
        if (tif->tif_curdir == TIFF_NON_EXISTENT_DIR_NUMBER)
2150
0
            tif->tif_curdir = 0;
2151
0
        else
2152
0
            tif->tif_curdir++;
2153
0
    }
2154
0
    if (retval && probablySubIFD)
2155
0
    {
2156
        /* Reset IFD list to start new one for SubIFD chain and also start
2157
         * SubIFD chain with tif_curdir=0. */
2158
0
        _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2159
0
        tif->tif_curdir = 0; /* first directory of new chain */
2160
        /* add this offset to new IFD list */
2161
0
        _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
2162
        /* To be able to return from SubIFD or custom-IFD to main-IFD */
2163
0
        tif->tif_setdirectory_force_absolute = TRUE;
2164
0
    }
2165
0
    return (retval);
2166
0
}
2167
2168
/*
2169
 * Return file offset of the current directory.
2170
 */
2171
0
uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
2172
2173
/*
2174
 * Return an indication of whether or not we are
2175
 * at the last directory in the file.
2176
 */
2177
0
int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
2178
2179
/*
2180
 * Unlink the specified directory from the directory chain.
2181
 * Note: First directory starts with number dirn=1.
2182
 * This is different to TIFFSetDirectory() where the first directory starts with
2183
 * zero.
2184
 */
2185
int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
2186
0
{
2187
0
    static const char module[] = "TIFFUnlinkDirectory";
2188
0
    uint64_t nextdir;
2189
0
    tdir_t nextdirnum;
2190
0
    uint64_t off;
2191
0
    tdir_t n;
2192
2193
0
    if (tif->tif_mode == O_RDONLY)
2194
0
    {
2195
0
        TIFFErrorExtR(tif, module,
2196
0
                      "Can not unlink directory in read-only file");
2197
0
        return (0);
2198
0
    }
2199
0
    if (dirn == 0)
2200
0
    {
2201
0
        TIFFErrorExtR(tif, module,
2202
0
                      "For TIFFUnlinkDirectory() first directory starts with "
2203
0
                      "number 1 and not 0");
2204
0
        return (0);
2205
0
    }
2206
    /*
2207
     * Go to the directory before the one we want
2208
     * to unlink and nab the offset of the link
2209
     * field we'll need to patch.
2210
     */
2211
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
2212
0
    {
2213
0
        nextdir = tif->tif_header.classic.tiff_diroff;
2214
0
        off = 4;
2215
0
    }
2216
0
    else
2217
0
    {
2218
0
        nextdir = tif->tif_header.big.tiff_diroff;
2219
0
        off = 8;
2220
0
    }
2221
0
    nextdirnum = 0; /* First directory is dirn=0 */
2222
2223
0
    for (n = dirn - 1; n > 0; n--)
2224
0
    {
2225
0
        if (nextdir == 0)
2226
0
        {
2227
0
            TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
2228
0
            return (0);
2229
0
        }
2230
0
        if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
2231
0
            return (0);
2232
0
    }
2233
    /*
2234
     * Advance to the directory to be unlinked and fetch
2235
     * the offset of the directory that follows.
2236
     */
2237
0
    if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
2238
0
        return (0);
2239
    /*
2240
     * Go back and patch the link field of the preceding
2241
     * directory to point to the offset of the directory
2242
     * that follows.
2243
     */
2244
0
    (void)TIFFSeekFile(tif, off, SEEK_SET);
2245
0
    if (!(tif->tif_flags & TIFF_BIGTIFF))
2246
0
    {
2247
0
        uint32_t nextdir32;
2248
0
        nextdir32 = (uint32_t)nextdir;
2249
0
        assert((uint64_t)nextdir32 == nextdir);
2250
0
        if (tif->tif_flags & TIFF_SWAB)
2251
0
            TIFFSwabLong(&nextdir32);
2252
0
        if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
2253
0
        {
2254
0
            TIFFErrorExtR(tif, module, "Error writing directory link");
2255
0
            return (0);
2256
0
        }
2257
0
    }
2258
0
    else
2259
0
    {
2260
0
        if (tif->tif_flags & TIFF_SWAB)
2261
0
            TIFFSwabLong8(&nextdir);
2262
0
        if (!WriteOK(tif, &nextdir, sizeof(uint64_t)))
2263
0
        {
2264
0
            TIFFErrorExtR(tif, module, "Error writing directory link");
2265
0
            return (0);
2266
0
        }
2267
0
    }
2268
2269
    /* For dirn=1 (first directory) also update the libtiff internal
2270
     * base offset variables. */
2271
0
    if (dirn == 1)
2272
0
    {
2273
0
        if (!(tif->tif_flags & TIFF_BIGTIFF))
2274
0
            tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
2275
0
        else
2276
0
            tif->tif_header.big.tiff_diroff = nextdir;
2277
0
    }
2278
2279
    /*
2280
     * Leave directory state setup safely.  We don't have
2281
     * facilities for doing inserting and removing directories,
2282
     * so it's safest to just invalidate everything.  This
2283
     * means that the caller can only append to the directory
2284
     * chain.
2285
     */
2286
0
    (*tif->tif_cleanup)(tif);
2287
0
    if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
2288
0
    {
2289
0
        _TIFFfreeExt(tif, tif->tif_rawdata);
2290
0
        tif->tif_rawdata = NULL;
2291
0
        tif->tif_rawcc = 0;
2292
0
        tif->tif_rawdataoff = 0;
2293
0
        tif->tif_rawdataloaded = 0;
2294
0
    }
2295
0
    tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
2296
0
                        TIFF_BUF4WRITE);
2297
0
    TIFFFreeDirectory(tif);
2298
0
    TIFFDefaultDirectory(tif);
2299
0
    tif->tif_diroff = 0;     /* force link on next write */
2300
0
    tif->tif_nextdiroff = 0; /* next write must be at end */
2301
0
    tif->tif_lastdiroff = 0; /* will be updated on next link */
2302
0
    tif->tif_curoff = 0;
2303
0
    tif->tif_row = (uint32_t)-1;
2304
0
    tif->tif_curstrip = (uint32_t)-1;
2305
0
    tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
2306
0
    _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
2307
0
    return (1);
2308
0
}