Coverage Report

Created: 2026-04-10 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/gtiff/libtiff/tif_read.c
Line
Count
Source
1
/*
2
 * Copyright (c) 1988-1997 Sam Leffler
3
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4
 *
5
 * Permission to use, copy, modify, distribute, and sell this software and
6
 * its documentation for any purpose is hereby granted without fee, provided
7
 * that (i) the above copyright notices and this permission notice appear in
8
 * all copies of the software and related documentation, and (ii) the names of
9
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10
 * publicity relating to the software without the specific, prior written
11
 * permission of Sam Leffler and Silicon Graphics.
12
 *
13
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16
 *
17
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22
 * OF THIS SOFTWARE.
23
 */
24
25
/*
26
 * TIFF Library.
27
 * Scanline-oriented Read Support
28
 */
29
#include "tiffiop.h"
30
#include <limits.h>
31
#include <stdio.h>
32
33
int TIFFFillStrip(TIFF *tif, uint32_t strip);
34
int TIFFFillTile(TIFF *tif, uint32_t tile);
35
static int TIFFStartStrip(TIFF *tif, uint32_t strip);
36
static int TIFFStartTile(TIFF *tif, uint32_t tile);
37
static int TIFFCheckRead(TIFF *, int);
38
static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
39
                                  tmsize_t size, const char *module);
40
static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
41
                                 tmsize_t size, const char *module);
42
43
0
#define NOSTRIP ((uint32_t)(-1)) /* undefined state */
44
0
#define NOTILE ((uint32_t)(-1))  /* undefined state */
45
46
0
#define INITIAL_THRESHOLD (1024 * 1024)
47
0
#define THRESHOLD_MULTIPLIER 10
48
#define MAX_THRESHOLD                                                          \
49
0
    (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER *      \
50
0
     INITIAL_THRESHOLD)
51
52
0
#define TIFF_INT64_MAX ((((int64_t)0x7FFFFFFF) << 32) | 0xFFFFFFFF)
53
54
/* Read 'size' bytes in tif_rawdata buffer starting at offset 'rawdata_offset'
55
 * Returns 1 in case of success, 0 otherwise. */
56
static int TIFFReadAndRealloc(TIFF *tif, tmsize_t size, tmsize_t rawdata_offset,
57
                              int is_strip, uint32_t strip_or_tile,
58
                              const char *module)
