Coverage Report

Created: 2026-08-14 06:52

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