Coverage Report

Created: 2025-11-16 07:40

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
0
#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
0
#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
42
43
static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
44
                         size_t elem_size)
45
46.0k
{
46
46.0k
    if (*vpp)
47
0
    {
48
0
        _TIFFfreeExt(tif, *vpp);
49
0
        *vpp = 0;
50
0
    }
51
46.0k
    if (vp)
52
46.0k
    {
53
46.0k
        tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
54
46.0k
        if (bytes)
55
46.0k
            *vpp = (void *)_TIFFmallocExt(tif, bytes);
56
46.0k
        if (*vpp)
57
46.0k
            _TIFFmemcpy(*vpp, vp, bytes);
58
46.0k
    }
59
46.0k
}
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
0
{
71
0
    setByteArray(tif, (void **)cpp, cp, n, 1);
72
0
}
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
0
{
81
0
    setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
82
0
}
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
0
{
97
0
    setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
98
0
}
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
0
{
106
0
    setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
107
0
}
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
0
{
116
0
    setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
117
0
}
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
0
{
137
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
138
0
#define EXTRASAMPLE_COREL_UNASSALPHA 999
139
140
0
    uint16_t *va;
141
0
    uint32_t i;
142
0
    TIFFDirectory *td = &tif->tif_dir;
143
0
    static const char module[] = "setExtraSamples";
144
145
0
    *v = (uint16_t)va_arg(ap, uint16_vap);
146
0
    if ((uint16_t)*v > td->td_samplesperpixel)
147
0
        return 0;
148
0
    va = va_arg(ap, uint16_t *);
149
0
    if (*v > 0 && va == NULL) /* typically missing param */
150
0
        return 0;
151
0
    for (i = 0; i < *v; i++)
152
0
    {
153
0
        if (va[i] > EXTRASAMPLE_UNASSALPHA)
154
0
        {
155
            /*
156
             * XXX: Corel Draw is known to produce incorrect
157
             * ExtraSamples tags which must be patched here if we
158
             * want to be able to open some of the damaged TIFF
159
             * files:
160
             */
161
0
            if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
162
0
                va[i] = EXTRASAMPLE_UNASSALPHA;
163
0
            else
164
0
                return 0;
165
0
        }
166
0
    }
167
168
0
    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
0
    td->td_extrasamples = (uint16_t)*v;
182
0
    _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
183
0
    return 1;
184
185
0
#undef EXTRASAMPLE_COREL_UNASSALPHA
186
0
}
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
0
{
194
0
    uint16_t i = 0;
195
196
0
    if (slen > 0)
197
0
    {
198
0
        const char *ep = s + slen;
199
0
        const char *cp = s;
200
0
        do
201
0
        {
202
0
            for (; cp < ep && *cp != '\0'; cp++)
203
0
            {
204
0
            }
205
0
            if (cp >= ep)
206
0
                goto bad;
207
0
            cp++; /* skip \0 */
208
0
            i++;
209
0
        } while (cp < ep);
210
0
        return (i);
211
0
    }
212
0
bad:
213
0
    TIFFErrorExtR(tif, "TIFFSetField",
214
0
                  "%s: Invalid InkNames value; no null at given buffer end "
215
0
                  "location %" PRIu32 ", after %" PRIu16 " ink",
216
0
                  tif->tif_name, slen, i);
217
0
    return (0);
218
0
}
219
220
static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
221
509k
{
222
509k
    static const char module[] = "_TIFFVSetField";
223
224
509k
    TIFFDirectory *td = &tif->tif_dir;
225
509k
    int status = 1;
226
509k
    uint32_t v32, v;
227
509k
    double dblval;
228
509k
    char *s;
229
509k
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
230
509k
    uint32_t standard_tag = tag;
231
509k
    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
509k
    if (fip->field_bit == FIELD_CUSTOM)
240
46.0k
    {
241
46.0k
        standard_tag = 0;
242
46.0k
    }
243
244
509k
    switch (standard_tag)
245
509k
    {
246
23.0k
        case TIFFTAG_SUBFILETYPE:
247
23.0k
            td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
248
23.0k
            break;
249
28.1k
        case TIFFTAG_IMAGEWIDTH:
250
28.1k
            td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
251
28.1k
            break;
252
28.1k
        case TIFFTAG_IMAGELENGTH:
253
28.1k
            td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
254
28.1k
            break;
255
28.1k
        case TIFFTAG_BITSPERSAMPLE:
256
28.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
28.1k
            if (tif->tif_flags & TIFF_SWAB)
265
0
            {
266
0
                if (td->td_bitspersample == 8)
267
0
                    tif->tif_postdecode = _TIFFNoPostDecode;
268
0
                else if (td->td_bitspersample == 16)
269
0
                    tif->tif_postdecode = _TIFFSwab16BitData;
270
0
                else if (td->td_bitspersample == 24)
271
0
                    tif->tif_postdecode = _TIFFSwab24BitData;
272
0
                else if (td->td_bitspersample == 32)
273
0
                    tif->tif_postdecode = _TIFFSwab32BitData;
274
0
                else if (td->td_bitspersample == 64)
275
0
                    tif->tif_postdecode = _TIFFSwab64BitData;
276
0
                else if (td->td_bitspersample == 128) /* two 64's */
277
0
                    tif->tif_postdecode = _TIFFSwab64BitData;
278
0
            }
279
28.1k
            break;
280
84.5k
        case TIFFTAG_COMPRESSION:
281
84.5k
            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
84.5k
            if (TIFFFieldSet(tif, FIELD_COMPRESSION))
288
28.1k
            {
289
28.1k
                if ((uint32_t)td->td_compression == v)
290
0
                    break;
291
28.1k
                (*tif->tif_cleanup)(tif);
292
28.1k
                tif->tif_flags &= ~TIFF_CODERSETUP;
293
28.1k
            }
294
            /*
295
             * Setup new compression routine state.
296
             */
297
84.5k
            if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
298
84.5k
                td->td_compression = (uint16_t)v;
299
0
            else
300
0
                status = 0;
301
84.5k
            break;
302
28.1k
        case TIFFTAG_PHOTOMETRIC:
303
28.1k
            td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
304
28.1k
            break;
305
0
        case TIFFTAG_THRESHHOLDING:
306
0
            td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
307
0
            break;
308
28.1k
        case TIFFTAG_FILLORDER:
309
28.1k
            v = (uint16_t)va_arg(ap, uint16_vap);
310
28.1k
            if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
311
0
                goto badvalue;
312
28.1k
            td->td_fillorder = (uint16_t)v;
313
28.1k
            break;
314
28.1k
        case TIFFTAG_ORIENTATION:
315
28.1k
            v = (uint16_t)va_arg(ap, uint16_vap);
316
28.1k
            if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
317
0
                goto badvalue;
318
28.1k
            else
319
28.1k
                td->td_orientation = (uint16_t)v;
320
28.1k
            break;
321
28.1k
        case TIFFTAG_SAMPLESPERPIXEL:
322
28.1k
            v = (uint16_t)va_arg(ap, uint16_vap);
323
28.1k
            if (v == 0)
324
0
                goto badvalue;
325
28.1k
            if (v != td->td_samplesperpixel)
326
4.48k
            {
327
                /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
328
4.48k
                if (td->td_sminsamplevalue != NULL)
329
0
                {
330
0
                    TIFFWarningExtR(tif, module,
331
0
                                    "SamplesPerPixel tag value is changing, "
332
0
                                    "but SMinSampleValue tag was read with a "
333
0
                                    "different value. Canceling it");
334
0
                    TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE);
335
0
                    _TIFFfreeExt(tif, td->td_sminsamplevalue);
336
0
                    td->td_sminsamplevalue = NULL;
337
0
                }
338
4.48k
                if (td->td_smaxsamplevalue != NULL)
339
0
                {
340
0
                    TIFFWarningExtR(tif, module,
341
0
                                    "SamplesPerPixel tag value is changing, "
342
0
                                    "but SMaxSampleValue tag was read with a "
343
0
                                    "different value. Canceling it");
344
0
                    TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE);
345
0
                    _TIFFfreeExt(tif, td->td_smaxsamplevalue);
346
0
                    td->td_smaxsamplevalue = NULL;
347
0
                }
348
                /* Test if 3 transfer functions instead of just one are now
349
                   needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820
350
                 */
351
4.48k
                if (td->td_transferfunction[0] != NULL &&
352
0
                    (v - td->td_extrasamples > 1) &&
353
0
                    !(td->td_samplesperpixel - td->td_extrasamples > 1))
354
0
                {
355
0
                    TIFFWarningExtR(tif, module,
356
0
                                    "SamplesPerPixel tag value is changing, "
357
0
                                    "but TransferFunction was read with a "
358
0
                                    "different value. Canceling it");
359
0
                    TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
360
0
                    _TIFFfreeExt(tif, td->td_transferfunction[0]);
361
0
                    td->td_transferfunction[0] = NULL;
362
0
                }
363
4.48k
            }