59
0
{
60
0
#if SIZEOF_SIZE_T == 8
61
0
    tmsize_t threshold = INITIAL_THRESHOLD;
62
0
#endif
63
0
    tmsize_t already_read = 0;
64
65
#if SIZEOF_SIZE_T != 8
66
    /* On 32 bit processes, if the request is large enough, check against */
67
    /* file size */
68
    if (size > 1000 * 1000 * 1000)
69
    {
70
        uint64_t filesize = TIFFGetFileSize(tif);
71
        if ((uint64_t)size >= filesize)
72
        {
73
            TIFFErrorExtR(tif, module,
74
                          "Chunk size requested is larger than file size.");
75
            return 0;
76
        }
77
    }
78
#endif
79
80
    /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
81
    /* so as to avoid allocating too much memory in case the file is too */
82
    /* short. We could ask for the file size, but this might be */
83
    /* expensive with some I/O layers (think of reading a gzipped file) */
84
    /* Restrict to 64 bit processes, so as to avoid reallocs() */
85
    /* on 32 bit processes where virtual memory is scarce.  */
86
0
    while (already_read < size)
87
0
    {
88
0
        tmsize_t bytes_read;
89
0
        tmsize_t to_read = size - already_read;
90
0
#if SIZEOF_SIZE_T == 8
91
0
        if (to_read >= threshold && threshold < MAX_THRESHOLD &&
92
0
            already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
93
0
        {
94
0
            to_read = threshold;
95
0
            threshold *= THRESHOLD_MULTIPLIER;
96
0
        }
97
0
#endif
98
0
        if (already_read + to_read + rawdata_offset > tif->tif_rawdatasize)
99
0
        {
100
0
            uint8_t *new_rawdata;
101
0
            assert((tif->tif_flags & TIFF_MYBUFFER) != 0);
102
0
            tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64(
103
0
                (uint64_t)already_read + (uint64_t)to_read +
104
0
                    (uint64_t)rawdata_offset,
105
0
                1024);
106
0
            if (tif->tif_rawdatasize == 0)
107
0
            {
108
0
                TIFFErrorExtR(tif, module, "Invalid buffer size");
109
0
                return 0;
110
0
            }
111
0
            new_rawdata = (uint8_t *)_TIFFreallocExt(tif, tif->tif_rawdata,
112
0
                                                     tif->tif_rawdatasize);
113
0
            if (new_rawdata == 0)
114
0
            {
115
0
                TIFFErrorExtR(tif, module,
116
0
                              "No space for data buffer at scanline %" PRIu32,
117
0
                              tif->tif_row);
118
0
                _TIFFfreeExt(tif, tif->tif_rawdata);
119
0
                tif->tif_rawdata = 0;
120
0
                tif->tif_rawdatasize = 0;
121
0
                return 0;
122
0
            }
123
0
            tif->tif_rawdata = new_rawdata;
124
0
        }
125
0
        if (tif->tif_rawdata == NULL)
126
0
        {
127
            /* should not happen in practice but helps CoverityScan */
128
0
            return 0;
129
0
        }
130
131
0
        bytes_read = TIFFReadFile(
132
0
            tif, tif->tif_rawdata + rawdata_offset + already_read, to_read);
133
0
        already_read += bytes_read;
134
0
        if (bytes_read != to_read)
135
0
        {
136
0
            memset(
137
0
                tif->tif_rawdata + rawdata_offset + already_read, 0,
138
0
                (size_t)(tif->tif_rawdatasize - rawdata_offset - already_read));
139
0
            if (is_strip)
140
0
            {
141
0
                TIFFErrorExtR(tif, module,
142
0
                              "Read error at scanline %" PRIu32
143
0
                              "; got %" TIFF_SSIZE_FORMAT " bytes, "
144
0
                              "expected %" TIFF_SSIZE_FORMAT,
145
0
                              tif->tif_row, already_read, size);
146
0
            }
147
0
            else
148
0
            {
149
0
                TIFFErrorExtR(tif, module,
150
0
                              "Read error at row %" PRIu32 ", col %" PRIu32
151
0
                              ", tile %" PRIu32 "; "
152
0
                              "got %" TIFF_SSIZE_FORMAT
153
0
                              " bytes, expected %" TIFF_SSIZE_FORMAT "",
154
0
                              tif->tif_row, tif->tif_col, strip_or_tile,
155
0
                              already_read, size);
156
0
            }
157
0
            return 0;
158
0
        }
159
0
    }
160
0
    return 1;
161
0
}
162
163
static int TIFFFillStripPartial(TIFF *tif, int strip, tmsize_t read_ahead,
164
                                int restart)
165
0
{
166
0
    static const char module[] = "TIFFFillStripPartial";
167
0
    TIFFDirectory *td = &tif->tif_dir;
168
0
    tmsize_t unused_data;
169
0
    uint64_t read_offset;
170
0
    tmsize_t to_read;
171
0
    tmsize_t read_ahead_mod;
172
    /* tmsize_t bytecountm; */
173
174
    /*
175
     * Expand raw data buffer, if needed, to hold data
176
     * strip coming from file (perhaps should set upper
177
     * bound on the size of a buffer we'll use?).
178
     */
179
180
    /* bytecountm=(tmsize_t) TIFFGetStrileByteCount(tif, strip); */
181
182
    /* Not completely sure where the * 2 comes from, but probably for */
183
    /* an exponentional growth strategy of tif_rawdatasize */
184
0
    if (read_ahead < TIFF_TMSIZE_T_MAX / 2)
185
0
        read_ahead_mod = read_ahead * 2;
186
0
    else
187
0
        read_ahead_mod = read_ahead;
188
0
    if (read_ahead_mod > tif->tif_rawdatasize)
189
0
    {
190
0
        assert(restart);
191
192
0
        tif->tif_curstrip = NOSTRIP;
193
0
        if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
194
0
        {
195
0
            TIFFErrorExtR(tif, module,
196
0
                          "Data buffer too small to hold part of strip %d",
197
0
                          strip);
198
0
            return (0);
199
0
        }
200
0
    }
201
202
0
    if (restart)
203
0
    {
204
0
        tif->tif_rawdataloaded = 0;
205
0
        tif->tif_rawdataoff = 0;
206
0
    }
207
208
    /*
209
    ** If we are reading more data, move any unused data to the
210
    ** start of the buffer.
211
    */
212
0
    if (tif->tif_rawdataloaded > 0)
213
0
        unused_data =
214
0
            tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
215
0
    else
216
0
        unused_data = 0;
217
218
0
    if (unused_data > 0)
219
0
    {
220
0
        assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
221
0
        memmove(tif->tif_rawdata, tif->tif_rawcp, (size_t)unused_data);
222
0
    }
223
224
    /*
225
    ** Seek to the point in the file where more data should be read.
226
    */
227
0
    read_offset = TIFFGetStrileOffset(tif, (uint32_t)strip);
228
0
    if (read_offset > UINT64_MAX - (uint64_t)tif->tif_rawdataoff ||
229
0
        read_offset + (uint64_t)tif->tif_rawdataoff >
230
0
            UINT64_MAX - (uint64_t)tif->tif_rawdataloaded)
231
0
    {
232
0
        TIFFErrorExtR(tif, module,
233
0
                      "Seek error at scanline %" PRIu32 ", strip %d",
234
0
                      tif->tif_row, strip);
235
0
        return 0;
236
0
    }
237
0
    read_offset +=
238
0
        (uint64_t)tif->tif_rawdataoff + (uint64_t)tif->tif_rawdataloaded;
239
240
0
    if (!SeekOK(tif, read_offset))
241
0
    {
242
0
        TIFFErrorExtR(tif, module,
243
0
                      "Seek error at scanline %" PRIu32 ", strip %d",
244
0
                      tif->tif_row, strip);
245
0
        return 0;
246
0
    }
247
248
    /*
249
    ** How much do we want to read?
250
    */
251
0
    if (read_ahead_mod > tif->tif_rawdatasize)
252
0
        to_read = read_ahead_mod - unused_data;
253
0
    else
254
0
        to_read = tif->tif_rawdatasize - unused_data;
255
0
    if ((uint64_t)to_read > TIFFGetStrileByteCount(tif, (uint32_t)strip) -
256
0
                                (uint64_t)tif->tif_rawdataoff -
257
0
                                (uint64_t)tif->tif_rawdataloaded)
258
0
    {
259
0
        to_read = (tmsize_t)(TIFFGetStrileByteCount(tif, (uint32_t)strip) -
260
0
                             (uint64_t)tif->tif_rawdataoff -
261
0
                             (uint64_t)tif->tif_rawdataloaded);
262
0
    }
263
264
0
    assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
265
0
    if (!TIFFReadAndRealloc(tif, to_read, unused_data, 1, /* is_strip */
266
0
                            0,                            /* strip_or_tile */
267
0
                            module))
268
0
    {
269
0
        return 0;
270
0
    }
271
272
0
    tif->tif_rawdataoff =
273
0
        tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data;
274
0
    tif->tif_rawdataloaded = unused_data + to_read;
275
276
0
    tif->tif_rawcc = tif->tif_rawdataloaded;
277
0
    tif->tif_rawcp = tif->tif_rawdata;
278
279
0
    if (!isFillOrder(tif, td->td_fillorder) &&
280
0
        (tif->tif_flags & TIFF_NOBITREV) == 0)
281
0
    {
282
0
        assert((tif->tif_flags & TIFF_BUFFERMMAP) == 0);
283
0
        TIFFReverseBits(tif->tif_rawdata + unused_data, to_read);
284
0
    }
285
286
    /*
287
    ** When starting a strip from the beginning we need to
288
    ** restart the decoder.
289
    */
290
0
    if (restart)
291
0
    {
292
293
0
#ifdef JPEG_SUPPORT
294
        /* A bit messy since breaks the codec abstraction. Ultimately */
295
        /* there should be a function pointer for that, but it seems */
296
        /* only JPEG is affected. */
297
        /* For JPEG, if there are multiple scans (can generally be known */
298
        /* with the  read_ahead used), we need to read the whole strip */
299
0
        if (tif->tif_dir.td_compression == COMPRESSION_JPEG &&
300
0
            (uint64_t)tif->tif_rawcc <
301
0
                TIFFGetStrileByteCount(tif, (uint32_t)strip))
302
0
        {
303
0
            if (TIFFJPEGIsFullStripRequired(tif))
304
0
            {
305
0
                return TIFFFillStrip(tif, (uint32_t)strip);
306
0
            }
307
0
        }
308
0
#endif
309
310
0
        return TIFFStartStrip(tif, (uint32_t)strip);
311
0
    }
312
0
    else
313
0
    {
314
0
        return 1;
315
0
    }
316
0
}
317
318
/*
319
 * Seek to a random row+sample in a file.
320
 *
321
 * Only used by TIFFReadScanline, and is only used on
322
 * strip organized files.  We do some tricky stuff to try
323
 * and avoid reading the whole compressed raw data for big
324
 * strips.
325
 */
326
static int TIFFSeek(TIFF *tif, uint32_t row, uint16_t sample)
327
0
{
328
0
    TIFFDirectory *td = &tif->tif_dir;
329
0
    uint32_t strip;
330
0
    int whole_strip;
331
0
    tmsize_t read_ahead = 0;
332
333
    /*
334
    ** Establish what strip we are working from.
335
    */
336
0
    if (row >= td->td_imagelength)
337
0
    { /* out of range */
338
0
        TIFFErrorExtR(tif, tif->tif_name,
339
0
                      "%" PRIu32 ": Row out of range, max %" PRIu32 "", row,
340
0
                      td->td_imagelength);
341
0
        return (0);
342
0
    }
343
0
    if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
344
0
    {
345
0
        if (sample >= td->td_samplesperpixel)
346
0
        {
347
0
            TIFFErrorExtR(tif, tif->tif_name,
348
0
                          "%" PRIu16 ": Sample out of range, max %" PRIu16 "",
349
0
                          sample, td->td_samplesperpixel);
350
0
            return (0);
351
0
        }
352
0
        strip = (uint32_t)sample * td->td_stripsperimage +
353
0
                row / td->td_rowsperstrip;
354
0
    }
355
0
    else
356
0
        strip = row / td->td_rowsperstrip;
357
358
        /*
359
         * Do we want to treat this strip as one whole chunk or
360
         * read it a few lines at a time?
361
         */
362
0
#if defined(CHUNKY_STRIP_READ_SUPPORT)
363
0
    whole_strip = TIFFGetStrileByteCount(tif, strip) < 10 || isMapped(tif);
364
0
    if (td->td_compression == COMPRESSION_LERC ||
365
0
        td->td_compression == COMPRESSION_JBIG)
366
0
    {
367
        /* Ideally plugins should have a way to declare they don't support
368
         * chunk strip */
369
0
        whole_strip = 1;
370
0
    }
371
372
0
    if (!whole_strip)
373
0
    {
374
        /* 16 is for YCbCr mode where we may need to read 16 */
375
        /* lines at a time to get a decompressed line, and 5000 */
376
        /* is some constant value, for example for JPEG tables */
377
378
        /* coverity[dead_error_line:SUPPRESS] */
379
0
        if (tif->tif_scanlinesize < TIFF_TMSIZE_T_MAX / 16 &&
380
0
            tif->tif_scanlinesize * 16 < TIFF_TMSIZE_T_MAX - 5000)
381
0
        {
382
0
            read_ahead = tif->tif_scanlinesize * 16 + 5000;
383
0
        }
384
0
        else
385
0
        {
386
0
            read_ahead = tif->tif_scanlinesize;
387
0
        }
388
0
    }
389
#else
390
    whole_strip = 1;
391
#endif
392
393
    /*
394
     * If we haven't loaded this strip, do so now, possibly
395
     * only reading the first part.
396
     */
397
0
    if (strip != tif->tif_curstrip)
398
0
    { /* different strip, refill */
399
400
0
        if (whole_strip)
401
0
        {
402
0
            if (!TIFFFillStrip(tif, strip))
403
0
                return (0);
404
0
        }
405
0
#if defined(CHUNKY_STRIP_READ_SUPPORT)
406
0
        else
407
0
        {
408
0
            if (!TIFFFillStripPartial(tif, strip, read_ahead, 1))
409
0
                return 0;
410
0
        }
411
0
#endif
412
0
    }
413
414
0
#if defined(CHUNKY_STRIP_READ_SUPPORT)
415
    /*
416
    ** If we already have some data loaded, do we need to read some more?
417
    */
418
0
    else if (!whole_strip)
419
0
    {
420
        /* coverity[dead_error_line:SUPPRESS] */
421
0
        if (((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) <
422
0
                read_ahead &&
423
0
            (uint64_t)tif->tif_rawdataoff + tif->tif_rawdataloaded <
424
0
                TIFFGetStrileByteCount(tif, strip))
425
0
        {
426
0
            if (!TIFFFillStripPartial(tif, strip, read_ahead, 0))
427
0
                return 0;
428
0
        }
429
0
    }
430
0
#endif
431
432
0
    if (row < tif->tif_row)
433
0
    {
434
        /*
435
         * Moving backwards within the same strip: backup
436
         * to the start and then decode forward (below).
437
         *
438
         * NB: If you're planning on lots of random access within a
439
         * strip, it's better to just read and decode the entire
440
         * strip, and then access the decoded data in a random fashion.
441
         */
442
443
0
        if (tif->tif_rawdataoff != 0)
444
0
        {
445
0
            if (!TIFFFillStripPartial(tif, (int)strip, read_ahead, 1))
446
0
                return 0;
447
0
        }
448
0
        else
449
0
        {
450
0
            if (!TIFFStartStrip(tif, strip))
451
0
                return (0);
452
0
        }
453
0
    }
454
455
0
    if (row != tif->tif_row)
456
0
    {
457
        /*
458
         * Seek forward to the desired row.
459
         */
460
461
        /* TODO: Will this really work with partial buffers? */
462
463
0
        if (!(*tif->tif_seek)(tif, row - tif->tif_row))
464
0
            return (0);
465
0
        tif->tif_row = row;
466
0
    }
467
468
0
    return (1);
469
0
}
470
471
int TIFFReadScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
472
0
{
473
0
    int e;
474
475
0
    if (!TIFFCheckRead(tif, 0))
476
0
        return (-1);
477
0
    if ((e = TIFFSeek(tif, row, sample)) != 0)
478
0
    {
479
        /*
480
         * Decompress desired row into user buffer.
481
         */
482
0
        e = (*tif->tif_decoderow)(tif, (uint8_t *)buf, tif->tif_scanlinesize,
483
0
                                  sample);
484
485
        /* we are now poised at the beginning of the next row */
486
0
        tif->tif_row = row + 1;
487
488
0
        if (e)
489
0
            (*tif->tif_postdecode)(tif, (uint8_t *)buf, tif->tif_scanlinesize);
490
0
    }
491
0
    else
492
0
    {
493
        /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
494
0
        if (buf)
495
0
            memset(buf, 0, (size_t)tif->tif_scanlinesize);
496
0
    }
497
0
    return (e > 0 ? 1 : -1);
498
0
}
499
500
/*
501
 * Calculate the strip size according to the number of
502
 * rows in the strip (check for truncated last strip on any
503
 * of the separations).
504
 */
505
static tmsize_t TIFFReadEncodedStripGetStripSize(TIFF *tif, uint32_t strip,
506
                                                 uint16_t *pplane)
507
0
{
508
0
    static const char module[] = "TIFFReadEncodedStrip";
509
0
    TIFFDirectory *td = &tif->tif_dir;
510
0
    uint32_t rowsperstrip;
511
0
    uint32_t stripsperplane;
512
0
    uint32_t stripinplane;
513
0
    uint32_t rows;
514
0
    tmsize_t stripsize;
515
0
    if (!TIFFCheckRead(tif, 0))
516
0
        return ((tmsize_t)(-1));
517
0
    if (strip >= td->td_nstrips)
518
0
    {
519
0
        TIFFErrorExtR(tif, module,
520
0
                      "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
521
0
                      td->td_nstrips);
522
0
        return ((tmsize_t)(-1));
523
0
    }
524
525
0
    rowsperstrip = td->td_rowsperstrip;
526
0
    if (rowsperstrip > td->td_imagelength)
527
0
        rowsperstrip = td->td_imagelength;
528
0
    if (rowsperstrip == 0)
529
0
    {
530
0
        TIFFErrorExtR(tif, module, "rowsperstrip is zero");
531
0
        return ((tmsize_t)(-1));
532
0
    }
533
0
    stripsperplane =
534
0
        TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
535
0
    stripinplane = (strip % stripsperplane);
536
0
    if (pplane)
537
0
        *pplane = (uint16_t)(strip / stripsperplane);
538
0
    rows = td->td_imagelength - stripinplane * rowsperstrip;
539
0
    if (rows > rowsperstrip)
540
0
        rows = rowsperstrip;
541
0
    stripsize = TIFFVStripSize(tif, rows);
542
0
    if (stripsize == 0)
543
0
        return ((tmsize_t)(-1));
544
0
    return stripsize;
545
0
}
546
547
/*
548
 * Read a strip of data and decompress the specified
549
 * amount into the user-supplied buffer.
550
 */
551
tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32_t strip, void *buf,
552
                              tmsize_t size)
553
0
{
554
0
    static const char module[] = "TIFFReadEncodedStrip";
555
0
    TIFFDirectory *td = &tif->tif_dir;
556
0
    tmsize_t stripsize;
557
0
    uint16_t plane;
558
559
0
    stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
560
0
    if (stripsize == ((tmsize_t)(-1)))
561
0
        return ((tmsize_t)(-1));
562
563
    /* shortcut to avoid an extra memcpy() */
564
0
    if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
565
0
        size >= stripsize && !isMapped(tif) &&
566
0
        ((tif->tif_flags & TIFF_NOREADRAW) == 0))
567
0
    {
568
0
        if (TIFFReadRawStrip1(tif, strip, buf, stripsize, module) != stripsize)
569
0
            return ((tmsize_t)(-1));
570
571
0
        if (!isFillOrder(tif, td->td_fillorder) &&
572
0
            (tif->tif_flags & TIFF_NOBITREV) == 0)
573
0
            TIFFReverseBits((uint8_t *)buf, stripsize);
574
575
0
        (*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
576
0
        return (stripsize);
577
0
    }
578
579
0
    if ((size != (tmsize_t)(-1)) && (size < stripsize))
580
0
        stripsize = size;
581
0
    if (!TIFFFillStrip(tif, strip))
582
0
    {
583
        /* The output buf may be NULL, in particular if TIFFTAG_FAXFILLFUNC
584
           is being used. Thus, memset must be conditional on buf not NULL. */
585
0
        if (buf)
586
0
            memset(buf, 0, (size_t)stripsize);
587
0
        return ((tmsize_t)(-1));
588
0
    }
589
0
    if ((*tif->tif_decodestrip)(tif, (uint8_t *)buf, stripsize, plane) <= 0)
590
0
        return ((tmsize_t)(-1));
591
0
    (*tif->tif_postdecode)(tif, (uint8_t *)buf, stripsize);
592
0
    return (stripsize);
593
0
}
594
595
/* Variant of TIFFReadEncodedStrip() that does
596
 * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
597
 * TIFFFillStrip() has succeeded. This avoid excessive memory allocation in case
598
 * of truncated file.
599
 * * calls regular TIFFReadEncodedStrip() if *buf != NULL
600
 */
601
tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32_t strip,
602
                                             void **buf,
603
                                             tmsize_t bufsizetoalloc,
604
                                             tmsize_t size_to_read)
