• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OSGeo / gdal / 15985453442

30 Jun 2025 11:00PM UTC coverage: 71.093% (+0.004%) from 71.089%
15985453442

Pull #12680

github

web-flow
Merge 346c552a0 into 3996c9be8
Pull Request #12680: Arrow/Parquet: handle list of binary and binary as JSON content (struct/list_of_list/array_of binary)

68 of 89 new or added lines in 1 file covered. (76.4%)

37 existing lines in 20 files now uncovered.

574098 of 807529 relevant lines covered (71.09%)

250439.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

54.16
/frmts/gtiff/libtiff/tif_dir.c
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
#define DATATYPE_VOID 0   /* !untyped data */
39
#define DATATYPE_INT 1    /* !signed integer data */
40
#define DATATYPE_UINT 2   /* !unsigned integer data */
41
#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
42

43
static void setByteArray(TIFF *tif, void **vpp, const void *vp, size_t nmemb,
55,455✔
44
                         size_t elem_size)
45
{
46
    if (*vpp)
55,455✔
47
    {
48
        _TIFFfreeExt(tif, *vpp);
1,425✔
49
        *vpp = 0;
1,425✔
50
    }
51
    if (vp)
55,455✔
52
    {
53
        tmsize_t bytes = _TIFFMultiplySSize(NULL, nmemb, elem_size, NULL);
55,360✔
54
        if (bytes)
55,391✔
55
            *vpp = (void *)_TIFFmallocExt(tif, bytes);
55,296✔
56
        if (*vpp)
55,492✔
57
            _TIFFmemcpy(*vpp, vp, bytes);
55,370✔
58
    }
59
}
55,544✔
60
void _TIFFsetByteArray(void **vpp, const void *vp, uint32_t n)
×
61
{
62
    setByteArray(NULL, vpp, vp, n, 1);
×
63
}
×
64
void _TIFFsetByteArrayExt(TIFF *tif, void **vpp, const void *vp, uint32_t n)
3,146✔
65
{
66
    setByteArray(tif, vpp, vp, n, 1);
3,146✔
67
}
3,146✔
68

69
static void _TIFFsetNString(TIFF *tif, char **cpp, const char *cp, uint32_t n)
×
70
{
71
    setByteArray(tif, (void **)cpp, cp, n, 1);
×
72
}
×
73

74
void _TIFFsetShortArray(uint16_t **wpp, const uint16_t *wp, uint32_t n)
×
75
{
76
    setByteArray(NULL, (void **)wpp, wp, n, sizeof(uint16_t));
×
77
}
×
78
void _TIFFsetShortArrayExt(TIFF *tif, uint16_t **wpp, const uint16_t *wp,
9,591✔
79
                           uint32_t n)
80
{
81
    setByteArray(tif, (void **)wpp, wp, n, sizeof(uint16_t));
9,591✔
82
}
9,591✔
83

84
void _TIFFsetLongArray(uint32_t **lpp, const uint32_t *lp, uint32_t n)
×
85
{
86
    setByteArray(NULL, (void **)lpp, lp, n, sizeof(uint32_t));
×
87
}
×
88
void _TIFFsetLongArrayExt(TIFF *tif, uint32_t **lpp, const uint32_t *lp,
×
89
                          uint32_t n)
90
{
91
    setByteArray(tif, (void **)lpp, lp, n, sizeof(uint32_t));
×
92
}
×
93

94
static void _TIFFsetLong8Array(TIFF *tif, uint64_t **lpp, const uint64_t *lp,
78✔
95
                               uint32_t n)
96
{
97
    setByteArray(tif, (void **)lpp, lp, n, sizeof(uint64_t));
78✔
98
}
78✔
99

100
void _TIFFsetFloatArray(float **fpp, const float *fp, uint32_t n)
×
101
{
102
    setByteArray(NULL, (void **)fpp, fp, n, sizeof(float));
×
103
}
×
104
void _TIFFsetFloatArrayExt(TIFF *tif, float **fpp, const float *fp, uint32_t n)
1,866✔
105
{
106
    setByteArray(tif, (void **)fpp, fp, n, sizeof(float));
1,866✔
107
}
1,866✔
108

109
void _TIFFsetDoubleArray(double **dpp, const double *dp, uint32_t n)
×
110
{
111
    setByteArray(NULL, (void **)dpp, dp, n, sizeof(double));
×
112
}
×
113
void _TIFFsetDoubleArrayExt(TIFF *tif, double **dpp, const double *dp,
×
114
                            uint32_t n)
115
{
116
    setByteArray(tif, (void **)dpp, dp, n, sizeof(double));
×
117
}
×
118

119
static void setDoubleArrayOneValue(TIFF *tif, double **vpp, double value,
×
120
                                   size_t nmemb)
121
{
122
    if (*vpp)
×
123
        _TIFFfreeExt(tif, *vpp);
×
124
    *vpp = _TIFFmallocExt(tif, nmemb * sizeof(double));
×
125
    if (*vpp)
×
126
    {
127
        while (nmemb--)
×
128
            ((double *)*vpp)[nmemb] = value;
×
129
    }
130
}
×
131

132
/*
133
 * Install extra samples information.
134
 */
135
static int setExtraSamples(TIFF *tif, va_list ap, uint32_t *v)
8,287✔
136
{
137
/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
138
#define EXTRASAMPLE_COREL_UNASSALPHA 999
139

140
    uint16_t *va;
141
    uint32_t i;
142
    TIFFDirectory *td = &tif->tif_dir;
8,287✔
143
    static const char module[] = "setExtraSamples";
144

145
    *v = (uint16_t)va_arg(ap, uint16_vap);
8,287✔
146
    if ((uint16_t)*v > td->td_samplesperpixel)
8,287✔
147
        return 0;
×
148
    va = va_arg(ap, uint16_t *);
8,287✔
149
    if (*v > 0 && va == NULL) /* typically missing param */
8,286✔
150
        return 0;
×
151
    for (i = 0; i < *v; i++)
1,561,790✔
152
    {
153
        if (va[i] > EXTRASAMPLE_UNASSALPHA)
1,553,510✔
154
        {
155
            /*
156
             * XXX: Corel Draw is known to produce incorrect
157
             * ExtraSamples tags which must be patched here if we
158
             * want to be able to open some of the damaged TIFF
159
             * files:
160
             */
161
            if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
×
162
                va[i] = EXTRASAMPLE_UNASSALPHA;
×
163
            else
164
                return 0;
×
165
        }
166
    }
167

168
    if (td->td_transferfunction[0] != NULL &&
8,286✔
169
        (td->td_samplesperpixel - *v > 1) &&
×
170
        !(td->td_samplesperpixel - td->td_extrasamples > 1))
×
171
    {
172
        TIFFWarningExtR(tif, module,
×
173
                        "ExtraSamples tag value is changing, "
174
                        "but TransferFunction was read with a different value. "
175
                        "Canceling it");
176
        TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
×
177
        _TIFFfreeExt(tif, td->td_transferfunction[0]);
×
178
        td->td_transferfunction[0] = NULL;
×
179
    }
180

181
    td->td_extrasamples = (uint16_t)*v;
8,286✔
182
    _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, va, td->td_extrasamples);
8,286✔
183
    return 1;
8,287✔
184

185
#undef EXTRASAMPLE_COREL_UNASSALPHA
186
}
187

188
/*
189
 * Count ink names separated by \0.  Returns
190
 * zero if the ink names are not as expected.
191
 */
192
static uint16_t countInkNamesString(TIFF *tif, uint32_t slen, const char *s)
×
193
{
194
    uint16_t i = 0;
×
195

196
    if (slen > 0)
×
197
    {
198
        const char *ep = s + slen;
×
199
        const char *cp = s;
×
200
        do
201
        {
202
            for (; cp < ep && *cp != '\0'; cp++)
×
203
            {
204
            }
205
            if (cp >= ep)
×
206
                goto bad;
×
207
            cp++; /* skip \0 */
×
208
            i++;
×
209
        } while (cp < ep);
×
210
        return (i);
×
211
    }
212
bad:
×
213
    TIFFErrorExtR(tif, "TIFFSetField",
×
214
                  "%s: Invalid InkNames value; no null at given buffer end "
215
                  "location %" PRIu32 ", after %" PRIu16 " ink",
216
                  tif->tif_name, slen, i);
217
    return (0);
×
218
}
219

220
static int _TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
1,189,840✔
221
{
222
    static const char module[] = "_TIFFVSetField";
223

224
    TIFFDirectory *td = &tif->tif_dir;
1,189,840✔
225
    int status = 1;
1,189,840✔
226
    uint32_t v32, v;
227
    double dblval;
228
    char *s;
229
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1,189,840✔
230
    uint32_t standard_tag = tag;
1,189,380✔
231
    if (fip == NULL) /* cannot happen since OkToChangeTag() already checks it */
1,189,380✔
232
        return 0;
×
233
    /*
234
     * We want to force the custom code to be used for custom
235
     * fields even if the tag happens to match a well known
236
     * one - important for reinterpreted handling of standard
237
     * tag values in custom directories (i.e. EXIF)
238
     */
239
    if (fip->field_bit == FIELD_CUSTOM)
1,189,380✔
240
    {
241
        standard_tag = 0;
149,216✔
242
    }
243

244
    switch (standard_tag)
1,189,380✔
245
    {
246
        case TIFFTAG_SUBFILETYPE:
6,764✔
247
            td->td_subfiletype = (uint32_t)va_arg(ap, uint32_t);
6,764✔
248
            break;
6,764✔
249
        case TIFFTAG_IMAGEWIDTH:
91,742✔
250
            td->td_imagewidth = (uint32_t)va_arg(ap, uint32_t);
91,742✔
251
            break;
91,760✔
252
        case TIFFTAG_IMAGELENGTH:
91,739✔
253
            td->td_imagelength = (uint32_t)va_arg(ap, uint32_t);
91,739✔
254
            break;
91,728✔
255
        case TIFFTAG_BITSPERSAMPLE:
91,713✔
256
            td->td_bitspersample = (uint16_t)va_arg(ap, uint16_vap);
91,713✔
257
            /*
258
             * If the data require post-decoding processing to byte-swap
259
             * samples, set it up here.  Note that since tags are required
260
             * to be ordered, compression code can override this behavior
261
             * in the setup method if it wants to roll the post decoding
262
             * work in with its normal work.
263
             */
264
            if (tif->tif_flags & TIFF_SWAB)
91,692✔
265
            {
266
                if (td->td_bitspersample == 8)
696✔
267
                    tif->tif_postdecode = _TIFFNoPostDecode;
386✔
268
                else if (td->td_bitspersample == 16)
310✔
269
                    tif->tif_postdecode = _TIFFSwab16BitData;
126✔
270
                else if (td->td_bitspersample == 24)
184✔
271
                    tif->tif_postdecode = _TIFFSwab24BitData;
×
272
                else if (td->td_bitspersample == 32)
184✔
273
                    tif->tif_postdecode = _TIFFSwab32BitData;
138✔
274
                else if (td->td_bitspersample == 64)
46✔
275
                    tif->tif_postdecode = _TIFFSwab64BitData;
21✔
276
                else if (td->td_bitspersample == 128) /* two 64's */
25✔
277
                    tif->tif_postdecode = _TIFFSwab64BitData;
7✔
278
            }
279
            break;
91,692✔
280
        case TIFFTAG_COMPRESSION:
224,573✔
281
            v = (uint16_t)va_arg(ap, uint16_vap);
224,573✔
282
            /*
283
             * If we're changing the compression scheme, notify the
284
             * previous module so that it can cleanup any state it's
285
             * setup.
286
             */
287
            if (TIFFFieldSet(tif, FIELD_COMPRESSION))
224,611✔
288
            {
289
                if ((uint32_t)td->td_compression == v)
91,500✔
290
                    break;
55,574✔
291
                (*tif->tif_cleanup)(tif);
35,926✔
292
                tif->tif_flags &= ~TIFF_CODERSETUP;
35,923✔
293
            }
294
            /*
295
             * Setup new compression routine state.
296
             */
297
            if ((status = TIFFSetCompressionScheme(tif, v)) != 0)
169,034✔
298
                td->td_compression = (uint16_t)v;
168,902✔
299
            else
300
                status = 0;
17✔
301
            break;
168,919✔
302
        case TIFFTAG_PHOTOMETRIC:
91,774✔
303
            td->td_photometric = (uint16_t)va_arg(ap, uint16_vap);
91,774✔
304
            break;
91,765✔
305
        case TIFFTAG_THRESHHOLDING:
×
306
            td->td_threshholding = (uint16_t)va_arg(ap, uint16_vap);
×
307
            break;
×
308
        case TIFFTAG_FILLORDER:
2✔
309
            v = (uint16_t)va_arg(ap, uint16_vap);
2✔
310
            if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
2✔
311
                goto badvalue;
×
312
            td->td_fillorder = (uint16_t)v;
2✔
313
            break;
2✔
314
        case TIFFTAG_ORIENTATION:
89✔
315
            v = (uint16_t)va_arg(ap, uint16_vap);
89✔
316
            if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
89✔
317
                goto badvalue;
×
318
            else
319
                td->td_orientation = (uint16_t)v;
89✔
320
            break;
89✔
321
        case TIFFTAG_SAMPLESPERPIXEL:
91,725✔
322
            v = (uint16_t)va_arg(ap, uint16_vap);
91,725✔
323
            if (v == 0)
91,689✔
324
                goto badvalue;
×
325
            if (v != td->td_samplesperpixel)
91,689✔
326
            {
327
                /* See http://bugzilla.maptools.org/show_bug.cgi?id=2500 */
328
                if (td->td_sminsamplevalue != NULL)
22,294✔
329
                {
330
                    TIFFWarningExtR(tif, module,
×
331
                                    "SamplesPerPixel tag value is changing, "
332
                                    "but SMinSampleValue tag was read with a "
333
                                    "different value. Canceling it");
334
                    TIFFClrFieldBit(tif, FIELD_SMINSAMPLEVALUE);
×
335
                    _TIFFfreeExt(tif, td->td_sminsamplevalue);
×
336
                    td->td_sminsamplevalue = NULL;
×
337
                }
338
                if (td->td_smaxsamplevalue != NULL)
22,294✔
339
                {
340
                    TIFFWarningExtR(tif, module,
×
341
                                    "SamplesPerPixel tag value is changing, "
342
                                    "but SMaxSampleValue tag was read with a "
343
                                    "different value. Canceling it");
344
                    TIFFClrFieldBit(tif, FIELD_SMAXSAMPLEVALUE);
×
345
                    _TIFFfreeExt(tif, td->td_smaxsamplevalue);
×
346
                    td->td_smaxsamplevalue = NULL;
×
347
                }
348
                /* Test if 3 transfer functions instead of just one are now
349
                   needed See http://bugzilla.maptools.org/show_bug.cgi?id=2820
350
                 */
351
                if (td->td_transferfunction[0] != NULL &&
22,294✔
352
                    (v - td->td_extrasamples > 1) &&
×
353
                    !(td->td_samplesperpixel - td->td_extrasamples > 1))
×
354
                {
355
                    TIFFWarningExtR(tif, module,
×
356
                                    "SamplesPerPixel tag value is changing, "
357
                                    "but TransferFunction was read with a "
358
                                    "different value. Canceling it");
359
                    TIFFClrFieldBit(tif, FIELD_TRANSFERFUNCTION);
×
360
                    _TIFFfreeExt(tif, td->td_transferfunction[0]);
×
361
                    td->td_transferfunction[0] = NULL;
×
362
                }
363
            }
364
            td->td_samplesperpixel = (uint16_t)v;
91,632✔
365
            break;
91,632✔
366
        case TIFFTAG_ROWSPERSTRIP:
81,350✔
367
            v32 = (uint32_t)va_arg(ap, uint32_t);
81,350✔
368
            if (v32 == 0)
81,348✔
369
                goto badvalue32;
×
370
            td->td_rowsperstrip = v32;
81,348✔
371
            if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS))