364
28.1k
            td->td_samplesperpixel = (uint16_t)v;
365
28.1k
            break;
366
28.1k
        case TIFFTAG_ROWSPERSTRIP:
367
28.1k
            v32 = (uint32_t)va_arg(ap, uint32_t);
368
28.1k
            if (v32 == 0)
369
0
                goto badvalue32;
370
28.1k
            td->td_rowsperstrip = v32;
371
28.1k
            if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
372
28.1k
            {
373
28.1k
                td->td_tilelength = v32;
374
28.1k
                td->td_tilewidth = td->td_imagewidth;
375
28.1k
            }
376
28.1k
            break;
377
0
        case TIFFTAG_MINSAMPLEVALUE:
378
0
            td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
379
0
            break;
380
0
        case TIFFTAG_MAXSAMPLEVALUE:
381
0
            td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
382
0
            break;
383
0
        case TIFFTAG_SMINSAMPLEVALUE:
384
0
            if (tif->tif_flags & TIFF_PERSAMPLE)
385
0
                _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
386
0
                                       va_arg(ap, double *),
387
0
                                       td->td_samplesperpixel);
388
0
            else
389
0
                setDoubleArrayOneValue(tif, &td->td_sminsamplevalue,
390
0
                                       va_arg(ap, double),
391
0
                                       td->td_samplesperpixel);
392
0
            break;
393
0
        case TIFFTAG_SMAXSAMPLEVALUE:
394
0
            if (tif->tif_flags & TIFF_PERSAMPLE)
395
0
                _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
396
0
                                       va_arg(ap, double *),
397
0
                                       td->td_samplesperpixel);
398
0
            else
399
0
                setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue,
400
0
                                       va_arg(ap, double),
401
0
                                       td->td_samplesperpixel);
402
0
            break;
403
28.1k
        case TIFFTAG_XRESOLUTION:
404
28.1k
            dblval = va_arg(ap, double);
405
28.1k
            if (dblval != dblval || dblval < 0)
406
0
                goto badvaluedouble;
407
28.1k
            td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
408
28.1k
            break;
409
28.1k
        case TIFFTAG_YRESOLUTION:
410
28.1k
            dblval = va_arg(ap, double);
411
28.1k
            if (dblval != dblval || dblval < 0)
412
0
                goto badvaluedouble;
413
28.1k
            td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
414
28.1k
            break;
415
28.1k
        case TIFFTAG_PLANARCONFIG:
416
28.1k
            v = (uint16_t)va_arg(ap, uint16_vap);