605
0
{
606
0
    tmsize_t this_stripsize;
607
0
    uint16_t plane;
608
609
0
    if (*buf != NULL)
610
0
    {
611
0
        return TIFFReadEncodedStrip(tif, strip, *buf, size_to_read);
612
0
    }
613
614
0
    this_stripsize = TIFFReadEncodedStripGetStripSize(tif, strip, &plane);
615
0
    if (this_stripsize == ((tmsize_t)(-1)))
616
0
        return ((tmsize_t)(-1));
617
618
0
    if ((size_to_read != (tmsize_t)(-1)) && (size_to_read < this_stripsize))
619
0
        this_stripsize = size_to_read;
620
0
    if (!TIFFFillStrip(tif, strip))
621
0
        return ((tmsize_t)(-1));
622
623
0
    *buf = _TIFFmallocExt(tif, bufsizetoalloc);
624
0
    if (*buf == NULL)
625
0
    {
626
0
        TIFFErrorExtR(tif, TIFFFileName(tif), "No space for strip buffer");
627
0
        return ((tmsize_t)(-1));
628
0
    }
629
0
    _TIFFmemset(*buf, 0, bufsizetoalloc);
630
631
0
    if ((*tif->tif_decodestrip)(tif, (uint8_t *)*buf, this_stripsize, plane) <=
632
0
        0)
633
0
        return ((tmsize_t)(-1));
634
0
    (*tif->tif_postdecode)(tif, (uint8_t *)*buf, this_stripsize);
635
0
    return (this_stripsize);
636
0
}
637
638
static tmsize_t TIFFReadRawStrip1(TIFF *tif, uint32_t strip, void *buf,
639
                                  tmsize_t size, const char *module)
640
0
{
641
0
    assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
642
0
    if (!isMapped(tif))
643
0
    {
644
0
        tmsize_t cc;
645
646
0
        if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip)))
647
0
        {
648
0
            TIFFErrorExtR(tif, module,
649
0
                          "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
650
0
                          tif->tif_row, strip);
651
0
            return ((tmsize_t)(-1));
652
0
        }
653
0
        cc = TIFFReadFile(tif, buf, size);
654
0
        if (cc != size)
655
0
        {
656
0
            TIFFErrorExtR(tif, module,
657
0
                          "Read error at scanline %" PRIu32
658
0
                          "; got %" TIFF_SSIZE_FORMAT
659
0
                          " bytes, expected %" TIFF_SSIZE_FORMAT,
660
0
                          tif->tif_row, cc, size);
661
0
            return ((tmsize_t)(-1));
662
0
        }
663
0
    }
664
0
    else