81,348✔
372
            {
373
                td->td_tilelength = v32;
81,288✔
374
                td->td_tilewidth = td->td_imagewidth;
81,288✔
375
            }
376
            break;
81,348✔
377
        case TIFFTAG_MINSAMPLEVALUE:
8✔
378
            td->td_minsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
8✔
379
            break;
8✔
380
        case TIFFTAG_MAXSAMPLEVALUE:
8✔
381
            td->td_maxsamplevalue = (uint16_t)va_arg(ap, uint16_vap);
8✔
382
            break;
8✔
383
        case TIFFTAG_SMINSAMPLEVALUE:
×
384
            if (tif->tif_flags & TIFF_PERSAMPLE)
×
385
                _TIFFsetDoubleArrayExt(tif, &td->td_sminsamplevalue,
×
386
                                       va_arg(ap, double *),
×
387
                                       td->td_samplesperpixel);
×
388
            else
389
                setDoubleArrayOneValue(tif, &td->td_sminsamplevalue,
×
390
                                       va_arg(ap, double),
391
                                       td->td_samplesperpixel);
×
392
            break;
×
393
        case TIFFTAG_SMAXSAMPLEVALUE:
×
394
            if (tif->tif_flags & TIFF_PERSAMPLE)
×
395
                _TIFFsetDoubleArrayExt(tif, &td->td_smaxsamplevalue,
×
396
                                       va_arg(ap, double *),
×
397
                                       td->td_samplesperpixel);
×
398
            else
399
                setDoubleArrayOneValue(tif, &td->td_smaxsamplevalue,
×
400
                                       va_arg(ap, double),
401
                                       td->td_samplesperpixel);
×
402
            break;
×
403
        case TIFFTAG_XRESOLUTION:
130✔
404
            dblval = va_arg(ap, double);
130✔
405
            if (dblval != dblval || dblval < 0)
130✔
406
                goto badvaluedouble;
×
407
            td->td_xresolution = _TIFFClampDoubleToFloat(dblval);
130✔
408
            break;
130✔
409
        case TIFFTAG_YRESOLUTION:
130✔
410
            dblval = va_arg(ap, double);
130✔
411
            if (dblval != dblval || dblval < 0)
130✔
412
                goto badvaluedouble;
×
413
            td->td_yresolution = _TIFFClampDoubleToFloat(dblval);
130✔
414
            break;
130✔
415
        case TIFFTAG_PLANARCONFIG:
143,692✔
416
            v = (uint16_t)va_arg(ap, uint16_vap);
143,692✔
417
            if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
143,734✔
418
                goto badvalue;
×
419
            td->td_planarconfig = (uint16_t)v;
143,734✔
420
            break;
143,734✔
421
        case TIFFTAG_XPOSITION:
2✔
422
            td->td_xposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
2✔
423
            break;
2✔
424
        case TIFFTAG_YPOSITION:
2✔
425
            td->td_yposition = _TIFFClampDoubleToFloat(va_arg(ap, double));
2✔
426
            break;
2✔
427
        case TIFFTAG_RESOLUTIONUNIT:
134✔
428
            v = (uint16_t)va_arg(ap, uint16_vap);
134✔
429
            if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
134✔
430
                goto badvalue;
×
431
            td->td_resolutionunit = (uint16_t)v;
134✔
432
            break;
134✔
433
        case TIFFTAG_PAGENUMBER:
×
434
            td->td_pagenumber[0] = (uint16_t)va_arg(ap, uint16_vap);
×
435
            td->td_pagenumber[1] = (uint16_t)va_arg(ap, uint16_vap);
×
436
            break;
×
437
        case TIFFTAG_HALFTONEHINTS:
×
438
            td->td_halftonehints[0] = (uint16_t)va_arg(ap, uint16_vap);
×
439
            td->td_halftonehints[1] = (uint16_t)va_arg(ap, uint16_vap);
×
440
            break;
×
441
        case TIFFTAG_COLORMAP:
415✔
442
            v32 = (uint32_t)(1L << td->td_bitspersample);
415✔
443
            _TIFFsetShortArrayExt(tif, &td->td_colormap[0],
415✔
444
                                  va_arg(ap, uint16_t *), v32);
415✔
445
            _TIFFsetShortArrayExt(tif, &td->td_colormap[1],
415✔
446
                                  va_arg(ap, uint16_t *), v32);
415✔
447
            _TIFFsetShortArrayExt(tif, &td->td_colormap[2],
415✔
448
                                  va_arg(ap, uint16_t *), v32);
415✔
449
            break;
415✔
450
        case TIFFTAG_EXTRASAMPLES:
8,287✔
451
            if (!setExtraSamples(tif, ap, &v))
8,287✔
452
                goto badvalue;
×
453
            break;
8,287✔
454
        case TIFFTAG_MATTEING:
2✔
455
            td->td_extrasamples = (((uint16_t)va_arg(ap, uint16_vap)) != 0);
2✔
456
            if (td->td_extrasamples)
2✔
457
            {
458
                uint16_t sv = EXTRASAMPLE_ASSOCALPHA;
×
459
                _TIFFsetShortArrayExt(tif, &td->td_sampleinfo, &sv, 1);
×
460
            }
461
            break;
2✔
462
        case TIFFTAG_TILEWIDTH:
10,502✔
463
            v32 = (uint32_t)va_arg(ap, uint32_t);
10,502✔
464
            if (v32 % 16)
10,502✔
465
            {
466
                if (tif->tif_mode != O_RDONLY)
2✔
467
                    goto badvalue32;
×
468
                TIFFWarningExtR(
2✔
469
                    tif, tif->tif_name,
2✔
470
                    "Nonstandard tile width %" PRIu32 ", convert file", v32);
471
            }
472
            td->td_tilewidth = v32;
10,502✔
473
            tif->tif_flags |= TIFF_ISTILED;
10,502✔
474
            break;
10,502✔
475
        case TIFFTAG_TILELENGTH:
10,502✔
476
            v32 = (uint32_t)va_arg(ap, uint32_t);
10,502✔
477
            if (v32 % 16)
10,502✔
478
            {
479
                if (tif->tif_mode != O_RDONLY)
4✔
480
                    goto badvalue32;
1✔
481
                TIFFWarningExtR(
3✔
482
                    tif, tif->tif_name,
3✔
483
                    "Nonstandard tile length %" PRIu32 ", convert file", v32);
484
            }
485
            td->td_tilelength = v32;
10,501✔
486
            tif->tif_flags |= TIFF_ISTILED;
10,501✔
487
            break;
10,501✔
488
        case TIFFTAG_TILEDEPTH:
×
489
            v32 = (uint32_t)va_arg(ap, uint32_t);
×
490
            if (v32 == 0)
×
491
                goto badvalue32;
×
492
            td->td_tiledepth = v32;
×
493
            break;
×
494
        case TIFFTAG_DATATYPE:
×
495
            v = (uint16_t)va_arg(ap, uint16_vap);
×
496
            switch (v)
×
497
            {
498
                case DATATYPE_VOID:
×
499
                    v = SAMPLEFORMAT_VOID;
×
500
                    break;
×
501
                case DATATYPE_INT:
×
502
                    v = SAMPLEFORMAT_INT;
×
503
                    break;
×
504
                case DATATYPE_UINT:
×
505
                    v = SAMPLEFORMAT_UINT;
×
506
                    break;
×
507
                case DATATYPE_IEEEFP:
×
508
                    v = SAMPLEFORMAT_IEEEFP;
×
509
                    break;
×
510
                default:
×
511
                    goto badvalue;
×
512
            }
513
            td->td_sampleformat = (uint16_t)v;
×
514
            break;
×
515
        case TIFFTAG_SAMPLEFORMAT:
90,686✔
516
            v = (uint16_t)va_arg(ap, uint16_vap);
90,686✔
517
            if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
90,637✔
518
                goto badvalue;
29✔
519
            td->td_sampleformat = (uint16_t)v;
90,608✔
520

521
            /*  Try to fix up the SWAB function for complex data. */
522
            if (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT &&
90,608✔
523
                td->td_bitspersample == 32 &&
1,466✔
524
                tif->tif_postdecode == _TIFFSwab32BitData)
814✔
525
                tif->tif_postdecode = _TIFFSwab16BitData;
81✔
526
            else if ((td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT ||
90,527✔
527
                      td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP) &&
89,153✔
528
                     td->td_bitspersample == 64 &&
3,101✔
529
                     tif->tif_postdecode == _TIFFSwab64BitData)
1,339✔
530
                tif->tif_postdecode = _TIFFSwab32BitData;
14✔
531
            break;
90,608✔
532
        case TIFFTAG_IMAGEDEPTH:
×
533
            td->td_imagedepth = (uint32_t)va_arg(ap, uint32_t);
×
534
            break;
×
535
        case TIFFTAG_SUBIFD:
78✔
536
            if ((tif->tif_flags & TIFF_INSUBIFD) == 0)
78✔
537
            {
538
                td->td_nsubifd = (uint16_t)va_arg(ap, uint16_vap);
78✔
539
                _TIFFsetLong8Array(tif, &td->td_subifd,
78✔
540
                                   (uint64_t *)va_arg(ap, uint64_t *),
78✔
541
                                   (uint32_t)td->td_nsubifd);
78✔
542
            }
543
            else
544
            {
545
                TIFFErrorExtR(tif, module, "%s: Sorry, cannot nest SubIFDs",
×
546
                              tif->tif_name);
547
                status = 0;
×
548
            }
549
            break;
78✔
550
        case TIFFTAG_YCBCRPOSITIONING:
11✔
551
            td->td_ycbcrpositioning = (uint16_t)va_arg(ap, uint16_vap);
11✔
552
            break;
11✔
553
        case TIFFTAG_YCBCRSUBSAMPLING:
2,187✔
554
            td->td_ycbcrsubsampling[0] = (uint16_t)va_arg(ap, uint16_vap);
2,187✔
555
            td->td_ycbcrsubsampling[1] = (uint16_t)va_arg(ap, uint16_vap);
2,187✔
556
            break;
2,187✔
557
        case TIFFTAG_TRANSFERFUNCTION:
19✔
558
        {
559
            uint32_t i;
560
            v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
19✔
561
            for (i = 0; i < v; i++)
76✔
562
                _TIFFsetShortArrayExt(tif, &td->td_transferfunction[i],
57✔
563
                                      va_arg(ap, uint16_t *),
57✔
564
                                      1U << td->td_bitspersample);
57✔
565
            break;
19✔
566
        }
567
        case TIFFTAG_REFERENCEBLACKWHITE:
1,866✔
568
            /* XXX should check for null range */
569
            _TIFFsetFloatArrayExt(tif, &td->td_refblackwhite,
1,866✔
570
                                  va_arg(ap, float *), 6);
1,866✔
571
            break;
1,866✔
572
        case TIFFTAG_INKNAMES:
×
573
        {
574
            v = (uint16_t)va_arg(ap, uint16_vap);
×
575
            s = va_arg(ap, char *);
×
576
            uint16_t ninksinstring;
577
            ninksinstring = countInkNamesString(tif, v, s);
×
578
            status = ninksinstring > 0;
×
579
            if (ninksinstring > 0)
×
580
            {
581
                _TIFFsetNString(tif, &td->td_inknames, s, v);
×
582
                td->td_inknameslen = v;
×
583
                /* Set NumberOfInks to the value ninksinstring */
584
                if (TIFFFieldSet(tif, FIELD_NUMBEROFINKS))
×
585
                {
586
                    if (td->td_numberofinks != ninksinstring)
×
587
                    {
588
                        TIFFErrorExtR(
×
589
                            tif, module,
590
                            "Warning %s; Tag %s:\n  Value %" PRIu16
591
                            " of NumberOfInks is different from the number of "
592
                            "inks %" PRIu16
593
                            ".\n  -> NumberOfInks value adapted to %" PRIu16 "",
594
                            tif->tif_name, fip->field_name, td->td_numberofinks,
×
595
                            ninksinstring, ninksinstring);
596
                        td->td_numberofinks = ninksinstring;
×
597
                    }
598
                }
599
                else
600
                {
601
                    td->td_numberofinks = ninksinstring;
×
602
                    TIFFSetFieldBit(tif, FIELD_NUMBEROFINKS);
×
603
                }
604
                if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
×
605
                {
606
                    if (td->td_numberofinks != td->td_samplesperpixel)
×
607
                    {
608
                        TIFFErrorExtR(tif, module,
×
609
                                      "Warning %s; Tag %s:\n  Value %" PRIu16
610
                                      " of NumberOfInks is different from the "
611
                                      "SamplesPerPixel value %" PRIu16 "",
612
                                      tif->tif_name, fip->field_name,
613
                                      td->td_numberofinks,
×
614
                                      td->td_samplesperpixel);
×
615
                    }
616
                }
617
            }
618
        }
619
        break;
×
620
        case TIFFTAG_NUMBEROFINKS:
×
621
            v = (uint16_t)va_arg(ap, uint16_vap);
×
622
            /* If InkNames already set also NumberOfInks is set accordingly and
623
             * should be equal */
624
            if (TIFFFieldSet(tif, FIELD_INKNAMES))
×
625
            {
626
                if (v != td->td_numberofinks)
×
627
                {
628
                    TIFFErrorExtR(
×
629
                        tif, module,
630
                        "Error %s; Tag %s:\n  It is not possible to set the "
631
                        "value %" PRIu32
632
                        " for NumberOfInks\n  which is different from the "
633
                        "number of inks in the InkNames tag (%" PRIu16 ")",
634
                        tif->tif_name, fip->field_name, v, td->td_numberofinks);
×
635
                    /* Do not set / overwrite number of inks already set by
636
                     * InkNames case accordingly. */
637
                    status = 0;
×
638
                }
639
            }
640
            else
641
            {
642
                td->td_numberofinks = (uint16_t)v;
×
643
                if (TIFFFieldSet(tif, FIELD_SAMPLESPERPIXEL))
×
644
                {
645
                    if (td->td_numberofinks != td->td_samplesperpixel)
×
646
                    {
647
                        TIFFErrorExtR(tif, module,
×
648
                                      "Warning %s; Tag %s:\n  Value %" PRIu32
649
                                      " of NumberOfInks is different from the "
650
                                      "SamplesPerPixel value %" PRIu16 "",
651
                                      tif->tif_name, fip->field_name, v,
652
                                      td->td_samplesperpixel);
×
653
                    }
654
                }
655
            }
656
            break;
×
657
        case TIFFTAG_PERSAMPLE:
×
658
            v = (uint16_t)va_arg(ap, uint16_vap);
×
659
            if (v == PERSAMPLE_MULTI)
×
660
                tif->tif_flags |= TIFF_PERSAMPLE;
×
661
            else
662
                tif->tif_flags &= ~TIFF_PERSAMPLE;
×
663
            break;
×
664
        default:
149,252✔
665
        {
666
            TIFFTagValue *tv;
667
            int tv_size, iCustom;
668

669
            /*
670
             * This can happen if multiple images are open with different
671
             * codecs which have private tags.  The global tag information
672
             * table may then have tags that are valid for one file but not
673
             * the other. If the client tries to set a tag that is not valid
674
             * for the image's codec then we'll arrive here.  This
675
             * happens, for example, when tiffcp is used to convert between
676
             * compression schemes and codec-specific tags are blindly copied.
677
             *
678
             * This also happens when a FIELD_IGNORE tag is written.
679
             */
680
            if (fip->field_bit == FIELD_IGNORE)
149,252✔
681
            {
682
                TIFFErrorExtR(
×
683
                    tif, module,
684
                    "%s: Ignored %stag \"%s\" (not supported by libtiff)",
685
                    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
686
                    fip->field_name);
687
                status = 0;
×
688
                break;
×
689
            }
690
            if (fip->field_bit != FIELD_CUSTOM)
149,252✔
691
            {
692
                TIFFErrorExtR(
×
693
                    tif, module,
694
                    "%s: Invalid %stag \"%s\" (not supported by codec)",
695
                    tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
696
                    fip->field_name);
697
                status = 0;
×
698
                break;
×
699
            }
700

701
            /*
702
             * Find the existing entry for this custom value.
703
             */
704
            tv = NULL;
149,252✔
705
            for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++)
389,074✔
706
            {
707
                if (td->td_customValues[iCustom].info->field_tag == tag)
241,894✔
708
                {
709
                    tv = td->td_customValues + iCustom;
2,072✔
710
                    if (tv->value != NULL)
2,072✔
711
                    {
712
                        _TIFFfreeExt(tif, tv->value);
2,072✔
713
                        tv->value = NULL;
2,072✔
714
                    }
715
                    break;
2,072✔
716
                }
717
            }
718

719
            /*
720
             * Grow the custom list if the entry was not found.
721
             */
722
            if (tv == NULL)
149,252✔
723
            {
724
                TIFFTagValue *new_customValues;
725

726
                new_customValues = (TIFFTagValue *)_TIFFreallocExt(
146,986✔
727
                    tif, td->td_customValues,
146,986✔
728
                    sizeof(TIFFTagValue) * (td->td_customValueCount + 1));
146,986✔
729
                if (!new_customValues)
147,261✔
730
                {
731
                    TIFFErrorExtR(tif, module,
23✔
732
                                  "%s: Failed to allocate space for list of "
733
                                  "custom values",
734
                                  tif->tif_name);
735
                    status = 0;
×
736
                    goto end;
×
737
                }
738

739
                td->td_customValueCount++;
147,238✔
740
                td->td_customValues = new_customValues;
147,238✔
741

742
                tv = td->td_customValues + (td->td_customValueCount - 1);
147,238✔
743
                tv->info = fip;
147,238✔
744
                tv->value = NULL;
147,238✔
745
                tv->count = 0;
147,238✔
746
            }
747

748
            /*
749
             * Set custom value ... save a copy of the custom tag value.
750
             */
751
            /*--: Rational2Double: For Rationals evaluate "set_get_field_type"
752
             * to determine internal storage size. */
753
            tv_size = TIFFFieldSetGetSize(fip);
149,504✔
754
            if (tv_size == 0)
149,096✔
755
            {
756
                status = 0;
32✔
757
                TIFFErrorExtR(tif, module, "%s: Bad field type %d for \"%s\"",
32✔
758
                              tif->tif_name, fip->field_type, fip->field_name);
32✔
759
                goto end;
×
760
            }
761

762
            if (fip->field_type == TIFF_ASCII)
149,064✔
763
            {
764
                uint32_t ma;
765
                const char *mb;
766
                if (fip->field_passcount)
40,682✔
767
                {
768
                    assert(fip->field_writecount == TIFF_VARIABLE2);
×
769
                    ma = (uint32_t)va_arg(ap, uint32_t);
×
770
                    mb = (const char *)va_arg(ap, const char *);
×
771
                }
772
                else
773
                {
774
                    mb = (const char *)va_arg(ap, const char *);
40,682✔
775
                    size_t len = strlen(mb) + 1;
40,691✔
776
                    if (len >= 0x80000000U)
40,691✔
777
                    {
778
                        status = 0;
29✔
779
                        TIFFErrorExtR(tif, module,
29✔
780
                                      "%s: Too long string value for \"%s\". "
781
                                      "Maximum supported is 2147483647 bytes",
782
                                      tif->tif_name, fip->field_name);
783
                        goto end;
×
784
                    }
785
                    ma = (uint32_t)len;
40,662✔
786
                }
787
                tv->count = ma;
40,662✔
788
                setByteArray(tif, &tv->value, mb, ma, 1);
40,662✔
789
            }
790
            else
791
            {
792
                if (fip->field_passcount)
108,382✔
793
                {
794
                    if (fip->field_writecount == TIFF_VARIABLE2)
108,261✔
795
                        tv->count = (uint32_t)va_arg(ap, uint32_t);
3,002✔
796
                    else
797
                        tv->count = (int)va_arg(ap, int);
105,259✔
798
                }
799
                else if (fip->field_writecount == TIFF_VARIABLE ||
121✔
800
                         fip->field_writecount == TIFF_VARIABLE2)
71✔
801
                    tv->count = 1;
50✔
802
                else if (fip->field_writecount == TIFF_SPP)
71✔
803
                    tv->count = td->td_samplesperpixel;
×
804
                else
805
                    tv->count = fip->field_writecount;
71✔
806

807
                if (tv->count == 0)
108,377✔
808
                {
809
                    TIFFWarningExtR(tif, module,
×
810
                                    "%s: Null count for \"%s\" (type "
811
                                    "%d, writecount %d, passcount %d)",
812
                                    tif->tif_name, fip->field_name,
813
                                    fip->field_type, fip->field_writecount,
×
814
                                    fip->field_passcount);
×
815
                    break;
×
816
                }
817

818
                tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
108,377✔
819
                                             "custom tag binary object");
820
                if (!tv->value)
108,507✔
821
                {
822
                    status = 0;
×
823
                    goto end;
×
824
                }
825

826
                if (fip->field_tag == TIFFTAG_DOTRANGE &&
108,507✔
827
                    strcmp(fip->field_name, "DotRange") == 0)
×
828
                {
×
829
                    /* TODO: This is an evil exception and should not have been
830
                       handled this way ... likely best if we move it into
831
                       the directory structure with an explicit field in
832
                       libtiff 4.1 and assign it a FIELD_ value */
833
                    uint16_t v2[2];
834
                    v2[0] = (uint16_t)va_arg(ap, int);
×
835
                    v2[1] = (uint16_t)va_arg(ap, int);
×
836
                    _TIFFmemcpy(tv->value, &v2, 4);
×
837
                }
838

839
                else if (fip->field_passcount ||
108,507✔
840
                         fip->field_writecount == TIFF_VARIABLE ||
71✔
841
                         fip->field_writecount == TIFF_VARIABLE2 ||
71✔
842
                         fip->field_writecount == TIFF_SPP || tv->count > 1)
71✔
843
                {
844
                    /*--: Rational2Double: For Rationals tv_size is set above to
845
                     * 4 or 8 according to fip->set_get_field_type! */
846
                    _TIFFmemcpy(tv->value, va_arg(ap, void *),
108,493✔
847
                                tv->count * tv_size);
108,499✔
848
                    /* Test here for too big values for LONG8, SLONG8 in
849
                     * ClassicTIFF and delete custom field from custom list */
850
                    if (!(tif->tif_flags & TIFF_BIGTIFF))
108,438✔
851
                    {
852
                        if (tv->info->field_type == TIFF_LONG8)
108,319✔
853
                        {
854
                            uint64_t *pui64 = (uint64_t *)tv->value;
×
855
                            for (int i = 0; i < tv->count; i++)
×
856
                            {
857
                                if (pui64[i] > 0xffffffffu)
×
858
                                {
859
                                    TIFFErrorExtR(
×
860
                                        tif, module,
861
                                        "%s: Bad LONG8 value %" PRIu64
862
                                        " at %d. array position for \"%s\" tag "
863
                                        "%d in ClassicTIFF. Tag won't be "
864
                                        "written to file",
865
                                        tif->tif_name, pui64[i], i,
×
866
                                        fip->field_name, tag);
867
                                    goto badvalueifd8long8;
×
868
                                }
869
                            }
870
                        }
871
                        else if (tv->info->field_type == TIFF_SLONG8)
108,319✔
872
                        {
873
                            int64_t *pi64 = (int64_t *)tv->value;
×
874
                            for (int i = 0; i < tv->count; i++)
×
875
                            {
876
                                if (pi64[i] > 2147483647 ||
×
877
                                    pi64[i] < (-2147483647 - 1))
×
878
                                {
879
                                    TIFFErrorExtR(
×
880
                                        tif, module,
881
                                        "%s: Bad SLONG8 value %" PRIi64
882
                                        " at %d. array position for \"%s\" tag "
883
                                        "%d in ClassicTIFF. Tag won't be "
884
                                        "written to file",
885
                                        tif->tif_name, pi64[i], i,
×
886
                                        fip->field_name, tag);
887
                                    goto badvalueifd8long8;
×
888
                                }
889
                            }
890
                        }
891
                    }
892
                }
893
                else