417
28.1k
            if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
418
0
                goto badvalue;
419
28.1k
            td->td_planarconfig = (uint16_t)v;
420
28.1k
            break;
421
0
        case TIFFTAG_XPOSITION:
422
0
            td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
423
0
            break;
424
0
        case TIFFTAG_YPOSITION:
425
0
            td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
426
0
            break;
427
23.0k
        case TIFFTAG_RESOLUTIONUNIT:
428
23.0k
            v = (uint16_t)va_arg(ap, uint16_vap);
429
23.0k
            if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
430
0
                goto badvalue;
431
23.0k
            td->td_resolutionunit = (uint16_t)v;
432
23.0k
            break;
433
23.0k
        case TIFFTAG_PAGENUMBER:
434
23.0k
            td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
435
23.0k
            td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
436
23.0k
            break;
437
0
        case TIFFTAG_HALFTONEHINTS:
438
0
            td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
439
0
            td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
440
0
            break;
441
0
        case TIFFTAG_COLORMAP:
442
0
            v32 = (uint32_t)(1L << td->td_bitspersample);
443
0
            _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
444
0
                                  va_arg(ap, uint16_t *), v32);
445
0
            _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
446
0
                                  va_arg(ap, uint16_t *), v32);
447
0
            _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
448
0
                                  va_arg(ap, uint16_t *), v32);
449
0
            break;
450
0
        case TIFFTAG_EXTRASAMPLES:
451
0
            if (!setExtraSamples(tif, ap, &v))
452
0
                goto badvalue;
453
0
            break;
454
0
        case TIFFTAG_MATTEING:
455
0
            td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
456
0
            if (td->td_extrasamples)
457
0
            {
458
0
                uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
459
0
                _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
460
0
            }
461
0
            break;
462
0
        case TIFFTAG_TILEWIDTH:
463
0
            v32 = (uint32_t)va_arg(ap, uint32_t);
464
0
            if (v32 % 16)
465
0
            {
466
0
                if (tif->tif_mode != O_RDONLY)
467
0
                    goto badvalue32;
468
0
                TIFFWarningExtR(
469
0
                    tif, tif->tif_name,
470
0
                    "Nonstandard tile width %" PRIu32 ", convert file", v32);
471
0
            }
472
0
            td->td_tilewidth = v32;
473
0
            tif->tif_flags |= TIFF_ISTILED;
474
0
            break;
475
0
        case TIFFTAG_TILELENGTH:
476
0
            v32 = (uint32_t)va_arg(ap, uint32_t);
477
0
            if (v32 % 16)
478
0
            {
479
0
                if (tif->tif_mode != O_RDONLY)
480
0
                    goto badvalue32;
481
0
                TIFFWarningExtR(
482
0
                    tif, tif->tif_name,
483
0
                    "Nonstandard tile length %" PRIu32 ", convert file", v32);
484
0
            }
485
0
            td->td_tilelength = v32;
486
0
            tif->tif_flags |= TIFF_ISTILED;
487
0
            break;
488
0
        case TIFFTAG_TILEDEPTH:
489
0
            v32 = (uint32_t)va_arg(ap, uint32_t);
490
0
            if (v32 == 0)
491
0
                goto badvalue32;
492
0
            td->td_tiledepth = v32;
493
0
            break;
494
0
        case TIFFTAG_DATATYPE:
495
0
            v = (uint16_t)va_arg(ap, uint16_vap);
496
0
            switch (v)
497
0
            {
498
0
                case DATATYPE_VOID:
499
0
                    v = SAMPLEFORMAT_VOID;
500
0
                    break;
501
0
                case DATATYPE_INT:
502
0
                    v = SAMPLEFORMAT_INT;
503
0
                    break;
504
0
                case DATATYPE_UINT:
505
0
                    v = SAMPLEFORMAT_UINT;
506
0
                    break;
507
0
                case DATATYPE_IEEEFP:
508
0
                    v = SAMPLEFORMAT_IEEEFP;
509
0
                    break;
510
0
                default:
511
0
                    goto badvalue;
512
0
            }
513
0
            td->td_sampleformat = (uint16_t)v;
514
0
            break;
515
0
        case TIFFTAG_SAMPLEFORMAT:
516
0
            v = (uint16_t)va_arg(ap, uint16_vap);
517
0
            if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
518
0
                goto badvalue;
519
0
            td->td_sampleformat = (uint16_t)v;
520
521
            /*  Try to fix up the SWAB function for complex data. */
522
0
            if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
523
0
                td->td_bitspersample == 32 &&
524
0
                tif->tif_postdecode == _TIFFSwab32BitData)
525
0
                tif->tif_postdecode = _TIFFSwab16BitData;
526
0
            else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
527
0
                      td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
528
0
                     td->td_bitspersample == 64 &&
529
0
                     tif->tif_postdecode == _TIFFSwab64BitData)
530
0
                tif->tif_postdecode = _TIFFSwab32BitData;
531
0
            break;
532
0
        case TIFFTAG_IMAGEDEPTH:
533
0
            td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
534
0
            break;
535
0
        case TIFFTAG_SUBIFD:
536
0
            if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
537
0
            {
538
0
                td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
539
0
                _TIFFsetLong8Array(tif, &td->td_subifd,
540
0
                                   (uint64_t *)va_arg(ap, uint64_t *),
541
0
                                   (uint32_t)td->td_nsubifd);
542
0
            }
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
0
            break;
550
0
        case TIFFTAG_YCBCRPOSITIONING:
551
0
            td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
552
0
            break;
553
0
        case TIFFTAG_YCBCRSUBSAMPLING:
554
0
            td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
555
0
            td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
556
0
            break;
557
0
        case TIFFTAG_TRANSFERFUNCTION:
