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

Generated by: LCOV version 1.14