665
0
    {
666
0
        tmsize_t ma = 0;
667
0
        tmsize_t n;
668
0
        if ((TIFFGetStrileOffset(tif, strip) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
669
0
            ((ma = (tmsize_t)TIFFGetStrileOffset(tif, strip)) > tif->tif_size))
670
0
        {
671
0
            n = 0;
672
0
        }
673
0
        else if (ma > TIFF_TMSIZE_T_MAX - size)
674
0
        {
675
0
            n = 0;
676
0
        }
677
0
        else
678
0
        {
679
0
            tmsize_t mb = ma + size;
680
0
            if (mb > tif->tif_size)
681
0
                n = tif->tif_size - ma;
682
0
            else
683
0
                n = size;
684
0
        }
685
0
        if (n != size)
686
0
        {
687
0
            TIFFErrorExtR(tif, module,
688
0
                          "Read error at scanline %" PRIu32 ", strip %" PRIu32
689
0
                          "; got %" TIFF_SSIZE_FORMAT
690
0
                          " bytes, expected %" TIFF_SSIZE_FORMAT,
691
0
                          tif->tif_row, strip, n, size);
692
0
            return ((tmsize_t)(-1));
693
0
        }
694
0
        _TIFFmemcpy(buf, tif->tif_base + ma, size);
695
0
    }
696
0
    return (size);
697
0
}
698
699
static tmsize_t TIFFReadRawStripOrTile2(TIFF *tif, uint32_t strip_or_tile,
700
                                        int is_strip, tmsize_t size,
701
                                        const char *module)
702
0
{
703
0
    assert(!isMapped(tif));
704
0
    assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
705
706
0
    if (!SeekOK(tif, TIFFGetStrileOffset(tif, strip_or_tile)))
707
0
    {
708
0
        if (is_strip)
709
0
        {
710
0
            TIFFErrorExtR(tif, module,
711
0
                          "Seek error at scanline %" PRIu32 ", strip %" PRIu32,
712
0
                          tif->tif_row, strip_or_tile);
713
0
        }
714
0
        else
715
0
        {
716
0
            TIFFErrorExtR(tif, module,
717
0
                          "Seek error at row %" PRIu32 ", col %" PRIu32
718
0
                          ", tile %" PRIu32,
719
0
                          tif->tif_row, tif->tif_col, strip_or_tile);
720
0
        }
721
0
        return ((tmsize_t)(-1));
722
0
    }
723
724
0
    if (!TIFFReadAndRealloc(tif, size, 0, is_strip, strip_or_tile, module))
725
0
    {
726
0
        return ((tmsize_t)(-1));
727
0
    }
728
729
0
    return (size);
730
0
}
731
732
/*
733
 * Read a strip of data from the file.
734
 */
735
tmsize_t TIFFReadRawStrip(TIFF *tif, uint32_t strip, void *buf, tmsize_t size)
736
0
{
737
0
    static const char module[] = "TIFFReadRawStrip";
738
0
    TIFFDirectory *td = &tif->tif_dir;
739
0
    uint64_t bytecount64;
740
0
    tmsize_t bytecountm;
741
742
0
    if (!TIFFCheckRead(tif, 0))
743
0
        return ((tmsize_t)(-1));
744
0
    if (strip >= td->td_nstrips)
745
0
    {
746
0
        TIFFErrorExtR(tif, module,
747
0
                      "%" PRIu32 ": Strip out of range, max %" PRIu32, strip,
748
0
                      td->td_nstrips);
749
0
        return ((tmsize_t)(-1));
750
0
    }
751
0
    if (tif->tif_flags & TIFF_NOREADRAW)
752
0
    {
753
0
        TIFFErrorExtR(tif, module,
754
0
                      "Compression scheme does not support access to raw "
755
0
                      "uncompressed data");
756
0
        return ((tmsize_t)(-1));
757
0
    }
758
0
    bytecount64 = TIFFGetStrileByteCount(tif, strip);
759
0
    if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
760
0
        bytecountm = size;
761
0
    else
762
0
        bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
763
0
    if (bytecountm == 0)
764
0
    {
765
0
        return ((tmsize_t)(-1));
766
0
    }
767
0
    return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
768
0
}
769
770
TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
771
0
static uint64_t NoSanitizeSubUInt64(uint64_t a, uint64_t b) { return a - b; }
772
773
/*
774
 * Read the specified strip and setup for decoding. The data buffer is
775
 * expanded, as necessary, to hold the strip's data.
776
 */
777
int TIFFFillStrip(TIFF *tif, uint32_t strip)
778
0
{
779
0
    static const char module[] = "TIFFFillStrip";
780
0
    TIFFDirectory *td = &tif->tif_dir;
781
782
0
    if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
783
0
    {
784
0
        uint64_t bytecount = TIFFGetStrileByteCount(tif, strip);
785
0
        if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
786
0
        {
787
0
            TIFFErrorExtR(tif, module,
788
0
                          "Invalid strip byte count %" PRIu64
789
0
                          ", strip %" PRIu32,
790
0
                          bytecount, strip);
791
0
            return (0);
792
0
        }
793
794
        /* To avoid excessive memory allocations: */
795
        /* Byte count should normally not be larger than a number of */
796
        /* times the uncompressed size plus some margin */
797
0
        if (bytecount > 1024 * 1024)
798
0
        {
799
            /* 10 and 4096 are just values that could be adjusted. */
800
            /* Hopefully they are safe enough for all codecs */
801
0
            tmsize_t stripsize = TIFFStripSize(tif);
802
0
            if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
803
0
            {
804
0
                uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
805
0
                TIFFErrorExtR(tif, module,
806
0
                              "Too large strip byte count %" PRIu64
807
0
                              ", strip %" PRIu32 ". Limiting to %" PRIu64,
808
0
                              bytecount, strip, newbytecount);
809
0
                bytecount = newbytecount;
810
0
            }
811
0
        }
812
813
0
        if (isMapped(tif))
814
0
        {
815
            /*
816
             * We must check for overflow, potentially causing
817
             * an OOB read. Instead of simple
818
             *
819
             *  TIFFGetStrileOffset(tif, strip)+bytecount > tif->tif_size
820
             *
821
             * comparison (which can overflow) we do the following
822
             * two comparisons:
823
             */
824
0
            if (bytecount > (uint64_t)tif->tif_size ||
825
0
                TIFFGetStrileOffset(tif, strip) >
826
0
                    (uint64_t)tif->tif_size - bytecount)
827
0
            {
828
                /*
829
                 * This error message might seem strange, but
830
                 * it's what would happen if a read were done
831
                 * instead.
832
                 */
833
0
                TIFFErrorExtR(
834
0
                    tif, module,
835
836
0
                    "Read error on strip %" PRIu32 "; "
837
0
                    "got %" PRIu64 " bytes, expected %" PRIu64,
838
0
                    strip,
839
0
                    NoSanitizeSubUInt64((uint64_t)tif->tif_size,
840
0
                                        TIFFGetStrileOffset(tif, strip)),
841
0
                    bytecount);
842
0
                tif->tif_curstrip = NOSTRIP;
843
0
                return (0);
844
0
            }
845
0
        }
846
847
0
        if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
848
0
                              (tif->tif_flags & TIFF_NOBITREV)))
849
0
        {
850
            /*
851
             * The image is mapped into memory and we either don't
852
             * need to flip bits or the compression routine is
853
             * going to handle this operation itself.  In this
854
             * case, avoid copying the raw data and instead just
855
             * reference the data from the memory mapped file
856
             * image.  This assumes that the decompression
857
             * routines do not modify the contents of the raw data
858
             * buffer (if they try to, the application will get a
859
             * fault since the file is mapped read-only).
860
             */
861
0
            if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
862
0
            {
863
0
                _TIFFfreeExt(tif, tif->tif_rawdata);
864
0
                tif->tif_rawdata = NULL;
865
0
                tif->tif_rawdatasize = 0;
866
0
            }
867
0
            tif->tif_flags &= ~TIFF_MYBUFFER;
868
0
            tif->tif_rawdatasize = (tmsize_t)bytecount;
869
0
            tif->tif_rawdata =
870
0
                tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, strip);
871
0
            tif->tif_rawdataoff = 0;
872
0
            tif->tif_rawdataloaded = (tmsize_t)bytecount;
873
874
            /*
875
             * When we have tif_rawdata reference directly into the memory
876
             * mapped file we need to be pretty careful about how we use the
877
             * rawdata.  It is not a general purpose working buffer as it
878
             * normally otherwise is.  So we keep track of this fact to avoid
879
             * using it improperly.
880
             */
881
0
            tif->tif_flags |= TIFF_BUFFERMMAP;
882
0
        }
883
0
        else