558
0
        {
559
0
            uint32_t i;
560
0
            v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
561
0
            for (i = 0; i < v; i++)
562
0
                _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
563
0
                                      va_arg(ap, uint16_t *),
564
0
                                      1U << td->td_bitspersample);
565
0
            break;
566
0
        }
567
0
        case TIFFTAG_REFERENCEBLACKWHITE:
568
            /* XXX should check for null range */
569
0
            _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
570
0
                                  va_arg(ap, float *), 6);
571
0
            break;
572
0
        case TIFFTAG_INKNAMES:
573
0
        {
574
0
            uint16_t ninksinstring;
575
0
            v = (uint16_t)va_arg(ap, uint16_vap);
576
0
            s = va_arg(ap, char *);
577
0
            ninksinstring = countInkNamesString(tif, v, s);
578
0
            status = ninksinstring > 0;
579
0
            if (ninksinstring > 0)
580
0
            {
581
0
                _TIFFsetNString(tif, &td->td_inknames, s, v);
582
0
                td->td_inknameslen = v;
583
                /* Set NumberOfInks to the value ninksinstring */
584
0
                if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
585
0
                {
586
0
                    if (td->td_numberofinks != ninksinstring)
587
0
                    {
588
0
                        TIFFErrorExtR(
589
0
                            tif, module,
590
0
                            "Warning %s; Tag %s:\n  Value %" PRIu16
591
0
                            " of NumberOfInks is different from the number of "
592
0
                            "inks %" PRIu16
593
0
                            ".\n  -> NumberOfInks value adapted to %" PRIu16 "",
594
0
                            tif->tif_name, fip->field_name, td->td_numberofinks,
595
0
                            ninksinstring, ninksinstring);
596
0
                        td->td_numberofinks = ninksinstring;
597
0
                    }
598
0
                }
599
0
                else
600
0
                {
601
0
                    td->td_numberofinks = ninksinstring;
602
0
                    TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
603
0
                }
604
0
                if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
605
0
                {
606
0
                    if (td->td_numberofinks != td->td_samplesperpixel)
607
0
                    {
608
0
                        TIFFErrorExtR(tif, module,
609
0
                                      "Warning %s; Tag %s:\n  Value %" PRIu16
610
0
                                      " of NumberOfInks is different from the "
611
0
                                      "SamplesPerPixel value %" PRIu16 "",
612
0
                                      tif->tif_name, fip->field_name,
613
0
                                      td->td_numberofinks,
614
0
                                      td->td_samplesperpixel);
615
0
                    }
616
0
                }
617
0
            }
618
0
        }
619
0
        break;
620
0
        case TIFFTAG_NUMBEROFINKS:
621
0
            v = (uint16_t)va_arg(ap, uint16_vap);
622
            /* If InkNames already set also NumberOfInks is set accordingly and
623
             * should be equal */
624
0
            if (TIFFFieldSet(tif, FIELD_INKNAMES))
625
0
            {
626
0
                if (v != td->td_numberofinks)
627
0
                {
628
0
                    TIFFErrorExtR(
629
0
                        tif, module,
630
0
                        "Error %s; Tag %s:\n  It is not possible to set the "
631
0
                        "value %" PRIu32
632
0
                        " for NumberOfInks\n  which is different from the "
633
0
                        "number of inks in the InkNames tag (%" PRIu16 ")",
634
0
                        tif->tif_name, fip->field_name, v, td->td_numberofinks);
635
                    /* Do not set / overwrite number of inks already set by
636
                     * InkNames case accordingly. */
637
0
                    status = 0;
638
0
                }
639
0
            }
640
0
            else
641
0
            {
642
0
                td->td_numberofinks = (uint16_t)v;
643
0
                if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
644
0
                {
645
0
                    if (td->td_numberofinks != td->td_samplesperpixel)
646
0
                    {
647
0
                        TIFFErrorExtR(tif, module,
648
0
                                      "Warning %s; Tag %s:\n  Value %" PRIu32
649
0
                                      " of NumberOfInks is different from the "
650
0
                                      "SamplesPerPixel value %" PRIu16 "",
651
0
                                      tif->tif_name, fip->field_name, v,
652
0
                                      td->td_samplesperpixel);
653
0
                    }
654
0
                }
655
0
            }
656
0
            break;
657
0
        case TIFFTAG_PERSAMPLE:
658
0
            v = (uint16_t)va_arg(ap, uint16_vap);
659
0
            if (v == PERSAMPLE_MULTI)
660
0
                tif->tif_flags |= TIFF_PERSAMPLE;
661
0
            else
662
0
                tif->tif_flags &= ~TIFF_PERSAMPLE;
663
0
            break;
664
46.0k
        default:
