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

Generated by: LCOV version 1.14