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

OSGeo / gdal / 15899162844

26 Jun 2025 10:14AM UTC coverage: 71.088% (+0.004%) from 71.084%
15899162844

Pull #12623

github

web-flow
Merge c704a8392 into f5cb024d4
Pull Request #12623: gdal raster overview add: add a --overview-src option

209 of 244 new or added lines in 5 files covered. (85.66%)

96 existing lines in 44 files now uncovered.

574014 of 807474 relevant lines covered (71.09%)

250815.03 hits per line

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

64.19
/frmts/gtiff/libtiff/tif_open.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

29
#ifdef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
30
#undef TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS
31
#endif
32

33
#include "tiffiop.h"
34
#include <assert.h>
35
#include <limits.h>
36

37
/*
38
 * Dummy functions to fill the omitted client procedures.
39
 */
40
int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
×
41
{
42
    (void)fd;
43
    (void)pbase;
44
    (void)psize;
45
    return (0);
×
46
}
47

48
void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
×
49
{
50
    (void)fd;
51
    (void)base;
52
    (void)size;
53
}
×
54

55
int _TIFFgetMode(TIFFOpenOptions *opts, thandle_t clientdata, const char *mode,
69,255✔
56
                 const char *module)
57
{
58
    int m = -1;
69,255✔
59

60
    switch (mode[0])
69,255✔
61
    {
62
        case 'r':
30,277✔
63
            m = O_RDONLY;
30,277✔
64
            if (mode[1] == '+')
30,277✔
65
                m = O_RDWR;
3,718✔
66
            break;
30,277✔
67
        case 'w':
38,975✔
68
        case 'a':
69
            m = O_RDWR | O_CREAT;
38,975✔
70
            if (mode[0] == 'w')
38,975✔
71
                m |= O_TRUNC;
38,975✔
72
            break;
38,975✔
73
        default:
3✔
74
            _TIFFErrorEarly(opts, clientdata, module, "\"%s\": Bad mode", mode);
3✔
75
            break;
×
76
    }
77
    return (m);
69,252✔
78
}
79

80
TIFFOpenOptions *TIFFOpenOptionsAlloc()
69,259✔
81
{
82
    TIFFOpenOptions *opts =
83
        (TIFFOpenOptions *)_TIFFcalloc(1, sizeof(TIFFOpenOptions));
69,259✔
84
    return opts;
69,255✔
85
}
86

87
void TIFFOpenOptionsFree(TIFFOpenOptions *opts) { _TIFFfree(opts); }
69,243✔
88

89
/** Define a limit in bytes for a single memory allocation done by libtiff.
90
 *  If max_single_mem_alloc is set to 0, which is the default, no other limit
91
 *  that the underlying _TIFFmalloc() or
92
 *  TIFFOpenOptionsSetMaxCumulatedMemAlloc() will be applied.
93
 */
94
void TIFFOpenOptionsSetMaxSingleMemAlloc(TIFFOpenOptions *opts,
×
95
                                         tmsize_t max_single_mem_alloc)
96
{
97
    opts->max_single_mem_alloc = max_single_mem_alloc;
×
98
}
×
99

100
/** Define a limit in bytes for the cumulated memory allocations done by libtiff
101
 *  on a given TIFF handle.
102
 *  If max_cumulated_mem_alloc is set to 0, which is the default, no other limit
103
 *  that the underlying _TIFFmalloc() or
104
 *  TIFFOpenOptionsSetMaxSingleMemAlloc() will be applied.
105
 */
106
void TIFFOpenOptionsSetMaxCumulatedMemAlloc(TIFFOpenOptions *opts,
69,255✔
107
                                            tmsize_t max_cumulated_mem_alloc)
108
{
109
    opts->max_cumulated_mem_alloc = max_cumulated_mem_alloc;
69,255✔
110
}
69,255✔
111

112
/** Whether a warning should be emitted when encountering a unknown tag.
113
 * Default is FALSE since libtiff 4.7.1
114
 */
115
void TIFFOpenOptionsSetWarnAboutUnknownTags(TIFFOpenOptions *opts,
×
116
                                            int warn_about_unknown_tags)
117
{
118
    opts->warn_about_unknown_tags = warn_about_unknown_tags;
×
119
}
×
120

121
void TIFFOpenOptionsSetErrorHandlerExtR(TIFFOpenOptions *opts,
69,258✔
122
                                        TIFFErrorHandlerExtR handler,
123
                                        void *errorhandler_user_data)
124
{
125
    opts->errorhandler = handler;
69,258✔
126
    opts->errorhandler_user_data = errorhandler_user_data;
69,258✔
127
}
69,258✔
128

129
void TIFFOpenOptionsSetWarningHandlerExtR(TIFFOpenOptions *opts,
69,256✔
130
                                          TIFFErrorHandlerExtR handler,
131
                                          void *warnhandler_user_data)
132
{
133
    opts->warnhandler = handler;
69,256✔
134
    opts->warnhandler_user_data = warnhandler_user_data;
69,256✔
135
}
69,256✔
136

137
static void _TIFFEmitErrorAboveMaxSingleMemAlloc(TIFF *tif,
×
138
                                                 const char *pszFunction,
139
                                                 tmsize_t s)
140
{
141
    TIFFErrorExtR(tif, pszFunction,
×
142
                  "Memory allocation of %" PRIu64
143
                  " bytes is beyond the %" PRIu64
144
                  " byte limit defined in open options",
145
                  (uint64_t)s, (uint64_t)tif->tif_max_single_mem_alloc);
×
146
}
×
147

148
static void _TIFFEmitErrorAboveMaxCumulatedMemAlloc(TIFF *tif,
×
149
                                                    const char *pszFunction,
150
                                                    tmsize_t s)
151
{
152
    TIFFErrorExtR(tif, pszFunction,
×
153
                  "Cumulated memory allocation of %" PRIu64 " + %" PRIu64
154
                  " bytes is beyond the %" PRIu64
155
                  " cumulated byte limit defined in open options",
156
                  (uint64_t)tif->tif_cur_cumulated_mem_alloc, (uint64_t)s,
×
157
                  (uint64_t)tif->tif_max_cumulated_mem_alloc);
×
158
}
×
159

160
/* When allocating memory, we write at the beginning of the buffer it size.
161
 * This allows us to keep track of the total memory allocated when we
162
 * malloc/calloc/realloc and free. In theory we need just SIZEOF_SIZE_T bytes
163
 * for that, but on x86_64, allocations of more than 16 bytes are aligned on
164
 * 16 bytes. Hence using 2 * SIZEOF_SIZE_T.
165
 * It is critical that _TIFFmallocExt/_TIFFcallocExt/_TIFFreallocExt are
166
 * paired with _TIFFfreeExt.
167
 * CMakeLists.txt defines TIFF_DO_NOT_USE_NON_EXT_ALLOC_FUNCTIONS, which in
168
 * turn disables the definition of the non Ext version in tiffio.h
169
 */
170
#define LEADING_AREA_TO_STORE_ALLOC_SIZE (2 * SIZEOF_SIZE_T)
171

172
/** malloc() version that takes into account memory-specific open options */
173
void *_TIFFmallocExt(TIFF *tif, tmsize_t s)
705,307✔
174
{
175
    if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
705,307✔
176
        s > tif->tif_max_single_mem_alloc)
×
177
    {
178
        _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFmallocExt", s);
×
179
        return NULL;
×
180
    }
181
    if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
705,307✔
182
    {
183
        if (s > tif->tif_max_cumulated_mem_alloc -
634,819✔
184
                    tif->tif_cur_cumulated_mem_alloc ||
634,819✔
185
            s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
634,823✔
186
        {
187
            _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFmallocExt", s);
3✔
188
            return NULL;
×
189
        }
190
        void *ptr = _TIFFmalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
634,816✔
191
        if (!ptr)
634,848✔
192
            return NULL;
×
193
        tif->tif_cur_cumulated_mem_alloc += s;
634,848✔
194
        memcpy(ptr, &s, sizeof(s));
634,848✔
195
        return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
634,848✔
196
    }
197
    return _TIFFmalloc(s);
70,488✔
198
}
199

200
/** calloc() version that takes into account memory-specific open options */
201
void *_TIFFcallocExt(TIFF *tif, tmsize_t nmemb, tmsize_t siz)
9,717✔
202
{
203
    if (nmemb <= 0 || siz <= 0 || nmemb > TIFF_TMSIZE_T_MAX / siz)
9,717✔
UNCOV
204
        return NULL;
×
205
    if (tif != NULL && tif->tif_max_single_mem_alloc > 0)
9,717✔
206
    {
207
        if (nmemb * siz > tif->tif_max_single_mem_alloc)
×
208
        {
209
            _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFcallocExt",
×
210
                                                 nmemb * siz);
211
            return NULL;
×
212
        }
213
    }
214
    if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
9,717✔
215
    {
216
        const tmsize_t s = nmemb * siz;
9,717✔
217
        if (s > tif->tif_max_cumulated_mem_alloc -
9,717✔
218
                    tif->tif_cur_cumulated_mem_alloc ||
9,717✔
219
            s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE)
9,717✔
220
        {
221
            _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFcallocExt", s);
×
222
            return NULL;
×
223
        }
224
        void *ptr = _TIFFcalloc(LEADING_AREA_TO_STORE_ALLOC_SIZE + s, 1);
9,717✔
225
        if (!ptr)
9,717✔
226
            return NULL;
×
227
        tif->tif_cur_cumulated_mem_alloc += s;
9,717✔
228
        memcpy(ptr, &s, sizeof(s));
9,717✔
229
        return (char *)ptr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
9,717✔
230
    }
231
    return _TIFFcalloc(nmemb, siz);
×
232
}
233

234
/** realloc() version that takes into account memory-specific open options */
235
void *_TIFFreallocExt(TIFF *tif, void *p, tmsize_t s)
1,773,360✔
236
{
237
    if (tif != NULL && tif->tif_max_single_mem_alloc > 0 &&
1,773,360✔
238
        s > tif->tif_max_single_mem_alloc)
×
239
    {
240
        _TIFFEmitErrorAboveMaxSingleMemAlloc(tif, "_TIFFreallocExt", s);
×
241
        return NULL;
×
242
    }
243
    if (tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
1,773,360✔
244
    {
245
        void *oldPtr = p;
1,700,880✔
246
        tmsize_t oldSize = 0;
1,700,880✔
247
        if (p)
1,700,880✔
248
        {
249
            oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
552,845✔
250
            memcpy(&oldSize, oldPtr, sizeof(oldSize));
552,845✔
251
            assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
552,845✔
252
        }
253
        if (s > oldSize &&
1,700,880✔
254
            (s > tif->tif_max_cumulated_mem_alloc -
1,699,740✔
255
                     (tif->tif_cur_cumulated_mem_alloc - oldSize) ||
1,699,740✔
256
             s > TIFF_TMSIZE_T_MAX - LEADING_AREA_TO_STORE_ALLOC_SIZE))
1,699,640✔
257
        {
258
            _TIFFEmitErrorAboveMaxCumulatedMemAlloc(tif, "_TIFFreallocExt",
99✔
259
                                                    s - oldSize);
260
            return NULL;
×
261
        }
262
        void *newPtr =
263
            _TIFFrealloc(oldPtr, LEADING_AREA_TO_STORE_ALLOC_SIZE + s);
1,700,780✔
264
        if (newPtr == NULL)
1,701,040✔
265
            return NULL;
×
266
        tif->tif_cur_cumulated_mem_alloc -= oldSize;
1,701,040✔
267
        tif->tif_cur_cumulated_mem_alloc += s;
1,701,040✔
268
        memcpy(newPtr, &s, sizeof(s));
1,701,040✔
269
        return (char *)newPtr + LEADING_AREA_TO_STORE_ALLOC_SIZE;
1,701,040✔
270
    }
271
    return _TIFFrealloc(p, s);
72,476✔
272
}
273

274
/** free() version that takes into account memory-specific open options */
275
void _TIFFfreeExt(TIFF *tif, void *p)
1,905,200✔
276
{
277
    if (p != NULL && tif != NULL && tif->tif_max_cumulated_mem_alloc > 0)
1,905,200✔
278
    {
279
        void *oldPtr = (char *)p - LEADING_AREA_TO_STORE_ALLOC_SIZE;
1,792,700✔
280
        tmsize_t oldSize;
281
        memcpy(&oldSize, oldPtr, sizeof(oldSize));
1,792,700✔
282
        assert(oldSize <= tif->tif_cur_cumulated_mem_alloc);
1,792,700✔
283
        tif->tif_cur_cumulated_mem_alloc -= oldSize;
1,792,700✔
284
        p = oldPtr;
1,792,700✔
285
    }
286
    _TIFFfree(p);
1,905,200✔
287
}
1,905,240✔
288

289
TIFF *TIFFClientOpen(const char *name, const char *mode, thandle_t clientdata,
×
290
                     TIFFReadWriteProc readproc, TIFFReadWriteProc writeproc,
291
                     TIFFSeekProc seekproc, TIFFCloseProc closeproc,
292
                     TIFFSizeProc sizeproc, TIFFMapFileProc mapproc,
293
                     TIFFUnmapFileProc unmapproc)
294
{
295
    return TIFFClientOpenExt(name, mode, clientdata, readproc, writeproc,
×
296
                             seekproc, closeproc, sizeproc, mapproc, unmapproc,
297
                             NULL);
298
}
299

300
TIFF *TIFFClientOpenExt(const char *name, const char *mode,
69,259✔
301
                        thandle_t clientdata, TIFFReadWriteProc readproc,
302
                        TIFFReadWriteProc writeproc, TIFFSeekProc seekproc,
303
                        TIFFCloseProc closeproc, TIFFSizeProc sizeproc,
304
                        TIFFMapFileProc mapproc, TIFFUnmapFileProc unmapproc,
305
                        TIFFOpenOptions *opts)
306
{
307
    static const char module[] = "TIFFClientOpenExt";
308
    TIFF *tif;
309
    int m;
310
    const char *cp;
311

312
    /* The following are configuration checks. They should be redundant, but
313
     * should not compile to any actual code in an optimised release build
314
     * anyway. If any of them fail, (makefile-based or other) configuration is
315
     * not correct */
316
    assert(sizeof(uint8_t) == 1);
317
    assert(sizeof(int8_t) == 1);
318
    assert(sizeof(uint16_t) == 2);
319
    assert(sizeof(int16_t) == 2);
320
    assert(sizeof(uint32_t) == 4);
321
    assert(sizeof(int32_t) == 4);
322
    assert(sizeof(uint64_t) == 8);
323
    assert(sizeof(int64_t) == 8);
324
    {
325
        union
326
        {
327
            uint8_t a8[2];
328
            uint16_t a16;
329
        } n;
330
        n.a8[0] = 1;
69,259✔
331
        n.a8[1] = 0;
69,259✔
332
        (void)n;
333
#ifdef WORDS_BIGENDIAN
334
        assert(n.a16 == 256);
335
#else
336
        assert(n.a16 == 1);
69,259✔
337
#endif
338
    }
339

340
    m = _TIFFgetMode(opts, clientdata, mode, module);
69,259✔
341
    if (m == -1)
69,251✔
342
        goto bad2;
×
343
    tmsize_t size_to_alloc = (tmsize_t)(sizeof(TIFF) + strlen(name) + 1);
69,251✔
344
    if (opts && opts->max_single_mem_alloc > 0 &&
69,251✔
345
        size_to_alloc > opts->max_single_mem_alloc)
×
346
    {
347
        _TIFFErrorEarly(opts, clientdata, module,
×
348
                        "%s: Memory allocation of %" PRIu64
349
                        " bytes is beyond the %" PRIu64
350
                        " byte limit defined in open options",
351
                        name, (uint64_t)size_to_alloc,
352
                        (uint64_t)opts->max_single_mem_alloc);
×
353
        goto bad2;
×
354
    }
355
    if (opts && opts->max_cumulated_mem_alloc > 0 &&
69,251✔
356
        size_to_alloc > opts->max_cumulated_mem_alloc)
69,256✔
357
    {
358
        _TIFFErrorEarly(opts, clientdata, module,
×
359
                        "%s: Memory allocation of %" PRIu64
360
                        " bytes is beyond the %" PRIu64
361
                        " cumulated byte limit defined in open options",
362
                        name, (uint64_t)size_to_alloc,
363
                        (uint64_t)opts->max_cumulated_mem_alloc);
×
364
        goto bad2;
×
365
    }
366
    tif = (TIFF *)_TIFFmallocExt(NULL, size_to_alloc);
69,251✔
367
    if (tif == NULL)
69,257✔
368
    {
369
        _TIFFErrorEarly(opts, clientdata, module,
×
370
                        "%s: Out of memory (TIFF structure)", name);
371
        goto bad2;
×
372
    }
373
    _TIFFmemset(tif, 0, sizeof(*tif));
69,257✔
374
    tif->tif_name = (char *)tif + sizeof(TIFF);
69,255✔
375
    strcpy(tif->tif_name, name);
69,255✔
376
    tif->tif_mode = m & ~(O_CREAT | O_TRUNC);
69,255✔
377
    tif->tif_curdir = TIFF_NON_EXISTENT_DIR_NUMBER; /* non-existent directory */
69,255✔
378
    tif->tif_curdircount = TIFF_NON_EXISTENT_DIR_NUMBER;
69,255✔
379
    tif->tif_curoff = 0;
69,255✔
380
    tif->tif_curstrip = (uint32_t)-1; /* invalid strip */
69,255✔
381
    tif->tif_row = (uint32_t)-1;      /* read/write pre-increment */
69,255✔
382
    tif->tif_clientdata = clientdata;
69,255✔
383
    tif->tif_readproc = readproc;
69,255✔
384
    tif->tif_writeproc = writeproc;
69,255✔
385
    tif->tif_seekproc = seekproc;
69,255✔
386
    tif->tif_closeproc = closeproc;
69,255✔
387
    tif->tif_sizeproc = sizeproc;
69,255✔
388
    tif->tif_mapproc = mapproc ? mapproc : _tiffDummyMapProc;
69,255✔
389
    tif->tif_unmapproc = unmapproc ? unmapproc : _tiffDummyUnmapProc;
69,255✔
390
    if (opts)
69,255✔
391
    {
392
        tif->tif_errorhandler = opts->errorhandler;
69,252✔
393
        tif->tif_errorhandler_user_data = opts->errorhandler_user_data;
69,252✔
394
        tif->tif_warnhandler = opts->warnhandler;
69,252✔
395
        tif->tif_warnhandler_user_data = opts->warnhandler_user_data;
69,252✔
396
        tif->tif_max_single_mem_alloc = opts->max_single_mem_alloc;
69,252✔
397
        tif->tif_max_cumulated_mem_alloc = opts->max_cumulated_mem_alloc;
69,252✔
398
        tif->tif_warn_about_unknown_tags = opts->warn_about_unknown_tags;
69,252✔
399
    }
400

401
    if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc)
69,255✔
402
    {
403
        TIFFErrorExtR(tif, module,
6✔
404
                      "One of the client procedures is NULL pointer.");
405
        _TIFFfreeExt(NULL, tif);
×
406
        goto bad2;
×
407
    }
408

409
    _TIFFSetDefaultCompressionState(tif); /* setup default state */
69,249✔
410
    /*
411
     * Default is to return data MSB2LSB and enable the
412
     * use of memory-mapped files and strip chopping when
413
     * a file is opened read-only.
414
     */
415
    tif->tif_flags = FILLORDER_MSB2LSB;
69,253✔
416
    if (m == O_RDONLY)
69,253✔
417
        tif->tif_flags |= TIFF_MAPPED;
26,559✔
418

419
#ifdef STRIPCHOP_DEFAULT
420
    if (m == O_RDONLY || m == O_RDWR)
69,253✔
421
        tif->tif_flags |= STRIPCHOP_DEFAULT;
30,277✔
422
#endif
423

424
    /*
425
     * Process library-specific flags in the open mode string.
426
     * The following flags may be used to control intrinsic library
427
     * behavior that may or may not be desirable (usually for
428
     * compatibility with some application that claims to support
429
     * TIFF but only supports some brain dead idea of what the
430
     * vendor thinks TIFF is):
431
     *
432
     * 'l' use little-endian byte order for creating a file
433
     * 'b' use big-endian byte order for creating a file
434
     * 'L' read/write information using LSB2MSB bit order
435
     * 'B' read/write information using MSB2LSB bit order
436
     * 'H' read/write information using host bit order
437
     * 'M' enable use of memory-mapped files when supported
438
     * 'm' disable use of memory-mapped files
439
     * 'C' enable strip chopping support when reading
440
     * 'c' disable strip chopping support
441
     * 'h' read TIFF header only, do not load the first IFD
442
     * '4' ClassicTIFF for creating a file (default)
443
     * '8' BigTIFF for creating a file
444
     * 'D' enable use of deferred strip/tile offset/bytecount array loading.
445
     * 'O' on-demand loading of values instead of whole array loading (implies
446
     * D)
447
     *
448
     * The use of the 'l' and 'b' flags is strongly discouraged.
449
     * These flags are provided solely because numerous vendors,
450
     * typically on the PC, do not correctly support TIFF; they
451
     * only support the Intel little-endian byte order.  This
452
     * support is not configured by default because it supports
453
     * the violation of the TIFF spec that says that readers *MUST*
454
     * support both byte orders.  It is strongly recommended that
455
     * you not use this feature except to deal with busted apps
456
     * that write invalid TIFF.  And even in those cases you should
457
     * bang on the vendors to fix their software.
458
     *
459
     * The 'L', 'B', and 'H' flags are intended for applications
460
     * that can optimize operations on data by using a particular
461
     * bit order.  By default the library returns data in MSB2LSB
462
     * bit order for compatibility with older versions of this
463
     * library.  Returning data in the bit order of the native CPU
464
     * makes the most sense but also requires applications to check
465
     * the value of the FillOrder tag; something they probably do
466
     * not do right now.
467
     *
468
     * The 'M' and 'm' flags are provided because some virtual memory
469
     * systems exhibit poor behavior when large images are mapped.
470
     * These options permit clients to control the use of memory-mapped
471
     * files on a per-file basis.
472
     *
473
     * The 'C' and 'c' flags are provided because the library support
474
     * for chopping up large strips into multiple smaller strips is not
475
     * application-transparent and as such can cause problems.  The 'c'
476
     * option permits applications that only want to look at the tags,
477
     * for example, to get the unadulterated TIFF tag information.
478
     */
479
    for (cp = mode; *cp; cp++)
282,074✔
480
        switch (*cp)
212,821✔
481
        {
482
            case 'b':
83✔
483
#ifndef WORDS_BIGENDIAN
484
                if (m & O_CREAT)
83✔
485
                    tif->tif_flags |= TIFF_SWAB;
83✔
486
#endif
487
                break;
83✔
488
            case 'l':
29,127✔
489
#ifdef WORDS_BIGENDIAN
490
                if ((m & O_CREAT))
491
                    tif->tif_flags |= TIFF_SWAB;
492
#endif
493
                break;
29,127✔
494
            case 'B':
×
495
                tif->tif_flags =
×
496
                    (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
×
497
                break;
×
498
            case 'L':
×
499
                tif->tif_flags =
×
500
                    (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_LSB2MSB;
×
501
                break;
×
502
            case 'H':
×
503
                TIFFWarningExtR(tif, name,
×
504
                                "H(ost) mode is deprecated. Since "
505
                                "libtiff 4.5.1, it is an alias of 'B' / "
506
                                "FILLORDER_MSB2LSB.");
507
                tif->tif_flags =
×
508
                    (tif->tif_flags & ~TIFF_FILLORDER) | FILLORDER_MSB2LSB;
×
509
                break;
×
510
            case 'M':
×
511
                if (m == O_RDONLY)
×
512
                    tif->tif_flags |= TIFF_MAPPED;
×
513
                break;
×
514
            case 'm':
×
515
                if (m == O_RDONLY)
×
516
                    tif->tif_flags &= ~TIFF_MAPPED;
×
517
                break;
×
518
            case 'C':
23,294✔
519
                if (m == O_RDONLY)
23,294✔
520
                    tif->tif_flags |= TIFF_STRIPCHOP;
22,507✔
521
                break;
23,294✔
522
            case 'c':
580✔
523
                if (m == O_RDONLY)
580✔
524
                    tif->tif_flags &= ~TIFF_STRIPCHOP;
580✔
525
                break;
580✔
526
            case 'h':
×
527
                tif->tif_flags |= TIFF_HEADERONLY;
×
528
                break;
×
529
            case '8':
84✔
530
                if (m & O_CREAT)
84✔
531
                    tif->tif_flags |= TIFF_BIGTIFF;
84✔
532
                break;
84✔
533
            case 'D':
24,571✔
534
                tif->tif_flags |= TIFF_DEFERSTRILELOAD;
24,571✔
535
                break;
24,571✔
536
            case 'O':
23,389✔
537
                if (m == O_RDONLY)
23,389✔
538
                    tif->tif_flags |=
23,387✔
539
                        (TIFF_LAZYSTRILELOAD | TIFF_DEFERSTRILELOAD);
540
                break;
23,389✔
541
        }
542

543
#ifdef DEFER_STRILE_LOAD
544
    /* Compatibility with old DEFER_STRILE_LOAD compilation flag */
545
    /* Probably unneeded, since to the best of my knowledge (E. Rouault) */
546
    /* GDAL was the only user of this, and will now use the new 'D' flag */
547
    tif->tif_flags |= TIFF_DEFERSTRILELOAD;
548
#endif
549

550
    /*
551
     * Read in TIFF header.
552
     */
553
    if ((m & O_TRUNC) ||
312,355✔
554
        !ReadOK(tif, &tif->tif_header, sizeof(TIFFHeaderClassic)))
30,273✔
555
    {
556
        if (tif->tif_mode == O_RDONLY)
38,975✔
557
        {
558
            TIFFErrorExtR(tif, name, "Cannot read TIFF header");
×
559
            goto bad;
2✔
560
        }
561
        /*
562
         * Setup header and write.
563
         */
564
#ifdef WORDS_BIGENDIAN
565
        tif->tif_header.common.tiff_magic =
566
            (tif->tif_flags & TIFF_SWAB) ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
567
#else
568
        tif->tif_header.common.tiff_magic =
38,975✔
569
            (tif->tif_flags & TIFF_SWAB) ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
38,975✔
570
#endif
571
        TIFFHeaderUnion tif_header_swapped;
572
        if (!(tif->tif_flags & TIFF_BIGTIFF))
38,975✔
573
        {
574
            tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
38,891✔
575
            tif->tif_header.classic.tiff_diroff = 0;
38,891✔
576
            tif->tif_header_size = sizeof(TIFFHeaderClassic);
38,891✔
577
            /* Swapped copy for writing */
578
            _TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
38,891✔
579
                        sizeof(TIFFHeaderUnion));
580
            if (tif->tif_flags & TIFF_SWAB)
38,891✔
581
                TIFFSwabShort(&tif_header_swapped.common.tiff_version);
79✔
582
        }
583
        else
584
        {
585
            tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
84✔
586
            tif->tif_header.big.tiff_offsetsize = 8;
84✔
587
            tif->tif_header.big.tiff_unused = 0;
84✔
588
            tif->tif_header.big.tiff_diroff = 0;
84✔
589
            tif->tif_header_size = sizeof(TIFFHeaderBig);
84✔
590
            /* Swapped copy for writing */
591
            _TIFFmemcpy(&tif_header_swapped, &tif->tif_header,
84✔
592
                        sizeof(TIFFHeaderUnion));
593
            if (tif->tif_flags & TIFF_SWAB)
84✔
594
            {
595
                TIFFSwabShort(&tif_header_swapped.common.tiff_version);
4✔
596
                TIFFSwabShort(&tif_header_swapped.big.tiff_offsetsize);
4✔
597
            }
598
        }
599
        /*
600
         * The doc for "fopen" for some STD_C_LIBs says that if you
601
         * open a file for modify ("+"), then you must fseek (or
602
         * fflush?) between any freads and fwrites.  This is not
603
         * necessary on most systems, but has been shown to be needed
604
         * on Solaris.
605
         */
606
        TIFFSeekFile(tif, 0, SEEK_SET);
38,975✔
607
        if (!WriteOK(tif, &tif_header_swapped,
38,975✔
608
                     (tmsize_t)(tif->tif_header_size)))
609
        {
610
            TIFFErrorExtR(tif, name, "Error writing TIFF header");
2✔
611
            goto bad;
2✔
612
        }
613
        /*
614
         * Setup default directory.
615
         */
616
        if (!TIFFDefaultDirectory(tif))
38,973✔
617
            goto bad;
×
618
        tif->tif_diroff = 0;
38,973✔
619
        tif->tif_lastdiroff = 0;
38,973✔
620
        tif->tif_setdirectory_force_absolute = FALSE;
38,973✔
621
        /* tif_curdircount = 0 means 'empty file opened for writing, but no IFD
622
         * written yet' */
623
        tif->tif_curdircount = 0;
38,973✔
624
        return (tif);
38,973✔
625
    }
626

627
    /*
628
     * Setup the byte order handling according to the opened file for reading.
629
     */
630
    if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
30,286✔
631
        tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
30,053✔
632
#if MDI_SUPPORT
633
        &&
634
#if HOST_BIGENDIAN
635
        tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
636
#else
637
        tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
638
#endif
639
    )
640
    {
641
        TIFFErrorExtR(tif, name,
642
                      "Not a TIFF or MDI file, bad magic number %" PRIu16
643
                      " (0x%" PRIx16 ")",
644
#else
645
    )
646
    {
647
        TIFFErrorExtR(tif, name,
×
648
                      "Not a TIFF file, bad magic number %" PRIu16
649
                      " (0x%" PRIx16 ")",
650
#endif
651
                      tif->tif_header.common.tiff_magic,
×
652
                      tif->tif_header.common.tiff_magic);
×
653
        goto bad;
×
654
    }
655
    if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN)
30,286✔
656
    {
657
#ifndef WORDS_BIGENDIAN
658
        tif->tif_flags |= TIFF_SWAB;
222✔
659
#endif
660
    }
661
    else
662
    {
663
#ifdef WORDS_BIGENDIAN
664
        tif->tif_flags |= TIFF_SWAB;
665
#endif
666
    }
667
    if (tif->tif_flags & TIFF_SWAB)
30,286✔
668
        TIFFSwabShort(&tif->tif_header.common.tiff_version);
222✔
669
    if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC) &&
30,277✔
670
        (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG))
327✔
671
    {
672
        TIFFErrorExtR(tif, name,
×
673
                      "Not a TIFF file, bad version number %" PRIu16
674
                      " (0x%" PRIx16 ")",
675
                      tif->tif_header.common.tiff_version,
×
676
                      tif->tif_header.common.tiff_version);
×
677
        goto bad;
×
678
    }
679
    if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
30,277✔
680
    {
681
        if (tif->tif_flags & TIFF_SWAB)
29,950✔
682
            TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
211✔
683
        tif->tif_header_size = sizeof(TIFFHeaderClassic);
29,947✔
684
    }
685
    else
686
    {
687
        if (!ReadOK(tif,
327✔
688
                    ((uint8_t *)(&tif->tif_header) + sizeof(TIFFHeaderClassic)),
689
                    (sizeof(TIFFHeaderBig) - sizeof(TIFFHeaderClassic))))
690
        {
691
            TIFFErrorExtR(tif, name, "Cannot read TIFF header");
×
692
            goto bad;
×
693
        }
694
        if (tif->tif_flags & TIFF_SWAB)
327✔
695
        {
696
            TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
11✔
697
            TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
11✔
698
        }
699
        if (tif->tif_header.big.tiff_offsetsize != 8)
327✔
700
        {
701
            TIFFErrorExtR(tif, name,
×
702
                          "Not a TIFF file, bad BigTIFF offsetsize %" PRIu16
703
                          " (0x%" PRIx16 ")",
704
                          tif->tif_header.big.tiff_offsetsize,
×
705
                          tif->tif_header.big.tiff_offsetsize);
×
706
            goto bad;
×
707
        }
708
        if (tif->tif_header.big.tiff_unused != 0)
327✔
709
        {
710
            TIFFErrorExtR(tif, name,
×
711
                          "Not a TIFF file, bad BigTIFF unused %" PRIu16
712
                          " (0x%" PRIx16 ")",
713
                          tif->tif_header.big.tiff_unused,
×
714
                          tif->tif_header.big.tiff_unused);
×
715
            goto bad;
×
716
        }
717
        tif->tif_header_size = sizeof(TIFFHeaderBig);
327✔
718
        tif->tif_flags |= TIFF_BIGTIFF;
327✔
719
    }
720
    tif->tif_flags |= TIFF_MYBUFFER;
30,274✔
721
    tif->tif_rawcp = tif->tif_rawdata = 0;
30,274✔
722
    tif->tif_rawdatasize = 0;
30,274✔
723
    tif->tif_rawdataoff = 0;
30,274✔
724
    tif->tif_rawdataloaded = 0;
30,274✔
725

726
    switch (mode[0])
30,274✔
727
    {
728
        case 'r':
30,282✔
729
            if (!(tif->tif_flags & TIFF_BIGTIFF))
30,282✔
730
                tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
29,955✔
731
            else
732
                tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
327✔
733
            /*
734
             * Try to use a memory-mapped file if the client
735
             * has not explicitly suppressed usage with the
736
             * 'm' flag in the open mode (see above).
737
             */
738
            if (tif->tif_flags & TIFF_MAPPED)
30,282✔
739
            {
740
                toff_t n;
741
                if (TIFFMapFileContents(tif, (void **)(&tif->tif_base), &n))
26,560✔
742
                {
743
                    tif->tif_size = (tmsize_t)n;
7✔
744
                    assert((toff_t)tif->tif_size == n);
7✔
745
                }
746
                else
747
                    tif->tif_flags &= ~TIFF_MAPPED;
26,548✔
748
            }
749
            /*
750
             * Sometimes we do not want to read the first directory (for
751
             * example, it may be broken) and want to proceed to other
752
             * directories. I this case we use the TIFF_HEADERONLY flag to open
753
             * file and return immediately after reading TIFF header.
754
             * However, the pointer to TIFFSetField() and TIFFGetField()
755
             * (i.e. tif->tif_tagmethods.vsetfield and
756
             * tif->tif_tagmethods.vgetfield) need to be initialized, which is
757
             * done in TIFFDefaultDirectory().
758
             */
759
            if (tif->tif_flags & TIFF_HEADERONLY)
30,277✔
760
            {
761
                if (!TIFFDefaultDirectory(tif))
×
762
                    goto bad;
×
763
                return (tif);
×
764
            }
765

766
            /*
767
             * Setup initial directory.
768
             */
769
            if (TIFFReadDirectory(tif))
30,277✔
770
            {
771
                return (tif);
30,264✔
772
            }
773
            break;
15✔
774
        case 'a':
×
775
            /*
776
             * New directories are automatically append
777
             * to the end of the directory chain when they
778
             * are written out (see TIFFWriteDirectory).
779
             */
780
            if (!TIFFDefaultDirectory(tif))
×
781
                goto bad;
×
782
            return (tif);
×
783
    }
784
bad:
9✔
785
    tif->tif_mode = O_RDONLY; /* XXX avoid flush */
9✔
786
    TIFFCleanup(tif);
9✔
787
bad2:
15✔
788
    return ((TIFF *)0);
15✔
789
}
790

791
/*
792
 * Query functions to access private data.
793
 */
794

795
/*
796
 * Return open file's name.
797
 */
798
const char *TIFFFileName(TIFF *tif) { return (tif->tif_name); }
6✔
799

800
/*
801
 * Set the file name.
802
 */
803
const char *TIFFSetFileName(TIFF *tif, const char *name)
×
804
{
805
    const char *old_name = tif->tif_name;
×
806
    tif->tif_name = (char *)name;
×
807
    return (old_name);
×
808
}
809

810
/*
811
 * Return open file's I/O descriptor.
812
 */
813
int TIFFFileno(TIFF *tif) { return (tif->tif_fd); }
×
814

815
/*
816
 * Set open file's I/O descriptor, and return previous value.
817
 */
818
int TIFFSetFileno(TIFF *tif, int fd)
×
819
{
820
    int old_fd = tif->tif_fd;
×
821
    tif->tif_fd = fd;
×
822
    return old_fd;
×
823
}
824

825
/*
826
 * Return open file's clientdata.
827
 */
828
thandle_t TIFFClientdata(TIFF *tif) { return (tif->tif_clientdata); }
99,155✔
829

830
/*
831
 * Set open file's clientdata, and return previous value.
832
 */
833
thandle_t TIFFSetClientdata(TIFF *tif, thandle_t newvalue)
×
834
{
835
    thandle_t m = tif->tif_clientdata;
×
836
    tif->tif_clientdata = newvalue;
×
837
    return m;
×
838
}
839

840
/*
841
 * Return read/write mode.
842
 */
843
int TIFFGetMode(TIFF *tif) { return (tif->tif_mode); }
×
844

845
/*
846
 * Return read/write mode.
847
 */
848
int TIFFSetMode(TIFF *tif, int mode)
×
849
{
850
    int old_mode = tif->tif_mode;
×
851
    tif->tif_mode = mode;
×
852
    return (old_mode);
×
853
}
854

855
/*
856
 * Return nonzero if file is organized in
857
 * tiles; zero if organized as strips.
858
 */
859
int TIFFIsTiled(TIFF *tif) { return (isTiled(tif)); }
5,039,370✔
860

861
/*
862
 * Return current row being read/written.
863
 */
864
uint32_t TIFFCurrentRow(TIFF *tif) { return (tif->tif_row); }
×
865

866
/*
867
 * Return index of the current directory.
868
 */
869
tdir_t TIFFCurrentDirectory(TIFF *tif) { return (tif->tif_curdir); }
×
870

871
/*
872
 * Return current strip.
873
 */
874
uint32_t TIFFCurrentStrip(TIFF *tif) { return (tif->tif_curstrip); }
×
875

876
/*
877
 * Return current tile.
878
 */
879
uint32_t TIFFCurrentTile(TIFF *tif) { return (tif->tif_curtile); }
×
880

881
/*
882
 * Return nonzero if the file has byte-swapped data.
883
 */
884
int TIFFIsByteSwapped(TIFF *tif) { return ((tif->tif_flags & TIFF_SWAB) != 0); }
107,044✔
885

886
/*
887
 * Return nonzero if the data is returned up-sampled.
888
 */
889
int TIFFIsUpSampled(TIFF *tif) { return (isUpSampled(tif)); }
×
890

891
/*
892
 * Return nonzero if the data is returned in MSB-to-LSB bit order.
893
 */
894
int TIFFIsMSB2LSB(TIFF *tif) { return (isFillOrder(tif, FILLORDER_MSB2LSB)); }
×
895

896
/*
897
 * Return nonzero if given file was written in big-endian order.
898
 */
899
int TIFFIsBigEndian(TIFF *tif)
26,759✔
900
{
901
    return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
26,759✔
902
}
903

904
/*
905
 * Return nonzero if given file is BigTIFF style.
906
 */
907
int TIFFIsBigTIFF(TIFF *tif) { return ((tif->tif_flags & TIFF_BIGTIFF) != 0); }
×
908

909
/*
910
 * Return pointer to file read method.
911
 */
912
TIFFReadWriteProc TIFFGetReadProc(TIFF *tif) { return (tif->tif_readproc); }
×
913

914
/*
915
 * Return pointer to file write method.
916
 */
917
TIFFReadWriteProc TIFFGetWriteProc(TIFF *tif) { return (tif->tif_writeproc); }
×
918

919
/*
920
 * Return pointer to file seek method.
921
 */
922
TIFFSeekProc TIFFGetSeekProc(TIFF *tif) { return (tif->tif_seekproc); }
×
923

924
/*
925
 * Return pointer to file close method.
926
 */
927
TIFFCloseProc TIFFGetCloseProc(TIFF *tif) { return (tif->tif_closeproc); }
×
928

929
/*
930
 * Return pointer to file size requesting method.
931
 */
932
TIFFSizeProc TIFFGetSizeProc(TIFF *tif) { return (tif->tif_sizeproc); }
15,097✔
933

934
/*
935
 * Return pointer to memory mapping method.
936
 */
937
TIFFMapFileProc TIFFGetMapFileProc(TIFF *tif) { return (tif->tif_mapproc); }
×
938

939
/*
940
 * Return pointer to memory unmapping method.
941
 */
942
TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF *tif)
×
943
{
944
    return (tif->tif_unmapproc);
×
945
}
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