665
46.0k
        {
666
46.0k
            TIFFTagValue *tv;
667
46.0k
            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
46.0k
            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
46.0k
            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
46.0k
            tv = NULL;
705
69.0k
            for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
706
23.0k
            {
707
23.0k
                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
23.0k
            }
718
719
            /*
720
             * Grow the custom list if the entry was not found.
721
             */
722
46.0k
            if (tv == NULL)
723
46.0k
            {
724
46.0k
                TIFFTagValue *new_customValues;
725
726
46.0k
                td->td_customValueCount++;
727
46.0k
                new_customValues = (TIFFTagValue *)_TIFFreallocExt(
728
46.0k
                    tif, td->td_customValues,
729
46.0k
                    sizeof(TIFFTagValue) * td->td_customValueCount);
730
46.0k
                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
46.0k
                td->td_customValues = new_customValues;
741
742
46.0k
                tv = td->td_customValues + (td->td_customValueCount - 1);
743
46.0k
                tv->info = fip;
744
46.0k
                tv->value = NULL;
745
46.0k
                tv->count = 0;
746
46.0k
            }
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
46.0k
            tv_size = TIFFFieldSetGetSize(fip);
754
46.0k
            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
46.0k
            if (fip->field_type == TIFF_ASCII)
763
46.0k
            {
764
46.0k
                uint32_t ma;
765
46.0k
                const char *mb;
766
46.0k
                if (fip->field_passcount)
767
0
                {
768
0
                    assert(fip->field_writecount == TIFF_VARIABLE2);
769
0
                    ma = (uint32_t)va_arg(ap, uint32_t);
770
0
                    mb = (const char *)va_arg(ap, const char *);
771
0
                }
772
46.0k
                else
773
46.0k
                {
774
46.0k
                    size_t len;
775
46.0k
                    mb = (const char *)va_arg(ap, const char *);
776
46.0k
                    len = strlen(mb) + 1;
777
46.0k
                    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
46.0k
                    ma = (uint32_t)len;
787
46.0k
                }
788
46.0k
                tv->count = ma;
789
46.0k
                setByteArray(tif, &tv->value, mb, ma, 1);
790
46.0k
            }
791
0
            else
792
0
            {
793
0
                if (fip->field_passcount)
794
0
                {
795
0
                    if (fip->field_writecount == TIFF_VARIABLE2)
796
0
                        tv->count = (uint32_t)va_arg(ap, uint32_t);
797
0
                    else
798
0
                        tv->count = (int)va_arg(ap, int);
799
0
                }
800
0
                else if (fip->field_writecount == TIFF_VARIABLE ||
801
0
                         fip->field_writecount == TIFF_VARIABLE2)
802
0
                    tv->count = 1;
803
0
                else if (fip->field_writecount == TIFF_SPP)
804
0
                    tv->count = td->td_samplesperpixel;
805
0
                else
806
0
                    tv->count = fip->field_writecount;
807
808
0
                if (tv->count == 0)
809
0
                {
810
0
                    status = 0;
811
0
                    TIFFErrorExtR(tif, module,
812
0
                                  "%s: Null count for \"%s\" (type "
813
0
                                  "%d, writecount %d, passcount %d)",
814
0
                                  tif->tif_name, fip->field_name,
815
0
                                  fip->field_type, fip->field_writecount,
816
0
                                  fip->field_passcount);
817
0
                    goto end;
818
0
                }
819
820
0
                tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
821
0
                                             "custom tag binary object");
822
0
                if (!tv->value)
823
0
                {
824
0
                    status = 0;
825
0
                    goto end;
826
0
                }
827
828
0
                if (fip->field_tag == TIFFTAG_DOTRANGE &&
829
0
                    strcmp(fip->field_name, "DotRange") == 0)
830
0
                {
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
0
                    uint16_t v2[2];
836
0
                    v2[0] = (uint16_t)va_arg(ap, int);
837
0
                    v2[1] = (uint16_t)va_arg(ap, int);
838
0
                    _TIFFmemcpy(tv->value, &v2, 4);
839
0
                }
840
841
0
                else if (fip->field_passcount ||
842
0
                         fip->field_writecount == TIFF_VARIABLE ||
843
0
                         fip->field_writecount == TIFF_VARIABLE2 ||
844
0
                         fip->field_writecount == TIFF_SPP || tv->count > 1)
845
0
                {
846
                    /*--: Rational2Double: For Rationals tv_size is set above to
847
                     * 4 or 8 according to fip->set_field_type! */
848
0
                    _TIFFmemcpy(tv->value, va_arg(ap, void *),
849
0
                                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
0
                    if (!(tif->tif_flags & TIFF_BIGTIFF))
853
0
                    {
854
0
                        if (tv->info->field_type == TIFF_LONG8)
855
0
                        {
856
0
                            uint64_t *pui64 = (uint64_t *)tv->value;
857
0
                            int i;
858
0
                            for (i = 0; i < tv->count; i++)
859
0
                            {
860
0
                                if (pui64[i] > 0xffffffffu)
861
0
                                {
862
0
                                    TIFFErrorExtR(
863
0
                                        tif, module,
864
0
                                        "%s: Bad LONG8 value %" PRIu64
865
0
                                        " at %d. array position for \"%s\" tag "
866
0
                                        "%d in ClassicTIFF. Tag won't be "
867
0
                                        "written to file",
868
0
                                        tif->tif_name, pui64[i], i,
869
0
                                        fip->field_name, tag);
870
0
                                    goto badvalueifd8long8;
871
0
                                }
872
0
                            }
873
0
                        }
874
0
                        else if (tv->info->field_type == TIFF_SLONG8)
875
0
                        {
876
0
                            int64_t *pi64 = (int64_t *)tv->value;
877
0
                            int i;
878
0
                            for (i = 0; i < tv->count; i++)
879
0
                            {
880
0
                                if (pi64[i] > 2147483647 ||
881
0
                                    pi64[i] < (-2147483647 - 1))
882
0
                                {
883
0
                                    TIFFErrorExtR(
884
0
                                        tif, module,
885
0
                                        "%s: Bad SLONG8 value %" PRIi64
886
0
                                        " at %d. array position for \"%s\" tag "
887
0
                                        "%d in ClassicTIFF. Tag won't be "
888
0
                                        "written to file",
889
0
                                        tif->tif_name, pi64[i], i,
890
0
                                        fip->field_name, tag);
891
0
                                    goto badvalueifd8long8;
892
0
                                }
893
0
                            }
894
0
                        }
895
0
                    }
896
0
                }
897
0
                else
898
0
                {
899
0
                    char *val = (char *)tv->value;
900
0
                    assert(tv->count == 1);
901
902
0
                    switch (fip->field_type)
903
0
                    {
904
0
                        case TIFF_BYTE:
905
0
                        case TIFF_UNDEFINED:
906
0
                        {
907
0
                            uint8_t v2 = (uint8_t)va_arg(ap, int);
908
0
                            _TIFFmemcpy(val, &v2, tv_size);
909
0
                        }
910
0
                        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
0
                        case TIFF_SHORT:
918
0
                        {
919
0
                            uint16_t v2 = (uint16_t)va_arg(ap, int);
920
0
                            _TIFFmemcpy(val, &v2, tv_size);
921
0
                        }
922
0
                        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
0
                        case TIFF_LONG:
930
0
                        case TIFF_IFD:
931
0
                        {
932
0
                            uint32_t v2 = va_arg(ap, uint32_t);
933
0
                            _TIFFmemcpy(val, &v2, tv_size);
934
0
                        }
935
0
                        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
0
                        case TIFF_IFD8:
944
0
                        {
945
0
                            uint64_t v2 = va_arg(ap, uint64_t);
946
0
                            _TIFFmemcpy(val, &v2, tv_size);
947
                            /* Test here for too big values for ClassicTIFF and
948
                             * delete custom field from custom list */
949
0
                            if (!(tif->tif_flags & TIFF_BIGTIFF) &&
950
0
                                (v2 > 0xffffffffu))
951
0
                            {
952
0
                                TIFFErrorExtR(
953
0
                                    tif, module,
954
0
                                    "%s: Bad LONG8 or IFD8 value %" PRIu64
955
0
                                    " for \"%s\" tag %d in ClassicTIFF. Tag "
956
0
                                    "won't be written to file",
957
0
                                    tif->tif_name, v2, fip->field_name, tag);
958
0
                                goto badvalueifd8long8;
959
0
                            }
960
0
                        }
961
0
                        break;
962
0
                        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
0
                        case TIFF_RATIONAL:
982
0
                        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
0
                            {
987
0
                                if (tv_size == 8)
988
0
                                {
989
0
                                    double v2 = va_arg(ap, double);
990
0
                                    _TIFFmemcpy(val, &v2, tv_size);
991
0
                                }
992
0
                                else
993
0
                                {
994
                                    /*-- default should be tv_size == 4 */
995
0
                                    float v3 = (float)va_arg(ap, double);
996
0
                                    _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
0
                                    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
0
                                }
1009
0
                            }
1010
0
                            break;
1011
0
                        case TIFF_FLOAT:
1012
0
                        {
1013
0
                            float v2 =
1014
0
                                _TIFFClampDoubleToFloat(va_arg(ap, double));
1015
0
                            _TIFFmemcpy(val, &v2, tv_size);
1016
0
                        }
1017
0
                        break;
1018
0
                        case TIFF_DOUBLE:
1019
0
                        {
1020
0
                            double v2 = va_arg(ap, double);
1021
0
                            _TIFFmemcpy(val, &v2, tv_size);
1022
0
                        }
1023
0
                        break;
1024
0
                        default:
1025
0
                            _TIFFmemset(val, 0, tv_size);
1026
0
                            status = 0;
1027
0
                            break;
1028
0
                    }
1029
0
                }
1030
0
            }
1031
46.0k
        }
