LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_read.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 444 668 66.5 %
Date: 2025-04-28 23:11:11 Functions: 27 29 93.1 %

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

Generated by: LCOV version 1.14