894
                {
895
                    char *val = (char *)tv->value;
8✔
896
                    assert(tv->count == 1);
8✔
897

898
                    switch (fip->field_type)
8✔
899
                    {
900
                        case TIFF_BYTE:
×
901
                        case TIFF_UNDEFINED:
902
                        {
903
                            uint8_t v2 = (uint8_t)va_arg(ap, int);
×
904
                            _TIFFmemcpy(val, &v2, tv_size);
×
905
                        }
906
                        break;
×
907
                        case TIFF_SBYTE:
×
908
                        {
909
                            int8_t v2 = (int8_t)va_arg(ap, int);
×
910
                            _TIFFmemcpy(val, &v2, tv_size);
×
911
                        }
912
                        break;
×
913
                        case TIFF_SHORT:
×
914
                        {
915
                            uint16_t v2 = (uint16_t)va_arg(ap, int);
×
916
                            _TIFFmemcpy(val, &v2, tv_size);
×
917
                        }
918
                        break;
×
919
                        case TIFF_SSHORT:
×
920
                        {
921
                            int16_t v2 = (int16_t)va_arg(ap, int);
×
922
                            _TIFFmemcpy(val, &v2, tv_size);
×
923
                        }
924
                        break;
×
925
                        case TIFF_LONG:
×
926
                        case TIFF_IFD:
927
                        {
928
                            uint32_t v2 = va_arg(ap, uint32_t);
×
929
                            _TIFFmemcpy(val, &v2, tv_size);
×
930
                        }
931
                        break;
×
932
                        case TIFF_SLONG:
×
933
                        {
934
                            int32_t v2 = va_arg(ap, int32_t);
×
935
                            _TIFFmemcpy(val, &v2, tv_size);
×
936
                        }
937
                        break;
×
938
                        case TIFF_LONG8:
8✔
939
                        case TIFF_IFD8:
940
                        {
941
                            uint64_t v2 = va_arg(ap, uint64_t);
8✔
942
                            _TIFFmemcpy(val, &v2, tv_size);
8✔
943
                            /* Test here for too big values for ClassicTIFF and
944
                             * delete custom field from custom list */
945
                            if (!(tif->tif_flags & TIFF_BIGTIFF) &&
8✔
946
                                (v2 > 0xffffffffu))
8✔
947
                            {
948
                                TIFFErrorExtR(
×
949
                                    tif, module,
950
                                    "%s: Bad LONG8 or IFD8 value %" PRIu64
951
                                    " for \"%s\" tag %d in ClassicTIFF. Tag "
952
                                    "won't be written to file",
953
                                    tif->tif_name, v2, fip->field_name, tag);
954
                                goto badvalueifd8long8;
×
955
                            }
956
                        }
957
                        break;
8✔
958
                        case TIFF_SLONG8:
×
959
                        {
960
                            int64_t v2 = va_arg(ap, int64_t);
×
961
                            _TIFFmemcpy(val, &v2, tv_size);
×
962
                            /* Test here for too big values for ClassicTIFF and
963
                             * delete custom field from custom list */
964
                            if (!(tif->tif_flags & TIFF_BIGTIFF) &&
×
965
                                ((v2 > 2147483647) || (v2 < (-2147483647 - 1))))
×
966
                            {
967
                                TIFFErrorExtR(
×
968
                                    tif, module,
969
                                    "%s: Bad SLONG8 value %" PRIi64
970
                                    " for \"%s\" tag %d in ClassicTIFF. Tag "
971
                                    "won't be written to file",
972
                                    tif->tif_name, v2, fip->field_name, tag);
973
                                goto badvalueifd8long8;
×
974
                            }
975
                        }
976
                        break;
×
977
                        case TIFF_RATIONAL:
×
978
                        case TIFF_SRATIONAL:
979
                            /*-- Rational2Double: For Rationals tv_size is set
980
                             * above to 4 or 8 according to
981
                             * fip->set_get_field_type!
982
                             */
983
                            {
984
                                if (tv_size == 8)
×
985
                                {
986
                                    double v2 = va_arg(ap, double);
×
987
                                    _TIFFmemcpy(val, &v2, tv_size);
×
988
                                }
989
                                else
990
                                {
991
                                    /*-- default should be tv_size == 4 */
992
                                    float v3 = (float)va_arg(ap, double);
×
993
                                    _TIFFmemcpy(val, &v3, tv_size);
×
994
                                    /*-- ToDo: After Testing, this should be
995
                                     * removed and tv_size==4 should be set as
996
                                     * default. */
997
                                    if (tv_size != 4)
×
998
                                    {
999
                                        TIFFErrorExtR(tif, module,
×
1000
                                                      "Rational2Double: "
1001
                                                      ".set_get_field_type "
1002
                                                      "in not 4 but %d",
1003
                                                      tv_size);
1004
                                    }
1005
                                }
1006
                            }
1007
                            break;
×
1008
                        case TIFF_FLOAT:
×
1009
                        {
1010
                            float v2 =
×
1011
                                _TIFFClampDoubleToFloat(va_arg(ap, double));
×
1012
                            _TIFFmemcpy(val, &v2, tv_size);
×
1013
                        }
1014
                        break;
×
1015
                        case TIFF_DOUBLE:
×
1016
                        {
1017
                            double v2 = va_arg(ap, double);
×
1018
                            _TIFFmemcpy(val, &v2, tv_size);
×
1019
                        }
1020
                        break;
×
1021
                        default:
×
1022
                            _TIFFmemset(val, 0, tv_size);
×
1023
                            status = 0;
×
1024
                            break;
×
1025
                    }
1026
                }
1027
            }
1028
        }
1029
    }
1030
    if (status)
1,188,650✔
1031
    {
1032
        const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1,188,650✔
1033
        if (fip2)
1,188,980✔
1034
            TIFFSetFieldBit(tif, fip2->field_bit);
1,189,100✔
1035
        tif->tif_flags |= TIFF_DIRTYDIRECT;
1,188,980✔
1036
    }
1037

1038
end:
×
1039
    va_end(ap);
1,188,980✔
1040
    return (status);
1,188,980✔
1041
badvalue:
29✔
1042
{
1043
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
29✔
1044
    TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
×
1045
                  tif->tif_name, v, fip2 ? fip2->field_name : "Unknown");
1046
    va_end(ap);
×
1047
}
1048
    return (0);
×
1049
badvalue32:
1✔
1050
{
1051
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
1✔
1052
    TIFFErrorExtR(tif, module, "%s: Bad value %" PRIu32 " for \"%s\" tag",
1✔
1053
                  tif->tif_name, v32, fip2 ? fip2->field_name : "Unknown");
1054
    va_end(ap);
1✔
1055
}
1056
    return (0);
1✔
1057
badvaluedouble:
×
1058
{
1059
    const TIFFField *fip2 = TIFFFieldWithTag(tif, tag);
×
1060
    TIFFErrorExtR(tif, module, "%s: Bad value %f for \"%s\" tag", tif->tif_name,
×
1061
                  dblval, fip2 ? fip2->field_name : "Unknown");
1062
    va_end(ap);
×
1063
}
1064
    return (0);
×
1065
badvalueifd8long8:
×
1066
{
1067
    /* Error message issued already above. */
1068
    TIFFTagValue *tv2 = NULL;
×
1069
    int iCustom2, iC2;
1070
    /* Find the existing entry for this custom value. */
1071
    for (iCustom2 = 0; iCustom2 < td->td_customValueCount; iCustom2++)
×
1072
    {
1073
        if (td->td_customValues[iCustom2].info->field_tag == tag)
×
1074
        {
1075
            tv2 = td->td_customValues + (iCustom2);
×
1076
            break;
×
1077
        }
1078
    }
1079
    if (tv2 != NULL)
×
1080
    {
1081
        /* Remove custom field from custom list */
1082
        if (tv2->value != NULL)
×
1083
        {
1084
            _TIFFfreeExt(tif, tv2->value);
×
1085
            tv2->value = NULL;
×
1086
        }
1087
        /* Shorten list and close gap in customValues list.
1088
         * Re-allocation of td_customValues not necessary here. */
1089
        td->td_customValueCount--;
×
1090
        for (iC2 = iCustom2; iC2 < td->td_customValueCount; iC2++)
×
1091
        {
1092
            td->td_customValues[iC2] = td->td_customValues[iC2 + 1];
×
1093
        }
1094
    }
1095
    else
1096
    {
1097
        assert(0);
×
1098
    }
1099
    va_end(ap);
×
1100
}
1101
    return (0);
×
1102
} /*-- _TIFFVSetField() --*/
1103

1104
/*
1105
 * Return 1/0 according to whether or not
1106
 * it is permissible to set the tag's value.
1107
 * Note that we allow ImageLength to be changed
1108
 * so that we can append and extend to images.
1109
 * Any other tag may not be altered once writing
1110
 * has commenced, unless its value has no effect
1111
 * on the format of the data that is written.
1112
 */
1113
static int OkToChangeTag(TIFF *tif, uint32_t tag)
1,213,570✔
1114
{
1115
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1,213,570✔
1116
    if (!fip)
1,214,220✔
1117
    { /* unknown tag */
1118
        TIFFErrorExtR(tif, "TIFFSetField", "%s: Unknown %stag %" PRIu32,
×
1119
                      tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
1120
        return (0);
×
1121
    }
1122
    if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
1,214,220✔
1123
        !fip->field_oktochange)
802✔
1124
    {
1125
        /*
1126
         * Consult info table to see if tag can be changed
1127
         * after we've started writing.  We only allow changes
1128
         * to those tags that don't/shouldn't affect the
1129
         * compression and/or format of the data.
1130
         */
1131
        TIFFErrorExtR(tif, "TIFFSetField",
2✔
1132
                      "%s: Cannot modify tag \"%s\" while writing",
1133
                      tif->tif_name, fip->field_name);
1134
        return (0);
2✔
1135
    }
1136
    return (1);
1,214,210✔
1137
}
1138

1139
/*
1140
 * Record the value of a field in the
1141
 * internal directory structure.  The
1142
 * field will be written to the file
1143
 * when/if the directory structure is
1144
 * updated.
1145
 */
1146
int TIFFSetField(TIFF *tif, uint32_t tag, ...)
1,213,790✔
1147
{
1148
    va_list ap;
1149
    int status;
1150

1151
    va_start(ap, tag);
1,213,790✔
1152
    status = TIFFVSetField(tif, tag, ap);
1,213,790✔
1153
    va_end(ap);
1,213,470✔
1154
    return (status);
1,213,470✔
1155
}
1156

1157
/*
1158
 * Clear the contents of the field in the internal structure.
1159
 */
1160
int TIFFUnsetField(TIFF *tif, uint32_t tag)
5,132✔
1161
{
1162
    const TIFFField *fip = TIFFFieldWithTag(tif, tag);
5,132✔
1163
    TIFFDirectory *td = &tif->tif_dir;
5,132✔
1164

1165
    if (!fip)
5,132✔
1166
        return 0;
×
1167

1168
    if (fip->field_bit != FIELD_CUSTOM)
5,132✔
1169
        TIFFClrFieldBit(tif, fip->field_bit);
5✔
1170
    else
1171
    {
1172
        TIFFTagValue *tv = NULL;
5,127✔
1173
        int i;
1174

1175
        for (i = 0; i < td->td_customValueCount; i++)
5,558✔
1176
        {
1177

1178
            tv = td->td_customValues + i;
543✔
1179
            if (tv->info->field_tag == tag)
543✔
1180
                break;
112✔
1181
        }
1182

1183
        if (i < td->td_customValueCount)
5,127✔
1184
        {
1185
            _TIFFfreeExt(tif, tv->value);
112✔
1186
            for (; i < td->td_customValueCount - 1; i++)
263✔
1187
            {
1188
                td->td_customValues[i] = td->td_customValues[i + 1];
151✔
1189
            }
1190
            td->td_customValueCount--;
112✔
1191
        }
1192
    }
1193

1194
    tif->tif_flags |= TIFF_DIRTYDIRECT;
5,132✔
1195

1196
    return (1);
5,132✔
1197
}
1198

1199
/*
1200
 * Like TIFFSetField, but taking a varargs
1201
 * parameter list.  This routine is useful
1202
 * for building higher-level interfaces on
1203
 * top of the library.
1204
 */
1205
int TIFFVSetField(TIFF *tif, uint32_t tag, va_list ap)
1,213,680✔
1206
{
1207
    return OkToChangeTag(tif, tag)
1,213,680✔
1208
               ? (*tif->tif_tagmethods.vsetfield)(tif, tag, ap)
1,214,150✔
1209
               : 0;
2,427,660✔
1210
}
1211