1032
509k
    }
1033
509k
    if (status)
1034
509k
    {
1035
509k
        const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1036
509k
        if (fip2)
1037
509k
            TIFFSetFieldBit(tif, fip2->field_bit);
1038
509k
        tif->tif_flags |= TIFF_DIRTYDIRECT;
1039
509k
    }
1040
1041
509k
end:
1042
509k
    va_end(ap);
1043
509k
    return (status);
1044
0
badvalue:
1045
0
{
1046
0
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1047
0
    TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1048
0
                  tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
1049
0
    va_end(ap);
1050
0
}
1051
0
    return (0);
1052
0
badvalue32:
1053
0
{
1054
0
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1055
0
    TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1056
0
                  tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
1057
0
    va_end(ap);
1058
0
}
1059
0
    return (0);
1060
0
badvaluedouble:
1061
0
{
1062
0
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1063
0
    TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
1064
0
                  dblval, fip2 ? fip2->field_name : "Unknown");
1065
0
    va_end(ap);
1066
0
}
1067
0
    return (0);
1068
0
badvalueifd8long8:
1069
0
{
1070
    /* Error message issued already above. */
1071
0
    TIFFTagValue *tv2 = NULL;
1072
0
    int iCustom2, iC2;
1073
    /* Find the existing entry for this custom value. */
1074
0
    for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
1075
0
    {
1076
0
        if (td->td_customValues[iCustom2].info->field_tag == tag)
1077
0
        {
1078
0
            tv2 = td->td_customValues + (iCustom2);
1079
0
            break;
1080
0
        }
1081
0
    }
1082
0
    if (tv2 != NULL)
1083
0
    {
1084
        /* Remove custom field from custom list */
1085
0
        if (tv2->value != NULL)
1086
0
        {
1087
0
            _TIFFfreeExt(tif, tv2->value);
1088
0
            tv2->value = NULL;
1089
0
        }
1090
        /* Shorten list and close gap in customValues list.
1091
         * Re-allocation of td_customValues not necessary here. */
1092
0
        td->td_customValueCount--;
1093
0
        for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
1094
0
        {
1095
0
            td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
1096
0
        }
1097
0
    }
1098
0
    else
1099
0
    {
1100
0
        assert(0);
1101
0
    }
1102
0
    va_end(ap);
1103
0
}
1104
0
    return (0);
1105
509k
} /*-- _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
555k
{
1118
555k
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1119
555k
    if (!fip)
1120
0
    { /* unknown tag */
1121
0
        TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
1122
0
                      tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
1123
0
        return (0);
1124
0
    }
1125
555k
    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
555k
    return (1);
