LCOV - code coverage report
Current view: directory - frmts/gtiff/libtiff - tif_read.c (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 320 150 46.9 %
Date: 2010-01-09 Functions: 20 14 70.0 %

       1                 : /* $Id: tif_read.c,v 1.29 2007/11/23 20:49:43 fwarmerdam Exp $ */
       2                 : 
       3                 : /*
       4                 :  * Copyright (c) 1988-1997 Sam Leffler
       5                 :  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
       6                 :  *
       7                 :  * Permission to use, copy, modify, distribute, and sell this software and 
       8                 :  * its documentation for any purpose is hereby granted without fee, provided
       9                 :  * that (i) the above copyright notices and this permission notice appear in
      10                 :  * all copies of the software and related documentation, and (ii) the names of
      11                 :  * Sam Leffler and Silicon Graphics may not be used in any advertising or
      12                 :  * publicity relating to the software without the specific, prior written
      13                 :  * permission of Sam Leffler and Silicon Graphics.
      14                 :  * 
      15                 :  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
      16                 :  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
      17                 :  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
      18                 :  * 
      19                 :  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
      20                 :  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
      21                 :  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
      22                 :  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
      23                 :  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
      24                 :  * OF THIS SOFTWARE.
      25                 :  */
      26                 : 
      27                 : /*
      28                 :  * TIFF Library.
      29                 :  * Scanline-oriented Read Support
      30                 :  */
      31                 : #include "tiffiop.h"
      32                 : #include <stdio.h>
      33                 : 
      34                 : int TIFFFillStrip(TIFF* tif, uint32 strip);
      35                 : int TIFFFillTile(TIFF* tif, uint32 tile);
      36                 : static int TIFFStartStrip(TIFF* tif, uint32 strip);
      37                 : static int TIFFStartTile(TIFF* tif, uint32 tile);
      38                 : static int TIFFCheckRead(TIFF*, int);
      39                 : 
      40                 : #define NOSTRIP ((uint32)(-1))       /* undefined state */
      41                 : #define NOTILE ((uint32)(-1))         /* undefined state */
      42                 : 
      43                 : /*
      44                 :  * Seek to a random row+sample in a file.
      45                 :  */
      46                 : static int
      47          137048 : TIFFSeek(TIFF* tif, uint32 row, uint16 sample)
      48                 : {
      49          137048 :   register TIFFDirectory *td = &tif->tif_dir;
      50                 :   uint32 strip;
      51                 : 
      52          137048 :   if (row >= td->td_imagelength) {  /* out of range */
      53               0 :     TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
      54                 :         "%lu: Row out of range, max %lu",
      55                 :         (unsigned long) row,
      56                 :         (unsigned long) td->td_imagelength);
      57               0 :     return (0);
      58                 :   }
      59          137048 :   if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
      60           64244 :     if (sample >= td->td_samplesperpixel) {
      61               0 :       TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
      62                 :           "%lu: Sample out of range, max %lu",
      63                 :           (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
      64               0 :       return (0);
      65                 :     }
      66           64244 :     strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip;
      67                 :   } else
      68           72804 :     strip = row / td->td_rowsperstrip;
      69          137048 :   if (strip != tif->tif_curstrip) {  /* different strip, refill */
      70              25 :     if (!TIFFFillStrip(tif, strip))
      71               0 :       return (0);
      72          137023 :   } else if (row < tif->tif_row) {
      73                 :     /*
      74                 :      * Moving backwards within the same strip: backup
      75                 :      * to the start and then decode forward (below).
      76                 :      *
      77                 :      * NB: If you're planning on lots of random access within a
      78                 :      * strip, it's better to just read and decode the entire
      79                 :      * strip, and then access the decoded data in a random fashion.
      80                 :      */
      81              22 :     if (!TIFFStartStrip(tif, strip))
      82               0 :       return (0);
      83                 :   }
      84          137048 :   if (row != tif->tif_row) {
      85                 :     /*
      86                 :      * Seek forward to the desired row.
      87                 :      */
      88               0 :     if (!(*tif->tif_seek)(tif, row - tif->tif_row))
      89               0 :       return (0);
      90               0 :     tif->tif_row = row;
      91                 :   }
      92          137048 :   return (1);
      93                 : }
      94                 : 
      95                 : int
      96          137048 : TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
      97                 : {
      98                 :   int e;
      99                 : 
     100          137048 :   if (!TIFFCheckRead(tif, 0))
     101               0 :     return (-1);
     102          137048 :   if( (e = TIFFSeek(tif, row, sample)) != 0) {
     103                 :     /*
     104                 :      * Decompress desired row into user buffer.
     105                 :      */
     106          137048 :     e = (*tif->tif_decoderow)
     107                 :         (tif, (uint8*) buf, tif->tif_scanlinesize, sample);  
     108                 : 
     109                 :     /* we are now poised at the beginning of the next row */
     110          137048 :     tif->tif_row = row + 1;
     111                 : 
     112          137048 :     if (e)
     113          137048 :       (*tif->tif_postdecode)(tif, (uint8*) buf,
     114                 :           tif->tif_scanlinesize);  
     115                 :   }
     116          137048 :   return (e > 0 ? 1 : -1);
     117                 : }
     118                 : 
     119                 : /*
     120                 :  * Read a strip of data and decompress the specified
     121                 :  * amount into the user-supplied buffer.
     122                 :  */
     123                 : tmsize_t
     124            3118 : TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
     125                 : {
     126                 :   static const char module[] = "TIFFReadEncodedStrip";
     127            3118 :   TIFFDirectory *td = &tif->tif_dir;
     128                 :   uint32 rowsperstrip;
     129                 :   uint32 stripsperplane;
     130                 :   uint32 stripinplane;
     131                 :   uint16 plane;
     132                 :   uint32 rows;
     133                 :   tmsize_t stripsize;
     134            3118 :   if (!TIFFCheckRead(tif,0))
     135               0 :     return((tmsize_t)(-1));
     136            3118 :   if (strip>=td->td_nstrips)
     137                 :   {
     138               0 :     TIFFErrorExt(tif->tif_clientdata,module,
     139                 :         "%lu: Strip out of range, max %lu",(unsigned long)strip,
     140                 :         (unsigned long)td->td_nstrips);
     141               0 :     return((tmsize_t)(-1));
     142                 :   }
     143                 :   /*
     144                 :    * Calculate the strip size according to the number of
     145                 :    * rows in the strip (check for truncated last strip on any
     146                 :    * of the separations).
     147                 :    */
     148            3118 :   rowsperstrip=td->td_rowsperstrip;
     149            3118 :   if (rowsperstrip>td->td_imagelength)
     150               6 :     rowsperstrip=td->td_imagelength;
     151            3118 :   stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
     152            3118 :   stripinplane=(strip%stripsperplane);
     153            3118 :   plane=(strip/stripsperplane);
     154            3118 :   rows=td->td_imagelength-stripinplane*rowsperstrip;
     155            3118 :   if (rows>rowsperstrip)
     156            1736 :     rows=rowsperstrip;
     157            3118 :   stripsize=TIFFVStripSize(tif,rows);
     158            3118 :   if (stripsize==0)
     159               0 :     return((tmsize_t)(-1));
     160            3118 :   if ((size!=(tmsize_t)(-1))&&(size<stripsize))
     161               0 :     stripsize=size;
     162            3118 :   if (!TIFFFillStrip(tif,strip))
     163               0 :     return((tmsize_t)(-1));
     164            3118 :   if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0)
     165               0 :     return((tmsize_t)(-1));
     166            3118 :   (*tif->tif_postdecode)(tif,buf,stripsize);
     167            3118 :   return(stripsize);
     168                 : }
     169                 : 
     170                 : static tmsize_t
     171            3143 : TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
     172                 :     const char* module)
     173                 : {
     174            3143 :   TIFFDirectory *td = &tif->tif_dir;
     175                 : 
     176            3143 :   assert((tif->tif_flags&TIFF_NOREADRAW)==0);
     177            3143 :   if (!isMapped(tif)) {
     178                 :     tmsize_t cc;
     179                 : 
     180            3143 :     if (!SeekOK(tif, td->td_stripoffset[strip])) {
     181               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     182                 :           "Seek error at scanline %lu, strip %lu",
     183                 :           (unsigned long) tif->tif_row, (unsigned long) strip);
     184               0 :       return ((tmsize_t)(-1));
     185                 :     }
     186            3143 :     cc = TIFFReadFile(tif, buf, size);
     187            3143 :     if (cc != size) {
     188                 : #if defined(__WIN32__) && defined(_MSC_VER)
     189                 :       TIFFErrorExt(tif->tif_clientdata, module,
     190                 :     "Read error at scanline %lu; got %I64u bytes, expected %I64u",
     191                 :              (unsigned long) tif->tif_row,
     192                 :              (unsigned __int64) cc,
     193                 :              (unsigned __int64) size);
     194                 : #else
     195               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     196                 :     "Read error at scanline %lu; got %llu bytes, expected %llu",
     197                 :              (unsigned long) tif->tif_row,
     198                 :              (unsigned long long) cc,
     199                 :              (unsigned long long) size);
     200                 : #endif
     201               0 :       return ((tmsize_t)(-1));
     202                 :     }
     203                 :   } else {
     204                 :     tmsize_t ma,mb;
     205                 :     tmsize_t n;
     206               0 :     ma=(tmsize_t)td->td_stripoffset[strip];
     207               0 :     mb=ma+size;
     208               0 :     if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
     209               0 :       n=0;
     210               0 :     else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
     211               0 :       n=tif->tif_size-ma;
     212                 :     else
     213               0 :       n=size;
     214               0 :     if (n!=size) {
     215                 : #if defined(__WIN32__) && defined(_MSC_VER)
     216                 :       TIFFErrorExt(tif->tif_clientdata, module,
     217                 :   "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u",
     218                 :              (unsigned long) tif->tif_row,
     219                 :              (unsigned long) strip,
     220                 :              (unsigned __int64) n,
     221                 :              (unsigned __int64) size);
     222                 : #else
     223               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     224                 :   "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu",
     225                 :              (unsigned long) tif->tif_row,
     226                 :              (unsigned long) strip,
     227                 :              (unsigned long long) n,
     228                 :              (unsigned long long) size);
     229                 : #endif
     230               0 :       return ((tmsize_t)(-1));
     231                 :     }
     232               0 :     _TIFFmemcpy(buf, tif->tif_base + ma,
     233                 :           size);
     234                 :   }
     235            3143 :   return (size);
     236                 : }
     237                 : 
     238                 : /*
     239                 :  * Read a strip of data from the file.
     240                 :  */
     241                 : tmsize_t
     242               0 : TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
     243                 : {
     244                 :   static const char module[] = "TIFFReadRawStrip";
     245               0 :   TIFFDirectory *td = &tif->tif_dir;
     246                 :   uint64 bytecount;
     247                 :   tmsize_t bytecountm;
     248                 : 
     249               0 :   if (!TIFFCheckRead(tif, 0))
     250               0 :     return ((tmsize_t)(-1));
     251               0 :   if (strip >= td->td_nstrips) {
     252               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     253                 :          "%lu: Strip out of range, max %lu",
     254                 :          (unsigned long) strip,
     255                 :          (unsigned long) td->td_nstrips);
     256               0 :     return ((tmsize_t)(-1));
     257                 :   }
     258               0 :   if (tif->tif_flags&TIFF_NOREADRAW)
     259                 :   {
     260               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     261                 :         "Compression scheme does not support access to raw uncompressed data");
     262               0 :     return ((tmsize_t)(-1));
     263                 :   }
     264               0 :   bytecount = td->td_stripbytecount[strip];
     265               0 :   if (bytecount <= 0) {
     266                 : #if defined(__WIN32__) && defined(_MSC_VER)
     267                 :     TIFFErrorExt(tif->tif_clientdata, module,
     268                 :            "%I64u: Invalid strip byte count, strip %lu",
     269                 :            (unsigned __int64) bytecount,
     270                 :            (unsigned long) strip);
     271                 : #else
     272               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     273                 :            "%llu: Invalid strip byte count, strip %lu",
     274                 :            (unsigned long long) bytecount,
     275                 :            (unsigned long) strip);
     276                 : #endif
     277               0 :     return ((tmsize_t)(-1));
     278                 :   }
     279               0 :   bytecountm = (tmsize_t)bytecount;
     280               0 :   if ((uint64)bytecountm!=bytecount) {
     281               0 :     TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
     282               0 :     return ((tmsize_t)(-1));
     283                 :   }
     284               0 :   if (size != (tmsize_t)(-1) && size < bytecountm)
     285               0 :     bytecountm = size;
     286               0 :   return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
     287                 : }
     288                 : 
     289                 : /*
     290                 :  * Read the specified strip and setup for decoding. The data buffer is
     291                 :  * expanded, as necessary, to hold the strip's data.
     292                 :  */
     293                 : int
     294            3143 : TIFFFillStrip(TIFF* tif, uint32 strip)
     295                 : {
     296                 :   static const char module[] = "TIFFFillStrip";
     297            3143 :   TIFFDirectory *td = &tif->tif_dir;
     298                 : 
     299            3143 :   if ((tif->tif_flags&TIFF_NOREADRAW)==0)
     300                 :   {
     301            3143 :     uint64 bytecount = td->td_stripbytecount[strip];
     302            3143 :     if (bytecount <= 0) {
     303                 : #if defined(__WIN32__) && defined(_MSC_VER)
     304                 :       TIFFErrorExt(tif->tif_clientdata, module,
     305                 :         "Invalid strip byte count %I64u, strip %lu",
     306                 :              (unsigned __int64) bytecount,
     307                 :              (unsigned long) strip);
     308                 : #else
     309               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     310                 :         "Invalid strip byte count %llu, strip %lu",
     311                 :              (unsigned long long) bytecount,
     312                 :              (unsigned long) strip);
     313                 : #endif
     314               0 :       return (0);
     315                 :     }
     316            3143 :     if (isMapped(tif) &&
     317               0 :         (isFillOrder(tif, td->td_fillorder)
     318               0 :         || (tif->tif_flags & TIFF_NOBITREV))) {
     319                 :       /*
     320                 :        * The image is mapped into memory and we either don't
     321                 :        * need to flip bits or the compression routine is
     322                 :        * going to handle this operation itself.  In this
     323                 :        * case, avoid copying the raw data and instead just
     324                 :        * reference the data from the memory mapped file
     325                 :        * image.  This assumes that the decompression
     326                 :        * routines do not modify the contents of the raw data
     327                 :        * buffer (if they try to, the application will get a
     328                 :        * fault since the file is mapped read-only).
     329                 :        */
     330               0 :       if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
     331               0 :         _TIFFfree(tif->tif_rawdata);
     332               0 :       tif->tif_flags &= ~TIFF_MYBUFFER;
     333                 :       /*
     334                 :        * We must check for overflow, potentially causing
     335                 :        * an OOB read. Instead of simple
     336                 :        *
     337                 :        *  td->td_stripoffset[strip]+bytecount > tif->tif_size
     338                 :        *
     339                 :        * comparison (which can overflow) we do the following
     340                 :        * two comparisons:
     341                 :        */
     342               0 :       if (bytecount > (uint64)tif->tif_size ||
     343               0 :           td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
     344                 :         /*
     345                 :          * This error message might seem strange, but
     346                 :          * it's what would happen if a read were done
     347                 :          * instead.
     348                 :          */
     349                 : #if defined(__WIN32__) && defined(_MSC_VER)
     350                 :         TIFFErrorExt(tif->tif_clientdata, module,
     351                 : 
     352                 :           "Read error on strip %lu; "
     353                 :           "got %I64u bytes, expected %I64u",
     354                 :           (unsigned long) strip,
     355                 :           (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
     356                 :           (unsigned __int64) bytecount);
     357                 : #else
     358               0 :         TIFFErrorExt(tif->tif_clientdata, module,
     359                 : 
     360                 :           "Read error on strip %lu; "
     361                 :           "got %llu bytes, expected %llu",
     362                 :           (unsigned long) strip,
     363               0 :           (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
     364                 :           (unsigned long long) bytecount);
     365                 : #endif
     366               0 :         tif->tif_curstrip = NOSTRIP;
     367               0 :         return (0);
     368                 :       }
     369               0 :       tif->tif_rawdatasize = (tmsize_t)bytecount;
     370               0 :       tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
     371                 :     } else {
     372                 :       /*
     373                 :        * Expand raw data buffer, if needed, to hold data
     374                 :        * strip coming from file (perhaps should set upper
     375                 :        * bound on the size of a buffer we'll use?).
     376                 :        */
     377                 :       tmsize_t bytecountm;
     378            3143 :       bytecountm=(tmsize_t)bytecount;
     379            3143 :       if ((uint64)bytecountm!=bytecount)
     380                 :       {
     381               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
     382               0 :         return(0);
     383                 :       }
     384            3143 :       if (bytecountm > tif->tif_rawdatasize) {
     385            1337 :         tif->tif_curstrip = NOSTRIP;
     386            1337 :         if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
     387               0 :           TIFFErrorExt(tif->tif_clientdata, module,
     388                 :               "Data buffer too small to hold strip %lu",
     389                 :               (unsigned long) strip);
     390               0 :           return (0);
     391                 :         }
     392            1337 :         if (!TIFFReadBufferSetup(tif, 0, bytecountm))
     393               0 :           return (0);
     394                 :       }
     395            3143 :       if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
     396                 :         bytecountm, module) != bytecountm)
     397               0 :         return (0);
     398            3143 :       if (!isFillOrder(tif, td->td_fillorder) &&
     399               0 :           (tif->tif_flags & TIFF_NOBITREV) == 0)
     400               0 :         TIFFReverseBits(tif->tif_rawdata, bytecountm);
     401                 :     }
     402                 :   }
     403            3143 :   return (TIFFStartStrip(tif, strip));
     404                 : }
     405                 : 
     406                 : /*
     407                 :  * Tile-oriented Read Support
     408                 :  * Contributed by Nancy Cam (Silicon Graphics).
     409                 :  */
     410                 : 
     411                 : /*
     412                 :  * Read and decompress a tile of data.  The
     413                 :  * tile is selected by the (x,y,z,s) coordinates.
     414                 :  */
     415                 : tmsize_t
     416               0 : TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
     417                 : {
     418               0 :   if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
     419               0 :     return ((tmsize_t)(-1));
     420               0 :   return (TIFFReadEncodedTile(tif,
     421                 :       TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
     422                 : }
     423                 : 
     424                 : /*
     425                 :  * Read a tile of data and decompress the specified
     426                 :  * amount into the user-supplied buffer.
     427                 :  */
     428                 : tmsize_t
     429             552 : TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
     430                 : {
     431                 :   static const char module[] = "TIFFReadEncodedTile";
     432             552 :   TIFFDirectory *td = &tif->tif_dir;
     433             552 :   tmsize_t tilesize = tif->tif_tilesize;
     434                 : 
     435             552 :   if (!TIFFCheckRead(tif, 1))
     436               0 :     return ((tmsize_t)(-1));
     437             552 :   if (tile >= td->td_nstrips) {
     438               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     439                 :         "%lu: Tile out of range, max %lu",
     440                 :         (unsigned long) tile, (unsigned long) td->td_nstrips);
     441               0 :     return ((tmsize_t)(-1));
     442                 :   }
     443             552 :   if (size == (tmsize_t)(-1))
     444               0 :     size = tilesize;
     445             552 :   else if (size > tilesize)
     446               0 :     size = tilesize;
     447            1104 :   if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
     448             552 :       (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) {
     449             552 :     (*tif->tif_postdecode)(tif, (uint8*) buf, size);
     450             552 :     return (size);
     451                 :   } else
     452               0 :     return ((tmsize_t)(-1));
     453                 : }
     454                 : 
     455                 : static tmsize_t
     456             552 : TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
     457                 : {
     458             552 :   TIFFDirectory *td = &tif->tif_dir;
     459                 : 
     460             552 :   assert((tif->tif_flags&TIFF_NOREADRAW)==0);
     461             552 :   if (!isMapped(tif)) {
     462                 :     tmsize_t cc;
     463                 : 
     464             552 :     if (!SeekOK(tif, td->td_stripoffset[tile])) {
     465               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     466                 :           "Seek error at row %lu, col %lu, tile %lu",
     467                 :           (unsigned long) tif->tif_row,
     468                 :           (unsigned long) tif->tif_col,
     469                 :           (unsigned long) tile);
     470               0 :       return ((tmsize_t)(-1));
     471                 :     }
     472             552 :     cc = TIFFReadFile(tif, buf, size);
     473             552 :     if (cc != size) {
     474                 : #if defined(__WIN32__) && defined(_MSC_VER)
     475                 :       TIFFErrorExt(tif->tif_clientdata, module,
     476                 :   "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u",
     477                 :              (unsigned long) tif->tif_row,
     478                 :              (unsigned long) tif->tif_col,
     479                 :              (unsigned __int64) cc,
     480                 :              (unsigned __int64) size);
     481                 : #else
     482               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     483                 :   "Read error at row %lu, col %lu; got %llu bytes, expected %llu",
     484                 :              (unsigned long) tif->tif_row,
     485                 :              (unsigned long) tif->tif_col,
     486                 :              (unsigned long long) cc,
     487                 :              (unsigned long long) size);
     488                 : #endif
     489               0 :       return ((tmsize_t)(-1));
     490                 :     }
     491                 :   } else {
     492                 :     tmsize_t ma,mb;
     493                 :     tmsize_t n;
     494               0 :     ma=(tmsize_t)td->td_stripoffset[tile];
     495               0 :     mb=ma+size;
     496               0 :     if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
     497               0 :       n=0;
     498               0 :     else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
     499               0 :       n=tif->tif_size-ma;
     500                 :     else
     501               0 :       n=size;
     502               0 :     if (n!=size) {
     503                 : #if defined(__WIN32__) && defined(_MSC_VER)
     504                 :       TIFFErrorExt(tif->tif_clientdata, module,
     505                 : "Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u",
     506                 :              (unsigned long) tif->tif_row,
     507                 :              (unsigned long) tif->tif_col,
     508                 :              (unsigned long) tile,
     509                 :              (unsigned __int64) n,
     510                 :              (unsigned __int64) size);
     511                 : #else
     512               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     513                 : "Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu",
     514                 :              (unsigned long) tif->tif_row,
     515                 :              (unsigned long) tif->tif_col,
     516                 :              (unsigned long) tile,
     517                 :              (unsigned long long) n,
     518                 :              (unsigned long long) size);
     519                 : #endif
     520               0 :       return ((tmsize_t)(-1));
     521                 :     }
     522               0 :     _TIFFmemcpy(buf, tif->tif_base + ma, size);
     523                 :   }
     524             552 :   return (size);
     525                 : }
     526                 : 
     527                 : /*
     528                 :  * Read a tile of data from the file.
     529                 :  */
     530                 : tmsize_t
     531               0 : TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
     532                 : {
     533                 :   static const char module[] = "TIFFReadRawTile";
     534               0 :   TIFFDirectory *td = &tif->tif_dir;
     535                 :   uint64 bytecount64;
     536                 :   tmsize_t bytecountm;
     537                 : 
     538               0 :   if (!TIFFCheckRead(tif, 1))
     539               0 :     return ((tmsize_t)(-1));
     540               0 :   if (tile >= td->td_nstrips) {
     541               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     542                 :         "%lu: Tile out of range, max %lu",
     543                 :         (unsigned long) tile, (unsigned long) td->td_nstrips);
     544               0 :     return ((tmsize_t)(-1));
     545                 :   }
     546               0 :   if (tif->tif_flags&TIFF_NOREADRAW)
     547                 :   {
     548               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     549                 :     "Compression scheme does not support access to raw uncompressed data");
     550               0 :     return ((tmsize_t)(-1));
     551                 :   }
     552               0 :   bytecount64 = td->td_stripbytecount[tile];
     553               0 :   if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
     554               0 :     bytecount64 = (uint64)size;
     555               0 :   bytecountm = (tmsize_t)bytecount64;
     556               0 :   if ((uint64)bytecountm!=bytecount64)
     557                 :   {
     558               0 :     TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
     559               0 :     return ((tmsize_t)(-1));
     560                 :   }
     561               0 :   return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
     562                 : }
     563                 : 
     564                 : /*
     565                 :  * Read the specified tile and setup for decoding. The data buffer is
     566                 :  * expanded, as necessary, to hold the tile's data.
     567                 :  */
     568                 : int
     569             552 : TIFFFillTile(TIFF* tif, uint32 tile)
     570                 : {
     571                 :   static const char module[] = "TIFFFillTile";
     572             552 :   TIFFDirectory *td = &tif->tif_dir;
     573                 : 
     574             552 :   if ((tif->tif_flags&TIFF_NOREADRAW)==0)
     575                 :   {
     576             552 :     uint64 bytecount = td->td_stripbytecount[tile];
     577             552 :     if (bytecount <= 0) {
     578                 : #if defined(__WIN32__) && defined(_MSC_VER)
     579                 :       TIFFErrorExt(tif->tif_clientdata, module,
     580                 :         "%I64u: Invalid tile byte count, tile %lu",
     581                 :              (unsigned __int64) bytecount,
     582                 :              (unsigned long) tile);
     583                 : #else
     584               0 :       TIFFErrorExt(tif->tif_clientdata, module,
     585                 :         "%llu: Invalid tile byte count, tile %lu",
     586                 :              (unsigned long long) bytecount,
     587                 :              (unsigned long) tile);
     588                 : #endif
     589               0 :       return (0);
     590                 :     }
     591             552 :     if (isMapped(tif) &&
     592               0 :         (isFillOrder(tif, td->td_fillorder)
     593               0 :          || (tif->tif_flags & TIFF_NOBITREV))) {
     594                 :       /*
     595                 :        * The image is mapped into memory and we either don't
     596                 :        * need to flip bits or the compression routine is
     597                 :        * going to handle this operation itself.  In this
     598                 :        * case, avoid copying the raw data and instead just
     599                 :        * reference the data from the memory mapped file
     600                 :        * image.  This assumes that the decompression
     601                 :        * routines do not modify the contents of the raw data
     602                 :        * buffer (if they try to, the application will get a
     603                 :        * fault since the file is mapped read-only).
     604                 :        */
     605               0 :       if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
     606               0 :         _TIFFfree(tif->tif_rawdata);
     607               0 :       tif->tif_flags &= ~TIFF_MYBUFFER;
     608                 :       /*
     609                 :        * We must check for overflow, potentially causing
     610                 :        * an OOB read. Instead of simple
     611                 :        *
     612                 :        *  td->td_stripoffset[tile]+bytecount > tif->tif_size
     613                 :        *
     614                 :        * comparison (which can overflow) we do the following
     615                 :        * two comparisons:
     616                 :        */
     617               0 :       if (bytecount > (uint64)tif->tif_size ||
     618               0 :           td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
     619               0 :         tif->tif_curtile = NOTILE;
     620               0 :         return (0);
     621                 :       }
     622               0 :       tif->tif_rawdatasize = (tmsize_t)bytecount;
     623               0 :       tif->tif_rawdata =
     624               0 :         tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
     625                 :     } else {
     626                 :       /*
     627                 :        * Expand raw data buffer, if needed, to hold data
     628                 :        * tile coming from file (perhaps should set upper
     629                 :        * bound on the size of a buffer we'll use?).
     630                 :        */
     631                 :       tmsize_t bytecountm;
     632             552 :       bytecountm=(tmsize_t)bytecount;
     633             552 :       if ((uint64)bytecountm!=bytecount)
     634                 :       {
     635               0 :         TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
     636               0 :         return(0);
     637                 :       }
     638             552 :       if (bytecountm > tif->tif_rawdatasize) {
     639              62 :         tif->tif_curtile = NOTILE;
     640              62 :         if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
     641               0 :           TIFFErrorExt(tif->tif_clientdata, module,
     642                 :               "Data buffer too small to hold tile %lu",
     643                 :               (unsigned long) tile);
     644               0 :           return (0);
     645                 :         }
     646              62 :         if (!TIFFReadBufferSetup(tif, 0, bytecountm))
     647               0 :           return (0);
     648                 :       }
     649             552 :       if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
     650                 :           bytecountm, module) != bytecountm)
     651               0 :         return (0);
     652             552 :       if (!isFillOrder(tif, td->td_fillorder) &&
     653               0 :           (tif->tif_flags & TIFF_NOBITREV) == 0)
     654               0 :         TIFFReverseBits(tif->tif_rawdata, bytecountm);
     655                 :     }
     656                 :   }
     657             552 :   return (TIFFStartTile(tif, tile));
     658                 : }
     659                 : 
     660                 : /*
     661                 :  * Setup the raw data buffer in preparation for
     662                 :  * reading a strip of raw data.  If the buffer
     663                 :  * is specified as zero, then a buffer of appropriate
     664                 :  * size is allocated by the library.  Otherwise,
     665                 :  * the client must guarantee that the buffer is
     666                 :  * large enough to hold any individual strip of
     667                 :  * raw data.
     668                 :  */
     669                 : int
     670            1399 : TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
     671                 : {
     672                 :   static const char module[] = "TIFFReadBufferSetup";
     673                 : 
     674            1399 :   assert((tif->tif_flags&TIFF_NOREADRAW)==0);
     675            1399 :   if (tif->tif_rawdata) {
     676              17 :     if (tif->tif_flags & TIFF_MYBUFFER)
     677              17 :       _TIFFfree(tif->tif_rawdata);
     678              17 :     tif->tif_rawdata = NULL;
     679                 :   }
     680            1399 :   if (bp) {
     681               0 :     tif->tif_rawdatasize = size;
     682               0 :     tif->tif_rawdata = (uint8*) bp;
     683               0 :     tif->tif_flags &= ~TIFF_MYBUFFER;
     684                 :   } else {
     685            1399 :     tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
     686            1399 :     if (tif->tif_rawdatasize==0)
     687               0 :       tif->tif_rawdatasize=(tmsize_t)(-1);
     688            1399 :     tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
     689            1399 :     tif->tif_flags |= TIFF_MYBUFFER;
     690                 :   }
     691            1399 :   if (tif->tif_rawdata == NULL) {
     692               0 :     TIFFErrorExt(tif->tif_clientdata, module,
     693                 :         "No space for data buffer at scanline %lu",
     694                 :         (unsigned long) tif->tif_row);
     695               0 :     tif->tif_rawdatasize = 0;
     696               0 :     return (0);
     697                 :   }
     698            1399 :   return (1);
     699                 : }
     700                 : 
     701                 : /*
     702                 :  * Set state to appear as if a
     703                 :  * strip has just been read in.
     704                 :  */
     705                 : static int
     706            3165 : TIFFStartStrip(TIFF* tif, uint32 strip)
     707                 : {
     708            3165 :   TIFFDirectory *td = &tif->tif_dir;
     709                 : 
     710            3165 :   if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
     711            1324 :     if (!(*tif->tif_setupdecode)(tif))
     712               0 :       return (0);
     713            1324 :     tif->tif_flags |= TIFF_CODERSETUP;
     714                 :   }
     715            3165 :   tif->tif_curstrip = strip;
     716            3165 :   tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
     717            3165 :         tif->tif_flags &= ~TIFF_BUF4WRITE;
     718                 : 
     719            3165 :   if (tif->tif_flags&TIFF_NOREADRAW)
     720                 :   {
     721               0 :     tif->tif_rawcp = NULL;
     722               0 :     tif->tif_rawcc = 0;  
     723                 :   }
     724                 :   else
     725                 :   {
     726            3165 :     tif->tif_rawcp = tif->tif_rawdata;
     727            3165 :     tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
     728                 :   }
     729            6330 :   return ((*tif->tif_predecode)(tif,
     730            3165 :       (uint16)(strip / td->td_stripsperimage)));
     731                 : }
     732                 : 
     733                 : /*
     734                 :  * Set state to appear as if a
     735                 :  * tile has just been read in.
     736                 :  */
     737                 : static int
     738             552 : TIFFStartTile(TIFF* tif, uint32 tile)
     739                 : {
     740             552 :   TIFFDirectory *td = &tif->tif_dir;
     741                 : 
     742             552 :   if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
     743              50 :     if (!(*tif->tif_setupdecode)(tif))
     744               0 :       return (0);
     745              50 :     tif->tif_flags |= TIFF_CODERSETUP;
     746                 :   }
     747             552 :   tif->tif_curtile = tile;
     748             552 :   tif->tif_row =
     749             552 :       (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
     750                 :     td->td_tilelength;
     751             552 :   tif->tif_col =
     752             552 :       (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
     753                 :     td->td_tilewidth;
     754             552 :         tif->tif_flags &= ~TIFF_BUF4WRITE;
     755             552 :   if (tif->tif_flags&TIFF_NOREADRAW)
     756                 :   {
     757               0 :     tif->tif_rawcp = NULL;
     758               0 :     tif->tif_rawcc = 0;
     759                 :   }
     760                 :   else
     761                 :   {
     762             552 :     tif->tif_rawcp = tif->tif_rawdata;
     763             552 :     tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
     764                 :   }
     765            1104 :   return ((*tif->tif_predecode)(tif,
     766             552 :       (uint16)(tile/td->td_stripsperimage)));
     767                 : }
     768                 : 
     769                 : static int
     770          140718 : TIFFCheckRead(TIFF* tif, int tiles)
     771                 : {
     772          140718 :   if (tif->tif_mode == O_WRONLY) {
     773               0 :     TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
     774               0 :     return (0);
     775                 :   }
     776          140718 :   if (tiles ^ isTiled(tif)) {
     777               0 :     TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
     778                 :         "Can not read tiles from a stripped image" :
     779                 :         "Can not read scanlines from a tiled image");
     780               0 :     return (0);
     781                 :   }
     782          140718 :   return (1);
     783                 : }
     784                 : 
     785                 : void
     786          237245 : _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
     787                 : {
     788                 :     (void) tif; (void) buf; (void) cc;
     789          237245 : }
     790                 : 
     791                 : void
     792               0 : _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc)
     793                 : {
     794                 :     (void) tif;
     795               0 :     assert((cc & 1) == 0);
     796               0 :     TIFFSwabArrayOfShort((uint16*) buf, cc/2);
     797               0 : }
     798                 : 
     799                 : void
     800               0 : _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc)
     801                 : {
     802                 :     (void) tif;
     803               0 :     assert((cc % 3) == 0);
     804               0 :     TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
     805               0 : }
     806                 : 
     807                 : void
     808              15 : _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc)
     809                 : {
     810                 :     (void) tif;
     811              15 :     assert((cc & 3) == 0);
     812              15 :     TIFFSwabArrayOfLong((uint32*) buf, cc/4);
     813              15 : }
     814                 : 
     815                 : void
     816               0 : _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc)
     817                 : {
     818                 :     (void) tif;
     819               0 :     assert((cc & 7) == 0);
     820               0 :     TIFFSwabArrayOfDouble((double*) buf, cc/8);
     821               0 : }
     822                 : 
     823                 : /* vim: set ts=8 sts=8 sw=8 noet: */

Generated by: LCOV version 1.7