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

Generated by: LCOV version 1.14