1140
555k
}
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
555k
{
1151
555k
    va_list ap;
1152
555k
    int status;
1153
1154
555k
    va_start(ap, tag);
1155
555k
    status = TIFFVSetField(tif, tag, ap);
1156
555k
    va_end(ap);
1157
555k
    return (status);
1158
555k
}
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
555k
{
1210
555k
    return OkToChangeTag(tif, tag)
1211
555k
               ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1212
555k
               : 0;
1213
555k
}
1214
1215
static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1216
0
{
1217
0
    TIFFDirectory *td = &tif->tif_dir;
1218
0
    int ret_val = 1;
1219
0
    uint32_t standard_tag = tag;
1220
0
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1221
0
    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
0
    if (fip->field_bit == FIELD_CUSTOM)
1231
0
    {
1232
0
        standard_tag = 0;
1233
0
    }
1234
1235
0
    switch (standard_tag)
1236
0
    {
1237
0
        case TIFFTAG_SUBFILETYPE:
1238
0
            *va_arg(ap, uint32_t *) = td->td_subfiletype;
1239
0
            break;
1240
0
        case TIFFTAG_IMAGEWIDTH:
1241
0
            *va_arg(ap, uint32_t *) = td->td_imagewidth;
1242
0
            break;
1243
0
        case TIFFTAG_IMAGELENGTH:
1244
0
            *va_arg(ap, uint32_t *) = td->td_imagelength;
1245
0
            break;
1246
0
        case TIFFTAG_BITSPERSAMPLE:
1247
0
            *va_arg(ap, uint16_t *) = td->td_bitspersample;
1248
0
            break;
1249
0
        case TIFFTAG_COMPRESSION:
1250
0
            *va_arg(ap, uint16_t *) = td->td_compression;
1251
0
            break;
1252
0
        case TIFFTAG_PHOTOMETRIC:
1253
0
            *va_arg(ap, uint16_t *) = td->td_photometric;
1254
0
            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
0
        case TIFFTAG_ORIENTATION:
1262
0
            *va_arg(ap, uint16_t *) = td->td_orientation;
1263
0
            break;
1264
0
        case TIFFTAG_SAMPLESPERPIXEL:
1265
0
            *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
1266
0
            break;
1267
0
        case TIFFTAG_ROWSPERSTRIP:
1268
0
            *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
1269
0
            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
0
        case TIFFTAG_XRESOLUTION:
1305
0
            *va_arg(ap, float *) = td->td_xresolution;
1306
0
            break;
1307
0
        case TIFFTAG_YRESOLUTION:
1308
0
            *va_arg(ap, float *) = td->td_yresolution;
1309
0
            break;
1310
0
        case TIFFTAG_PLANARCONFIG:
1311
0
            *va_arg(ap, uint16_t *) = td->td_planarconfig;
1312
0
            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
0
        case TIFFTAG_COLORMAP:
1331
0
            *va_arg(ap, const uint16_t **) = td->td_colormap[0];
1332
0
            *va_arg(ap, const uint16_t **) = td->td_colormap[1];
1333
0
            *va_arg(ap, const uint16_t **) = td->td_colormap[2];
1334
0
            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
0
        case TIFFTAG_EXTRASAMPLES:
1355
0
            *va_arg(ap, uint16_t *) = td->td_extrasamples;
1356
0
            *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
1357
0
            break;
1358
0
        case TIFFTAG_TILEWIDTH:
1359
0
            *va_arg(ap, uint32_t *) = td->td_tilewidth;
1360
0
            break;
1361
0
        case TIFFTAG_TILELENGTH:
1362
0
            *va_arg(ap, uint32_t *) = td->td_tilelength;
1363
0
            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
0
        case TIFFTAG_YCBCRSUBSAMPLING:
1398
0
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
1399
0
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
1400
0
            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
0
        case TIFFTAG_REFERENCEBLACKWHITE:
1415
0
            *va_arg(ap, const float **) = td->td_refblackwhite;
1416
0
            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
0
        default:
1424
0
        {
1425
0
            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
0
            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
0
            ret_val = 0;
1451
0
            for (i = 0; i < td->td_customValueCount; i++)
1452
0
            {
1453
0
                TIFFTagValue *tv = td->td_customValues + i;
1454
1455
0
                if (tv->info->field_tag != tag)
1456
0
                    continue;
1457
1458
0
                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
0
                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
0
                else
1479
0
                {
1480
0
                    if (fip->field_type == TIFF_ASCII ||
1481
0
                        fip->field_readcount == TIFF_VARIABLE ||
1482
0
                        fip->field_readcount == TIFF_VARIABLE2 ||
1483
0
                        fip->field_readcount == TIFF_SPP || tv->count > 1)
1484
0
                    {
1485
0
                        *va_arg(ap, void **) = tv->value;
1486
0
                        ret_val = 1;
1487
0
                    }
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
0
                }
1574
0
                break;
1575
0
            }
1576
0
        }
1577
0
    }
1578
0
    return (ret_val);
1579
0
}
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
0
{
1587
0
    int status;
1588
0
    va_list ap;
1589
1590
0
    va_start(ap, tag);
1591
0
    status = TIFFVGetField(tif, tag, ap);
1592
0
    va_end(ap);
1593
0
    return (status);
1594
0
}
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
0
{
1604
0
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1605
0
    return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
1606
0
                ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
1607
0
                : 0);
1608
0
}
1609
1610
#define CleanupField(member)                                                   \
1611
1.26M
    {                                                                          \
1612
1.26M
        if (td->member)                                                        \
1613
1.26M
        {                                                                      \
1614
79.3k
            _TIFFfreeExt(tif, td->member);                                     \
1615
79.3k
            td->member = 0;                                                    \
1616
79.3k
        }                                                                      \
1617
1.26M
    }
1618
1619
/*
1620
 * Release storage associated with a directory.
1621
 */