1212
static int _TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
1,969,000✔
1213
{
1214
    TIFFDirectory *td = &tif->tif_dir;
1,969,000✔
1215
    int ret_val = 1;
1,969,000✔
1216
    uint32_t standard_tag = tag;
1,969,000✔
1217
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
1,969,000✔
1218
    if (fip == NULL) /* cannot happen since TIFFGetField() already checks it */
1,967,730✔
1219
        return 0;
×
1220

1221
    /*
1222
     * We want to force the custom code to be used for custom
1223
     * fields even if the tag happens to match a well known
1224
     * one - important for reinterpreted handling of standard
1225
     * tag values in custom directories (i.e. EXIF)
1226
     */
1227
    if (fip->field_bit == FIELD_CUSTOM)
1,967,730✔
1228
    {
1229
        standard_tag = 0;
381,995✔
1230
    }
1231

1232
    switch (standard_tag)
1,967,730✔
1233
    {
1234
        case TIFFTAG_SUBFILETYPE:
1,421✔
1235
            *va_arg(ap, uint32_t *) = td->td_subfiletype;
1,421✔
1236
            break;
1,421✔
1237
        case TIFFTAG_IMAGEWIDTH:
50,564✔
1238
            *va_arg(ap, uint32_t *) = td->td_imagewidth;
50,564✔
1239
            break;
50,652✔
1240
        case TIFFTAG_IMAGELENGTH:
50,599✔
1241
            *va_arg(ap, uint32_t *) = td->td_imagelength;
50,599✔
1242
            break;
50,581✔
1243
        case TIFFTAG_BITSPERSAMPLE:
33,626✔
1244
            *va_arg(ap, uint16_t *) = td->td_bitspersample;
33,626✔
1245
            break;
33,614✔
1246
        case TIFFTAG_COMPRESSION:
57,629✔
1247
            *va_arg(ap, uint16_t *) = td->td_compression;
57,629✔
1248
            break;
57,575✔
1249
        case TIFFTAG_PHOTOMETRIC:
41,475✔
1250
            *va_arg(ap, uint16_t *) = td->td_photometric;
41,475✔
1251
            break;
41,451✔
1252
        case TIFFTAG_THRESHHOLDING:
×
1253
            *va_arg(ap, uint16_t *) = td->td_threshholding;
×
1254
            break;
×
1255
        case TIFFTAG_FILLORDER:
×
1256
            *va_arg(ap, uint16_t *) = td->td_fillorder;
×
1257
            break;
×
1258
        case TIFFTAG_ORIENTATION:
16✔
1259
            *va_arg(ap, uint16_t *) = td->td_orientation;
16✔
1260
            break;
16✔
1261
        case TIFFTAG_SAMPLESPERPIXEL:
28,553✔
1262
            *va_arg(ap, uint16_t *) = td->td_samplesperpixel;
28,553✔
1263
            break;
28,548✔
1264
        case TIFFTAG_ROWSPERSTRIP:
28,459✔
1265
            *va_arg(ap, uint32_t *) = td->td_rowsperstrip;
28,459✔
1266
            break;
28,432✔
1267
        case TIFFTAG_MINSAMPLEVALUE:
5✔
1268
            *va_arg(ap, uint16_t *) = td->td_minsamplevalue;
5✔
1269
            break;
5✔
1270
        case TIFFTAG_MAXSAMPLEVALUE:
5✔
1271
            *va_arg(ap, uint16_t *) = td->td_maxsamplevalue;
5✔
1272
            break;
5✔
1273
        case TIFFTAG_SMINSAMPLEVALUE:
×
1274
            if (tif->tif_flags & TIFF_PERSAMPLE)
×
1275
                *va_arg(ap, double **) = td->td_sminsamplevalue;
×
1276
            else
1277
            {
1278
                /* libtiff historically treats this as a single value. */
1279
                uint16_t i;
1280
                double v = td->td_sminsamplevalue[0];
×
1281
                for (i = 1; i < td->td_samplesperpixel; ++i)
×
1282
                    if (td->td_sminsamplevalue[i] < v)
×
1283
                        v = td->td_sminsamplevalue[i];
×
1284
                *va_arg(ap, double *) = v;
×
1285
            }
1286
            break;
×
1287
        case TIFFTAG_SMAXSAMPLEVALUE:
×
1288
            if (tif->tif_flags & TIFF_PERSAMPLE)
×
1289
                *va_arg(ap, double **) = td->td_smaxsamplevalue;
×
1290
            else
1291
            {
1292
                /* libtiff historically treats this as a single value. */
1293
                uint16_t i;
1294
                double v = td->td_smaxsamplevalue[0];
×
1295
                for (i = 1; i < td->td_samplesperpixel; ++i)
×
1296
                    if (td->td_smaxsamplevalue[i] > v)
×
1297
                        v = td->td_smaxsamplevalue[i];
×
1298
                *va_arg(ap, double *) = v;
×
1299
            }
1300
            break;
×
1301
        case TIFFTAG_XRESOLUTION:
87✔
1302
            *va_arg(ap, float *) = td->td_xresolution;
87✔
1303
            break;
87✔
1304
        case TIFFTAG_YRESOLUTION:
86✔
1305
            *va_arg(ap, float *) = td->td_yresolution;
86✔
1306
            break;
86✔
1307
        case TIFFTAG_PLANARCONFIG:
34,447✔
1308
            *va_arg(ap, uint16_t *) = td->td_planarconfig;
34,447✔
1309
            break;
34,517✔
1310
        case TIFFTAG_XPOSITION:
×
1311
            *va_arg(ap, float *) = td->td_xposition;
×
1312
            break;
×
1313
        case TIFFTAG_YPOSITION:
×
1314
            *va_arg(ap, float *) = td->td_yposition;
×
1315
            break;
×
1316
        case TIFFTAG_RESOLUTIONUNIT:
89✔
1317
            *va_arg(ap, uint16_t *) = td->td_resolutionunit;
89✔
1318
            break;
89✔
1319
        case TIFFTAG_PAGENUMBER:
×
1320
            *va_arg(ap, uint16_t *) = td->td_pagenumber[0];
×
1321
            *va_arg(ap, uint16_t *) = td->td_pagenumber[1];
×
1322
            break;
×
1323
        case TIFFTAG_HALFTONEHINTS:
×
1324
            *va_arg(ap, uint16_t *) = td->td_halftonehints[0];
×
1325
            *va_arg(ap, uint16_t *) = td->td_halftonehints[1];
×
1326
            break;
×
1327
        case TIFFTAG_COLORMAP:
160✔
1328
            *va_arg(ap, const uint16_t **) = td->td_colormap[0];
160✔
1329
            *va_arg(ap, const uint16_t **) = td->td_colormap[1];
160✔
1330
            *va_arg(ap, const uint16_t **) = td->td_colormap[2];
160✔
1331
            break;
160✔
1332
        case TIFFTAG_STRIPOFFSETS:
128,570✔
1333
        case TIFFTAG_TILEOFFSETS:
1334
            _TIFFFillStriles(tif);
128,570✔
1335
            *va_arg(ap, const uint64_t **) = td->td_stripoffset_p;
128,568✔
1336
            if (td->td_stripoffset_p == NULL)
128,568✔
1337
                ret_val = 0;
×
1338
            break;
128,568✔
1339
        case TIFFTAG_STRIPBYTECOUNTS:
156,043✔
1340
        case TIFFTAG_TILEBYTECOUNTS:
1341
            _TIFFFillStriles(tif);
156,043✔
1342
            *va_arg(ap, const uint64_t **) = td->td_stripbytecount_p;
156,042✔
1343
            if (td->td_stripbytecount_p == NULL)
156,042✔
1344
                ret_val = 0;
×
1345
            break;
156,042✔
1346
        case TIFFTAG_MATTEING:
×
1347
            *va_arg(ap, uint16_t *) =
×
1348
                (td->td_extrasamples == 1 &&
×
1349
                 td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
×
1350
            break;
×
1351
        case TIFFTAG_EXTRASAMPLES:
928,951✔
1352
            *va_arg(ap, uint16_t *) = td->td_extrasamples;
928,951✔
1353
            *va_arg(ap, const uint16_t **) = td->td_sampleinfo;
928,951✔
1354
            break;
928,951✔
1355
        case TIFFTAG_TILEWIDTH:
4,063✔
1356
            *va_arg(ap, uint32_t *) = td->td_tilewidth;
4,063✔
1357
            break;
4,063✔
1358
        case TIFFTAG_TILELENGTH:
4,063✔
1359
            *va_arg(ap, uint32_t *) = td->td_tilelength;
4,063✔
1360
            break;
4,063✔
1361
        case TIFFTAG_TILEDEPTH:
×
1362
            *va_arg(ap, uint32_t *) = td->td_tiledepth;
×
1363
            break;
×
1364
        case TIFFTAG_DATATYPE:
×
1365
            switch (td->td_sampleformat)
×
1366
            {
1367
                case SAMPLEFORMAT_UINT:
×
1368
                    *va_arg(ap, uint16_t *) = DATATYPE_UINT;
×
1369
                    break;
×
1370
                case SAMPLEFORMAT_INT:
×
1371
                    *va_arg(ap, uint16_t *) = DATATYPE_INT;
×
1372
                    break;
×
1373
                case SAMPLEFORMAT_IEEEFP:
×
1374
                    *va_arg(ap, uint16_t *) = DATATYPE_IEEEFP;
×
1375
                    break;
×
1376
                case SAMPLEFORMAT_VOID:
×
1377
                    *va_arg(ap, uint16_t *) = DATATYPE_VOID;
×
1378
                    break;
×
1379
            }
1380
            break;
×
1381
        case TIFFTAG_SAMPLEFORMAT:
32,383✔
1382
            *va_arg(ap, uint16_t *) = td->td_sampleformat;
32,383✔
1383
            break;
32,295✔
1384
        case TIFFTAG_IMAGEDEPTH:
×
1385
            *va_arg(ap, uint32_t *) = td->td_imagedepth;
×
1386
            break;
×
1387
        case TIFFTAG_SUBIFD:
21✔
1388
            *va_arg(ap, uint16_t *) = td->td_nsubifd;
21✔
1389
            *va_arg(ap, const uint64_t **) = td->td_subifd;
21✔
1390
            break;
21✔
1391
        case TIFFTAG_YCBCRPOSITIONING:
×
1392
            *va_arg(ap, uint16_t *) = td->td_ycbcrpositioning;
×
1393
            break;
×
1394
        case TIFFTAG_YCBCRSUBSAMPLING:
3,701✔
1395
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[0];
3,701✔
1396
            *va_arg(ap, uint16_t *) = td->td_ycbcrsubsampling[1];
3,701✔
1397
            break;
3,949✔
1398
        case TIFFTAG_TRANSFERFUNCTION:
6✔
1399
            *va_arg(ap, const uint16_t **) = td->td_transferfunction[0];
6✔
1400
            if (td->td_samplesperpixel - td->td_extrasamples > 1)
6✔
1401
            {
1402
                *va_arg(ap, const uint16_t **) = td->td_transferfunction[1];
6✔
1403
                *va_arg(ap, const uint16_t **) = td->td_transferfunction[2];
6✔
1404
            }
1405
            else
1406
            {
1407
                *va_arg(ap, const uint16_t **) = NULL;
×
1408
                *va_arg(ap, const uint16_t **) = NULL;
×
1409
            }
1410
            break;
6✔
1411
        case TIFFTAG_REFERENCEBLACKWHITE:
773✔
1412
            *va_arg(ap, const float **) = td->td_refblackwhite;
773✔
1413
            break;
773✔
1414
        case TIFFTAG_INKNAMES:
×
1415
            *va_arg(ap, const char **) = td->td_inknames;
×
1416
            break;
×
1417
        case TIFFTAG_NUMBEROFINKS:
×
1418
            *va_arg(ap, uint16_t *) = td->td_numberofinks;
×
1419
            break;
×
1420
        default:
381,937✔
1421
        {
1422
            int i;
1423

1424
            /*
1425
             * This can happen if multiple images are open
1426
             * with different codecs which have private
1427
             * tags.  The global tag information table may
1428
             * then have tags that are valid for one file
1429
             * but not the other. If the client tries to
1430
             * get a tag that is not valid for the image's
1431
             * codec then we'll arrive here.
1432
             */
1433
            if (fip->field_bit != FIELD_CUSTOM)
381,937✔
1434
            {
1435
                TIFFErrorExtR(tif, "_TIFFVGetField",
×
1436
                              "%s: Invalid %stag \"%s\" "
1437
                              "(not supported by codec)",
1438
                              tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
1439
                              fip->field_name);
1440
                ret_val = 0;
×
1441
                break;
×
1442
            }
1443

1444
            /*
1445
             * Do we have a custom value?
1446
             */
1447
            ret_val = 0;
381,937✔
1448
            for (i = 0; i < td->td_customValueCount; i++)
1,619,340✔
1449
            {
1450
                TIFFTagValue *tv = td->td_customValues + i;
1,320,110✔
1451

1452
                if (tv->info->field_tag != tag)
1,320,110✔
1453
                    continue;
1,237,400✔
1454

1455
                if (fip->field_passcount)
82,708✔
1456
                {
1457
                    if (fip->field_readcount == TIFF_VARIABLE2)
59,897✔
1458
                        *va_arg(ap, uint32_t *) = (uint32_t)tv->count;
392✔
1459
                    else /* Assume TIFF_VARIABLE */
1460
                        *va_arg(ap, uint16_t *) = (uint16_t)tv->count;
59,505✔
1461
                    *va_arg(ap, const void **) = tv->value;
59,897✔
1462
                    ret_val = 1;
59,895✔
1463
                }
1464
                else if (fip->field_tag == TIFFTAG_DOTRANGE &&
22,811✔
1465
                         strcmp(fip->field_name, "DotRange") == 0)
×
1466
                {
1467
                    /* TODO: This is an evil exception and should not have been
1468
                       handled this way ... likely best if we move it into
1469
                       the directory structure with an explicit field in
1470
                       libtiff 4.1 and assign it a FIELD_ value */
1471
                    *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[0];
×
1472
                    *va_arg(ap, uint16_t *) = ((uint16_t *)tv->value)[1];
×
1473
                    ret_val = 1;
×
1474
                }
1475
                else
1476
                {
1477
                    if (fip->field_type == TIFF_ASCII ||
22,811✔
1478
                        fip->field_readcount == TIFF_VARIABLE ||
39✔
1479
                        fip->field_readcount == TIFF_VARIABLE2 ||
39✔
1480
                        fip->field_readcount == TIFF_SPP || tv->count > 1)
39✔
1481
                    {
1482
                        *va_arg(ap, void **) = tv->value;
22,805✔
1483
                        ret_val = 1;
22,805✔
1484
                    }
1485
                    else
1486
                    {
1487
                        char *val = (char *)tv->value;
6✔
1488
                        assert(tv->count == 1);
6✔
1489
                        switch (fip->field_type)
6✔
1490
                        {
1491
                            case TIFF_BYTE:
×
1492
                            case TIFF_UNDEFINED:
1493
                                *va_arg(ap, uint8_t *) = *(uint8_t *)val;
×
1494
                                ret_val = 1;
×
1495
                                break;
×
1496
                            case TIFF_SBYTE:
×
1497
                                *va_arg(ap, int8_t *) = *(int8_t *)val;
×
1498
                                ret_val = 1;
×
1499
                                break;
×
1500
                            case TIFF_SHORT:
×
1501
                                *va_arg(ap, uint16_t *) = *(uint16_t *)val;
×
1502
                                ret_val = 1;
×
1503
                                break;
×
1504
                            case TIFF_SSHORT:
×
1505
                                *va_arg(ap, int16_t *) = *(int16_t *)val;
×
1506
                                ret_val = 1;
×
1507
                                break;
×
1508
                            case TIFF_LONG:
×
1509
                            case TIFF_IFD:
1510
                                *va_arg(ap, uint32_t *) = *(uint32_t *)val;
×
1511
                                ret_val = 1;
×
1512
                                break;
×
1513
                            case TIFF_SLONG:
×
1514
                                *va_arg(ap, int32_t *) = *(int32_t *)val;
×
1515
                                ret_val = 1;
×
1516
                                break;
×
1517
                            case TIFF_LONG8:
6✔
1518
                            case TIFF_IFD8:
1519
                                *va_arg(ap, uint64_t *) = *(uint64_t *)val;
6✔
1520
                                ret_val = 1;
6✔
1521
                                break;
6✔
1522
                            case TIFF_SLONG8:
×
1523
                                *va_arg(ap, int64_t *) = *(int64_t *)val;
×
1524
                                ret_val = 1;
×
1525
                                break;
×
1526
                            case TIFF_RATIONAL:
×
1527
                            case TIFF_SRATIONAL:
1528
                            {
1529
                                /*-- Rational2Double: For Rationals evaluate
1530
                                 * "set_get_field_type" to determine internal
1531
                                 * storage size and return value size. */
1532
                                int tv_size = TIFFFieldSetGetSize(fip);
×
1533
                                if (tv_size == 8)
×
1534
                                {
1535
                                    *va_arg(ap, double *) = *(double *)val;
×
1536
                                    ret_val = 1;
×
1537
                                }
1538
                                else
1539
                                {
1540
                                    /*-- default should be tv_size == 4  */
1541
                                    *va_arg(ap, float *) = *(float *)val;
×
1542
                                    ret_val = 1;
×
1543
                                    /*-- ToDo: After Testing, this should be
1544
                                     * removed and tv_size==4 should be set as
1545
                                     * default. */
1546
                                    if (tv_size != 4)
×
1547
                                    {
1548
                                        TIFFErrorExtR(tif, "_TIFFVGetField",
×
1549
                                                      "Rational2Double: "
1550
                                                      ".set_get_field_type "
1551
                                                      "in not 4 but %d",
1552
                                                      tv_size);
1553
                                    }
1554
                                }
1555
                            }
1556
                            break;
×
1557
                            case TIFF_FLOAT:
×
1558
                                *va_arg(ap, float *) = *(float *)val;
×
1559
                                ret_val = 1;
×
1560
                                break;
×
1561
                            case TIFF_DOUBLE:
×
1562
                                *va_arg(ap, double *) = *(double *)val;
×
1563
                                ret_val = 1;
×
1564
                                break;
×
1565
                            default:
×
1566
                                ret_val = 0;
×
1567
                                break;
×
1568
                        }
1569
                    }
1570
                }
1571
                break;
82,705✔
1572
            }
1573
        }
1574
    }
1575
    return (ret_val);
1,967,900✔
1576
}
1577

1578
/*
1579
 * Return the value of a field in the
1580
 * internal directory structure.
1581
 */
1582
int TIFFGetField(TIFF *tif, uint32_t tag, ...)
2,386,850✔
1583
{
1584
    int status;
1585
    va_list ap;
1586

1587
    va_start(ap, tag);
2,386,850✔
1588
    status = TIFFVGetField(tif, tag, ap);
2,386,850✔
1589
    va_end(ap);
2,386,560✔
1590
    return (status);
2,386,560✔
1591
}
1592

1593
/*
1594
 * Like TIFFGetField, but taking a varargs
1595
 * parameter list.  This routine is useful
1596
 * for building higher-level interfaces on
1597
 * top of the library.
1598
 */
1599
int TIFFVGetField(TIFF *tif, uint32_t tag, va_list ap)
2,397,430✔
1600
{
1601
    const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
2,397,430✔
1602
    return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit))