884
0
        {
885
            /*
886
             * Expand raw data buffer, if needed, to hold data
887
             * strip coming from file (perhaps should set upper
888
             * bound on the size of a buffer we'll use?).
889
             */
890
0
            tmsize_t bytecountm;
891
0
            bytecountm = (tmsize_t)bytecount;
892
0
            if ((uint64_t)bytecountm != bytecount)
893
0
            {
894
0
                TIFFErrorExtR(tif, module, "Integer overflow");
895
0
                return (0);
896
0
            }
897
0
            if (bytecountm > tif->tif_rawdatasize)
898
0
            {
899
0
                tif->tif_curstrip = NOSTRIP;
900
0
                if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
901
0
                {
902
0
                    TIFFErrorExtR(
903
0
                        tif, module,
904
0
                        "Data buffer too small to hold strip %" PRIu32, strip);
905
0
                    return (0);
906
0
                }
907
0
            }
908
0
            if (tif->tif_flags & TIFF_BUFFERMMAP)
909
0
            {
910
0
                tif->tif_curstrip = NOSTRIP;
911
0
                tif->tif_rawdata = NULL;
912
0
                tif->tif_rawdatasize = 0;
913
0
                tif->tif_flags &= ~TIFF_BUFFERMMAP;
914
0
            }
915
916
0
            if (isMapped(tif))
917
0
            {
918
0
                if (bytecountm > tif->tif_rawdatasize &&
919
0
                    !TIFFReadBufferSetup(tif, 0, bytecountm))
920
0
                {
921
0
                    return (0);
922
0
                }
923
0
                if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata, bytecountm,
924
0
                                      module) != bytecountm)
925
0
                {
926
0
                    return (0);
927
0
                }
928
0
            }
929
0
            else
930
0
            {
931
0
                if (TIFFReadRawStripOrTile2(tif, strip, 1, bytecountm,
932
0
                                            module) != bytecountm)
933
0
                {
934
0
                    return (0);
935
0
                }
936
0
            }
937
938
0
            tif->tif_rawdataoff = 0;
939
0
            tif->tif_rawdataloaded = bytecountm;
940
941
0
            if (!isFillOrder(tif, td->td_fillorder) &&
942
0
                (tif->tif_flags & TIFF_NOBITREV) == 0)
943
0
                TIFFReverseBits(tif->tif_rawdata, bytecountm);
944
0
        }
945
0
    }
946
0
    return (TIFFStartStrip(tif, strip));
947
0
}
948
949
/*
950
 * Tile-oriented Read Support
951
 * Contributed by Nancy Cam (Silicon Graphics).
952
 */
953
954
/*
955
 * Read and decompress a tile of data.  The
956
 * tile is selected by the (x,y,z,s) coordinates.
957
 */
958
tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
959
                      uint16_t s)
960
0
{
961
0
    if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
962
0
        return ((tmsize_t)(-1));
963
0
    return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
964
0
                                (tmsize_t)(-1)));
965
0
}
966
967
/*
968
 * Read a tile of data and decompress the specified
969
 * amount into the user-supplied buffer.
970
 */
971
tmsize_t TIFFReadEncodedTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
972
0
{
973
0
    static const char module[] = "TIFFReadEncodedTile";
974
0
    TIFFDirectory *td = &tif->tif_dir;
975
0
    tmsize_t tilesize = tif->tif_tilesize;
976
977
0
    if (!TIFFCheckRead(tif, 1))
978
0
        return ((tmsize_t)(-1));
979
0
    if (tile >= td->td_nstrips)
980
0
    {
981
0
        TIFFErrorExtR(tif, module,
982
0
                      "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
983
0
                      td->td_nstrips);
984
0
        return ((tmsize_t)(-1));
985
0
    }
986
987
    /* shortcut to avoid an extra memcpy() */
988
0
    if (td->td_compression == COMPRESSION_NONE && size != (tmsize_t)(-1) &&
989
0
        size >= tilesize && !isMapped(tif) &&
990
0
        ((tif->tif_flags & TIFF_NOREADRAW) == 0))
991
0
    {
992
0
        if (TIFFReadRawTile1(tif, tile, buf, tilesize, module) != tilesize)
993
0
            return ((tmsize_t)(-1));
994
995
0
        if (!isFillOrder(tif, td->td_fillorder) &&
996
0
            (tif->tif_flags & TIFF_NOBITREV) == 0)
997
0
            TIFFReverseBits((uint8_t *)buf, tilesize);
998
999
0
        (*tif->tif_postdecode)(tif, (uint8_t *)buf, tilesize);
1000
0
        return (tilesize);
1001
0
    }
1002
1003
0
    if (size == (tmsize_t)(-1))
1004
0
        size = tilesize;
1005
0
    else if (size > tilesize)
1006
0
        size = tilesize;
1007
0
    if (!TIFFFillTile(tif, tile))
1008
0
    {
1009
        /* See TIFFReadEncodedStrip comment regarding TIFFTAG_FAXFILLFUNC. */
1010
0
        if (buf)
1011
0
            memset(buf, 0, (size_t)size);
1012
0
        return ((tmsize_t)(-1));
1013
0
    }
1014
0
    else if ((*tif->tif_decodetile)(tif, (uint8_t *)buf, size,
1015
0
                                    (uint16_t)(tile / td->td_stripsperimage)))
1016
0
    {
1017
0
        (*tif->tif_postdecode)(tif, (uint8_t *)buf, size);
1018
0
        return (size);
1019
0
    }
1020
0
    else
1021
0
        return ((tmsize_t)(-1));
1022
0
}
1023
1024
/* Variant of TIFFReadTile() that does
1025
 * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
1026
 * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
1027
 * of truncated file.
1028
 * * calls regular TIFFReadEncodedTile() if *buf != NULL
1029
 */
1030
tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf,
1031
                                     tmsize_t bufsizetoalloc, uint32_t x,
1032
                                     uint32_t y, uint32_t z, uint16_t s)
1033
0
{
1034
0
    if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
1035
0
        return ((tmsize_t)(-1));
1036
0
    return (_TIFFReadEncodedTileAndAllocBuffer(
1037
0
        tif, TIFFComputeTile(tif, x, y, z, s), buf, bufsizetoalloc,
1038
0
        (tmsize_t)(-1)));
1039
0
}
1040
1041
/* Variant of TIFFReadEncodedTile() that does
1042
 * * if *buf == NULL, *buf = _TIFFmallocExt(tif, bufsizetoalloc) only after
1043
 * TIFFFillTile() has succeeded. This avoid excessive memory allocation in case
1044
 * of truncated file.
1045
 * * calls regular TIFFReadEncodedTile() if *buf != NULL
1046
 */
1047
tmsize_t _TIFFReadEncodedTileAndAllocBuffer(TIFF *tif, uint32_t tile,
1048
                                            void **buf, tmsize_t bufsizetoalloc,
1049
                                            tmsize_t size_to_read)
1050
0
{
1051
0
    static const char module[] = "_TIFFReadEncodedTileAndAllocBuffer";
1052
0
    TIFFDirectory *td = &tif->tif_dir;
1053
0
    tmsize_t tilesize = tif->tif_tilesize;
1054
1055
0
    if (*buf != NULL)
1056
0
    {
1057
0
        return TIFFReadEncodedTile(tif, tile, *buf, size_to_read);
1058
0
    }
1059
1060
0
    if (!TIFFCheckRead(tif, 1))
1061
0
        return ((tmsize_t)(-1));
1062
0
    if (tile >= td->td_nstrips)
1063
0
    {
1064
0
        TIFFErrorExtR(tif, module,
1065
0
                      "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1066
0
                      td->td_nstrips);
1067
0
        return ((tmsize_t)(-1));
1068
0
    }
1069
1070
0
    if (!TIFFFillTile(tif, tile))
1071
0
        return ((tmsize_t)(-1));
1072
1073
    /* Sanity checks to avoid excessive memory allocation */
1074
    /* Cf https://gitlab.com/libtiff/libtiff/-/issues/479 */
1075
0
    if (td->td_compression == COMPRESSION_NONE)
1076
0
    {
1077
0
        if (tif->tif_rawdatasize != tilesize)
1078
0
        {
1079
0
            TIFFErrorExtR(tif, TIFFFileName(tif),
1080
0
                          "Invalid tile byte count for tile %u. "
1081
0
                          "Expected %" PRIu64 ", got %" PRIu64,
1082
0
                          tile, (uint64_t)tilesize,
1083
0
                          (uint64_t)tif->tif_rawdatasize);
1084
0
            return ((tmsize_t)(-1));
1085
0
        }
1086
0
    }
1087
0
    else
1088
0
    {
1089
        /* Max compression ratio experimentally determined. Might be fragile...
1090
         * Only apply this heuristics to situations where the memory allocation
1091
         * would be big, to avoid breaking nominal use cases.
1092
         */
1093
0
        const int maxCompressionRatio =
1094
0
            td->td_compression == COMPRESSION_ZSTD ? 33000
1095
0
            : td->td_compression == COMPRESSION_JXL
1096
0
                ?
1097
                /* Evaluated on a 8000x8000 tile */
1098
0
                25000 * (td->td_planarconfig == PLANARCONFIG_CONTIG
1099
0
                             ? td->td_samplesperpixel
1100
0
                             : 1)
1101
0
                : td->td_compression == COMPRESSION_LZMA ? 7000 : 1000;
1102
0
        if (bufsizetoalloc > 100 * 1000 * 1000 &&
1103
0
            tif->tif_rawdatasize < tilesize / maxCompressionRatio)
1104
0
        {
1105
0
            TIFFErrorExtR(tif, TIFFFileName(tif),
1106
0
                          "Likely invalid tile byte count for tile %u. "
1107
0
                          "Uncompressed tile size is %" PRIu64 ", "
1108
0
                          "compressed one is %" PRIu64,
1109
0
                          tile, (uint64_t)tilesize,
1110
0
                          (uint64_t)tif->tif_rawdatasize);
1111
0
            return ((tmsize_t)(-1));
1112
0
        }
1113
0
    }
1114
1115
0
    *buf = _TIFFmallocExt(tif, bufsizetoalloc);
1116
0
    if (*buf == NULL)
1117
0
    {
1118
0
        TIFFErrorExtR(tif, TIFFFileName(tif), "No space for tile buffer");
1119
0
        return ((tmsize_t)(-1));
1120
0
    }
1121
0
    _TIFFmemset(*buf, 0, bufsizetoalloc);
1122
1123
0
    if (size_to_read == (tmsize_t)(-1))
1124
0
        size_to_read = tilesize;
1125
0
    else if (size_to_read > tilesize)
1126
0
        size_to_read = tilesize;
1127
0
    if ((*tif->tif_decodetile)(tif, (uint8_t *)*buf, size_to_read,
1128
0
                               (uint16_t)(tile / td->td_stripsperimage)))
1129
0
    {
1130
0
        (*tif->tif_postdecode)(tif, (uint8_t *)*buf, size_to_read);
1131
0
        return (size_to_read);
1132
0
    }
1133
0
    else
1134
0
        return ((tmsize_t)(-1));
1135
0
}
1136
1137
static tmsize_t TIFFReadRawTile1(TIFF *tif, uint32_t tile, void *buf,
1138
                                 tmsize_t size, const char *module)
