Coverage Report

Created: 2026-04-01 06:20

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