2,400,730✔
1603
                ? (*tif->tif_tagmethods.vgetfield)(tif, tag, ap)
2,001,000✔
1604
                : 0);
4,799,970✔
1605
}
1606

1607
#define CleanupField(member)                                                   \
1608
    {                                                                          \
1609
        if (td->member)                                                        \
1610
        {                                                                      \
1611
            _TIFFfreeExt(tif, td->member);                                     \
1612
            td->member = 0;                                                    \
1613
        }                                                                      \
1614
    }
1615

1616
/*
1617
 * Release storage associated with a directory.
1618
 */
1619
void TIFFFreeDirectory(TIFF *tif)
204,503✔
1620
{
1621
    TIFFDirectory *td = &tif->tif_dir;
204,503✔
1622
    int i;
1623

1624
    (*tif->tif_cleanup)(tif);
204,503✔
1625
    _TIFFmemset(td->td_fieldsset, 0, sizeof(td->td_fieldsset));
204,477✔
1626
    CleanupField(td_sminsamplevalue);
204,348✔
1627
    CleanupField(td_smaxsamplevalue);
204,348✔
1628
    CleanupField(td_colormap[0]);
204,348✔
1629
    CleanupField(td_colormap[1]);
204,348✔
1630
    CleanupField(td_colormap[2]);
204,348✔
1631
    CleanupField(td_sampleinfo);
204,348✔
1632
    CleanupField(td_subifd);
204,349✔
1633
    CleanupField(td_inknames);
204,349✔
1634
    CleanupField(td_refblackwhite);
204,349✔
1635
    CleanupField(td_transferfunction[0]);
204,349✔
1636
    CleanupField(td_transferfunction[1]);
204,349✔
1637
    CleanupField(td_transferfunction[2]);
204,349✔
1638
    CleanupField(td_stripoffset_p);
204,349✔
1639
    CleanupField(td_stripbytecount_p);
204,351✔
1640
    td->td_stripoffsetbyteallocsize = 0;
204,353✔
1641
    TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
204,353✔
1642
    TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
204,353✔
1643

1644
    /* Cleanup custom tag values */
1645
    for (i = 0; i < td->td_customValueCount; i++)
351,743✔
1646
    {
1647
        if (td->td_customValues[i].value)
147,390✔
1648
            _TIFFfreeExt(tif, td->td_customValues[i].value);
147,390✔
1649
    }
1650

1651
    td->td_customValueCount = 0;
204,353✔
1652
    CleanupField(td_customValues);
204,353✔
1653

1654
    _TIFFmemset(&(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
204,353✔
1655
    _TIFFmemset(&(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
204,330✔
1656

1657
    /* Reset some internal parameters for IFD data size checking. */
1658
    tif->tif_dir.td_dirdatasize_read = 0;
204,351✔
1659
    tif->tif_dir.td_dirdatasize_write = 0;
204,351✔
1660
    if (tif->tif_dir.td_dirdatasize_offsets != NULL)
204,351✔
1661
    {
1662
        _TIFFfreeExt(tif, tif->tif_dir.td_dirdatasize_offsets);
52,045✔
1663
        tif->tif_dir.td_dirdatasize_offsets = NULL;
52,046✔
1664
        tif->tif_dir.td_dirdatasize_Noffsets = 0;
52,046✔
1665
    }
1666
    tif->tif_dir.td_iswrittentofile = FALSE;
204,352✔
1667
}
204,352✔
1668
#undef CleanupField
1669

1670
/*
1671
 * Client Tag extension support (from Niles Ritter).
1672
 */
1673
static TIFFExtendProc _TIFFextender = (TIFFExtendProc)NULL;
1674

1675
TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc extender)
1,218✔
1676
{
1677
    TIFFExtendProc prev = _TIFFextender;
1,218✔
1678
    _TIFFextender = extender;
1,218✔
1679
    return (prev);
1,218✔
1680
}
1681

1682
/*
1683
 * Setup for a new directory.  Should we automatically call
1684
 * TIFFWriteDirectory() if the current one is dirty?
1685
 *
1686
 * The newly created directory will not exist on the file till
1687
 * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
1688
 */
1689
int TIFFCreateDirectory(TIFF *tif)
42,102✔
1690
{
1691
    /* Free previously allocated memory and setup default values. */
1692
    TIFFFreeDirectory(tif);
42,102✔
1693
    TIFFDefaultDirectory(tif);
42,103✔
1694
    tif->tif_diroff = 0;
42,102✔
1695
    tif->tif_nextdiroff = 0;
42,102✔
1696
    tif->tif_curoff = 0;
42,102✔
1697
    tif->tif_row = (uint32_t)-1;
42,102✔
1698
    tif->tif_curstrip = (uint32_t)-1;
42,102✔
1699
    tif->tif_dir.td_iswrittentofile = FALSE;
42,102✔
1700

1701
    return 0;
42,102✔
1702
}
1703

1704
int TIFFCreateCustomDirectory(TIFF *tif, const TIFFFieldArray *infoarray)
×
1705
{
1706
    /* Free previously allocated memory and setup default values. */
1707
    TIFFFreeDirectory(tif);
×
1708
    TIFFDefaultDirectory(tif);
×
1709

1710
    /*
1711
     * Reset the field definitions to match the application provided list.
1712
     * Hopefully TIFFDefaultDirectory() won't have done anything irreversible
1713
     * based on it's assumption this is an image directory.
1714
     */
1715
    _TIFFSetupFields(tif, infoarray);
×
1716

1717
    tif->tif_diroff = 0;
×
1718
    tif->tif_nextdiroff = 0;
×
1719
    tif->tif_curoff = 0;
×
1720
    tif->tif_row = (uint32_t)-1;
×
1721
    tif->tif_curstrip = (uint32_t)-1;
×
1722
    /* invalidate directory index */
1723
    tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
×
1724
    /* invalidate IFD loop lists */
1725
    _TIFFCleanupIFDOffsetAndNumberMaps(tif);
×
1726
    /* To be able to return from SubIFD or custom-IFD to main-IFD */
1727
    tif->tif_setdirectory_force_absolute = TRUE;
×
1728

1729
    return 0;
×
1730
}
1731

1732
int TIFFCreateEXIFDirectory(TIFF *tif)
×
1733
{
1734
    const TIFFFieldArray *exifFieldArray;
1735
    exifFieldArray = _TIFFGetExifFields();
×
1736
    return TIFFCreateCustomDirectory(tif, exifFieldArray);
×
1737
}
1738

1739
/*
1740
 * Creates the EXIF GPS custom directory
1741
 */
1742
int TIFFCreateGPSDirectory(TIFF *tif)
×
1743
{
1744
    const TIFFFieldArray *gpsFieldArray;
1745
    gpsFieldArray = _TIFFGetGpsFields();
×
1746
    return TIFFCreateCustomDirectory(tif, gpsFieldArray);
×
1747
}
1748

1749
/*
1750
 * Setup a default directory structure.
1751
 */
1752
int TIFFDefaultDirectory(TIFF *tif)
133,112✔
1753
{
1754
    register TIFFDirectory *td = &tif->tif_dir;
133,112✔
1755
    const TIFFFieldArray *tiffFieldArray;
1756

1757
    tiffFieldArray = _TIFFGetFields();
133,112✔
1758
    _TIFFSetupFields(tif, tiffFieldArray);
133,052✔
1759

1760
    _TIFFmemset(td, 0, sizeof(*td));
133,104✔
1761
    td->td_fillorder = FILLORDER_MSB2LSB;
133,086✔
1762
    td->td_bitspersample = 1;
133,086✔
1763
    td->td_threshholding = THRESHHOLD_BILEVEL;
133,086✔
1764
    td->td_orientation = ORIENTATION_TOPLEFT;
133,086✔
1765
    td->td_samplesperpixel = 1;
133,086✔
1766
    td->td_rowsperstrip = (uint32_t)-1;
133,086✔
1767
    td->td_tilewidth = 0;
133,086✔
1768
    td->td_tilelength = 0;
133,086✔
1769
    td->td_tiledepth = 1;
133,086✔
1770
#ifdef STRIPBYTECOUNTSORTED_UNUSED
1771
    td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
1772
#endif
1773
    td->td_resolutionunit = RESUNIT_INCH;
133,086✔
1774
    td->td_sampleformat = SAMPLEFORMAT_UINT;
133,086✔
1775
    td->td_imagedepth = 1;
133,086✔
1776
    td->td_ycbcrsubsampling[0] = 2;
133,086✔
1777
    td->td_ycbcrsubsampling[1] = 2;
133,086✔
1778
    td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
133,086✔
1779
    tif->tif_postdecode = _TIFFNoPostDecode;
133,086✔
1780
    tif->tif_foundfield = NULL;
133,086✔
1781
    tif->tif_tagmethods.vsetfield = _TIFFVSetField;
133,086✔
1782
    tif->tif_tagmethods.vgetfield = _TIFFVGetField;
133,086✔
1783
    tif->tif_tagmethods.printdir = NULL;
133,086✔
1784
    /* additional default values */
1785
    td->td_planarconfig = PLANARCONFIG_CONTIG;
133,086✔
1786
    td->td_compression = COMPRESSION_NONE;
133,086✔
1787
    td->td_subfiletype = 0;
133,086✔
1788
    td->td_minsamplevalue = 0;
133,086✔
1789
    /* td_bitspersample=1 is always set in TIFFDefaultDirectory().
1790
     * Therefore, td_maxsamplevalue has to be re-calculated in
1791
     * TIFFGetFieldDefaulted(). */
1792
    td->td_maxsamplevalue = 1; /* Default for td_bitspersample=1 */
133,086✔
1793
    td->td_extrasamples = 0;
133,086✔
1794
    td->td_sampleinfo = NULL;
133,086✔
1795

1796
    /*
1797
     *  Give client code a chance to install their own
1798
     *  tag extensions & methods, prior to compression overloads,
1799
     *  but do some prior cleanup first.
1800
     * (http://trac.osgeo.org/gdal/ticket/5054)
1801
     */
1802
    if (tif->tif_nfieldscompat > 0)
133,086✔
1803
    {
1804
        uint32_t i;
1805

1806
        for (i = 0; i < tif->tif_nfieldscompat; i++)
191,674✔
1807
        {
1808
            if (tif->tif_fieldscompat[i].allocated_size)
127,782✔
1809
                _TIFFfreeExt(tif, tif->tif_fieldscompat[i].fields);
127,784✔
1810
        }
1811
        _TIFFfreeExt(tif, tif->tif_fieldscompat);
63,892✔
1812
        tif->tif_nfieldscompat = 0;
63,891✔
1813
        tif->tif_fieldscompat = NULL;
63,891✔
1814
    }
1815
    if (_TIFFextender)
133,086✔
1816
        (*_TIFFextender)(tif);
133,093✔
1817
    (void)TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
133,115✔
1818
    /*
1819
     * NB: The directory is marked dirty as a result of setting
1820
     * up the default compression scheme.  However, this really
1821
     * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
1822
     * if the user does something.  We could just do the setup
1823
     * by hand, but it seems better to use the normal mechanism
1824
     * (i.e. TIFFSetField).
1825
     */
1826
    tif->tif_flags &= ~TIFF_DIRTYDIRECT;
132,978✔
1827

1828
    /*
1829
     * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
1830
     * we clear the ISTILED flag when setting up a new directory.
1831
     * Should we also be clearing stuff like INSUBIFD?
1832
     */
1833
    tif->tif_flags &= ~TIFF_ISTILED;
132,978✔
1834

1835
    return (1);
132,978✔
1836
}
1837

1838
static int TIFFAdvanceDirectory(TIFF *tif, uint64_t *nextdiroff, uint64_t *off,
16,281✔
1839
                                tdir_t *nextdirnum)
1840
{
1841
    static const char module[] = "TIFFAdvanceDirectory";
1842

1843
    /* Add this directory to the directory list, if not already in. */
1844
    if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
16,281✔
1845
    {
UNCOV
1846
        TIFFErrorExtR(tif, module,
×
1847
                      "Starting directory %u at offset 0x%" PRIx64 " (%" PRIu64
1848
                      ") might cause an IFD loop",
1849
                      *nextdirnum, *nextdiroff, *nextdiroff);
1850
        *nextdiroff = 0;
×
1851
        *nextdirnum = 0;
×
1852
        return (0);
×
1853
    }
1854

1855
    if (isMapped(tif))
16,281✔
1856
    {
1857
        uint64_t poff = *nextdiroff;
×
1858
        if (!(tif->tif_flags & TIFF_BIGTIFF))
×
1859
        {
1860
            tmsize_t poffa, poffb, poffc, poffd;
1861
            uint16_t dircount;
1862
            uint32_t nextdir32;
1863
            poffa = (tmsize_t)poff;
×
1864
            poffb = poffa + sizeof(uint16_t);
×
1865
            if (((uint64_t)poffa != poff) || (poffb < poffa) ||
×
1866
                (poffb < (tmsize_t)sizeof(uint16_t)) || (poffb > tif->tif_size))
×
1867
            {
1868
                TIFFErrorExtR(tif, module,
×
1869
                              "%s:%d: %s: Error fetching directory count",
1870
                              __FILE__, __LINE__, tif->tif_name);
1871
                *nextdiroff = 0;
×
1872
                return (0);
×
1873
            }
1874
            _TIFFmemcpy(&dircount, tif->tif_base + poffa, sizeof(uint16_t));
×
1875
            if (tif->tif_flags & TIFF_SWAB)
×
1876
                TIFFSwabShort(&dircount);
×
1877
            poffc = poffb + dircount * 12;
×
1878
            poffd = poffc + sizeof(uint32_t);
×
1879
            if ((poffc < poffb) || (poffc < dircount * 12) || (poffd < poffc) ||
×
1880
                (poffd < (tmsize_t)sizeof(uint32_t)) || (poffd > tif->tif_size))
×
1881
            {
1882
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
1883
                return (0);
×
1884
            }
1885
            if (off != NULL)
×
1886
                *off = (uint64_t)poffc;
×
1887
            _TIFFmemcpy(&nextdir32, tif->tif_base + poffc, sizeof(uint32_t));
×
1888
            if (tif->tif_flags & TIFF_SWAB)
×
1889
                TIFFSwabLong(&nextdir32);
×
1890
            *nextdiroff = nextdir32;
×
1891
        }
1892
        else
1893
        {
1894
            tmsize_t poffa, poffb, poffc, poffd;
1895
            uint64_t dircount64;
1896
            uint16_t dircount16;
1897
            if (poff > (uint64_t)TIFF_TMSIZE_T_MAX - sizeof(uint64_t))
×
1898
            {
1899
                TIFFErrorExtR(tif, module,
×
1900
                              "%s:%d: %s: Error fetching directory count",
1901
                              __FILE__, __LINE__, tif->tif_name);
1902
                return (0);
×
1903
            }
1904
            poffa = (tmsize_t)poff;
×
1905
            poffb = poffa + sizeof(uint64_t);
×
1906
            if (poffb > tif->tif_size)
×
1907
            {
1908
                TIFFErrorExtR(tif, module,
×
1909
                              "%s:%d: %s: Error fetching directory count",
1910
                              __FILE__, __LINE__, tif->tif_name);
1911
                return (0);
×
1912
            }
1913
            _TIFFmemcpy(&dircount64, tif->tif_base + poffa, sizeof(uint64_t));
×
1914
            if (tif->tif_flags & TIFF_SWAB)
×
1915
                TIFFSwabLong8(&dircount64);
×
1916
            if (dircount64 > 0xFFFF)
×
1917
            {
1918
                TIFFErrorExtR(tif, module,
×
1919
                              "Sanity check on directory count failed");
1920
                return (0);
×
1921
            }
1922
            dircount16 = (uint16_t)dircount64;
×
1923
            if (poffb > TIFF_TMSIZE_T_MAX - (tmsize_t)(dircount16 * 20) -
×
1924
                            (tmsize_t)sizeof(uint64_t))
1925
            {
1926
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
1927
                return (0);
×
1928
            }
1929
            poffc = poffb + dircount16 * 20;
×
1930
            poffd = poffc + sizeof(uint64_t);
×
1931
            if (poffd > tif->tif_size)
×
1932
            {
1933
                TIFFErrorExtR(tif, module, "Error fetching directory link");
×
1934
                return (0);
×
1935
            }
1936
            if (off != NULL)
×
1937
                *off = (uint64_t)poffc;
×
1938
            _TIFFmemcpy(nextdiroff, tif->tif_base + poffc, sizeof(uint64_t));
×
1939
            if (tif->tif_flags & TIFF_SWAB)
×
1940
                TIFFSwabLong8(nextdiroff);
×
1941
        }
1942
    }
1943
    else
1944
    {
1945
        if (!(tif->tif_flags & TIFF_BIGTIFF))
16,281✔
1946
        {
1947
            uint16_t dircount;
1948
            uint32_t nextdir32;
1949
            if (!SeekOK(tif, *nextdiroff) ||
30,768✔
1950
                !ReadOK(tif, &dircount, sizeof(uint16_t)))
15,384✔
1951
            {
1952
                TIFFErrorExtR(tif, module,
7✔
1953
                              "%s:%d: %s: Error fetching directory count",
1954
                              __FILE__, __LINE__, tif->tif_name);
1955
                return (0);
7✔
1956
            }
1957
            if (tif->tif_flags & TIFF_SWAB)
15,377✔
1958
                TIFFSwabShort(&dircount);
272✔
1959
            if (off != NULL)
15,377✔
1960
                *off = TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
9✔
1961
            else
1962
                (void)TIFFSeekFile(tif, dircount * 12, SEEK_CUR);
15,368✔
1963
            if (!ReadOK(tif, &nextdir32, sizeof(uint32_t)))
15,377✔
1964
            {
1965
                TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
×
1966
                              tif->tif_name);
1967
                return (0);
×
1968
            }
1969
            if (tif->tif_flags & TIFF_SWAB)
15,377✔
1970
                TIFFSwabLong(&nextdir32);
272✔
1971
            *nextdiroff = nextdir32;
15,377✔
1972
        }
1973
        else
1974
        {
1975
            uint64_t dircount64;
1976
            uint16_t dircount16;
1977
            if (!SeekOK(tif, *nextdiroff) ||
1,794✔
1978
                !ReadOK(tif, &dircount64, sizeof(uint64_t)))
897✔
1979
            {
1980
                TIFFErrorExtR(tif, module,
×
1981
                              "%s:%d: %s: Error fetching directory count",
1982
                              __FILE__, __LINE__, tif->tif_name);
1983
                return (0);
×
1984
            }
1985
            if (tif->tif_flags & TIFF_SWAB)
897✔
1986
                TIFFSwabLong8(&dircount64);
4✔
1987
            if (dircount64 > 0xFFFF)
897✔
1988
            {
1989
                TIFFErrorExtR(tif, module,
×
1990
                              "%s:%d: %s: Error fetching directory count",
1991
                              __FILE__, __LINE__, tif->tif_name);
1992
                return (0);
×
1993
            }
1994
            dircount16 = (uint16_t)dircount64;
897✔
1995
            if (off != NULL)
897✔
1996
                *off = TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
×
1997
            else
1998
                (void)TIFFSeekFile(tif, dircount16 * 20, SEEK_CUR);
897✔
1999
            if (!ReadOK(tif, nextdiroff, sizeof(uint64_t)))
897✔
2000
            {
2001
                TIFFErrorExtR(tif, module, "%s: Error fetching directory link",
×
2002
                              tif->tif_name);
2003
                return (0);
×
2004
            }
2005
            if (tif->tif_flags & TIFF_SWAB)
897✔
2006
                TIFFSwabLong8(nextdiroff);
4✔
2007
        }
2008
    }
2009
    if (*nextdiroff != 0)
16,274✔
2010
    {
2011
        (*nextdirnum)++;
5,997✔
2012
        /* Check next directory for IFD looping and if so, set it as last
2013
         * directory. */
2014
        if (!_TIFFCheckDirNumberAndOffset(tif, *nextdirnum, *nextdiroff))
5,997✔
2015
        {
2016
            TIFFWarningExtR(
×
2017
                tif, module,
2018
                "the next directory %u at offset 0x%" PRIx64 " (%" PRIu64
2019
                ") might be an IFD loop. Treating directory %d as "
2020
                "last directory",
2021
                *nextdirnum, *nextdiroff, *nextdiroff, (int)(*nextdirnum) - 1);
×
2022
            *nextdiroff = 0;
×
2023
            (*nextdirnum)--;
×
2024
        }
2025
    }
2026
    return (1);
16,274✔
2027
}
2028

2029
/*
2030
 * Count the number of directories in a file.
2031
 */
2032
tdir_t TIFFNumberOfDirectories(TIFF *tif)
10,278✔
2033
{
2034
    uint64_t nextdiroff;
2035
    tdir_t nextdirnum;
2036
    tdir_t n;
2037
    if (!(tif->tif_flags & TIFF_BIGTIFF))
10,278✔
2038
        nextdiroff = tif->tif_header.classic.tiff_diroff;
9,969✔
2039
    else
2040
        nextdiroff = tif->tif_header.big.tiff_diroff;
309✔
2041
    nextdirnum = 0;
10,278✔
2042
    n = 0;
10,278✔
2043
    while (nextdiroff != 0 &&
42,803✔
2044
           TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
16,266✔
2045
    {
2046
        ++n;
16,259✔
2047
    }
2048
    /* Update number of main-IFDs in file. */
2049
    tif->tif_curdircount = n;
10,278✔
2050
    return (n);
10,278✔
2051
}
2052

2053
/*
2054
 * Set the n-th directory as the current directory.
2055
 * NB: Directories are numbered starting at 0.
2056
 */
2057
int TIFFSetDirectory(TIFF *tif, tdir_t dirn)
10,434✔
2058
{
2059
    uint64_t nextdiroff;
2060
    tdir_t nextdirnum = 0;
10,434✔
2061
    tdir_t n;
2062

2063
    if (tif->tif_setdirectory_force_absolute)
10,434✔
2064
    {
2065
        /* tif_setdirectory_force_absolute=1 will force parsing the main IFD
2066
         * chain from the beginning, thus IFD directory list needs to be cleared
2067
         * from possible SubIFD offsets.
2068
         */
2069
        _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
×
2070
    }
2071

2072
    /* Even faster path, if offset is available within IFD loop hash list. */
2073
    if (!tif->tif_setdirectory_force_absolute &&
20,868✔
2074
        _TIFFGetOffsetFromDirNumber(tif, dirn, &nextdiroff))
10,434✔
2075
    {
2076
        /* Set parameters for following TIFFReadDirectory() below. */
2077
        tif->tif_nextdiroff = nextdiroff;
10,434✔
2078
        tif->tif_curdir = dirn;
10,434✔
2079
        /* Reset to relative stepping */
2080
        tif->tif_setdirectory_force_absolute = FALSE;
10,434✔
2081
    }
2082
    else
2083
    {
2084

2085
        /* Fast path when we just advance relative to the current directory:
2086
         * start at the current dir offset and continue to seek from there.
2087
         * Check special cases when relative is not allowed:
2088
         * - jump back from SubIFD or custom directory
2089
         * - right after TIFFWriteDirectory() jump back to that directory
2090
         *   using TIFFSetDirectory() */
2091
        const int relative = (dirn >= tif->tif_curdir) &&
×
2092
                             (tif->tif_diroff != 0) &&
×
2093
                             !tif->tif_setdirectory_force_absolute;
×
2094

2095
        if (relative)
×
2096
        {
2097
            nextdiroff = tif->tif_diroff;
×
2098
            dirn -= tif->tif_curdir;
×
2099
            nextdirnum = tif->tif_curdir;
×
2100
        }
2101
        else if (!(tif->tif_flags & TIFF_BIGTIFF))
×
2102
            nextdiroff = tif->tif_header.classic.tiff_diroff;
×
2103
        else
2104
            nextdiroff = tif->tif_header.big.tiff_diroff;
×
2105

2106
        /* Reset to relative stepping */
2107
        tif->tif_setdirectory_force_absolute = FALSE;
×
2108

2109
        for (n = dirn; n > 0 && nextdiroff != 0; n--)
×
2110
            if (!TIFFAdvanceDirectory(tif, &nextdiroff, NULL, &nextdirnum))
×
2111
                return (0);
×
2112
        /* If the n-th directory could not be reached (does not exist),
2113
         * return here without touching anything further. */
2114
        if (nextdiroff == 0 || n > 0)
×
2115
            return (0);
×
2116

2117
        tif->tif_nextdiroff = nextdiroff;
×
2118

2119
        /* Set curdir to the actual directory index. */
2120
        if (relative)
×
2121
            tif->tif_curdir += dirn - n;
×
2122
        else
2123
            tif->tif_curdir = dirn - n;
×
2124
    }
2125

2126
    /* The -1 decrement is because TIFFReadDirectory will increment
2127
     * tif_curdir after successfully reading the directory. */
2128
    if (tif->tif_curdir == 0)
10,434✔
2129
        tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
9,658✔
2130
    else
2131
        tif->tif_curdir--;
776✔
2132

2133
    tdir_t curdir = tif->tif_curdir;
10,434✔
2134

2135
    int retval = TIFFReadDirectory(tif);
10,434✔
2136

2137
    if (!retval && tif->tif_curdir == curdir)
10,434✔
2138
    {
2139
        /* If tif_curdir has not be incremented, TIFFFetchDirectory() in
2140
         * TIFFReadDirectory() has failed and tif_curdir shall be set
2141
         * specifically. */
2142
        tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
4✔
2143
    }
2144
    return (retval);
10,434✔
2145
}
2146

2147
/*
2148
 * Set the current directory to be the directory
2149
 * located at the specified file offset.  This interface
2150
 * is used mainly to access directories linked with
2151
 * the SubIFD tag (e.g. thumbnail images).
2152
 */
2153
int TIFFSetSubDirectory(TIFF *tif, uint64_t diroff)
17,973✔
2154
{
2155
    /* Match nextdiroff and curdir for consistent IFD-loop checking.
2156
     * Only with TIFFSetSubDirectory() the IFD list can be corrupted with
2157
     * invalid offsets within the main IFD tree. In the case of several subIFDs
2158
     * of a main image, there are two possibilities that are not even mutually
2159
     * exclusive. a.) The subIFD tag contains an array with all offsets of the
2160
     * subIFDs. b.) The SubIFDs are concatenated with their NextIFD parameters.
2161
     * (refer to
2162
     * https://www.awaresystems.be/imaging/tiff/specification/TIFFPM6.pdf.)
2163
     */
2164
    int retval;
2165
    uint32_t curdir = 0;
17,973✔
2166
    int8_t probablySubIFD = 0;
17,973✔
2167
    if (diroff == 0)
17,973✔
2168
    {
2169
        /* Special case to set tif_diroff=0, which is done in
2170
         * TIFFReadDirectory() below to indicate that the currently read IFD is
2171
         * treated as a new, fresh IFD. */
2172
        tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
7,776✔
2173
        tif->tif_dir.td_iswrittentofile = FALSE;
7,776✔
2174
    }
2175
    else
2176
    {
2177
        if (!_TIFFGetDirNumberFromOffset(tif, diroff, &curdir))
10,197✔
2178
        {
2179
            /* Non-existing offsets might point to a SubIFD or invalid IFD.*/
2180
            probablySubIFD = 1;
57✔
2181
        }
2182
        /* -1 because TIFFReadDirectory() will increment tif_curdir. */
2183
        if (curdir >= 1)
10,197✔
2184
            tif->tif_curdir = curdir - 1;
1,802✔
2185
        else
2186
            tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
8,395✔
2187
    }
2188
    curdir = tif->tif_curdir;
17,973✔
2189

2190
    tif->tif_nextdiroff = diroff;
17,973✔
2191
    retval = TIFFReadDirectory(tif);
17,973✔
2192

2193
    /* tif_curdir is incremented in TIFFReadDirectory(), but if it has not been
2194
     * incremented, TIFFFetchDirectory() has failed there and tif_curdir shall
2195
     * be set specifically. */
2196
    if (!retval && diroff != 0 && tif->tif_curdir == curdir)
17,972✔
2197
    {
2198
        tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
×
2199
    }
2200

2201
    if (probablySubIFD)
17,972✔
2202
    {
2203
        if (retval)
57✔
2204
        {
2205
            /* Reset IFD list to start new one for SubIFD chain and also start
2206
             * SubIFD chain with tif_curdir=0 for IFD loop checking. */
2207
            /* invalidate IFD loop lists */
2208
            _TIFFCleanupIFDOffsetAndNumberMaps(tif);
57✔
2209
            tif->tif_curdir = 0; /* first directory of new chain */
57✔
2210
            /* add this offset to new IFD list */
2211
            retval = _TIFFCheckDirNumberAndOffset(tif, tif->tif_curdir, diroff);
57✔
2212
        }
2213
        /* To be able to return from SubIFD or custom-IFD to main-IFD */
2214
        tif->tif_setdirectory_force_absolute = TRUE;
57✔
2215
    }
2216

2217
    return (retval);
17,972✔
2218
}
2219

2220
/*
2221
 * Return file offset of the current directory.
2222
 */
2223
uint64_t TIFFCurrentDirOffset(TIFF *tif) { return (tif->tif_diroff); }
128,773✔
2224

2225
/*
2226
 * Return an indication of whether or not we are
2227
 * at the last directory in the file.
2228
 */
2229
int TIFFLastDirectory(TIFF *tif) { return (tif->tif_nextdiroff == 0); }
8,567✔
2230

2231
/*
2232
 * Unlink the specified directory from the directory chain.
2233
 * Note: First directory starts with number dirn=1.
2234
 * This is different to TIFFSetDirectory() where the first directory starts with
2235
 * zero.
2236
 */
2237
int TIFFUnlinkDirectory(TIFF *tif, tdir_t dirn)
6✔
2238
{
2239
    static const char module[] = "TIFFUnlinkDirectory";
2240
    uint64_t nextdir;
2241
    tdir_t nextdirnum;
2242
    uint64_t off;
2243
    tdir_t n;
2244

2245
    if (tif->tif_mode == O_RDONLY)
6✔
2246
    {
2247
        TIFFErrorExtR(tif, module,
×
2248
                      "Can not unlink directory in read-only file");
2249
        return (0);
×
2250
    }
2251
    if (dirn == 0)
6✔
2252
    {
2253
        TIFFErrorExtR(tif, module,
×
2254
                      "For TIFFUnlinkDirectory() first directory starts with "
2255
                      "number 1 and not 0");
2256
        return (0);
×
2257
    }
2258
    /*
2259
     * Go to the directory before the one we want
2260
     * to unlink and nab the offset of the link
2261
     * field we'll need to patch.
2262
     */
2263
    if (!(tif->tif_flags & TIFF_BIGTIFF))
6✔
2264
    {
2265
        nextdir = tif->tif_header.classic.tiff_diroff;
6✔
2266
        off = 4;
6✔
2267
    }
2268
    else
2269
    {
2270
        nextdir = tif->tif_header.big.tiff_diroff;
×
2271
        off = 8;
×
2272
    }
2273
    nextdirnum = 0; /* First directory is dirn=0 */
6✔
2274

2275
    for (n = dirn - 1; n > 0; n--)
15✔
2276
    {
2277
        if (nextdir == 0)
9✔
2278
        {
2279
            TIFFErrorExtR(tif, module, "Directory %u does not exist", dirn);
×
2280
            return (0);
×
2281
        }
2282
        if (!TIFFAdvanceDirectory(tif, &nextdir, &off, &nextdirnum))
9✔
2283
            return (0);
×
2284
    }
2285
    /*
2286
     * Advance to the directory to be unlinked and fetch
2287
     * the offset of the directory that follows.
2288
     */
2289
    if (!TIFFAdvanceDirectory(tif, &nextdir, NULL, &nextdirnum))
6✔
2290
        return (0);
×
2291
    /*
2292
     * Go back and patch the link field of the preceding
2293
     * directory to point to the offset of the directory
2294
     * that follows.
2295
     */
2296
    (void)TIFFSeekFile(tif, off, SEEK_SET);
6✔
2297
    if (!(tif->tif_flags & TIFF_BIGTIFF))
6✔
2298
    {
2299
        uint32_t nextdir32;
2300
        nextdir32 = (uint32_t)nextdir;
6✔
2301
        assert((uint64_t)nextdir32 == nextdir);
6✔
2302
        if (tif->tif_flags & TIFF_SWAB)
6✔
2303
            TIFFSwabLong(&nextdir32);
×
2304
        if (!WriteOK(tif, &nextdir32, sizeof(uint32_t)))
6✔
2305
        {
2306
            TIFFErrorExtR(tif, module, "Error writing directory link");
×
2307
            return (0);
×
2308
        }
2309
    }
2310
    else
2311
    {
2312
        /* Need local swap because nextdir has to be used unswapped below. */
2313
        uint64_t nextdir64 = nextdir;
×
2314
        if (tif->tif_flags & TIFF_SWAB)
×
2315
            TIFFSwabLong8(&nextdir64);
×
2316
        if (!WriteOK(tif, &nextdir64, sizeof(uint64_t)))
×
2317
        {
2318
            TIFFErrorExtR(tif, module, "Error writing directory link");
×
2319
            return (0);
×
2320
        }
2321
    }
2322

2323
    /* For dirn=1 (first directory) also update the libtiff internal
2324
     * base offset variables. */
2325
    if (dirn == 1)
6✔
2326
    {
2327
        if (!(tif->tif_flags & TIFF_BIGTIFF))
×
2328
            tif->tif_header.classic.tiff_diroff = (uint32_t)nextdir;
×
2329
        else
2330
            tif->tif_header.big.tiff_diroff = nextdir;
×
2331
    }
2332

2333
    /*
2334
     * Leave directory state setup safely.  We don't have
2335
     * facilities for doing inserting and removing directories,
2336
     * so it's safest to just invalidate everything.  This
2337
     * means that the caller can only append to the directory
2338
     * chain.
2339
     */
2340
    if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
6✔
2341
    {
2342
        _TIFFfreeExt(tif, tif->tif_rawdata);
×
2343
        tif->tif_rawdata = NULL;
×
2344
        tif->tif_rawcc = 0;
×
2345
        tif->tif_rawcp = NULL;
×
2346
        tif->tif_rawdataoff = 0;
×
2347
        tif->tif_rawdataloaded = 0;
×
2348
    }
2349
    tif->tif_flags &= ~(TIFF_BEENWRITING | TIFF_BUFFERSETUP | TIFF_POSTENCODE |
6✔
2350
                        TIFF_BUF4WRITE);
2351
    TIFFFreeDirectory(tif);
6✔
2352
    TIFFDefaultDirectory(tif);
6✔
2353
    tif->tif_diroff = 0;     /* force link on next write */
6✔
2354
    tif->tif_nextdiroff = 0; /* next write must be at end */
6✔
2355
    tif->tif_lastdiroff = 0; /* will be updated on next link */
6✔
2356
    tif->tif_curoff = 0;
6✔
2357
    tif->tif_row = (uint32_t)-1;
6✔
2358
    tif->tif_curstrip = (uint32_t)-1;
6✔
2359
    tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER;
6✔
2360
    if (tif->tif_curdircount > 0)
6✔
2361
        tif->tif_curdircount--;
6✔
2362
    else
2363
        tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
×
2364
    _TIFFCleanupIFDOffsetAndNumberMaps(tif); /* invalidate IFD loop lists */
6✔
2365
    return (1);
6✔
2366
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc