LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_zip.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 234 299 78.3 %
Date: 2024-05-03 15:49:35 Functions: 12 12 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1995-1997 Sam Leffler
       3             :  * Copyright (c) 1995-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             : #include "tiffiop.h"
      26             : #ifdef ZIP_SUPPORT
      27             : /*
      28             :  * TIFF Library.
      29             :  *
      30             :  * ZIP (aka Deflate) Compression Support
      31             :  *
      32             :  * This file is an interface to the zlib library written by
      33             :  * Jean-loup Gailly and Mark Adler.  You must use version 1.0 or later
      34             :  * of the library.
      35             :  *
      36             :  * Optionally, libdeflate (https://github.com/ebiggers/libdeflate) may be used
      37             :  * to do the compression and decompression, but only for whole strips and tiles.
      38             :  * For scanline access, zlib will be sued as a fallback.
      39             :  */
      40             : #include "tif_predict.h"
      41             : #include "zlib.h"
      42             : 
      43             : #if LIBDEFLATE_SUPPORT
      44             : #include "libdeflate.h"
      45             : #endif
      46             : #define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
      47             : 
      48             : #include <stdio.h>
      49             : 
      50             : /*
      51             :  * Sigh, ZLIB_VERSION is defined as a string so there's no
      52             :  * way to do a proper check here.  Instead we guess based
      53             :  * on the presence of #defines that were added between the
      54             :  * 0.95 and 1.0 distributions.
      55             :  */
      56             : #if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
      57             : #error "Antiquated ZLIB software; you must use version 1.0 or later"
      58             : #endif
      59             : 
      60             : #define SAFE_MSG(sp) ((sp)->stream.msg == NULL ? "" : (sp)->stream.msg)
      61             : 
      62             : /*
      63             :  * State block for each open TIFF
      64             :  * file using ZIP compression/decompression.
      65             :  */
      66             : typedef struct
      67             : {
      68             :     TIFFPredictorState predict;
      69             :     z_stream stream;
      70             :     int zipquality; /* compression level */
      71             :     int state;      /* state flags */
      72             :     int subcodec;   /* DEFLATE_SUBCODEC_ZLIB or DEFLATE_SUBCODEC_LIBDEFLATE */
      73             : #if LIBDEFLATE_SUPPORT
      74             :     int libdeflate_state; /* -1 = until first time ZIPEncode() / ZIPDecode() is
      75             :                              called, 0 = use zlib, 1 = use libdeflate */
      76             :     struct libdeflate_decompressor *libdeflate_dec;
      77             :     struct libdeflate_compressor *libdeflate_enc;
      78             : #endif
      79             : #define ZSTATE_INIT_DECODE 0x01
      80             : #define ZSTATE_INIT_ENCODE 0x02
      81             : 
      82             :     TIFFVGetMethod vgetparent; /* super-class method */
      83             :     TIFFVSetMethod vsetparent; /* super-class method */
      84             : } ZIPState;
      85             : 
      86             : #define GetZIPState(tif) ((ZIPState *)(tif)->tif_data)
      87             : #define ZIPDecoderState(tif) GetZIPState(tif)
      88             : #define ZIPEncoderState(tif) GetZIPState(tif)
      89             : 
      90             : static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
      91             : static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
      92             : 
      93        1907 : static int ZIPFixupTags(TIFF *tif)
      94             : {
      95             :     (void)tif;
      96        1907 :     return (1);
      97             : }
      98             : 
      99         450 : static int ZIPSetupDecode(TIFF *tif)
     100             : {
     101             :     static const char module[] = "ZIPSetupDecode";
     102         450 :     ZIPState *sp = ZIPDecoderState(tif);
     103             : 
     104         450 :     assert(sp != NULL);
     105             : 
     106             :     /* if we were last encoding, terminate this mode */
     107         450 :     if (sp->state & ZSTATE_INIT_ENCODE)
     108             :     {
     109          15 :         deflateEnd(&sp->stream);
     110          15 :         sp->state = 0;
     111             :     }
     112             : 
     113             :     /* This function can possibly be called several times by */
     114             :     /* PredictorSetupDecode() if this function succeeds but */
     115             :     /* PredictorSetup() fails */
     116         900 :     if ((sp->state & ZSTATE_INIT_DECODE) == 0 &&
     117         450 :         inflateInit(&sp->stream) != Z_OK)
     118             :     {
     119           0 :         TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
     120           0 :         return (0);
     121             :     }
     122             :     else
     123             :     {
     124         450 :         sp->state |= ZSTATE_INIT_DECODE;
     125         450 :         return (1);
     126             :     }
     127             : }
     128             : 
     129             : /*
     130             :  * Setup state for decoding a strip.
     131             :  */
     132        3043 : static int ZIPPreDecode(TIFF *tif, uint16_t s)
     133             : {
     134        3043 :     ZIPState *sp = ZIPDecoderState(tif);
     135             : 
     136             :     (void)s;
     137        3043 :     assert(sp != NULL);
     138             : 
     139        3043 :     if ((sp->state & ZSTATE_INIT_DECODE) == 0)
     140          15 :         tif->tif_setupdecode(tif);
     141             : 
     142             : #if LIBDEFLATE_SUPPORT
     143        3043 :     sp->libdeflate_state = -1;
     144             : #endif
     145        3043 :     sp->stream.next_in = tif->tif_rawdata;
     146             :     assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
     147             :          we need to simplify this code to reflect a ZLib that is likely updated
     148             :          to deal with 8byte memory sizes, though this code will respond
     149             :          appropriately even before we simplify it */
     150        6086 :     sp->stream.avail_in = (uint64_t)tif->tif_rawcc < 0xFFFFFFFFU
     151        3043 :                               ? (uInt)tif->tif_rawcc
     152        3043 :                               : 0xFFFFFFFFU;
     153        3043 :     return (inflateReset(&sp->stream) == Z_OK);
     154             : }
     155             : 
     156        5043 : static int ZIPDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
     157             : {
     158             :     static const char module[] = "ZIPDecode";
     159        5043 :     ZIPState *sp = ZIPDecoderState(tif);
     160             : 
     161             :     (void)s;
     162        5043 :     assert(sp != NULL);
     163        5043 :     assert(sp->state == ZSTATE_INIT_DECODE);
     164             : 
     165             : #if LIBDEFLATE_SUPPORT
     166        5043 :     if (sp->libdeflate_state == 1)
     167           0 :         return 0;
     168             : 
     169             :     /* If we have libdeflate support and we are asked to read a whole */
     170             :     /* strip/tile, then go for using it */
     171             :     do
     172             :     {
     173        5043 :         TIFFDirectory *td = &tif->tif_dir;
     174             : 
     175        5043 :         if (sp->libdeflate_state == 0)
     176        2000 :             break;
     177        3043 :         if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
     178           0 :             break;
     179             : 
     180             :         /* Check if we are in the situation where we can use libdeflate */
     181        3043 :         if (isTiled(tif))
     182             :         {
     183         926 :             if (TIFFTileSize64(tif) != (uint64_t)occ)
     184         144 :                 break;
     185             :         }
     186             :         else
     187             :         {
     188        2117 :             uint32_t strip_height = td->td_imagelength - tif->tif_row;
     189        2117 :             if (strip_height > td->td_rowsperstrip)
     190        1484 :                 strip_height = td->td_rowsperstrip;
     191        2117 :             if (TIFFVStripSize64(tif, strip_height) != (uint64_t)occ)
     192           2 :                 break;
     193             :         }
     194             : 
     195             :         /* Check for overflow */
     196             :         if ((size_t)tif->tif_rawcc != (uint64_t)tif->tif_rawcc)
     197             :             break;
     198             :         if ((size_t)occ != (uint64_t)occ)
     199             :             break;
     200             : 
     201             :         /* Go for decompression using libdeflate */
     202             :         {
     203             :             enum libdeflate_result res;
     204        2897 :             if (sp->libdeflate_dec == NULL)
     205             :             {
     206         390 :                 sp->libdeflate_dec = libdeflate_alloc_decompressor();
     207         390 :                 if (sp->libdeflate_dec == NULL)
     208             :                 {
     209           0 :                     break;
     210             :                 }
     211             :             }
     212             : 
     213        2897 :             sp->libdeflate_state = 1;
     214             : 
     215        2897 :             res = libdeflate_zlib_decompress(sp->libdeflate_dec, tif->tif_rawcp,
     216        2897 :                                              (size_t)tif->tif_rawcc, op,
     217             :                                              (size_t)occ, NULL);
     218             : 
     219        2897 :             tif->tif_rawcp += tif->tif_rawcc;
     220        2897 :             tif->tif_rawcc = 0;
     221             : 
     222             :             /* We accept LIBDEFLATE_INSUFFICIENT_SPACE has a return */
     223             :             /* There are odd files in the wild where the last strip, when */
     224             :             /* it is smaller in height than td_rowsperstrip, actually contains
     225             :              */
     226             :             /* data for td_rowsperstrip lines. Just ignore that silently. */
     227        2897 :             if (res != LIBDEFLATE_SUCCESS &&
     228             :                 res != LIBDEFLATE_INSUFFICIENT_SPACE)
     229             :             {
     230           0 :                 TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
     231           0 :                               (unsigned long)tif->tif_row);
     232           0 :                 return 0;
     233             :             }
     234             : 
     235        2897 :             return 1;
     236             :         }
     237             :     } while (0);
     238        2146 :     sp->libdeflate_state = 0;
     239             : #endif /* LIBDEFLATE_SUPPORT */
     240             : 
     241        2146 :     sp->stream.next_in = tif->tif_rawcp;
     242             : 
     243        2146 :     sp->stream.next_out = op;
     244             :     assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
     245             :          we need to simplify this code to reflect a ZLib that is likely updated
     246             :          to deal with 8byte memory sizes, though this code will respond
     247             :          appropriately even before we simplify it */
     248             :     do
     249             :     {
     250             :         int state;
     251        4292 :         uInt avail_in_before = (uint64_t)tif->tif_rawcc <= 0xFFFFFFFFU
     252        2146 :                                    ? (uInt)tif->tif_rawcc
     253        2146 :                                    : 0xFFFFFFFFU;
     254        2146 :         uInt avail_out_before =
     255        2146 :             (uint64_t)occ < 0xFFFFFFFFU ? (uInt)occ : 0xFFFFFFFFU;
     256        2146 :         sp->stream.avail_in = avail_in_before;
     257        2146 :         sp->stream.avail_out = avail_out_before;
     258             :         /* coverity[overrun-buffer-arg] */
     259        2146 :         state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
     260        2146 :         tif->tif_rawcc -= (avail_in_before - sp->stream.avail_in);
     261        2146 :         occ -= (avail_out_before - sp->stream.avail_out);
     262        2146 :         if (state == Z_STREAM_END)
     263           1 :             break;
     264        2145 :         if (state == Z_DATA_ERROR)
     265             :         {
     266           1 :             TIFFErrorExtR(tif, module, "Decoding error at scanline %lu, %s",
     267           2 :                           (unsigned long)tif->tif_row, SAFE_MSG(sp));
     268           1 :             return (0);
     269             :         }
     270        2144 :         if (state != Z_OK)
     271             :         {
     272           0 :             TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
     273           0 :             return (0);
     274             :         }
     275        2144 :     } while (occ > 0);
     276        2145 :     if (occ != 0)
     277             :     {
     278           0 :         TIFFErrorExtR(tif, module,
     279             :                       "Not enough data at scanline %lu (short %" PRIu64
     280             :                       " bytes)",
     281           0 :                       (unsigned long)tif->tif_row, (uint64_t)occ);
     282           0 :         return (0);
     283             :     }
     284             : 
     285        2145 :     tif->tif_rawcp = sp->stream.next_in;
     286             : 
     287        2145 :     return (1);
     288             : }
     289             : 
     290        5619 : static int ZIPSetupEncode(TIFF *tif)
     291             : {
     292             :     static const char module[] = "ZIPSetupEncode";
     293        5619 :     ZIPState *sp = ZIPEncoderState(tif);
     294             :     int cappedQuality;
     295             : 
     296        5619 :     assert(sp != NULL);
     297        5619 :     if (sp->state & ZSTATE_INIT_DECODE)
     298             :     {
     299           8 :         inflateEnd(&sp->stream);
     300           8 :         sp->state = 0;
     301             :     }
     302             : 
     303        5619 :     cappedQuality = sp->zipquality;
     304        5619 :     if (cappedQuality > Z_BEST_COMPRESSION)
     305           0 :         cappedQuality = Z_BEST_COMPRESSION;
     306             : 
     307        5619 :     if (deflateInit(&sp->stream, cappedQuality) != Z_OK)
     308             :     {
     309           0 :         TIFFErrorExtR(tif, module, "%s", SAFE_MSG(sp));
     310           0 :         return (0);
     311             :     }
     312             :     else
     313             :     {
     314        5620 :         sp->state |= ZSTATE_INIT_ENCODE;
     315        5620 :         return (1);
     316             :     }
     317             : }
     318             : 
     319             : /*
     320             :  * Reset encoding state at the start of a strip.
     321             :  */
     322       13142 : static int ZIPPreEncode(TIFF *tif, uint16_t s)
     323             : {
     324       13142 :     ZIPState *sp = ZIPEncoderState(tif);
     325             : 
     326             :     (void)s;
     327       13142 :     assert(sp != NULL);
     328       13142 :     if (sp->state != ZSTATE_INIT_ENCODE)
     329           8 :         tif->tif_setupencode(tif);
     330             : 
     331             : #if LIBDEFLATE_SUPPORT
     332       13130 :     sp->libdeflate_state = -1;
     333             : #endif
     334       13130 :     sp->stream.next_out = tif->tif_rawdata;
     335             :     assert(sizeof(sp->stream.avail_out) == 4); /* if this assert gets raised,
     336             :          we need to simplify this code to reflect a ZLib that is likely updated
     337             :          to deal with 8byte memory sizes, though this code will respond
     338             :          appropriately even before we simplify it */
     339       26260 :     sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
     340       13130 :                                ? (uInt)tif->tif_rawdatasize
     341       13130 :                                : 0xFFFFFFFFU;
     342       13130 :     return (deflateReset(&sp->stream) == Z_OK);
     343             : }
     344             : 
     345             : /*
     346             :  * Encode a chunk of pixels.
     347             :  */
     348       15145 : static int ZIPEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
     349             : {
     350             :     static const char module[] = "ZIPEncode";
     351       15145 :     ZIPState *sp = ZIPEncoderState(tif);
     352             : 
     353       15145 :     assert(sp != NULL);
     354       15145 :     assert(sp->state == ZSTATE_INIT_ENCODE);
     355             : 
     356             :     (void)s;
     357             : 
     358             : #if LIBDEFLATE_SUPPORT
     359       15145 :     if (sp->libdeflate_state == 1)
     360           0 :         return 0;
     361             : 
     362             :     /* If we have libdeflate support and we are asked to write a whole */
     363             :     /* strip/tile, then go for using it */
     364             :     do
     365             :     {
     366       15145 :         TIFFDirectory *td = &tif->tif_dir;
     367             : 
     368       15145 :         if (sp->libdeflate_state == 0)
     369        2000 :             break;
     370       13145 :         if (sp->subcodec == DEFLATE_SUBCODEC_ZLIB)
     371        4097 :             break;
     372             : 
     373             :         /* Libdeflate does not support the 0-compression level */
     374        9048 :         if (sp->zipquality == Z_NO_COMPRESSION)
     375           0 :             break;
     376             : 
     377             :         /* Check if we are in the situation where we can use libdeflate */
     378        9048 :         if (isTiled(tif))
     379             :         {
     380        5678 :             if (TIFFTileSize64(tif) != (uint64_t)cc)
     381           0 :                 break;
     382             :         }
     383             :         else
     384             :         {
     385        3370 :             uint32_t strip_height = td->td_imagelength - tif->tif_row;
     386        3370 :             if (strip_height > td->td_rowsperstrip)
     387        2018 :                 strip_height = td->td_rowsperstrip;
     388        3370 :             if (TIFFVStripSize64(tif, strip_height) != (uint64_t)cc)
     389           1 :                 break;
     390             :         }
     391             : 
     392             :         /* Check for overflow */
     393             :         if ((size_t)tif->tif_rawdatasize != (uint64_t)tif->tif_rawdatasize)
     394             :             break;
     395             :         if ((size_t)cc != (uint64_t)cc)
     396             :             break;
     397             : 
     398             :         /* Go for compression using libdeflate */
     399             :         {
     400             :             size_t nCompressedBytes;
     401        9048 :             if (sp->libdeflate_enc == NULL)
     402             :             {
     403             :                 /* To get results as good as zlib, we asked for an extra */
     404             :                 /* level of compression */
     405        1517 :                 sp->libdeflate_enc = libdeflate_alloc_compressor(
     406        1517 :                     sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
     407          11 :                     : sp->zipquality >= 6 && sp->zipquality <= 9
     408          11 :                         ? sp->zipquality + 1
     409          30 :                         : sp->zipquality);
     410        1517 :                 if (sp->libdeflate_enc == NULL)
     411             :                 {
     412           0 :                     TIFFErrorExtR(tif, module, "Cannot allocate compressor");
     413           0 :                     break;
     414             :                 }
     415             :             }
     416             : 
     417             :             /* Make sure the output buffer is large enough for the worse case.
     418             :              */
     419             :             /* In TIFFWriteBufferSetup(), when libtiff allocates the buffer */
     420             :             /* we've taken a 10% margin over the uncompressed size, which should
     421             :              */
     422             :             /* be large enough even for the the worse case scenario. */
     423        9048 :             if (libdeflate_zlib_compress_bound(sp->libdeflate_enc, (size_t)cc) >
     424        9049 :                 (size_t)tif->tif_rawdatasize)
     425             :             {
     426           0 :                 break;
     427             :             }
     428             : 
     429        9049 :             sp->libdeflate_state = 1;
     430        9049 :             nCompressedBytes = libdeflate_zlib_compress(
     431        9049 :                 sp->libdeflate_enc, bp, (size_t)cc, tif->tif_rawdata,
     432        9049 :                 (size_t)tif->tif_rawdatasize);
     433             : 
     434        9047 :             if (nCompressedBytes == 0)
     435             :             {
     436           0 :                 TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
     437           0 :                               (unsigned long)tif->tif_row);
     438           0 :                 return 0;
     439             :             }
     440             : 
     441        9047 :             tif->tif_rawcc = nCompressedBytes;
     442             : 
     443        9047 :             if (!TIFFFlushData1(tif))
     444           0 :                 return 0;
     445             : 
     446        9048 :             return 1;
     447             :         }
     448             :     } while (0);
     449        6098 :     sp->libdeflate_state = 0;
     450             : #endif /* LIBDEFLATE_SUPPORT */
     451             : 
     452        6098 :     sp->stream.next_in = bp;
     453             :     assert(sizeof(sp->stream.avail_in) == 4); /* if this assert gets raised,
     454             :          we need to simplify this code to reflect a ZLib that is likely updated
     455             :          to deal with 8byte memory sizes, though this code will respond
     456             :          appropriately even before we simplify it */
     457             :     do
     458             :     {
     459        6098 :         uInt avail_in_before =
     460        6098 :             (uint64_t)cc <= 0xFFFFFFFFU ? (uInt)cc : 0xFFFFFFFFU;
     461        6098 :         sp->stream.avail_in = avail_in_before;
     462             :         /* coverity[overrun-buffer-arg] */
     463        6098 :         if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK)
     464             :         {
     465           0 :             TIFFErrorExtR(tif, module, "Encoder error: %s", SAFE_MSG(sp));
     466           0 :             return (0);
     467             :         }
     468        6098 :         if (sp->stream.avail_out == 0)
     469             :         {
     470           0 :             tif->tif_rawcc = tif->tif_rawdatasize;
     471           0 :             if (!TIFFFlushData1(tif))
     472           0 :                 return 0;
     473           0 :             sp->stream.next_out = tif->tif_rawdata;
     474           0 :             sp->stream.avail_out = (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
     475           0 :                                        ? (uInt)tif->tif_rawdatasize
     476           0 :                                        : 0xFFFFFFFFU;
     477             :         }
     478        6098 :         cc -= (avail_in_before - sp->stream.avail_in);
     479        6098 :     } while (cc > 0);
     480        6098 :     return (1);
     481             : }
     482             : 
     483             : /*
     484             :  * Finish off an encoded strip by flushing the last
     485             :  * string and tacking on an End Of Information code.
     486             :  */
     487       13144 : static int ZIPPostEncode(TIFF *tif)
     488             : {
     489             :     static const char module[] = "ZIPPostEncode";
     490       13144 :     ZIPState *sp = ZIPEncoderState(tif);
     491             :     int state;
     492             : 
     493             : #if LIBDEFLATE_SUPPORT
     494       13144 :     if (sp->libdeflate_state == 1)
     495        9049 :         return 1;
     496             : #endif
     497             : 
     498        4095 :     sp->stream.avail_in = 0;
     499             :     do
     500             :     {
     501        4095 :         state = deflate(&sp->stream, Z_FINISH);
     502        4098 :         switch (state)
     503             :         {
     504        4098 :             case Z_STREAM_END:
     505             :             case Z_OK:
     506        4098 :                 if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
     507             :                 {
     508        4098 :                     tif->tif_rawcc =
     509        4098 :                         tif->tif_rawdatasize - sp->stream.avail_out;
     510        4098 :                     if (!TIFFFlushData1(tif))
     511           0 :                         return 0;
     512        4098 :                     sp->stream.next_out = tif->tif_rawdata;
     513        4098 :                     sp->stream.avail_out =
     514        4098 :                         (uint64_t)tif->tif_rawdatasize <= 0xFFFFFFFFU
     515        4098 :                             ? (uInt)tif->tif_rawdatasize
     516        4098 :                             : 0xFFFFFFFFU;
     517             :                 }
     518        4098 :                 break;
     519           0 :             default:
     520           0 :                 TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
     521           0 :                 return (0);
     522             :         }
     523        4098 :     } while (state != Z_STREAM_END);
     524        4098 :     return (1);
     525             : }
     526             : 
     527        7614 : static void ZIPCleanup(TIFF *tif)
     528             : {
     529        7614 :     ZIPState *sp = GetZIPState(tif);
     530             : 
     531        7614 :     assert(sp != 0);
     532             : 
     533        7614 :     (void)TIFFPredictorCleanup(tif);
     534             : 
     535        7614 :     tif->tif_tagmethods.vgetfield = sp->vgetparent;
     536        7614 :     tif->tif_tagmethods.vsetfield = sp->vsetparent;
     537             : 
     538        7614 :     if (sp->state & ZSTATE_INIT_ENCODE)
     539             :     {
     540        5605 :         deflateEnd(&sp->stream);
     541        5605 :         sp->state = 0;
     542             :     }
     543        2009 :     else if (sp->state & ZSTATE_INIT_DECODE)
     544             :     {
     545         442 :         inflateEnd(&sp->stream);
     546         442 :         sp->state = 0;
     547             :     }
     548             : 
     549             : #if LIBDEFLATE_SUPPORT
     550        7614 :     if (sp->libdeflate_dec)
     551         390 :         libdeflate_free_decompressor(sp->libdeflate_dec);
     552        7614 :     if (sp->libdeflate_enc)
     553        1517 :         libdeflate_free_compressor(sp->libdeflate_enc);
     554             : #endif
     555             : 
     556        7614 :     _TIFFfreeExt(tif, sp);
     557        7614 :     tif->tif_data = NULL;
     558             : 
     559        7614 :     _TIFFSetDefaultCompressionState(tif);
     560        7614 : }
     561             : 
     562       50640 : static int ZIPVSetField(TIFF *tif, uint32_t tag, va_list ap)
     563             : {
     564             :     static const char module[] = "ZIPVSetField";
     565       50640 :     ZIPState *sp = GetZIPState(tif);
     566             : 
     567       50640 :     switch (tag)
     568             :     {
     569          46 :         case TIFFTAG_ZIPQUALITY:
     570          46 :             sp->zipquality = (int)va_arg(ap, int);
     571          46 :             if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
     572          46 :                 sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
     573             :             {
     574           0 :                 TIFFErrorExtR(
     575             :                     tif, module,
     576             :                     "Invalid ZipQuality value. Should be in [-1,%d] range",
     577             :                     LIBDEFLATE_MAX_COMPRESSION_LEVEL);
     578           0 :                 return 0;
     579             :             }
     580             : 
     581          46 :             if (sp->state & ZSTATE_INIT_ENCODE)
     582             :             {
     583           0 :                 int cappedQuality = sp->zipquality;
     584           0 :                 if (cappedQuality > Z_BEST_COMPRESSION)
     585           0 :                     cappedQuality = Z_BEST_COMPRESSION;
     586           0 :                 if (deflateParams(&sp->stream, cappedQuality,
     587             :                                   Z_DEFAULT_STRATEGY) != Z_OK)
     588             :                 {
     589           0 :                     TIFFErrorExtR(tif, module, "ZLib error: %s", SAFE_MSG(sp));
     590           0 :                     return (0);
     591             :                 }
     592             :             }
     593             : 
     594             : #if LIBDEFLATE_SUPPORT
     595          46 :             if (sp->libdeflate_enc)
     596             :             {
     597           0 :                 libdeflate_free_compressor(sp->libdeflate_enc);
     598           0 :                 sp->libdeflate_enc = NULL;
     599             :             }
     600             : #endif
     601             : 
     602          46 :             return (1);
     603             : 
     604        4097 :         case TIFFTAG_DEFLATE_SUBCODEC:
     605        4097 :             sp->subcodec = (int)va_arg(ap, int);
     606        4097 :             if (sp->subcodec != DEFLATE_SUBCODEC_ZLIB &&
     607           0 :                 sp->subcodec != DEFLATE_SUBCODEC_LIBDEFLATE)
     608             :             {
     609           0 :                 TIFFErrorExtR(tif, module, "Invalid DeflateCodec value.");
     610           0 :                 return 0;
     611             :             }
     612             : #if !LIBDEFLATE_SUPPORT
     613             :             if (sp->subcodec == DEFLATE_SUBCODEC_LIBDEFLATE)
     614             :             {
     615             :                 TIFFErrorExtR(tif, module,
     616             :                               "DeflateCodec = DEFLATE_SUBCODEC_LIBDEFLATE "
     617             :                               "unsupported in this build");
     618             :                 return 0;
     619             :             }
     620             : #endif
     621        4097 :             return 1;
     622             : 
     623       46497 :         default:
     624       46497 :             return (*sp->vsetparent)(tif, tag, ap);
     625             :     }
     626             :     /*NOTREACHED*/
     627             : }
     628             : 
     629       47709 : static int ZIPVGetField(TIFF *tif, uint32_t tag, va_list ap)
     630             : {
     631       47709 :     ZIPState *sp = GetZIPState(tif);
     632             : 
     633       47709 :     switch (tag)
     634             :     {
     635           0 :         case TIFFTAG_ZIPQUALITY:
     636           0 :             *va_arg(ap, int *) = sp->zipquality;
     637           0 :             break;
     638             : 
     639           0 :         case TIFFTAG_DEFLATE_SUBCODEC:
     640           0 :             *va_arg(ap, int *) = sp->subcodec;
     641           0 :             break;
     642             : 
     643       47709 :         default:
     644       47709 :             return (*sp->vgetparent)(tif, tag, ap);
     645             :     }
     646           0 :     return (1);
     647             : }
     648             : 
     649             : static const TIFFField zipFields[] = {
     650             :     {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
     651             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
     652             :     {TIFFTAG_DEFLATE_SUBCODEC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
     653             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
     654             : };
     655             : 
     656        7615 : int TIFFInitZIP(TIFF *tif, int scheme)
     657             : {
     658             :     static const char module[] = "TIFFInitZIP";
     659             :     ZIPState *sp;
     660             : 
     661        7615 :     assert((scheme == COMPRESSION_DEFLATE) ||
     662             :            (scheme == COMPRESSION_ADOBE_DEFLATE));
     663             : #ifdef NDEBUG
     664             :     (void)scheme;
     665             : #endif
     666             : 
     667             :     /*
     668             :      * Merge codec-specific tag information.
     669             :      */
     670        7615 :     if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields)))
     671             :     {
     672           0 :         TIFFErrorExtR(tif, module,
     673             :                       "Merging Deflate codec-specific tags failed");
     674           0 :         return 0;
     675             :     }
     676             : 
     677             :     /*
     678             :      * Allocate state block so tag methods have storage to record values.
     679             :      */
     680        7615 :     tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, sizeof(ZIPState), 1);
     681        7614 :     if (tif->tif_data == NULL)
     682           0 :         goto bad;
     683        7614 :     sp = GetZIPState(tif);
     684        7614 :     sp->stream.zalloc = NULL;
     685        7614 :     sp->stream.zfree = NULL;
     686        7614 :     sp->stream.opaque = NULL;
     687        7614 :     sp->stream.data_type = Z_BINARY;
     688             : 
     689             :     /*
     690             :      * Override parent get/set field methods.
     691             :      */
     692        7614 :     sp->vgetparent = tif->tif_tagmethods.vgetfield;
     693        7614 :     tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
     694        7614 :     sp->vsetparent = tif->tif_tagmethods.vsetfield;
     695        7614 :     tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
     696             : 
     697             :     /* Default values for codec-specific fields */
     698        7614 :     sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
     699        7614 :     sp->state = 0;
     700             : #if LIBDEFLATE_SUPPORT
     701        7614 :     sp->subcodec = DEFLATE_SUBCODEC_LIBDEFLATE;
     702             : #else
     703             :     sp->subcodec = DEFLATE_SUBCODEC_ZLIB;
     704             : #endif
     705             : 
     706             :     /*
     707             :      * Install codec methods.
     708             :      */
     709        7614 :     tif->tif_fixuptags = ZIPFixupTags;
     710        7614 :     tif->tif_setupdecode = ZIPSetupDecode;
     711        7614 :     tif->tif_predecode = ZIPPreDecode;
     712        7614 :     tif->tif_decoderow = ZIPDecode;
     713        7614 :     tif->tif_decodestrip = ZIPDecode;
     714        7614 :     tif->tif_decodetile = ZIPDecode;
     715        7614 :     tif->tif_setupencode = ZIPSetupEncode;
     716        7614 :     tif->tif_preencode = ZIPPreEncode;
     717        7614 :     tif->tif_postencode = ZIPPostEncode;
     718        7614 :     tif->tif_encoderow = ZIPEncode;
     719        7614 :     tif->tif_encodestrip = ZIPEncode;
     720        7614 :     tif->tif_encodetile = ZIPEncode;
     721        7614 :     tif->tif_cleanup = ZIPCleanup;
     722             :     /*
     723             :      * Setup predictor setup.
     724             :      */
     725        7614 :     (void)TIFFPredictorInit(tif);
     726        7615 :     return (1);
     727           0 : bad:
     728           0 :     TIFFErrorExtR(tif, module, "No space for ZIP state block");
     729           0 :     return (0);
     730             : }
     731             : #endif /* ZIP_SUPPORT */

Generated by: LCOV version 1.14