LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_write.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 250 448 55.8 %
Date: 2026-06-08 18:52:12 Functions: 12 14 85.7 %

          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             :  *
      28             :  * Scanline-oriented Write Support
      29             :  */
      30             : #include "tiffiop.h"
      31             : #include <stdio.h>
      32             : 
      33             : #define NOSTRIP ((uint32_t)(-1)) /* undefined state */
      34             : 
      35             : #define WRITECHECKSTRIPS(tif, module)                                          \
      36             :     (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 0, module))
      37             : #define WRITECHECKTILES(tif, module)                                           \
      38             :     (((tif)->tif_flags & TIFF_BEENWRITING) || TIFFWriteCheck((tif), 1, module))
      39             : #define BUFFERCHECK(tif)                                                       \
      40             :     ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) ||            \
      41             :      TIFFWriteBufferSetup((tif), NULL, (tmsize_t)(-1)))
      42             : 
      43             : static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module);
      44             : static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
      45             :                              tmsize_t cc);
      46             : 
      47       57252 : int TIFFWriteScanline(TIFF *tif, void *buf, uint32_t row, uint16_t sample)
      48             : {
      49             :     static const char module[] = "TIFFWriteScanline";
      50             :     TIFFDirectory *td;
      51       57252 :     int status, imagegrew = 0;
      52             :     uint32_t strip;
      53             : 
      54       57252 :     if (!WRITECHECKSTRIPS(tif, module))
      55           0 :         return (-1);
      56             :     /*
      57             :      * Handle delayed allocation of data buffer.  This
      58             :      * permits it to be sized more intelligently (using
      59             :      * directory information).
      60             :      */
      61       57252 :     if (!BUFFERCHECK(tif))
      62           0 :         return (-1);
      63       57252 :     tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
      64             : 
      65       57252 :     td = &tif->tif_dir;
      66             :     /*
      67             :      * Extend image length if needed
      68             :      * (but only for PlanarConfig=1).
      69             :      */
      70       57252 :     if (row >= td->td_imagelength)
      71             :     { /* extend image */
      72           0 :         if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
      73             :         {
      74           0 :             TIFFErrorExtR(
      75             :                 tif, module,
      76             :                 "Can not change \"ImageLength\" when using separate planes");
      77           0 :             return (-1);
      78             :         }
      79           0 :         td->td_imagelength = row + 1;
      80           0 :         imagegrew = 1;
      81             :     }
      82             :     /*
      83             :      * Calculate strip and check for crossings.
      84             :      */
      85       57252 :     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
      86             :     {
      87       15000 :         if (sample >= td->td_samplesperpixel)
      88             :         {
      89           0 :             TIFFErrorExtR(tif, module, "%lu: Sample out of range, max %lu",
      90             :                           (unsigned long)sample,
      91           0 :                           (unsigned long)td->td_samplesperpixel);
      92           0 :             return (-1);
      93             :         }
      94       15000 :         strip = sample * td->td_stripsperimage + row / td->td_rowsperstrip;
      95             :     }
      96             :     else
      97       42252 :         strip = row / td->td_rowsperstrip;
      98             :     /*
      99             :      * Check strip array to make sure there's space. We don't support
     100             :      * dynamically growing files that have data organized in separate
     101             :      * bitplanes because it's too painful.  In that case we require that
     102             :      * the imagelength be set properly before the first write (so that the
     103             :      * strips array will be fully allocated above).
     104             :      */
     105       57252 :     if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
     106           0 :         return (-1);
     107       57252 :     if (strip != tif->tif_dir.td_curstrip)
     108             :     {
     109             :         /*
     110             :          * Changing strips -- flush any data present.
     111             :          */
     112          11 :         if (!TIFFFlushData(tif))
     113           0 :             return (-1);
     114          11 :         tif->tif_dir.td_curstrip = strip;
     115             :         /*
     116             :          * Watch out for a growing image.  The value of strips/image
     117             :          * will initially be 1 (since it can't be deduced until the
     118             :          * imagelength is known).
     119             :          */
     120          11 :         if (strip >= td->td_stripsperimage && imagegrew)
     121           0 :             td->td_stripsperimage =
     122           0 :                 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
     123          11 :         if (td->td_stripsperimage == 0)
     124             :         {
     125           0 :             TIFFErrorExtR(tif, module, "Zero strips per image");
     126           0 :             return (-1);
     127             :         }
     128          11 :         tif->tif_dir.td_row =
     129          11 :             (strip % td->td_stripsperimage) * td->td_rowsperstrip;
     130          11 :         if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
     131             :         {
     132           9 :             if (!(*tif->tif_setupencode)(tif))
     133           0 :                 return (-1);
     134           9 :             tif->tif_flags |= TIFF_CODERSETUP;
     135             :         }
     136             : 
     137          11 :         tif->tif_rawcc = 0;
     138          11 :         tif->tif_rawcp = tif->tif_rawdata;
     139             : 
     140             :         /* this informs TIFFAppendToStrip() we have changed strip */
     141          11 :         tif->tif_curoff = 0;
     142             : 
     143          11 :         if (!(*tif->tif_preencode)(tif, sample))
     144           0 :             return (-1);
     145          11 :         tif->tif_flags |= TIFF_POSTENCODE;
     146             :     }
     147             :     /*
     148             :      * Ensure the write is either sequential or at the
     149             :      * beginning of a strip (or that we can randomly
     150             :      * access the data -- i.e. no encoding).
     151             :      */
     152       57252 :     if (row != tif->tif_dir.td_row)
     153             :     {
     154           0 :         if (row < tif->tif_dir.td_row)
     155             :         {
     156             :             /*
     157             :              * Moving backwards within the same strip:
     158             :              * backup to the start and then decode
     159             :              * forward (below).
     160             :              */
     161           0 :             tif->tif_dir.td_row =
     162           0 :                 (strip % td->td_stripsperimage) * td->td_rowsperstrip;
     163           0 :             tif->tif_rawcp = tif->tif_rawdata;
     164             :         }
     165             :         /*
     166             :          * Seek forward to the desired row.
     167             :          */
     168           0 :         if (!(*tif->tif_seek)(tif, row - tif->tif_dir.td_row))
     169           0 :             return (-1);
     170           0 :         tif->tif_dir.td_row = row;
     171             :     }
     172             : 
     173             :     /* swab if needed - note that source buffer will be altered */
     174       57252 :     tif->tif_postdecode(tif, (uint8_t *)buf, tif->tif_dir.td_scanlinesize);
     175             : 
     176       57252 :     status = (*tif->tif_encoderow)(tif, (uint8_t *)buf,
     177             :                                    tif->tif_dir.td_scanlinesize, sample);
     178             : 
     179             :     /* we are now poised at the beginning of the next row */
     180       57252 :     tif->tif_dir.td_row = row + 1;
     181       57252 :     return (status);
     182             : }
     183             : 
     184             : /* Make sure that at the first attempt of rewriting a tile/strip, we will have
     185             :  */
     186             : /* more bytes available in the output buffer than the previous byte count, */
     187             : /* so that TIFFAppendToStrip() will detect the overflow when it is called the
     188             :  * first */
     189             : /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
     190      199791 : static int _TIFFReserveLargeEnoughWriteBuffer(TIFF *tif, uint32_t strip_or_tile)
     191             : {
     192             :     static const char module[] = "_TIFFReserveLargeEnoughWriteBuffer";
     193      199791 :     TIFFDirectory *td = &tif->tif_dir;
     194             : 
     195      199791 :     if (td->td_stripbytecount_p == NULL)
     196             :     {
     197           0 :         TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL");
     198           0 :         return 0;
     199             :     }
     200             : 
     201      199791 :     if (strip_or_tile == NOSTRIP || strip_or_tile >= td->td_nstrips)
     202             :     {
     203           0 :         TIFFErrorExtR(tif, module, "Strip/tile number not valid");
     204           0 :         return 0;
     205             :     }
     206             : 
     207      199796 :     if (td->td_stripbytecount_p[strip_or_tile] > 0)
     208             :     {
     209             :         /* The +1 is to ensure at least one extra bytes */
     210             :         /* The +4 is because the LZW encoder flushes 4 bytes before the limit */
     211       40460 :         uint64_t safe_buffer_size =
     212       40460 :             (uint64_t)(td->td_stripbytecount_p[strip_or_tile] + 1 + 4);
     213       40460 :         if (tif->tif_rawdatasize <= (tmsize_t)safe_buffer_size)
     214             :         {
     215           0 :             if (!(TIFFWriteBufferSetup(
     216             :                     tif, NULL,
     217           0 :                     (tmsize_t)TIFFroundup_64(safe_buffer_size, 1024))))
     218           0 :                 return 0;
     219             :         }
     220             :     }
     221      199796 :     return 1;
     222             : }
     223             : 
     224             : /*
     225             :  * Encode the supplied data and write it to the
     226             :  * specified strip.
     227             :  *
     228             :  * NB: Image length must be setup before writing.
     229             :  */
     230      170503 : tmsize_t TIFFWriteEncodedStrip(TIFF *tif, uint32_t strip, void *data,
     231             :                                tmsize_t cc)
     232             : {
     233             :     static const char module[] = "TIFFWriteEncodedStrip";
     234      170503 :     TIFFDirectory *td = &tif->tif_dir;
     235             :     uint16_t sample;
     236             : 
     237      170503 :     if (!WRITECHECKSTRIPS(tif, module))
     238           0 :         return ((tmsize_t)-1);
     239             :     /*
     240             :      * Check strip array to make sure there's space.
     241             :      * We don't support dynamically growing files that
     242             :      * have data organized in separate bitplanes because
     243             :      * it's too painful.  In that case we require that
     244             :      * the imagelength be set properly before the first
     245             :      * write (so that the strips array will be fully
     246             :      * allocated above).
     247             :      */
     248      170503 :     if (strip >= td->td_nstrips)
     249             :     {
     250           0 :         if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
     251             :         {
     252           0 :             TIFFErrorExtR(
     253             :                 tif, module,
     254             :                 "Can not grow image by strips when using separate planes");
     255           0 :             return ((tmsize_t)-1);
     256             :         }
     257           0 :         if (!TIFFGrowStrips(tif, 1, module))
     258           0 :             return ((tmsize_t)-1);
     259           0 :         td->td_stripsperimage =
     260           0 :             TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
     261             :     }
     262             :     /*
     263             :      * Handle delayed allocation of data buffer.  This
     264             :      * permits it to be sized according to the directory
     265             :      * info.
     266             :      */
     267      170503 :     if (!BUFFERCHECK(tif))
     268           0 :         return ((tmsize_t)-1);
     269             : 
     270      170508 :     tif->tif_flags |= TIFF_BUF4WRITE;
     271             : 
     272      170508 :     tif->tif_dir.td_curstrip = strip;
     273             : 
     274             :     /* this informs TIFFAppendToStrip() we have changed or reset strip */
     275      170508 :     tif->tif_curoff = 0;
     276             : 
     277      170508 :     if (!_TIFFReserveLargeEnoughWriteBuffer(tif, strip))
     278             :     {
     279           0 :         return ((tmsize_t)(-1));
     280             :     }
     281             : 
     282      170475 :     tif->tif_rawcc = 0;
     283      170475 :     tif->tif_rawcp = tif->tif_rawdata;
     284             : 
     285      170475 :     if (td->td_stripsperimage == 0)
     286             :     {
     287           0 :         TIFFErrorExtR(tif, module, "Zero strips per image");
     288           0 :         return ((tmsize_t)-1);
     289             :     }
     290             : 
     291      170475 :     tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
     292      170475 :     if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
     293             :     {
     294       36053 :         if (!(*tif->tif_setupencode)(tif))
     295           0 :             return ((tmsize_t)-1);
     296       36053 :         tif->tif_flags |= TIFF_CODERSETUP;
     297             :     }
     298             : 
     299      170475 :     tif->tif_flags &= ~TIFF_POSTENCODE;
     300             : 
     301             :     /* shortcut to avoid an extra memcpy() */
     302      170475 :     if (td->td_compression == COMPRESSION_NONE)
     303             :     {
     304             :         /* swab if needed - note that source buffer will be altered */
     305      140618 :         tif->tif_postdecode(tif, (uint8_t *)data, cc);
     306             : 
     307      140639 :         if (!isFillOrder(tif, td->td_fillorder) &&
     308           0 :             (tif->tif_flags & TIFF_NOBITREV) == 0)
     309           0 :             TIFFReverseBits((uint8_t *)data, cc);
     310             : 
     311      140654 :         if (cc > 0 && !TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc))
     312           4 :             return ((tmsize_t)-1);
     313      140907 :         return (cc);
     314             :     }
     315             : 
     316       29857 :     sample = (uint16_t)(strip / td->td_stripsperimage);
     317       29857 :     if (!(*tif->tif_preencode)(tif, sample))
     318           2 :         return ((tmsize_t)-1);
     319             : 
     320             :     /* swab if needed - note that source buffer will be altered */
     321       29844 :     tif->tif_postdecode(tif, (uint8_t *)data, cc);
     322             : 
     323       29844 :     if (!(*tif->tif_encodestrip)(tif, (uint8_t *)data, cc, sample))
     324           0 :         return ((tmsize_t)-1);
     325       29843 :     if (!(*tif->tif_postencode)(tif))
     326           1 :         return ((tmsize_t)-1);
     327       29842 :     if (!isFillOrder(tif, td->td_fillorder) &&
     328           0 :         (tif->tif_flags & TIFF_NOBITREV) == 0)
     329           0 :         TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
     330       45823 :     if (tif->tif_rawcc > 0 &&
     331       15980 :         !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
     332           0 :         return ((tmsize_t)-1);
     333       29843 :     tif->tif_rawcc = 0;
     334       29843 :     tif->tif_rawcp = tif->tif_rawdata;
     335       29843 :     return (cc);
     336             : }
     337             : 
     338             : /*
     339             :  * Write the supplied data to the specified strip.
     340             :  *
     341             :  * NB: Image length must be setup before writing.
     342             :  */
     343        7713 : tmsize_t TIFFWriteRawStrip(TIFF *tif, uint32_t strip, void *data, tmsize_t cc)
     344             : {
     345             :     static const char module[] = "TIFFWriteRawStrip";
     346        7713 :     TIFFDirectory *td = &tif->tif_dir;
     347             : 
     348        7713 :     if (!WRITECHECKSTRIPS(tif, module))
     349           0 :         return ((tmsize_t)-1);
     350             :     /*
     351             :      * Check strip array to make sure there's space.
     352             :      * We don't support dynamically growing files that
     353             :      * have data organized in separate bitplanes because
     354             :      * it's too painful.  In that case we require that
     355             :      * the imagelength be set properly before the first
     356             :      * write (so that the strips array will be fully
     357             :      * allocated above).
     358             :      */
     359        7713 :     if (strip >= td->td_nstrips)
     360             :     {
     361           0 :         if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
     362             :         {
     363           0 :             TIFFErrorExtR(
     364             :                 tif, module,
     365             :                 "Can not grow image by strips when using separate planes");
     366           0 :             return ((tmsize_t)-1);
     367             :         }
     368             :         /*
     369             :          * Watch out for a growing image.  The value of
     370             :          * strips/image will initially be 1 (since it
     371             :          * can't be deduced until the imagelength is known).
     372             :          */
     373           0 :         if (strip >= td->td_stripsperimage)
     374           0 :             td->td_stripsperimage =
     375           0 :                 TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
     376           0 :         if (!TIFFGrowStrips(tif, 1, module))
     377           0 :             return ((tmsize_t)-1);
     378             :     }
     379             : 
     380        7713 :     if (tif->tif_dir.td_curstrip != strip)
     381             :     {
     382        7713 :         tif->tif_dir.td_curstrip = strip;
     383             : 
     384             :         /* this informs TIFFAppendToStrip() we have changed or reset strip */
     385        7713 :         tif->tif_curoff = 0;
     386             :     }
     387             : 
     388        7713 :     if (td->td_stripsperimage == 0)
     389             :     {
     390           0 :         TIFFErrorExtR(tif, module, "Zero strips per image");
     391           0 :         return ((tmsize_t)-1);
     392             :     }
     393        7713 :     tif->tif_dir.td_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
     394        7713 :     return (TIFFAppendToStrip(tif, strip, (uint8_t *)data, cc) ? cc
     395        7713 :                                                                : (tmsize_t)-1);
     396             : }
     397             : 
     398             : /*
     399             :  * Write and compress a tile of data.  The
     400             :  * tile is selected by the (x,y,z,s) coordinates.
     401             :  */
     402           0 : tmsize_t TIFFWriteTile(TIFF *tif, void *buf, uint32_t x, uint32_t y, uint32_t z,
     403             :                        uint16_t s)
     404             : {
     405           0 :     if (!TIFFCheckTile(tif, x, y, z, s))
     406           0 :         return ((tmsize_t)(-1));
     407             :     /*
     408             :      * NB: A tile size of -1 is used instead of tif_tilesize knowing
     409             :      *     that TIFFWriteEncodedTile will clamp this to the tile size.
     410             :      *     This is done because the tile size may not be defined until
     411             :      *     after the output buffer is setup in TIFFWriteBufferSetup.
     412             :      */
     413           0 :     return (TIFFWriteEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf,
     414             :                                  (tmsize_t)(-1)));
     415             : }
     416             : 
     417             : /*
     418             :  * Encode the supplied data and write it to the
     419             :  * specified tile.  There must be space for the
     420             :  * data.  The function clamps individual writes
     421             :  * to a tile to the tile size, but does not (and
     422             :  * can not) check that multiple writes to the same
     423             :  * tile do not write more than tile size data.
     424             :  *
     425             :  * NB: Image length must be setup before writing; this
     426             :  *     interface does not support automatically growing
     427             :  *     the image on each write (as TIFFWriteScanline does).
     428             :  */
     429       29343 : tmsize_t TIFFWriteEncodedTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
     430             : {
     431             :     static const char module[] = "TIFFWriteEncodedTile";
     432             :     TIFFDirectory *td;
     433             :     uint16_t sample;
     434             :     uint32_t howmany32;
     435             : 
     436       29343 :     if (!WRITECHECKTILES(tif, module))
     437           0 :         return ((tmsize_t)(-1));
     438       29343 :     td = &tif->tif_dir;
     439       29343 :     if (tile >= td->td_nstrips)
     440             :     {
     441           0 :         TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
     442           0 :                       (unsigned long)tile, (unsigned long)td->td_nstrips);
     443           0 :         return ((tmsize_t)(-1));
     444             :     }
     445             :     /*
     446             :      * Handle delayed allocation of data buffer.  This
     447             :      * permits it to be sized more intelligently (using
     448             :      * directory information).
     449             :      */
     450       29343 :     if (!BUFFERCHECK(tif))
     451           0 :         return ((tmsize_t)(-1));
     452             : 
     453       29343 :     tif->tif_flags |= TIFF_BUF4WRITE;
     454             : 
     455       29343 :     tif->tif_dir.td_curtile = tile;
     456             : 
     457             :     /* this informs TIFFAppendToStrip() we have changed or reset tile */
     458       29343 :     tif->tif_curoff = 0;
     459             : 
     460       29343 :     if (!_TIFFReserveLargeEnoughWriteBuffer(tif, tile))
     461             :     {
     462           0 :         return ((tmsize_t)(-1));
     463             :     }
     464             : 
     465       29343 :     tif->tif_rawcc = 0;
     466       29343 :     tif->tif_rawcp = tif->tif_rawdata;
     467             : 
     468             :     /*
     469             :      * Compute tiles per row & per column to compute
     470             :      * current row and column
     471             :      */
     472       29343 :     howmany32 = TIFFhowmany_32(td->td_imagelength, td->td_tilelength);
     473       29343 :     if (howmany32 == 0)
     474             :     {
     475           0 :         TIFFErrorExtR(tif, module, "Zero tiles");
     476           0 :         return ((tmsize_t)(-1));
     477             :     }
     478       29343 :     tif->tif_dir.td_row = (tile % howmany32) * td->td_tilelength;
     479       29343 :     howmany32 = TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth);
     480       29343 :     if (howmany32 == 0)
     481             :     {
     482           0 :         TIFFErrorExtR(tif, module, "Zero tiles");
     483           0 :         return ((tmsize_t)(-1));
     484             :     }
     485       29343 :     tif->tif_dir.td_col = (tile % howmany32) * td->td_tilewidth;
     486             : 
     487       29343 :     if ((tif->tif_flags & TIFF_CODERSETUP) == 0)
     488             :     {
     489        1304 :         if (!(*tif->tif_setupencode)(tif))
     490           0 :             return ((tmsize_t)(-1));
     491        1304 :         tif->tif_flags |= TIFF_CODERSETUP;
     492             :     }
     493       29343 :     tif->tif_flags &= ~TIFF_POSTENCODE;
     494             : 
     495             :     /*
     496             :      * Clamp write amount to the tile size.  This is mostly
     497             :      * done so that callers can pass in some large number
     498             :      * (e.g. -1) and have the tile size used instead.
     499             :      */
     500       29343 :     if (cc < 1 || cc > tif->tif_dir.td_tilesize)
     501           0 :         cc = tif->tif_dir.td_tilesize;
     502             : 
     503             :     /* shortcut to avoid an extra memcpy() */
     504       29343 :     if (td->td_compression == COMPRESSION_NONE)
     505             :     {
     506             :         /* swab if needed - note that source buffer will be altered */
     507       20303 :         tif->tif_postdecode(tif, (uint8_t *)data, cc);
     508             : 
     509       20303 :         if (!isFillOrder(tif, td->td_fillorder) &&
     510           0 :             (tif->tif_flags & TIFF_NOBITREV) == 0)
     511           0 :             TIFFReverseBits((uint8_t *)data, cc);
     512             : 
     513       20303 :         if (cc > 0 && !TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc))
     514           0 :             return ((tmsize_t)-1);
     515       20303 :         return (cc);
     516             :     }
     517             : 
     518        9040 :     sample = (uint16_t)(tile / td->td_stripsperimage);
     519        9040 :     if (!(*tif->tif_preencode)(tif, sample))
     520           0 :         return ((tmsize_t)(-1));
     521             :     /* swab if needed - note that source buffer will be altered */
     522        9024 :     tif->tif_postdecode(tif, (uint8_t *)data, cc);
     523             : 
     524        9042 :     if (!(*tif->tif_encodetile)(tif, (uint8_t *)data, cc, sample))
     525           0 :         return ((tmsize_t)-1);
     526        9047 :     if (!(*tif->tif_postencode)(tif))
     527           1 :         return ((tmsize_t)(-1));
     528        9046 :     if (!isFillOrder(tif, td->td_fillorder) &&
     529           0 :         (tif->tif_flags & TIFF_NOBITREV) == 0)
     530           0 :         TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
     531       11028 :     if (tif->tif_rawcc > 0 &&
     532        1984 :         !TIFFAppendToStrip(tif, tile, tif->tif_rawdata, tif->tif_rawcc))
     533          12 :         return ((tmsize_t)(-1));
     534        9032 :     tif->tif_rawcc = 0;
     535        9032 :     tif->tif_rawcp = tif->tif_rawdata;
     536        9032 :     return (cc);
     537             : }
     538             : 
     539             : /*
     540             :  * Write the supplied data to the specified strip.
     541             :  * There must be space for the data; we don't check
     542             :  * if strips overlap!
     543             :  *
     544             :  * NB: Image length must be setup before writing; this
     545             :  *     interface does not support automatically growing
     546             :  *     the image on each write (as TIFFWriteScanline does).
     547             :  */
     548       26421 : tmsize_t TIFFWriteRawTile(TIFF *tif, uint32_t tile, void *data, tmsize_t cc)
     549             : {
     550             :     static const char module[] = "TIFFWriteRawTile";
     551             : 
     552       26421 :     if (!WRITECHECKTILES(tif, module))
     553           0 :         return ((tmsize_t)(-1));
     554       26421 :     if (tile >= tif->tif_dir.td_nstrips)
     555             :     {
     556           0 :         TIFFErrorExtR(tif, module, "Tile %lu out of range, max %lu",
     557             :                       (unsigned long)tile,
     558           0 :                       (unsigned long)tif->tif_dir.td_nstrips);
     559           0 :         return ((tmsize_t)(-1));
     560             :     }
     561       26421 :     return (TIFFAppendToStrip(tif, tile, (uint8_t *)data, cc) ? cc
     562       26421 :                                                               : (tmsize_t)(-1));
     563             : }
     564             : 
     565             : #define isUnspecified(tif, f)                                                  \
     566             :     (TIFFFieldSet(tif, f) && (tif)->tif_dir.td_imagelength == 0)
     567             : 
     568       41870 : int TIFFSetupStrips(TIFF *tif)
     569             : {
     570       41870 :     TIFFDirectory *td = &tif->tif_dir;
     571             : 
     572       41870 :     if (isTiled(tif))
     573        6146 :         td->td_stripsperimage = isUnspecified(tif, FIELD_TILEDIMENSIONS)
     574           0 :                                     ? td->td_samplesperpixel
     575        6146 :                                     : TIFFNumberOfTiles(tif);
     576             :     else
     577       77593 :         td->td_stripsperimage = isUnspecified(tif, FIELD_ROWSPERSTRIP)
     578           0 :                                     ? td->td_samplesperpixel
     579       77594 :                                     : TIFFNumberOfStrips(tif);
     580       41869 :     td->td_nstrips = td->td_stripsperimage;
     581             :     /* TIFFWriteDirectoryTagData has a limitation to 0x80000000U bytes */
     582       83738 :     if (td->td_nstrips >=
     583       41869 :         0x80000000U / ((tif->tif_flags & TIFF_BIGTIFF) ? 0x8U : 0x4U))
     584             :     {
     585           0 :         TIFFErrorExtR(tif, "TIFFSetupStrips",
     586             :                       "Too large Strip/Tile Offsets/ByteCounts arrays");
     587           0 :         return 0;
     588             :     }
     589       41869 :     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
     590        4002 :         td->td_stripsperimage /= td->td_samplesperpixel;
     591             : 
     592       41869 :     if (td->td_stripoffset_p != NULL)
     593           0 :         _TIFFfreeExt(tif, td->td_stripoffset_p);
     594       83739 :     td->td_stripoffset_p = (uint64_t *)_TIFFCheckMalloc(
     595       41869 :         tif, td->td_nstrips, sizeof(uint64_t), "for \"StripOffsets\" array");
     596       41870 :     if (td->td_stripbytecount_p != NULL)
     597           0 :         _TIFFfreeExt(tif, td->td_stripbytecount_p);
     598       83740 :     td->td_stripbytecount_p = (uint64_t *)_TIFFCheckMalloc(
     599       41870 :         tif, td->td_nstrips, sizeof(uint64_t), "for \"StripByteCounts\" array");
     600       41870 :     if (td->td_stripoffset_p == NULL || td->td_stripbytecount_p == NULL)
     601           0 :         return (0);
     602             :     /*
     603             :      * Place data at the end-of-file
     604             :      * (by setting offsets to zero).
     605             :      */
     606       41870 :     _TIFFmemset(td->td_stripoffset_p, 0,
     607       41870 :                 (tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t)));
     608       41870 :     _TIFFmemset(td->td_stripbytecount_p, 0,
     609       41870 :                 (tmsize_t)((size_t)td->td_nstrips * sizeof(uint64_t)));
     610       41870 :     TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
     611       41870 :     TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
     612       41870 :     return (1);
     613             : }
     614             : #undef isUnspecified
     615             : 
     616             : /*
     617             :  * Verify file is writable and that the directory
     618             :  * information is setup properly.  In doing the latter
     619             :  * we also "freeze" the state of the directory so
     620             :  * that important information is not changed.
     621             :  */
     622       52688 : int TIFFWriteCheck(TIFF *tif, int tiles, const char *module)
     623             : {
     624       52688 :     if (tif->tif_mode == O_RDONLY)
     625             :     {
     626           0 :         TIFFErrorExtR(tif, module, "File not open for writing");
     627           0 :         return (0);
     628             :     }
     629       52688 :     if (tiles ^ isTiled(tif))
     630             :     {
     631           0 :         TIFFErrorExtR(tif, module,
     632             :                       tiles ? "Can not write tiles to a striped image"
     633             :                             : "Can not write scanlines to a tiled image");
     634           0 :         return (0);
     635             :     }
     636             : 
     637       52688 :     _TIFFFillStriles(tif);
     638             : 
     639             :     /*
     640             :      * On the first write verify all the required information
     641             :      * has been setup and initialize any data structures that
     642             :      * had to wait until directory information was set.
     643             :      * Note that a lot of our work is assumed to remain valid
     644             :      * because we disallow any of the important parameters
     645             :      * from changing after we start writing (i.e. once
     646             :      * TIFF_BEENWRITING is set, TIFFSetField will only allow
     647             :      * the image's length to be changed).
     648             :      */
     649       52688 :     if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS))
     650             :     {
     651           0 :         TIFFErrorExtR(tif, module,
     652             :                       "Must set \"ImageWidth\" before writing data");
     653           0 :         return (0);
     654             :     }
     655       52688 :     if (tif->tif_dir.td_stripoffset_p == NULL && !TIFFSetupStrips(tif))
     656             :     {
     657           0 :         tif->tif_dir.td_nstrips = 0;
     658           0 :         TIFFErrorExtR(tif, module, "No space for %s arrays",
     659           0 :                       isTiled(tif) ? "tile" : "strip");
     660           0 :         return (0);
     661             :     }
     662       52688 :     if (isTiled(tif))
     663             :     {
     664        3523 :         tif->tif_dir.td_tilesize = TIFFTileSize(tif);
     665        3523 :         if (tif->tif_dir.td_tilesize == 0)
     666           0 :             return (0);
     667             :     }
     668             :     else
     669       49165 :         tif->tif_dir.td_tilesize = (tmsize_t)(-1);
     670       52688 :     tif->tif_dir.td_scanlinesize = TIFFScanlineSize(tif);
     671       52688 :     if (tif->tif_dir.td_scanlinesize == 0)
     672           0 :         return (0);
     673       52688 :     tif->tif_flags |= TIFF_BEENWRITING;
     674             : 
     675       52688 :     if (tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
     676       11396 :         tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
     677           0 :         tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
     678           0 :         tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
     679           0 :         tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
     680           0 :         tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
     681           0 :         tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
     682           0 :         tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 &&
     683           0 :         !(tif->tif_flags & TIFF_DIRTYDIRECT))
     684             :     {
     685           0 :         TIFFForceStrileArrayWriting(tif);
     686             :     }
     687             : 
     688       52688 :     return (1);
     689             : }
     690             : 
     691             : /*
     692             :  * Setup the raw data buffer used for encoding.
     693             :  */
     694       37455 : int TIFFWriteBufferSetup(TIFF *tif, void *bp, tmsize_t size)
     695             : {
     696             :     static const char module[] = "TIFFWriteBufferSetup";
     697             : 
     698       37455 :     if (tif->tif_rawdata)
     699             :     {
     700          26 :         if (tif->tif_flags & TIFF_MYBUFFER)
     701             :         {
     702          26 :             _TIFFfreeExt(tif, tif->tif_rawdata);
     703          26 :             tif->tif_flags &= ~TIFF_MYBUFFER;
     704             :         }
     705          26 :         tif->tif_rawdata = NULL;
     706             :     }
     707       37455 :     if (size == (tmsize_t)(-1))
     708             :     {
     709       37455 :         size = (isTiled(tif) ? tif->tif_dir.td_tilesize : TIFFStripSize(tif));
     710             : 
     711             :         /* Adds 10% margin for cases where compression would expand a bit */
     712       37455 :         if (size < TIFF_TMSIZE_T_MAX - size / 10)
     713       37455 :             size += size / 10;
     714             :         /*
     715             :          * Make raw data buffer at least 8K
     716             :          */
     717       37455 :         if (size < 8 * 1024)
     718       27174 :             size = 8 * 1024;
     719       37455 :         bp = NULL; /* NB: force malloc */
     720             :     }
     721       37455 :     if (bp == NULL)
     722             :     {
     723       37455 :         bp = _TIFFmallocExt(tif, size);
     724       37455 :         if (bp == NULL)
     725             :         {
     726           0 :             TIFFErrorExtR(tif, module, "No space for output buffer");
     727           0 :             return (0);
     728             :         }
     729       37455 :         tif->tif_flags |= TIFF_MYBUFFER;
     730             :     }
     731             :     else
     732           0 :         tif->tif_flags &= ~TIFF_MYBUFFER;
     733       37455 :     tif->tif_rawdata = (uint8_t *)bp;
     734       37455 :     tif->tif_rawdatasize = size;
     735       37455 :     tif->tif_rawcc = 0;
     736       37455 :     tif->tif_rawcp = tif->tif_rawdata;
     737       37455 :     tif->tif_flags |= TIFF_BUFFERSETUP;
     738       37455 :     return (1);
     739             : }
     740             : 
     741             : /*
     742             :  * Grow the strip data structures by delta strips.
     743             :  */
     744           0 : static int TIFFGrowStrips(TIFF *tif, uint32_t delta, const char *module)
     745             : {
     746           0 :     TIFFDirectory *td = &tif->tif_dir;
     747             :     uint64_t *new_stripoffset;
     748             :     uint64_t *new_stripbytecount;
     749             : 
     750           0 :     assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
     751           0 :     new_stripoffset = (uint64_t *)_TIFFreallocExt(
     752           0 :         tif, td->td_stripoffset_p,
     753           0 :         (tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) *
     754             :                    sizeof(uint64_t)));
     755             :     /*
     756             :      * Update td_stripoffset_p immediately so the old pointer is not left
     757             :      * dangling if the second realloc fails.
     758             :      */
     759           0 :     if (new_stripoffset)
     760           0 :         td->td_stripoffset_p = new_stripoffset;
     761           0 :     new_stripbytecount = (uint64_t *)_TIFFreallocExt(
     762           0 :         tif, td->td_stripbytecount_p,
     763           0 :         (tmsize_t)(((size_t)td->td_nstrips + (size_t)delta) *
     764             :                    sizeof(uint64_t)));
     765           0 :     if (new_stripbytecount)
     766           0 :         td->td_stripbytecount_p = new_stripbytecount;
     767           0 :     if (new_stripoffset == NULL || new_stripbytecount == NULL)
     768             :     {
     769           0 :         td->td_nstrips = 0;
     770           0 :         TIFFErrorExtR(tif, module, "No space to expand strip arrays");
     771           0 :         return (0);
     772             :     }
     773           0 :     _TIFFmemset(td->td_stripoffset_p + td->td_nstrips, 0,
     774           0 :                 (tmsize_t)((size_t)delta * sizeof(uint64_t)));
     775           0 :     _TIFFmemset(td->td_stripbytecount_p + td->td_nstrips, 0,
     776           0 :                 (tmsize_t)((size_t)delta * sizeof(uint64_t)));
     777           0 :     td->td_nstrips += delta;
     778           0 :     tif->tif_flags |= TIFF_DIRTYDIRECT;
     779             : 
     780           0 :     return (1);
     781             : }
     782             : 
     783             : /*
     784             :  * Append the data to the specified strip.
     785             :  */
     786      233999 : static int TIFFAppendToStrip(TIFF *tif, uint32_t strip, uint8_t *data,
     787             :                              tmsize_t cc)
     788             : {
     789             :     static const char module[] = "TIFFAppendToStrip";
     790      233999 :     TIFFDirectory *td = &tif->tif_dir;
     791             :     uint64_t m;
     792      233999 :     int64_t old_byte_count = -1;
     793             : 
     794             :     /* Some security checks */
     795      233999 :     if (td->td_stripoffset_p == NULL)
     796             :     {
     797           0 :         TIFFErrorExtR(tif, module, "Strip offset array pointer is NULL");
     798           0 :         return (0);
     799             :     }
     800      233999 :     if (td->td_stripbytecount_p == NULL)
     801             :     {
     802           0 :         TIFFErrorExtR(tif, module, "Strip bytecount array pointer is NULL");
     803           0 :         return (0);
     804             :     }
     805      233999 :     if (strip == NOSTRIP)
     806             :     {
     807           0 :         TIFFErrorExtR(tif, module, "Strip number not valid (NOSTRIP)");
     808           0 :         return (0);
     809             :     }
     810             : 
     811      233999 :     if (tif->tif_curoff == 0)
     812      208350 :         tif->tif_lastvalidoff = 0;
     813             : 
     814      233999 :     if (td->td_stripoffset_p[strip] == 0 || tif->tif_curoff == 0)
     815             :     {
     816      233985 :         assert(td->td_nstrips > 0);
     817             : 
     818      233985 :         if (td->td_stripbytecount_p[strip] != 0 &&
     819       40867 :             td->td_stripoffset_p[strip] != 0 &&
     820       40872 :             td->td_stripbytecount_p[strip] >= (uint64_t)cc)
     821             :         {
     822             :             /*
     823             :              * There is already tile data on disk, and the new tile
     824             :              * data we have will fit in the same space.  The only
     825             :              * aspect of this that is risky is that there could be
     826             :              * more data to append to this strip before we are done
     827             :              * depending on how we are getting called.
     828             :              */
     829       40843 :             if (!SeekOK(tif, td->td_stripoffset_p[strip]))
     830             :             {
     831          16 :                 TIFFErrorExtR(tif, module, "Seek error at scanline %lu",
     832          16 :                               (unsigned long)tif->tif_dir.td_row);
     833           0 :                 return (0);
     834             :             }
     835             : 
     836       41010 :             tif->tif_lastvalidoff =
     837       41010 :                 td->td_stripoffset_p[strip] + td->td_stripbytecount_p[strip];
     838             :         }
     839             :         else
     840             :         {
     841             :             /*
     842             :              * Seek to end of file, and set that as our location to
     843             :              * write this strip.
     844             :              */
     845      193142 :             td->td_stripoffset_p[strip] = TIFFSeekFile(tif, 0, SEEK_END);
     846      193157 :             tif->tif_flags |= TIFF_DIRTYSTRIP;
     847             :         }
     848             : 
     849      234167 :         tif->tif_curoff = td->td_stripoffset_p[strip];
     850             : 
     851             :         /*
     852             :          * We are starting a fresh strip/tile, so set the size to zero.
     853             :          */
     854      234167 :         old_byte_count = (int64_t)td->td_stripbytecount_p[strip];
     855      234167 :         td->td_stripbytecount_p[strip] = 0;
     856             :     }
     857             : 
     858      234181 :     m = tif->tif_curoff + (uint64_t)cc;
     859      234181 :     if (!(tif->tif_flags & TIFF_BIGTIFF))
     860      219076 :         m = (uint32_t)m;
     861      234181 :     if ((m < tif->tif_curoff) || (m < (uint64_t)cc))
     862             :     {
     863           0 :         TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
     864           0 :         return (0);
     865             :     }
     866             : 
     867      234193 :     if (tif->tif_lastvalidoff != 0 && m > tif->tif_lastvalidoff &&
     868           0 :         td->td_stripbytecount_p[strip] > 0)
     869             :     {
     870             :         /* Ouch: we have detected that we are rewriting in place a strip/tile */
     871             :         /* with several calls to TIFFAppendToStrip(). The first call was with */
     872             :         /* a size smaller than the previous size of the strip/tile, so we */
     873             :         /* opted to rewrite in place, but a following call causes us to go */
     874             :         /* outsize of the strip/tile area, so we have to finally go for a */
     875             :         /* append-at-end-of-file strategy, and start by moving what we already
     876             :          */
     877             :         /* wrote. */
     878             :         tmsize_t tempSize;
     879             :         void *temp;
     880             :         uint64_t offsetRead;
     881             :         uint64_t offsetWrite;
     882           0 :         uint64_t toCopy = td->td_stripbytecount_p[strip];
     883             : 
     884           0 :         if (toCopy < 1024 * 1024)
     885           0 :             tempSize = (tmsize_t)toCopy;
     886             :         else
     887           0 :             tempSize = 1024 * 1024;
     888             : 
     889           0 :         offsetRead = td->td_stripoffset_p[strip];
     890           0 :         offsetWrite = TIFFSeekFile(tif, 0, SEEK_END);
     891             : 
     892           0 :         m = offsetWrite + (uint64_t)toCopy + (uint64_t)cc;
     893           0 :         if (!(tif->tif_flags & TIFF_BIGTIFF) && m != (uint32_t)m)
     894             :         {
     895           0 :             TIFFErrorExtR(tif, module, "Maximum TIFF file size exceeded");
     896           0 :             return (0);
     897             :         }
     898             : 
     899           0 :         temp = _TIFFmallocExt(tif, tempSize);
     900           0 :         if (temp == NULL)
     901             :         {
     902           0 :             TIFFErrorExtR(tif, module, "No space for output buffer");
     903           0 :             return (0);
     904             :         }
     905             : 
     906           0 :         tif->tif_flags |= TIFF_DIRTYSTRIP;
     907             : 
     908           0 :         td->td_stripoffset_p[strip] = offsetWrite;
     909           0 :         td->td_stripbytecount_p[strip] = 0;
     910             : 
     911             :         /* Move data written by previous calls to us at end of file */
     912           0 :         while (toCopy > 0)
     913             :         {
     914           0 :             tmsize_t chunkSize =
     915           0 :                 toCopy < (uint64_t)tempSize ? (tmsize_t)toCopy : tempSize;
     916           0 :             if (!SeekOK(tif, offsetRead))
     917             :             {
     918           0 :                 TIFFErrorExtR(tif, module, "Seek error");
     919           0 :                 _TIFFfreeExt(tif, temp);
     920           0 :                 return (0);
     921             :             }
     922           0 :             if (!ReadOK(tif, temp, chunkSize))
     923             :             {
     924           0 :                 TIFFErrorExtR(tif, module, "Cannot read");
     925           0 :                 _TIFFfreeExt(tif, temp);
     926           0 :                 return (0);
     927             :             }
     928           0 :             if (!SeekOK(tif, offsetWrite))
     929             :             {
     930           0 :                 TIFFErrorExtR(tif, module, "Seek error");
     931           0 :                 _TIFFfreeExt(tif, temp);
     932           0 :                 return (0);
     933             :             }
     934           0 :             if (!WriteOK(tif, temp, chunkSize))
     935             :             {
     936           0 :                 TIFFErrorExtR(tif, module, "Cannot write");
     937           0 :                 _TIFFfreeExt(tif, temp);
     938           0 :                 return (0);
     939             :             }
     940           0 :             offsetRead += (uint64_t)chunkSize;
     941           0 :             offsetWrite += (uint64_t)chunkSize;
     942           0 :             td->td_stripbytecount_p[strip] += (uint64_t)chunkSize;
     943           0 :             toCopy -= (uint64_t)chunkSize;
     944             :         }
     945           0 :         _TIFFfreeExt(tif, temp);
     946             : 
     947             :         /* Append the data of this call */
     948           0 :         offsetWrite += (uint64_t)cc;
     949           0 :         m = offsetWrite;
     950             :     }
     951             : 
     952      234193 :     if (!WriteOK(tif, data, cc))
     953             :     {
     954          45 :         TIFFErrorExtR(tif, module, "Write error at scanline %lu",
     955          45 :                       (unsigned long)tif->tif_dir.td_row);
     956          40 :         return (0);
     957             :     }
     958      234218 :     tif->tif_curoff = m;
     959      234218 :     td->td_stripbytecount_p[strip] += (uint64_t)cc;
     960             : 
     961      234218 :     if ((int64_t)td->td_stripbytecount_p[strip] != old_byte_count)
     962      193142 :         tif->tif_flags |= TIFF_DIRTYSTRIP;
     963             : 
     964      234218 :     return (1);
     965             : }
     966             : 
     967             : /*
     968             :  * Internal version of TIFFFlushData that can be
     969             :  * called by ``encodestrip routines'' w/o concern
     970             :  * for infinite recursion.
     971             :  */
     972       59623 : int TIFFFlushData1(TIFF *tif)
     973             : {
     974       59623 :     if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE)
     975             :     {
     976       20947 :         if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
     977           0 :             (tif->tif_flags & TIFF_NOBITREV) == 0)
     978           0 :             TIFFReverseBits((uint8_t *)tif->tif_rawdata, tif->tif_rawcc);
     979       20946 :         if (!TIFFAppendToStrip(tif,
     980       20946 :                                isTiled(tif) ? tif->tif_dir.td_curtile
     981             :                                             : tif->tif_dir.td_curstrip,
     982             :                                tif->tif_rawdata, tif->tif_rawcc))
     983             :         {
     984             :             /* We update those variables even in case of error since there's */
     985             :             /* code that doesn't really check the return code of this */
     986             :             /* function */
     987          12 :             tif->tif_rawcc = 0;
     988          12 :             tif->tif_rawcp = tif->tif_rawdata;
     989          12 :             return (0);
     990             :         }
     991       20935 :         tif->tif_rawcc = 0;
     992       20935 :         tif->tif_rawcp = tif->tif_rawdata;
     993             :     }
     994       59611 :     return (1);
     995             : }
     996             : 
     997             : /*
     998             :  * Set the current write offset.  This should only be
     999             :  * used to set the offset to a known previous location
    1000             :  * (very carefully), or to 0 so that the next write gets
    1001             :  * appended to the end of the file.
    1002             :  */
    1003         360 : void TIFFSetWriteOffset(TIFF *tif, toff_t off)
    1004             : {
    1005         360 :     tif->tif_curoff = off;
    1006         360 :     tif->tif_lastvalidoff = 0;
    1007         360 : }

Generated by: LCOV version 1.14