Coverage Report

Created: 2026-05-16 06:16

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