Coverage Report

Created: 2026-04-10 07:04

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