Coverage Report

Created: 2026-07-24 07:44

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