1622
void TIFFFreeDirectory(TIFF *tif)
1623
84.5k
{
1624
84.5k
    TIFFDirectory *td = &tif->tif_dir;
1625
84.5k
    int i;
1626
1627
84.5k
    _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
1628
84.5k
    CleanupField(td_sminsamplevalue);
1629
84.5k
    CleanupField(td_smaxsamplevalue);
1630
84.5k
    CleanupField(td_colormap[0]);
1631
84.5k
    CleanupField(td_colormap[1]);
1632
84.5k
    CleanupField(td_colormap[2]);
1633
84.5k
    CleanupField(td_sampleinfo);
1634
84.5k
    CleanupField(td_subifd);
1635
84.5k
    CleanupField(td_inknames);
1636
84.5k
    CleanupField(td_refblackwhite);
1637
84.5k
    CleanupField(td_transferfunction[0]);
1638
84.5k
    CleanupField(td_transferfunction[1]);
1639
84.5k
    CleanupField(td_transferfunction[2]);
1640
84.5k
    CleanupField(td_stripoffset_p);
1641
84.5k
    CleanupField(td_stripbytecount_p);
1642
84.5k
    td->td_stripoffsetbyteallocsize = 0;
1643
84.5k
    TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
1644
84.5k
    TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
1645
1646
    /* Cleanup custom tag values */
1647
130k
    for (i = 0; i < td->td_customValueCount; i++)
1648
46.0k
    {
1649
46.0k
        if (td->td_customValues[i].value)
1650
46.0k
            _TIFFfreeExt(tif, td->td_customValues[i].value);
1651
46.0k
    }
1652
1653
84.5k
    td->td_customValueCount = 0;
1654
84.5k
    CleanupField(td_customValues);
1655
1656
84.5k
    _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
1657
84.5k
    _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
1658
1659
    /* Reset some internal parameters for IFD data size checking. */
1660
84.5k
    tif->tif_dir.td_dirdatasize_read = 0;
1661
84.5k
    tif->tif_dir.td_dirdatasize_write = 0;
1662
84.5k
    if (tif->tif_dir.td_dirdatasize_offsets != NULL)
1663
0
    {
1664
0
        _TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
1665
0
        tif->tif_dir.td_dirdatasize_offsets = NULL;
1666
0
        tif->tif_dir.td_dirdatasize_Noffsets = 0;
1667
0
    }
1668
84.5k
    tif->tif_dir.td_iswrittentofile = FALSE;
1669
84.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
28.1k
{
1693
    /* Free previously allocated memory and setup default values. */
1694
28.1k
    TIFFFreeDirectory(tif);
1695
28.1k
    TIFFDefaultDirectory(tif);
1696
28.1k
    tif->tif_diroff = 0;
1697
28.1k
    tif->tif_nextdiroff = 0;
1698
28.1k
    tif->tif_curoff = 0;
1699
28.1k
    tif->tif_row = (uint32_t)-1;
1700
28.1k
    tif->tif_curstrip = (uint32_t)-1;
1701
28.1k
    tif->tif_dir.td_iswrittentofile = FALSE;
1702
1703
28.1k
    return 0;
1704
28.1k
}
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
56.3k
{
1756
56.3k
    register TIFFDirectory *td = &tif->tif_dir;
1757
56.3k
    const TIFFFieldArray *tiffFieldArray;
1758
1759
56.3k
    tiffFieldArray = _TIFFGetFields();
1760
56.3k
    _TIFFSetupFields(tif, tiffFieldArray);
1761
1762
56.3k
    _TIFFmemset(td, 0, sizeof(*td));
1763
56.3k
    td->td_fillorder = FILLORDER_MSB2LSB;
1764
56.3k
    td->td_bitspersample = 1;
1765
56.3k
    td->td_threshholding = THRESHHOLD_BILEVEL;
1766
56.3k
    td->td_orientation = ORIENTATION_TOPLEFT;
1767
56.3k
    td->td_samplesperpixel = 1;
1768
56.3k
    td->td_rowsperstrip = (uint32_t)-1;
1769
56.3k
    td->td_tilewidth = 0;
1770
56.3k
    td->td_tilelength = 0;
1771
56.3k
    td->td_tiledepth = 1;
1772
#ifdef STRIPBYTECOUNTSORTED_UNUSED
1773
    td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1774
#endif
1775
56.3k
    td->td_resolutionunit = RESUNIT_INCH;
1776
56.3k
    td->td_sampleformat = SAMPLEFORMAT_UINT;
1777
56.3k
    td->td_imagedepth = 1;
1778
56.3k
    td->td_ycbcrsubsampling[0] = 2;
1779
56.3k
    td->td_ycbcrsubsampling[1] = 2;
1780
56.3k
    td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
1781
56.3k
    tif->tif_postdecode = _TIFFNoPostDecode;
1782
56.3k
    tif->tif_foundfield = NULL;
1783
56.3k
    tif->tif_tagmethods.vsetfield = _TIFFVSetField;
1784
56.3k
    tif->tif_tagmethods.vgetfield = _TIFFVGetField;
1785
56.3k
    tif->tif_tagmethods.printdir = NULL;
1786
    /* additional default values */
1787
56.3k
    td->td_planarconfig = PLANARCONFIG_CONTIG;
1788
56.3k
    td->td_compression = COMPRESSION_NONE;
1789
56.3k
    td->td_subfiletype = 0;
1790
56.3k
    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
56.3k
    td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
1795
56.3k
    td->td_extrasamples = 0;
1796
56.3k
    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
56.3k
    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
56.3k
    if (_TIFFextender)
1818
0
        (*_TIFFextender)(tif);
1819
56.3k
    (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
56.3k
    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
56.3k
    tif->tif_flags &= ~TIFF_ISTILED;
1836
1837
56.3k
    return (1);
1838
56.3k
}
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
}