1139
0
{
1140
0
    assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1141
0
    if (!isMapped(tif))
1142
0
    {
1143
0
        tmsize_t cc;
1144
1145
0
        if (!SeekOK(tif, TIFFGetStrileOffset(tif, tile)))
1146
0
        {
1147
0
            TIFFErrorExtR(tif, module,
1148
0
                          "Seek error at row %" PRIu32 ", col %" PRIu32
1149
0
                          ", tile %" PRIu32,
1150
0
                          tif->tif_row, tif->tif_col, tile);
1151
0
            return ((tmsize_t)(-1));
1152
0
        }
1153
0
        cc = TIFFReadFile(tif, buf, size);
1154
0
        if (cc != size)
1155
0
        {
1156
0
            TIFFErrorExtR(tif, module,
1157
0
                          "Read error at row %" PRIu32 ", col %" PRIu32
1158
0
                          "; got %" TIFF_SSIZE_FORMAT
1159
0
                          " bytes, expected %" TIFF_SSIZE_FORMAT,
1160
0
                          tif->tif_row, tif->tif_col, cc, size);
1161
0
            return ((tmsize_t)(-1));
1162
0
        }
1163
0
    }
1164
0
    else
1165
0
    {
1166
0
        tmsize_t ma, mb;
1167
0
        tmsize_t n;
1168
0
        ma = (tmsize_t)TIFFGetStrileOffset(tif, tile);
1169
0
        mb = ma + size;
1170
0
        if ((TIFFGetStrileOffset(tif, tile) > (uint64_t)TIFF_TMSIZE_T_MAX) ||
1171
0
            (ma > tif->tif_size))
1172
0
            n = 0;
1173
0
        else if ((mb < ma) || (mb < size) || (mb > tif->tif_size))
1174
0
            n = tif->tif_size - ma;
1175
0
        else
1176
0
            n = size;
1177
0
        if (n != size)
1178
0
        {
1179
0
            TIFFErrorExtR(tif, module,
1180
0
                          "Read error at row %" PRIu32 ", col %" PRIu32
1181
0
                          ", tile %" PRIu32 "; got %" TIFF_SSIZE_FORMAT
1182
0
                          " bytes, expected %" TIFF_SSIZE_FORMAT,
1183
0
                          tif->tif_row, tif->tif_col, tile, n, size);
1184
0
            return ((tmsize_t)(-1));
1185
0
        }
1186
0
        _TIFFmemcpy(buf, tif->tif_base + ma, size);
1187
0
    }
1188
0
    return (size);
1189
0
}
1190
1191
/*
1192
 * Read a tile of data from the file.
1193
 */
1194
tmsize_t TIFFReadRawTile(TIFF *tif, uint32_t tile, void *buf, tmsize_t size)
1195
0
{
1196
0
    static const char module[] = "TIFFReadRawTile";
1197
0
    TIFFDirectory *td = &tif->tif_dir;
1198
0
    uint64_t bytecount64;
1199
0
    tmsize_t bytecountm;
1200
1201
0
    if (!TIFFCheckRead(tif, 1))
1202
0
        return ((tmsize_t)(-1));
1203
0
    if (tile >= td->td_nstrips)
1204
0
    {
1205
0
        TIFFErrorExtR(tif, module,
1206
0
                      "%" PRIu32 ": Tile out of range, max %" PRIu32, tile,
1207
0
                      td->td_nstrips);
1208
0
        return ((tmsize_t)(-1));
1209
0
    }
1210
0
    if (tif->tif_flags & TIFF_NOREADRAW)
1211
0
    {
1212
0
        TIFFErrorExtR(tif, module,
1213
0
                      "Compression scheme does not support access to raw "
1214
0
                      "uncompressed data");
1215
0
        return ((tmsize_t)(-1));
1216
0
    }
1217
0
    bytecount64 = TIFFGetStrileByteCount(tif, tile);
1218
0
    if (size != (tmsize_t)(-1) && (uint64_t)size <= bytecount64)
1219
0
        bytecountm = size;
1220
0
    else
1221
0
        bytecountm = _TIFFCastUInt64ToSSize(tif, bytecount64, module);
1222
0
    if (bytecountm == 0)
1223
0
    {
1224
0
        return ((tmsize_t)(-1));
1225
0
    }
1226
0
    return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
1227
0
}
1228
1229
/*
1230
 * Read the specified tile and setup for decoding. The data buffer is
1231
 * expanded, as necessary, to hold the tile's data.
1232
 */
1233
int TIFFFillTile(TIFF *tif, uint32_t tile)
1234
0
{
1235
0
    static const char module[] = "TIFFFillTile";
1236
0
    TIFFDirectory *td = &tif->tif_dir;
1237
1238
0
    if ((tif->tif_flags & TIFF_NOREADRAW) == 0)
1239
0
    {
1240
0
        uint64_t bytecount = TIFFGetStrileByteCount(tif, tile);
1241
0
        if (bytecount == 0 || bytecount > (uint64_t)TIFF_INT64_MAX)
1242
0
        {
1243
0
            TIFFErrorExtR(tif, module,
1244
0
                          "%" PRIu64 ": Invalid tile byte count, tile %" PRIu32,
1245
0
                          bytecount, tile);
1246
0
            return (0);
1247
0
        }
1248
1249
        /* To avoid excessive memory allocations: */
1250
        /* Byte count should normally not be larger than a number of */
1251
        /* times the uncompressed size plus some margin */
1252
0
        if (bytecount > 1024 * 1024)
1253
0
        {
1254
            /* 10 and 4096 are just values that could be adjusted. */
1255
            /* Hopefully they are safe enough for all codecs */
1256
0
            tmsize_t stripsize = TIFFTileSize(tif);
1257
0
            if (stripsize != 0 && (bytecount - 4096) / 10 > (uint64_t)stripsize)
1258
0
            {
1259
0
                uint64_t newbytecount = (uint64_t)stripsize * 10 + 4096;
1260
0
                TIFFErrorExtR(tif, module,
1261
0
                              "Too large tile byte count %" PRIu64
1262
0
                              ", tile %" PRIu32 ". Limiting to %" PRIu64,
1263
0
                              bytecount, tile, newbytecount);
1264
0
                bytecount = newbytecount;
1265
0
            }
1266
0
        }
1267
1268
0
        if (isMapped(tif))
1269
0
        {
1270
            /*
1271
             * We must check for overflow, potentially causing
1272
             * an OOB read. Instead of simple
1273
             *
1274
             *  TIFFGetStrileOffset(tif, tile)+bytecount > tif->tif_size
1275
             *
1276
             * comparison (which can overflow) we do the following
1277
             * two comparisons:
1278
             */
1279
0
            if (bytecount > (uint64_t)tif->tif_size ||
1280
0
                TIFFGetStrileOffset(tif, tile) >
1281
0
                    (uint64_t)tif->tif_size - bytecount)
1282
0
            {
1283
0
                tif->tif_curtile = NOTILE;
1284
0
                return (0);
1285
0
            }
1286
0
        }
1287
1288
0
        if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) ||
1289
0
                              (tif->tif_flags & TIFF_NOBITREV)))
1290
0
        {
1291
            /*
1292
             * The image is mapped into memory and we either don't
1293
             * need to flip bits or the compression routine is
1294
             * going to handle this operation itself.  In this
1295
             * case, avoid copying the raw data and instead just
1296
             * reference the data from the memory mapped file
1297
             * image.  This assumes that the decompression
1298
             * routines do not modify the contents of the raw data
1299
             * buffer (if they try to, the application will get a
1300
             * fault since the file is mapped read-only).
1301
             */
1302
0
            if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
1303
0
            {
1304
0
                _TIFFfreeExt(tif, tif->tif_rawdata);
1305
0
                tif->tif_rawdata = NULL;
1306
0
                tif->tif_rawdatasize = 0;
1307
0
            }
1308
0
            tif->tif_flags &= ~TIFF_MYBUFFER;
1309
1310
0
            tif->tif_rawdatasize = (tmsize_t)bytecount;
1311
0
            tif->tif_rawdata =
1312
0
                tif->tif_base + (tmsize_t)TIFFGetStrileOffset(tif, tile);
1313
0
            tif->tif_rawdataoff = 0;
1314
0
            tif->tif_rawdataloaded = (tmsize_t)bytecount;
1315
0
            tif->tif_flags |= TIFF_BUFFERMMAP;
1316
0
        }
1317
0
        else
1318
0
        {
1319
            /*
1320
             * Expand raw data buffer, if needed, to hold data
1321
             * tile coming from file (perhaps should set upper
1322
             * bound on the size of a buffer we'll use?).
1323
             */
1324
0
            tmsize_t bytecountm;
1325
0
            bytecountm = (tmsize_t)bytecount;
1326
0
            if ((uint64_t)bytecountm != bytecount)
1327
0
            {
1328
0
                TIFFErrorExtR(tif, module, "Integer overflow");
1329
0
                return (0);
1330
0
            }
1331
0
            if (bytecountm > tif->tif_rawdatasize)
1332
0
            {
1333
0
                tif->tif_curtile = NOTILE;
1334
0
                if ((tif->tif_flags & TIFF_MYBUFFER) == 0)
1335
0
                {
1336
0
                    TIFFErrorExtR(tif, module,
1337
0
                                  "Data buffer too small to hold tile %" PRIu32,
1338
0
                                  tile);
1339
0
                    return (0);
1340
0
                }
1341
0
            }
1342
0
            if (tif->tif_flags & TIFF_BUFFERMMAP)
1343
0
            {
1344
0
                tif->tif_curtile = NOTILE;
1345
0
                tif->tif_rawdata = NULL;
1346
0
                tif->tif_rawdatasize = 0;
1347
0
                tif->tif_flags &= ~TIFF_BUFFERMMAP;
1348
0
            }
1349
1350
0
            if (isMapped(tif))
1351
0
            {
1352
0
                if (bytecountm > tif->tif_rawdatasize &&
1353
0
                    !TIFFReadBufferSetup(tif, 0, bytecountm))
1354
0
                {
1355
0
                    return (0);
1356
0
                }
1357
0
                if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata, bytecountm,
1358
0
                                     module) != bytecountm)
1359
0
                {
1360
0
                    return (0);
1361
0
                }
1362
0
            }
1363
0
            else
1364
0
            {
1365
0
                if (TIFFReadRawStripOrTile2(tif, tile, 0, bytecountm, module) !=
1366
0
                    bytecountm)
1367
0
                {
1368
0
                    return (0);
1369
0
                }
1370
0
            }
1371
1372
0
            tif->tif_rawdataoff = 0;
1373
0
            tif->tif_rawdataloaded = bytecountm;
1374
1375
0
            if (tif->tif_rawdata != NULL &&
1376
0
                !isFillOrder(tif, td->td_fillorder) &&
1377
0
                (tif->tif_flags & TIFF_NOBITREV) == 0)
1378
0
                TIFFReverseBits(tif->tif_rawdata, tif->tif_rawdataloaded);
1379
0
        }
1380
0
    }
1381
0
    return (TIFFStartTile(tif, tile));
1382
0
}
1383
1384
/*
1385
 * Setup the raw data buffer in preparation for
1386
 * reading a strip of raw data.  If the buffer
1387
 * is specified as zero, then a buffer of appropriate
1388
 * size is allocated by the library.  Otherwise,
1389
 * the client must guarantee that the buffer is
1390
 * large enough to hold any individual strip of
1391
 * raw data.
1392
 */
1393
int TIFFReadBufferSetup(TIFF *tif, void *bp, tmsize_t size)
1394
0
{
1395
0
    static const char module[] = "TIFFReadBufferSetup";
1396
1397
0
    assert((tif->tif_flags & TIFF_NOREADRAW) == 0);
1398
0
    tif->tif_flags &= ~TIFF_BUFFERMMAP;
1399
1400
0
    if (tif->tif_rawdata)
1401
0
    {
1402
0
        if (tif->tif_flags & TIFF_MYBUFFER)
1403
0
            _TIFFfreeExt(tif, tif->tif_rawdata);
1404
0
        tif->tif_rawdata = NULL;
1405
0
        tif->tif_rawdatasize = 0;
1406
0
    }
1407
0
    if (bp)
1408
0
    {
1409
0
        tif->tif_rawdatasize = size;
1410
0
        tif->tif_rawdata = (uint8_t *)bp;
1411
0
        tif->tif_flags &= ~TIFF_MYBUFFER;
1412
0
    }
1413
0
    else
1414
0
    {
1415
0
        tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64_t)size, 1024);
1416
0
        if (tif->tif_rawdatasize == 0)
1417
0
        {
1418
0
            TIFFErrorExtR(tif, module, "Invalid buffer size");
1419
0
            return (0);
1420
0
        }
1421
        /* Initialize to zero to avoid uninitialized buffers in case of */
1422
        /* short reads (http://bugzilla.maptools.org/show_bug.cgi?id=2651) */
1423
0
        tif->tif_rawdata =
1424
0
            (uint8_t *)_TIFFcallocExt(tif, 1, tif->tif_rawdatasize);
1425
0
        tif->tif_flags |= TIFF_MYBUFFER;
1426
0
    }
1427
0
    if (tif->tif_rawdata == NULL)
1428
0
    {
1429
0
        TIFFErrorExtR(tif, module,
1430
0
                      "No space for data buffer at scanline %" PRIu32,
1431
0
                      tif->tif_row);
1432
0
        tif->tif_rawdatasize = 0;
1433
0
        return (0);
1434
0
    }
1435
0
    return (1);
1436
0
}
1437
1438
/*
1439
 * Set state to appear as if a
1440
 * strip has just been read in.
1441
 */
1442
static int TIFFStartStrip(TIFF *tif, uint32_t strip)
1443
0
{
1444
0
    TIFFDirectory *td = &tif->tif_dir;
1445
1446
0
    if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1447
0
    {
1448
0
        if (!(*tif->tif_setupdecode)(tif))
1449
0
            return (0);
1450
0
        tif->tif_flags |= TIFF_CODERSETUP;
1451
0
    }
1452
0
    tif->tif_curstrip = strip;
1453
0
    tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
1454
0
    tif->tif_flags &= ~TIFF_BUF4WRITE;
1455
1456
0
    if (tif->tif_flags & TIFF_NOREADRAW)
1457
0
    {
1458
0
        tif->tif_rawcp = NULL;
1459
0
        tif->tif_rawcc = 0;
1460
0
    }
1461
0
    else
1462
0
    {
1463
0
        tif->tif_rawcp = tif->tif_rawdata;
1464
0
        if (tif->tif_rawdataloaded > 0)
1465
0
            tif->tif_rawcc = tif->tif_rawdataloaded;
1466
0
        else
1467
0
            tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, strip);
1468
0
    }
1469
0
    if ((*tif->tif_predecode)(tif, (uint16_t)(strip / td->td_stripsperimage)) ==
1470
0
        0)
1471
0
    {
1472
        /* Needed for example for scanline access, if tif_predecode */
1473
        /* fails, and we try to read the same strip again. Without invalidating
1474
         */
1475
        /* tif_curstrip, we'd call tif_decoderow() on a possibly invalid */
1476
        /* codec state. */
1477
0
        tif->tif_curstrip = NOSTRIP;
1478
0
        return 0;
1479
0
    }
1480
0
    return 1;
1481
0
}
1482
1483
/*
1484
 * Set state to appear as if a
1485
 * tile has just been read in.
1486
 */
1487
static int TIFFStartTile(TIFF *tif, uint32_t tile)
1488
0
{
1489
0
    static const char module[] = "TIFFStartTile";
1490
0
    TIFFDirectory *td = &tif->tif_dir;
1491
0
    uint32_t howmany32;
1492
1493
0
    if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
1494
0
    {
1495
0
        if (!(*tif->tif_setupdecode)(tif))
1496
0
            return (0);
1497
0
        tif->tif_flags |= TIFF_CODERSETUP;
1498
0
    }
1499
0
    tif->tif_curtile = tile;
1500
0
    if (td->td_tilewidth == 0)
1501
0
    {
1502
0
        TIFFErrorExtR(tif, module, "Zero tilewidth");
1503
0
        return 0;
1504
0
    }
1505
0
    howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
1506
0
    if (howmany32 == 0)
1507
0
    {
1508
0
        TIFFErrorExtR(tif, module, "Zero tiles");
1509
0
        return 0;
1510
0
    }
1511
0
    tif->tif_row = (tile % howmany32) * td->td_tilelength;
1512
0
    howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
1513
0
    if (howmany32 == 0)
1514
0
    {
1515
0
        TIFFErrorExtR(tif, module, "Zero tiles");
1516
0
        return 0;
1517
0
    }
1518
0
    tif->tif_col = (tile % howmany32) * td->td_tilewidth;
1519
0
    tif->tif_flags &= ~TIFF_BUF4WRITE;
1520
0
    if (tif->tif_flags & TIFF_NOREADRAW)
1521
0
    {
1522
0
        tif->tif_rawcp = NULL;
1523
0
        tif->tif_rawcc = 0;
1524
0
    }
1525
0
    else
1526
0
    {
1527
0
        tif->tif_rawcp = tif->tif_rawdata;
1528
0
        if (tif->tif_rawdataloaded > 0)
1529
0
            tif->tif_rawcc = tif->tif_rawdataloaded;
1530
0
        else
1531
0
            tif->tif_rawcc = (tmsize_t)TIFFGetStrileByteCount(tif, tile);
1532
0
    }
1533
0
    return (
1534
0
        (*tif->tif_predecode)(tif, (uint16_t)(tile / td->td_stripsperimage)));
1535
0
}
1536
1537
static int TIFFCheckRead(TIFF *tif, int tiles)
1538
0
{
1539
0
    if (tif->tif_mode == O_WRONLY)
1540
0
    {
1541
0
        TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1542
0
        return (0);
1543
0
    }
1544
0
    if (tiles ^ isTiled(tif))
1545
0
    {
1546
0
        TIFFErrorExtR(tif, tif->tif_name,
1547
0
                      tiles ? "Can not read tiles from a striped image"
1548
0
                            : "Can not read scanlines from a tiled image");
1549
0
        return (0);
1550
0
    }
1551
0
    return (1);
1552
0
}
1553
1554
/* Use the provided input buffer (inbuf, insize) and decompress it into
1555
 * (outbuf, outsize).
1556
 * This function replaces the use of
1557
 * TIFFReadEncodedStrip()/TIFFReadEncodedTile() when the user can provide the
1558
 * buffer for the input data, for example when he wants to avoid libtiff to read
1559
 * the strile offset/count values from the [Strip|Tile][Offsets/ByteCounts]
1560
 * array. inbuf content must be writable (if bit reversal is needed) Returns 1
1561
 * in case of success, 0 otherwise.
1562
 */
1563
int TIFFReadFromUserBuffer(TIFF *tif, uint32_t strile, void *inbuf,
1564
                           tmsize_t insize, void *outbuf, tmsize_t outsize)
1565
0
{
1566
0
    static const char module[] = "TIFFReadFromUserBuffer";
1567
0
    TIFFDirectory *td = &tif->tif_dir;
1568
0
    int ret = 1;
1569
0
    uint32_t old_tif_flags = tif->tif_flags;
1570
0
    tmsize_t old_rawdatasize = tif->tif_rawdatasize;
1571
0
    void *old_rawdata = tif->tif_rawdata;
1572
1573
0
    if (tif->tif_mode == O_WRONLY)
1574
0
    {
1575
0
        TIFFErrorExtR(tif, tif->tif_name, "File not open for reading");
1576
0
        return 0;
1577
0
    }
1578
0
    if (tif->tif_flags & TIFF_NOREADRAW)
1579
0
    {
1580
0
        TIFFErrorExtR(tif, module,
1581
0
                      "Compression scheme does not support access to raw "
1582
0
                      "uncompressed data");
1583
0
        return 0;
1584
0
    }
1585
1586
0
    tif->tif_flags &= ~TIFF_MYBUFFER;
1587
0
    tif->tif_flags |= TIFF_BUFFERMMAP;
1588
0
    tif->tif_rawdatasize = insize;
1589
0
    tif->tif_rawdata = (uint8_t *)inbuf;
1590
0
    tif->tif_rawdataoff = 0;
1591
0
    tif->tif_rawdataloaded = insize;
1592
1593
0
    if (!isFillOrder(tif, td->td_fillorder) &&
1594
0
        (tif->tif_flags & TIFF_NOBITREV) == 0)
1595
0
    {
1596
0
        TIFFReverseBits((uint8_t *)inbuf, insize);
1597
0
    }
1598
1599
0
    if (TIFFIsTiled(tif))
1600
0
    {
1601
0
        if (!TIFFStartTile(tif, strile))
1602
0
        {
1603
0
            ret = 0;
1604
            /* See related TIFFReadEncodedStrip comment. */
1605
0
            if (outbuf)
1606
0
                memset(outbuf, 0, (size_t)outsize);
1607
0
        }
1608
0
        else if (!(*tif->tif_decodetile)(
1609
0
                     tif, (uint8_t *)outbuf, outsize,
1610
0
                     (uint16_t)(strile / td->td_stripsperimage)))
1611
0
        {
1612
0
            ret = 0;
1613
0
        }
1614
0
    }
1615
0
    else
1616
0
    {
1617
0
        uint32_t rowsperstrip = td->td_rowsperstrip;
1618
0
        uint32_t stripsperplane;
1619
0
        if (rowsperstrip > td->td_imagelength)
1620
0
            rowsperstrip = td->td_imagelength;
1621
0
        if (rowsperstrip == 0)
1622
0
        {
1623
0
            TIFFErrorExtR(tif, module, "rowsperstrip is zero");
1624
0
            ret = 0;
1625
0
        }
1626
0
        else
1627
0
        {
1628
0
            stripsperplane =
1629
0
                TIFFhowmany_32_maxuint_compat(td->td_imagelength, rowsperstrip);
1630
0
            if (!TIFFStartStrip(tif, strile))
1631
0
            {
1632
0
                ret = 0;
1633
                /* See related TIFFReadEncodedStrip comment. */
1634
0
                if (outbuf)
1635
0
                    memset(outbuf, 0, (size_t)outsize);
1636
0
            }
1637
0
            else if (!(*tif->tif_decodestrip)(
1638
0
                         tif, (uint8_t *)outbuf, outsize,
1639
0
                         (uint16_t)(strile / stripsperplane)))
1640
0
            {
1641
0
                ret = 0;
1642
0
            }
1643
0
        }
1644
0
    }
1645
0
    if (ret)
1646
0
    {
1647
0
        (*tif->tif_postdecode)(tif, (uint8_t *)outbuf, outsize);
1648
0
    }
1649
1650
0
    if (!isFillOrder(tif, td->td_fillorder) &&
1651
0
        (tif->tif_flags & TIFF_NOBITREV) == 0)
1652
0
    {
1653
0
        TIFFReverseBits((uint8_t *)inbuf, insize);
1654
0
    }
1655
1656
0
    tif->tif_flags = (old_tif_flags & (TIFF_MYBUFFER | TIFF_BUFFERMMAP)) |
1657
0
                     (tif->tif_flags & ~(TIFF_MYBUFFER | TIFF_BUFFERMMAP));
1658
0
    tif->tif_rawdatasize = old_rawdatasize;
1659
0
    tif->tif_rawdata = (uint8_t *)old_rawdata;
1660
0
    tif->tif_rawdataoff = 0;
1661
0
    tif->tif_rawdataloaded = 0;
1662
1663
0
    return ret;
1664
0
}
1665
1666
void _TIFFNoPostDecode(TIFF *tif, uint8_t *buf, tmsize_t cc)
1667
0
{
1668
0
    (void)tif;
1669
0
    (void)buf;
1670
0
    (void)cc;
1671
0
}
1672
1673
void _TIFFSwab16BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1674
0
{
1675
0
    (void)tif;
1676
0
    assert((cc & 1) == 0);
1677
0
    TIFFSwabArrayOfShort((uint16_t *)buf, cc / 2);
1678
0
}
1679
1680
void _TIFFSwab24BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1681
0
{
1682
0
    (void)tif;
1683
0
    assert((cc % 3) == 0);
1684
0
    TIFFSwabArrayOfTriples((uint8_t *)buf, cc / 3);
1685
0
}
1686
1687
void _TIFFSwab32BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1688
0
{
1689
0
    (void)tif;
1690
0
    assert((cc & 3) == 0);
1691
0
    TIFFSwabArrayOfLong((uint32_t *)buf, cc / 4);
1692
0
}
1693
1694
void _TIFFSwab64BitData(TIFF *tif, uint8_t *buf, tmsize_t cc)
1695
0
{
1696
0
    (void)tif;
1697
0
    assert((cc & 7) == 0);
1698
0
    TIFFSwabArrayOfDouble((double *)buf, cc / 8);
1699
0
}