LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_lerc.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 468 595 78.7 %
Date: 2024-11-21 22:18:42 Functions: 15 15 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018, Even Rouault
       3             :  * Author: <even.rouault at spatialys.com>
       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 LERC_SUPPORT
      27             : /*
      28             :  * TIFF Library.
      29             :  *
      30             :  * LERC Compression Support
      31             :  *
      32             :  */
      33             : 
      34             : #include "Lerc_c_api.h"
      35             : #include "zlib.h"
      36             : #ifdef ZSTD_SUPPORT
      37             : #include "zstd.h"
      38             : #endif
      39             : 
      40             : #if LIBDEFLATE_SUPPORT
      41             : #include "libdeflate.h"
      42             : #endif
      43             : #define LIBDEFLATE_MAX_COMPRESSION_LEVEL 12
      44             : 
      45             : #include <assert.h>
      46             : 
      47             : #define LSTATE_INIT_DECODE 0x01
      48             : #define LSTATE_INIT_ENCODE 0x02
      49             : 
      50             : #ifndef LERC_AT_LEAST_VERSION
      51             : #define LERC_AT_LEAST_VERSION(maj, min, patch) 0
      52             : #endif
      53             : 
      54             : /*
      55             :  * State block for each open TIFF file using LERC compression/decompression.
      56             :  */
      57             : typedef struct
      58             : {
      59             :     double maxzerror; /* max z error */
      60             :     int lerc_version;
      61             :     int additional_compression;
      62             :     int zstd_compress_level; /* zstd */
      63             :     int zipquality;          /* deflate */
      64             :     int state;               /* state flags */
      65             : 
      66             :     uint32_t segment_width;
      67             :     uint32_t segment_height;
      68             : 
      69             :     unsigned int uncompressed_size;
      70             :     unsigned int uncompressed_alloc;
      71             :     uint8_t *uncompressed_buffer;
      72             :     unsigned int uncompressed_offset;
      73             : 
      74             :     uint8_t *uncompressed_buffer_multiband;
      75             :     unsigned int uncompressed_buffer_multiband_alloc;
      76             : 
      77             :     unsigned int mask_size;
      78             :     uint8_t *mask_buffer;
      79             : 
      80             :     unsigned int compressed_size;
      81             :     void *compressed_buffer;
      82             : 
      83             : #if LIBDEFLATE_SUPPORT
      84             :     struct libdeflate_decompressor *libdeflate_dec;
      85             :     struct libdeflate_compressor *libdeflate_enc;
      86             : #endif
      87             : 
      88             :     TIFFVGetMethod vgetparent; /* super-class method */
      89             :     TIFFVSetMethod vsetparent; /* super-class method */
      90             : } LERCState;
      91             : 
      92             : #define GetLERCState(tif) ((LERCState *)(tif)->tif_data)
      93             : #define LERCDecoderState(tif) GetLERCState(tif)
      94             : #define LERCEncoderState(tif) GetLERCState(tif)
      95             : 
      96             : static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s);
      97             : static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s);
      98             : 
      99         789 : static int LERCFixupTags(TIFF *tif)
     100             : {
     101             :     (void)tif;
     102         789 :     return 1;
     103             : }
     104             : 
     105         193 : static int LERCSetupDecode(TIFF *tif)
     106             : {
     107         193 :     LERCState *sp = LERCDecoderState(tif);
     108             : 
     109         193 :     assert(sp != NULL);
     110             : 
     111             :     /* if we were last encoding, terminate this mode */
     112         193 :     if (sp->state & LSTATE_INIT_ENCODE)
     113             :     {
     114          25 :         sp->state = 0;
     115             :     }
     116             : 
     117         193 :     sp->state |= LSTATE_INIT_DECODE;
     118         193 :     return 1;
     119             : }
     120             : 
     121        1378 : static int GetLercDataType(TIFF *tif)
     122             : {
     123        1378 :     TIFFDirectory *td = &tif->tif_dir;
     124             :     static const char module[] = "GetLercDataType";
     125             : 
     126        1378 :     if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 8)
     127             :     {
     128           3 :         return 0;
     129             :     }
     130             : 
     131        1375 :     if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 8)
     132             :     {
     133        1163 :         return 1;
     134             :     }
     135             : 
     136         212 :     if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 16)
     137             :     {
     138           3 :         return 2;
     139             :     }
     140             : 
     141         209 :     if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 16)
     142             :     {
     143           3 :         return 3;
     144             :     }
     145             : 
     146         206 :     if (td->td_sampleformat == SAMPLEFORMAT_INT && td->td_bitspersample == 32)
     147             :     {
     148           3 :         return 4;
     149             :     }
     150             : 
     151         203 :     if (td->td_sampleformat == SAMPLEFORMAT_UINT && td->td_bitspersample == 32)
     152             :     {
     153           3 :         return 5;
     154             :     }
     155             : 
     156         200 :     if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     157         198 :         td->td_bitspersample == 32)
     158             :     {
     159         102 :         return 6;
     160             :     }
     161             : 
     162          98 :     if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     163          96 :         td->td_bitspersample == 64)
     164             :     {
     165          96 :         return 7;
     166             :     }
     167             : 
     168           2 :     TIFFErrorExtR(
     169             :         tif, module,
     170             :         "Unsupported combination of SampleFormat and td_bitspersample");
     171           2 :     return -1;
     172             : }
     173             : 
     174         901 : static int SetupBuffers(TIFF *tif, LERCState *sp, const char *module)
     175             : {
     176         901 :     TIFFDirectory *td = &tif->tif_dir;
     177             :     uint64_t new_size_64;
     178             :     uint64_t new_alloc_64;
     179             :     unsigned int new_size;
     180             :     unsigned int new_alloc;
     181             : 
     182         901 :     sp->uncompressed_offset = 0;
     183             : 
     184         901 :     if (isTiled(tif))
     185             :     {
     186         111 :         sp->segment_width = td->td_tilewidth;
     187         111 :         sp->segment_height = td->td_tilelength;
     188             :     }
     189             :     else
     190             :     {
     191         790 :         sp->segment_width = td->td_imagewidth;
     192         790 :         sp->segment_height = td->td_imagelength - tif->tif_row;
     193         790 :         if (sp->segment_height > td->td_rowsperstrip)
     194         533 :             sp->segment_height = td->td_rowsperstrip;
     195             :     }
     196             : 
     197         901 :     new_size_64 = (uint64_t)sp->segment_width * sp->segment_height *
     198         901 :                   (td->td_bitspersample / 8);
     199         901 :     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
     200             :     {
     201         793 :         new_size_64 *= td->td_samplesperpixel;
     202             :     }
     203             : 
     204         901 :     new_size = (unsigned int)new_size_64;
     205         901 :     sp->uncompressed_size = new_size;
     206             : 
     207             :     /* add some margin as we are going to use it also to store deflate/zstd
     208             :      * compressed data. We also need extra margin when writing very small
     209             :      * rasters with one mask per band. */
     210         901 :     new_alloc_64 = 256 + new_size_64 + new_size_64 / 3;
     211             : #ifdef ZSTD_SUPPORT
     212             :     {
     213         901 :         size_t zstd_max = ZSTD_compressBound((size_t)new_size_64);
     214         901 :         if (new_alloc_64 < zstd_max)
     215             :         {
     216           0 :             new_alloc_64 = zstd_max;
     217             :         }
     218             :     }
     219             : #endif
     220         901 :     new_alloc = (unsigned int)new_alloc_64;
     221         901 :     if (new_alloc != new_alloc_64)
     222             :     {
     223           0 :         TIFFErrorExtR(tif, module, "Too large uncompressed strip/tile");
     224           0 :         _TIFFfreeExt(tif, sp->uncompressed_buffer);
     225           0 :         sp->uncompressed_buffer = 0;
     226           0 :         sp->uncompressed_alloc = 0;
     227           0 :         return 0;
     228             :     }
     229             : 
     230         901 :     if (sp->uncompressed_alloc < new_alloc)
     231             :     {
     232         323 :         _TIFFfreeExt(tif, sp->uncompressed_buffer);
     233         323 :         sp->uncompressed_buffer = _TIFFmallocExt(tif, new_alloc);
     234         323 :         if (!sp->uncompressed_buffer)
     235             :         {
     236           0 :             TIFFErrorExtR(tif, module, "Cannot allocate buffer");
     237           0 :             _TIFFfreeExt(tif, sp->uncompressed_buffer);
     238           0 :             sp->uncompressed_buffer = 0;
     239           0 :             sp->uncompressed_alloc = 0;
     240           0 :             return 0;
     241             :         }
     242         323 :         sp->uncompressed_alloc = new_alloc;
     243             :     }
     244             : 
     245         901 :     if ((td->td_planarconfig == PLANARCONFIG_CONTIG &&
     246         793 :          td->td_extrasamples > 0 &&
     247          68 :          td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
     248          28 :          GetLercDataType(tif) == 1) ||
     249         873 :         (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     250         100 :          (td->td_bitspersample == 32 || td->td_bitspersample == 64)))
     251             :     {
     252         128 :         unsigned int mask_size = sp->segment_width * sp->segment_height;
     253             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
     254             :         if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     255             :             td->td_planarconfig == PLANARCONFIG_CONTIG)
     256             :         {
     257             :             /* We may need one mask per band */
     258             :             mask_size *= td->td_samplesperpixel;
     259             :         }
     260             : #endif
     261         128 :         if (sp->mask_size < mask_size)
     262             :         {
     263             :             void *mask_buffer =
     264          94 :                 _TIFFreallocExt(tif, sp->mask_buffer, mask_size);
     265          94 :             if (mask_buffer == NULL)
     266             :             {
     267           0 :                 TIFFErrorExtR(tif, module, "Cannot allocate buffer");
     268           0 :                 sp->mask_size = 0;
     269           0 :                 _TIFFfreeExt(tif, sp->uncompressed_buffer);
     270           0 :                 sp->uncompressed_buffer = 0;
     271           0 :                 sp->uncompressed_alloc = 0;
     272           0 :                 return 0;
     273             :             }
     274          94 :             sp->mask_buffer = (uint8_t *)mask_buffer;
     275          94 :             sp->mask_size = mask_size;
     276             :         }
     277             :     }
     278             : 
     279         901 :     return 1;
     280             : }
     281             : 
     282             : /*
     283             :  * Setup state for decoding a strip.
     284             :  */
     285         530 : static int LERCPreDecode(TIFF *tif, uint16_t s)
     286             : {
     287             :     static const char module[] = "LERCPreDecode";
     288             :     lerc_status lerc_ret;
     289         530 :     TIFFDirectory *td = &tif->tif_dir;
     290         530 :     LERCState *sp = LERCDecoderState(tif);
     291             :     int lerc_data_type;
     292             :     unsigned int infoArray[9];
     293         530 :     unsigned nomask_bands = td->td_samplesperpixel;
     294             :     int ndims;
     295         530 :     int use_mask = 0;
     296         530 :     uint8_t *lerc_data = tif->tif_rawcp;
     297         530 :     unsigned int lerc_data_size = (unsigned int)tif->tif_rawcc;
     298             : 
     299             :     (void)s;
     300         530 :     assert(sp != NULL);
     301         530 :     if (sp->state != LSTATE_INIT_DECODE)
     302          25 :         tif->tif_setupdecode(tif);
     303             : 
     304         530 :     lerc_data_type = GetLercDataType(tif);
     305         530 :     if (lerc_data_type < 0)
     306           0 :         return 0;
     307             : 
     308         530 :     if (!SetupBuffers(tif, sp, module))
     309           0 :         return 0;
     310             : 
     311         530 :     if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
     312             :     {
     313         313 :         if (sp->compressed_size < sp->uncompressed_alloc)
     314             :         {
     315          65 :             _TIFFfreeExt(tif, sp->compressed_buffer);
     316          65 :             sp->compressed_buffer = _TIFFmallocExt(tif, sp->uncompressed_alloc);
     317          65 :             if (!sp->compressed_buffer)
     318             :             {
     319           0 :                 sp->compressed_size = 0;
     320           0 :                 return 0;
     321             :             }
     322          65 :             sp->compressed_size = sp->uncompressed_alloc;
     323             :         }
     324             :     }
     325             : 
     326         530 :     if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
     327             :     {
     328             : #if LIBDEFLATE_SUPPORT
     329             :         enum libdeflate_result res;
     330         159 :         size_t lerc_data_sizet = 0;
     331         159 :         if (sp->libdeflate_dec == NULL)
     332             :         {
     333          47 :             sp->libdeflate_dec = libdeflate_alloc_decompressor();
     334          47 :             if (sp->libdeflate_dec == NULL)
     335             :             {
     336           0 :                 TIFFErrorExtR(tif, module, "Cannot allocate decompressor");
     337           0 :                 return 0;
     338             :             }
     339             :         }
     340             : 
     341         159 :         res = libdeflate_zlib_decompress(
     342         159 :             sp->libdeflate_dec, tif->tif_rawcp, (size_t)tif->tif_rawcc,
     343         159 :             sp->compressed_buffer, sp->compressed_size, &lerc_data_sizet);
     344         159 :         if (res != LIBDEFLATE_SUCCESS)
     345             :         {
     346           0 :             TIFFErrorExtR(tif, module, "Decoding error at scanline %lu",
     347           0 :                           (unsigned long)tif->tif_row);
     348           0 :             return 0;
     349             :         }
     350         159 :         assert(lerc_data_sizet == (unsigned int)lerc_data_sizet);
     351         159 :         lerc_data = sp->compressed_buffer;
     352         159 :         lerc_data_size = (unsigned int)lerc_data_sizet;
     353             : #else
     354             :         z_stream strm;
     355             :         int zlib_ret;
     356             : 
     357             :         memset(&strm, 0, sizeof(strm));
     358             :         strm.zalloc = NULL;
     359             :         strm.zfree = NULL;
     360             :         strm.opaque = NULL;
     361             :         zlib_ret = inflateInit(&strm);
     362             :         if (zlib_ret != Z_OK)
     363             :         {
     364             :             TIFFErrorExtR(tif, module, "inflateInit() failed");
     365             :             inflateEnd(&strm);
     366             :             return 0;
     367             :         }
     368             : 
     369             :         strm.avail_in = (uInt)tif->tif_rawcc;
     370             :         strm.next_in = tif->tif_rawcp;
     371             :         strm.avail_out = sp->compressed_size;
     372             :         strm.next_out = sp->compressed_buffer;
     373             :         zlib_ret = inflate(&strm, Z_FINISH);
     374             :         if (zlib_ret != Z_STREAM_END && zlib_ret != Z_OK)
     375             :         {
     376             :             TIFFErrorExtR(tif, module, "inflate() failed");
     377             :             inflateEnd(&strm);
     378             :             return 0;
     379             :         }
     380             :         lerc_data = sp->compressed_buffer;
     381             :         lerc_data_size = sp->compressed_size - strm.avail_out;
     382             :         inflateEnd(&strm);
     383             : #endif
     384             :     }
     385         371 :     else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
     386             :     {
     387             : #ifdef ZSTD_SUPPORT
     388             :         size_t zstd_ret;
     389             : 
     390         154 :         zstd_ret = ZSTD_decompress(sp->compressed_buffer, sp->compressed_size,
     391         154 :                                    tif->tif_rawcp, tif->tif_rawcc);
     392         154 :         if (ZSTD_isError(zstd_ret))
     393             :         {
     394           0 :             TIFFErrorExtR(tif, module, "Error in ZSTD_decompress(): %s",
     395             :                           ZSTD_getErrorName(zstd_ret));
     396           0 :             return 0;
     397             :         }
     398             : 
     399         154 :         lerc_data = sp->compressed_buffer;
     400         154 :         lerc_data_size = (unsigned int)zstd_ret;
     401             : #else
     402             :         TIFFErrorExtR(tif, module, "ZSTD support missing");
     403             :         return 0;
     404             : #endif
     405             :     }
     406         217 :     else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
     407             :     {
     408           0 :         TIFFErrorExtR(tif, module, "Unhandled additional compression");
     409           0 :         return 0;
     410             :     }
     411             : 
     412             :     lerc_ret =
     413         530 :         lerc_getBlobInfo(lerc_data, lerc_data_size, infoArray, NULL, 9, 0);
     414         530 :     if (lerc_ret != 0)
     415             :     {
     416           0 :         TIFFErrorExtR(tif, module, "lerc_getBlobInfo() failed");
     417           0 :         return 0;
     418             :     }
     419             : 
     420             :     /* If the configuration is compatible of a LERC mask, and that the */
     421             :     /* LERC info has dim == samplesperpixel - 1, then there is a LERC */
     422             :     /* mask. */
     423         530 :     if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
     424          32 :         td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
     425          14 :         GetLercDataType(tif) == 1 &&
     426          14 :         infoArray[2] == td->td_samplesperpixel - 1U)
     427             :     {
     428           2 :         use_mask = 1;
     429           2 :         nomask_bands--;
     430             :     }
     431         528 :     else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
     432             :     {
     433          48 :         use_mask = 1;
     434             :     }
     435             : 
     436         530 :     ndims = td->td_planarconfig == PLANARCONFIG_CONTIG ? nomask_bands : 1;
     437             : 
     438             :     /* Info returned in infoArray is { version, dataType, nDim/nDepth, nCols,
     439             :         nRows, nBands, nValidPixels, blobSize,
     440             :         and starting with liblerc 3.0 nRequestedMasks } */
     441         530 :     if (infoArray[0] != (unsigned)sp->lerc_version)
     442             :     {
     443           0 :         TIFFWarningExtR(tif, module,
     444             :                         "Unexpected version number: %d. Expected: %d",
     445             :                         infoArray[0], sp->lerc_version);
     446             :     }
     447         530 :     if (infoArray[1] != (unsigned)lerc_data_type)
     448             :     {
     449           0 :         TIFFErrorExtR(tif, module, "Unexpected dataType: %d. Expected: %d",
     450             :                       infoArray[1], lerc_data_type);
     451           0 :         return 0;
     452             :     }
     453             : 
     454         530 :     const unsigned nFoundDims = infoArray[2];
     455             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
     456             :     if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     457             :         td->td_planarconfig == PLANARCONFIG_CONTIG &&
     458             :         td->td_samplesperpixel > 1)
     459             :     {
     460             :         if (nFoundDims != 1 && nFoundDims != (unsigned)ndims)
     461             :         {
     462             :             TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: 1 or %d",
     463             :                           nFoundDims, ndims);
     464             :             return 0;
     465             :         }
     466             :     }
     467             :     else
     468             : #endif
     469         530 :         if (nFoundDims != (unsigned)ndims)
     470             :     {
     471           0 :         TIFFErrorExtR(tif, module, "Unexpected nDim: %d. Expected: %d",
     472             :                       nFoundDims, ndims);
     473           0 :         return 0;
     474             :     }
     475             : 
     476         530 :     if (infoArray[3] != sp->segment_width)
     477             :     {
     478           0 :         TIFFErrorExtR(tif, module, "Unexpected nCols: %d. Expected: %du",
     479             :                       infoArray[3], sp->segment_width);
     480           0 :         return 0;
     481             :     }
     482         530 :     if (infoArray[4] != sp->segment_height)
     483             :     {
     484           0 :         TIFFErrorExtR(tif, module, "Unexpected nRows: %d. Expected: %u",
     485             :                       infoArray[4], sp->segment_height);
     486           0 :         return 0;
     487             :     }
     488             : 
     489         530 :     const unsigned nFoundBands = infoArray[5];
     490         530 :     if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     491          48 :         td->td_planarconfig == PLANARCONFIG_CONTIG &&
     492          24 :         td->td_samplesperpixel > 1 && nFoundDims == 1)
     493             :     {
     494             : #if !LERC_AT_LEAST_VERSION(3, 0, 0)
     495           0 :         if (nFoundBands == td->td_samplesperpixel)
     496             :         {
     497           0 :             TIFFErrorExtR(
     498             :                 tif, module,
     499             :                 "Unexpected nBands: %d. This file may have been generated with "
     500             :                 "a liblerc version >= 3.0, with one mask per band, and is not "
     501             :                 "supported by this older version of liblerc",
     502             :                 nFoundBands);
     503           0 :             return 0;
     504             :         }
     505             : #endif
     506           0 :         if (nFoundBands != td->td_samplesperpixel)
     507             :         {
     508           0 :             TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
     509           0 :                           nFoundBands, td->td_samplesperpixel);
     510           0 :             return 0;
     511             :         }
     512             :     }
     513         530 :     else if (nFoundBands != 1)
     514             :     {
     515           0 :         TIFFErrorExtR(tif, module, "Unexpected nBands: %d. Expected: %d",
     516             :                       nFoundBands, 1);
     517           0 :         return 0;
     518             :     }
     519             : 
     520         530 :     if (infoArray[7] != lerc_data_size)
     521             :     {
     522           0 :         TIFFErrorExtR(tif, module, "Unexpected blobSize: %d. Expected: %u",
     523             :                       infoArray[7], lerc_data_size);
     524           0 :         return 0;
     525             :     }
     526             : 
     527         530 :     int nRequestedMasks = use_mask ? 1 : 0;
     528             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
     529             :     const int nFoundMasks = infoArray[8];
     530             :     if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     531             :         td->td_planarconfig == PLANARCONFIG_CONTIG &&
     532             :         td->td_samplesperpixel > 1 && nFoundDims == 1)
     533             :     {
     534             :         if (nFoundMasks != 0 && nFoundMasks != td->td_samplesperpixel)
     535             :         {
     536             :             TIFFErrorExtR(tif, module,
     537             :                           "Unexpected nFoundMasks: %d. Expected: 0 or %d",
     538             :                           nFoundMasks, td->td_samplesperpixel);
     539             :             return 0;
     540             :         }
     541             :         nRequestedMasks = nFoundMasks;
     542             :     }
     543             :     else
     544             :     {
     545             :         if (nFoundMasks != 0 && nFoundMasks != 1)
     546             :         {
     547             :             TIFFErrorExtR(tif, module,
     548             :                           "Unexpected nFoundMasks: %d. Expected: 0 or 1",
     549             :                           nFoundMasks);
     550             :             return 0;
     551             :         }
     552             :     }
     553             :     if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP && nFoundMasks == 0)
     554             :     {
     555             :         nRequestedMasks = 0;
     556             :         use_mask = 0;
     557             :     }
     558             : #endif
     559             : 
     560         530 :     const unsigned nb_pixels = sp->segment_width * sp->segment_height;
     561             : 
     562             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
     563             :     if (nRequestedMasks > 1)
     564             :     {
     565             :         unsigned int num_bytes_needed =
     566             :             nb_pixels * td->td_samplesperpixel * (td->td_bitspersample / 8);
     567             :         if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
     568             :         {
     569             :             _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
     570             :             sp->uncompressed_buffer_multiband =
     571             :                 _TIFFmallocExt(tif, num_bytes_needed);
     572             :             if (!sp->uncompressed_buffer_multiband)
     573             :             {
     574             :                 sp->uncompressed_buffer_multiband_alloc = 0;
     575             :                 return 0;
     576             :             }
     577             :             sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
     578             :         }
     579             :         lerc_ret = lerc_decode(lerc_data, lerc_data_size, nRequestedMasks,
     580             :                                sp->mask_buffer, nFoundDims, sp->segment_width,
     581             :                                sp->segment_height, nFoundBands, lerc_data_type,
     582             :                                sp->uncompressed_buffer_multiband);
     583             :     }
     584             :     else
     585             : #endif
     586             :     {
     587             :         lerc_ret =
     588         530 :             lerc_decode(lerc_data, lerc_data_size,
     589             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
     590             :                         nRequestedMasks,
     591             : #endif
     592             :                         use_mask ? sp->mask_buffer : NULL, nFoundDims,
     593         530 :                         sp->segment_width, sp->segment_height, nFoundBands,
     594         530 :                         lerc_data_type, sp->uncompressed_buffer);
     595             :     }
     596         530 :     if (lerc_ret != 0)
     597             :     {
     598           0 :         TIFFErrorExtR(tif, module, "lerc_decode() failed");
     599           0 :         return 0;
     600             :     }
     601             : 
     602             :     /* Interleave alpha mask with other samples. */
     603         530 :     if (use_mask && GetLercDataType(tif) == 1)
     604           2 :     {
     605           2 :         unsigned src_stride =
     606           2 :             (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
     607           2 :         unsigned dst_stride =
     608           2 :             td->td_samplesperpixel * (td->td_bitspersample / 8);
     609           2 :         unsigned i = sp->segment_width * sp->segment_height;
     610             :         /* Operate from end to begin to be able to move in place */
     611         972 :         while (i > 0 && i > nomask_bands)
     612             :         {
     613         970 :             i--;
     614         970 :             sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
     615         970 :                                     1] = 255 * sp->mask_buffer[i];
     616         970 :             memcpy(sp->uncompressed_buffer + i * dst_stride,
     617         970 :                    sp->uncompressed_buffer + i * src_stride, src_stride);
     618             :         }
     619             :         /* First pixels must use memmove due to overlapping areas */
     620           8 :         while (i > 0)
     621             :         {
     622           6 :             i--;
     623           6 :             sp->uncompressed_buffer[i * dst_stride + td->td_samplesperpixel -
     624           6 :                                     1] = 255 * sp->mask_buffer[i];
     625           6 :             memmove(sp->uncompressed_buffer + i * dst_stride,
     626           6 :                     sp->uncompressed_buffer + i * src_stride, src_stride);
     627             :         }
     628             :     }
     629         528 :     else if (use_mask && td->td_sampleformat == SAMPLEFORMAT_IEEEFP)
     630             :     {
     631             :         unsigned i;
     632             : #if WORDS_BIGENDIAN
     633             :         const unsigned char nan_bytes[] = {0x7f, 0xc0, 0, 0};
     634             : #else
     635          48 :         const unsigned char nan_bytes[] = {0, 0, 0xc0, 0x7f};
     636             : #endif
     637             :         float nan_float32;
     638          48 :         memcpy(&nan_float32, nan_bytes, 4);
     639             : 
     640          48 :         if (td->td_planarconfig == PLANARCONFIG_SEPARATE ||
     641          24 :             td->td_samplesperpixel == 1)
     642             :         {
     643          44 :             if (td->td_bitspersample == 32)
     644             :             {
     645        2242 :                 for (i = 0; i < nb_pixels; i++)
     646             :                 {
     647        2220 :                     if (sp->mask_buffer[i] == 0)
     648         404 :                         ((float *)sp->uncompressed_buffer)[i] = nan_float32;
     649             :                 }
     650             :             }
     651             :             else
     652             :             {
     653          22 :                 const double nan_float64 = nan_float32;
     654        2242 :                 for (i = 0; i < nb_pixels; i++)
     655             :                 {
     656        2220 :                     if (sp->mask_buffer[i] == 0)
     657         404 :                         ((double *)sp->uncompressed_buffer)[i] = nan_float64;
     658             :                 }
     659             :             }
     660             :         }
     661           4 :         else if (nRequestedMasks == 1)
     662             :         {
     663           4 :             assert(nFoundDims == td->td_samplesperpixel);
     664           4 :             assert(nFoundBands == 1);
     665             : 
     666           4 :             unsigned k = 0;
     667           4 :             if (td->td_bitspersample == 32)
     668             :             {
     669         305 :                 for (i = 0; i < nb_pixels; i++)
     670             :                 {
     671         909 :                     for (int j = 0; j < td->td_samplesperpixel; j++)
     672             :                     {
     673         606 :                         if (sp->mask_buffer[i] == 0)
     674           0 :                             ((float *)sp->uncompressed_buffer)[k] = nan_float32;
     675         606 :                         ++k;
     676             :                     }
     677             :                 }
     678             :             }
     679             :             else
     680             :             {
     681           2 :                 const double nan_float64 = nan_float32;
     682         305 :                 for (i = 0; i < nb_pixels; i++)
     683             :                 {
     684         909 :                     for (int j = 0; j < td->td_samplesperpixel; j++)
     685             :                     {
     686         606 :                         if (sp->mask_buffer[i] == 0)
     687           0 :                             ((double *)sp->uncompressed_buffer)[k] =
     688             :                                 nan_float64;
     689         606 :                         ++k;
     690             :                     }
     691             :                 }
     692             :             }
     693             :         }
     694             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
     695             :         else
     696             :         {
     697             :             assert(nRequestedMasks == td->td_samplesperpixel);
     698             :             assert(nFoundDims == 1);
     699             :             assert(nFoundBands == td->td_samplesperpixel);
     700             : 
     701             :             unsigned k = 0;
     702             :             if (td->td_bitspersample == 32)
     703             :             {
     704             :                 for (i = 0; i < nb_pixels; i++)
     705             :                 {
     706             :                     for (int j = 0; j < td->td_samplesperpixel; j++)
     707             :                     {
     708             :                         if (sp->mask_buffer[i + j * nb_pixels] == 0)
     709             :                             ((float *)sp->uncompressed_buffer)[k] = nan_float32;
     710             :                         else
     711             :                             ((float *)sp->uncompressed_buffer)[k] =
     712             :                                 ((float *)sp->uncompressed_buffer_multiband)
     713             :                                     [i + j * nb_pixels];
     714             :                         ++k;
     715             :                     }
     716             :                 }
     717             :             }
     718             :             else
     719             :             {
     720             :                 const double nan_float64 = nan_float32;
     721             :                 for (i = 0; i < nb_pixels; i++)
     722             :                 {
     723             :                     for (int j = 0; j < td->td_samplesperpixel; j++)
     724             :                     {
     725             :                         if (sp->mask_buffer[i + j * nb_pixels] == 0)
     726             :                             ((double *)sp->uncompressed_buffer)[k] =
     727             :                                 nan_float64;
     728             :                         else
     729             :                             ((double *)sp->uncompressed_buffer)[k] =
     730             :                                 ((double *)sp->uncompressed_buffer_multiband)
     731             :                                     [i + j * nb_pixels];
     732             :                         ++k;
     733             :                     }
     734             :                 }
     735             :             }
     736             :         }
     737             : #endif
     738             :     }
     739             : 
     740         530 :     return 1;
     741             : }
     742             : 
     743             : /*
     744             :  * Decode a strip, tile or scanline.
     745             :  */
     746         530 : static int LERCDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
     747             : {
     748             :     static const char module[] = "LERCDecode";
     749         530 :     LERCState *sp = LERCDecoderState(tif);
     750             : 
     751             :     (void)s;
     752         530 :     assert(sp != NULL);
     753         530 :     assert(sp->state == LSTATE_INIT_DECODE);
     754             : 
     755         530 :     if (sp->uncompressed_buffer == 0)
     756             :     {
     757           0 :         memset(op, 0, (size_t)occ);
     758           0 :         TIFFErrorExtR(tif, module, "Uncompressed buffer not allocated");
     759           0 :         return 0;
     760             :     }
     761             : 
     762         530 :     if ((uint64_t)sp->uncompressed_offset + (uint64_t)occ >
     763         530 :         sp->uncompressed_size)
     764             :     {
     765           0 :         memset(op, 0, (size_t)occ);
     766           0 :         TIFFErrorExtR(tif, module, "Too many bytes read");
     767           0 :         return 0;
     768             :     }
     769             : 
     770         530 :     memcpy(op, sp->uncompressed_buffer + sp->uncompressed_offset, occ);
     771         530 :     sp->uncompressed_offset += (unsigned)occ;
     772             : 
     773         530 :     return 1;
     774             : }
     775             : 
     776         156 : static int LERCSetupEncode(TIFF *tif)
     777             : {
     778         156 :     LERCState *sp = LERCEncoderState(tif);
     779             : 
     780         156 :     assert(sp != NULL);
     781         156 :     if (sp->state & LSTATE_INIT_DECODE)
     782             :     {
     783           0 :         sp->state = 0;
     784             :     }
     785             : 
     786         156 :     sp->state |= LSTATE_INIT_ENCODE;
     787             : 
     788         156 :     return 1;
     789             : }
     790             : 
     791             : /*
     792             :  * Reset encoding state at the start of a strip.
     793             :  */
     794         373 : static int LERCPreEncode(TIFF *tif, uint16_t s)
     795             : {
     796             :     static const char module[] = "LERCPreEncode";
     797         373 :     LERCState *sp = LERCEncoderState(tif);
     798             :     int lerc_data_type;
     799             : 
     800             :     (void)s;
     801         373 :     assert(sp != NULL);
     802         373 :     if (sp->state != LSTATE_INIT_ENCODE)
     803           0 :         tif->tif_setupencode(tif);
     804             : 
     805         373 :     lerc_data_type = GetLercDataType(tif);
     806         373 :     if (lerc_data_type < 0)
     807           2 :         return 0;
     808             : 
     809         371 :     if (!SetupBuffers(tif, sp, module))
     810           0 :         return 0;
     811             : 
     812         371 :     return 1;
     813             : }
     814             : 
     815             : /*
     816             :  * Encode a chunk of pixels.
     817             :  */
     818         371 : static int LERCEncode(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
     819             : {
     820             :     static const char module[] = "LERCEncode";
     821         371 :     LERCState *sp = LERCEncoderState(tif);
     822             : 
     823             :     (void)s;
     824         371 :     assert(sp != NULL);
     825         371 :     assert(sp->state == LSTATE_INIT_ENCODE);
     826             : 
     827         371 :     if ((uint64_t)sp->uncompressed_offset + (uint64_t)cc >
     828         371 :         sp->uncompressed_size)
     829             :     {
     830           0 :         TIFFErrorExtR(tif, module, "Too many bytes written");
     831           0 :         return 0;
     832             :     }
     833             : 
     834         371 :     memcpy(sp->uncompressed_buffer + sp->uncompressed_offset, bp, cc);
     835         371 :     sp->uncompressed_offset += (unsigned)cc;
     836             : 
     837         371 :     return 1;
     838             : }
     839             : 
     840             : /*
     841             :  * Finish off an encoded strip by flushing it.
     842             :  */
     843         371 : static int LERCPostEncode(TIFF *tif)
     844             : {
     845             :     lerc_status lerc_ret;
     846             :     static const char module[] = "LERCPostEncode";
     847         371 :     LERCState *sp = LERCEncoderState(tif);
     848         371 :     unsigned int numBytesWritten = 0;
     849         371 :     TIFFDirectory *td = &tif->tif_dir;
     850         371 :     int use_mask = 0;
     851         371 :     unsigned dst_nbands = td->td_samplesperpixel;
     852             : 
     853         371 :     if (sp->uncompressed_offset != sp->uncompressed_size)
     854             :     {
     855           0 :         TIFFErrorExtR(tif, module, "Unexpected number of bytes in the buffer");
     856           0 :         return 0;
     857             :     }
     858             : 
     859         371 :     int mask_count = 1;
     860         371 :     const unsigned nb_pixels = sp->segment_width * sp->segment_height;
     861             : 
     862             :     /* Extract alpha mask (if containing only 0 and 255 values, */
     863             :     /* and compact array of regular bands */
     864         371 :     if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_extrasamples > 0 &&
     865          36 :         td->td_sampleinfo[td->td_extrasamples - 1] == EXTRASAMPLE_UNASSALPHA &&
     866          14 :         GetLercDataType(tif) == 1)
     867          14 :     {
     868          14 :         const unsigned dst_stride =
     869          14 :             (td->td_samplesperpixel - 1) * (td->td_bitspersample / 8);
     870          14 :         const unsigned src_stride =
     871          14 :             td->td_samplesperpixel * (td->td_bitspersample / 8);
     872          14 :         unsigned i = 0;
     873             : 
     874          14 :         use_mask = 1;
     875        3023 :         for (i = 0; i < nb_pixels; i++)
     876             :         {
     877        3021 :             int v = sp->uncompressed_buffer[i * src_stride +
     878        3021 :                                             td->td_samplesperpixel - 1];
     879        3021 :             if (v != 0 && v != 255)
     880             :             {
     881          12 :                 use_mask = 0;
     882          12 :                 break;
     883             :             }
     884             :         }
     885             : 
     886          14 :         if (use_mask)
     887             :         {
     888           2 :             dst_nbands--;
     889             :             /* First pixels must use memmove due to overlapping areas */
     890           8 :             for (i = 0; i < dst_nbands && i < nb_pixels; i++)
     891             :             {
     892           6 :                 memmove(sp->uncompressed_buffer + i * dst_stride,
     893           6 :                         sp->uncompressed_buffer + i * src_stride, dst_stride);
     894           6 :                 sp->mask_buffer[i] =
     895           6 :                     sp->uncompressed_buffer[i * src_stride +
     896           6 :                                             td->td_samplesperpixel - 1];
     897             :             }
     898         972 :             for (; i < nb_pixels; i++)
     899             :             {
     900         970 :                 memcpy(sp->uncompressed_buffer + i * dst_stride,
     901         970 :                        sp->uncompressed_buffer + i * src_stride, dst_stride);
     902         970 :                 sp->mask_buffer[i] =
     903         970 :                     sp->uncompressed_buffer[i * src_stride +
     904         970 :                                             td->td_samplesperpixel - 1];
     905             :             }
     906             :         }
     907             :     }
     908         357 :     else if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP &&
     909          52 :              (td->td_bitspersample == 32 || td->td_bitspersample == 64))
     910             :     {
     911             :         /* Check for NaN values */
     912             :         unsigned i;
     913          52 :         if (td->td_bitspersample == 32)
     914             :         {
     915          28 :             if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
     916           6 :             {
     917           6 :                 unsigned k = 0;
     918       25397 :                 for (i = 0; i < nb_pixels; i++)
     919             :                 {
     920       25393 :                     int count_nan = 0;
     921     2535000 :                     for (int j = 0; j < td->td_samplesperpixel; ++j)
     922             :                     {
     923     2509610 :                         const float val = ((float *)sp->uncompressed_buffer)[k];
     924     2509610 :                         ++k;
     925     2509610 :                         if (val != val)
     926             :                         {
     927          85 :                             ++count_nan;
     928             :                         }
     929             :                     }
     930       25393 :                     if (count_nan > 0)
     931             :                     {
     932           2 :                         use_mask = 1;
     933           2 :                         if (count_nan < td->td_samplesperpixel)
     934             :                         {
     935           2 :                             mask_count = td->td_samplesperpixel;
     936           2 :                             break;
     937             :                         }
     938             :                     }
     939             :                 }
     940             :             }
     941             :             else
     942             :             {
     943        1640 :                 for (i = 0; i < nb_pixels; i++)
     944             :                 {
     945        1626 :                     const float val = ((float *)sp->uncompressed_buffer)[i];
     946        1626 :                     if (val != val)
     947             :                     {
     948           8 :                         use_mask = 1;
     949           8 :                         break;
     950             :                     }
     951             :                 }
     952             :             }
     953             :         }
     954             :         else
     955             :         {
     956          24 :             if (td->td_planarconfig == PLANARCONFIG_CONTIG && dst_nbands > 1)
     957           2 :             {
     958           2 :                 unsigned k = 0;
     959         305 :                 for (i = 0; i < nb_pixels; i++)
     960             :                 {
     961         303 :                     int count_nan = 0;
     962         909 :                     for (int j = 0; j < td->td_samplesperpixel; ++j)
     963             :                     {
     964         606 :                         const double val =
     965         606 :                             ((double *)sp->uncompressed_buffer)[k];
     966         606 :                         ++k;
     967         606 :                         if (val != val)
     968             :                         {
     969           0 :                             ++count_nan;
     970             :                         }
     971             :                     }
     972         303 :                     if (count_nan > 0)
     973             :                     {
     974           0 :                         use_mask = 1;
     975           0 :                         if (count_nan < td->td_samplesperpixel)
     976             :                         {
     977           0 :                             mask_count = td->td_samplesperpixel;
     978           0 :                             break;
     979             :                         }
     980             :                     }
     981             :                 }
     982             :             }
     983             :             else
     984             :             {
     985        1640 :                 for (i = 0; i < nb_pixels; i++)
     986             :                 {
     987        1626 :                     const double val = ((double *)sp->uncompressed_buffer)[i];
     988        1626 :                     if (val != val)
     989             :                     {
     990           8 :                         use_mask = 1;
     991           8 :                         break;
     992             :                     }
     993             :                 }
     994             :             }
     995             :         }
     996             : 
     997          52 :         if (use_mask)
     998             :         {
     999          18 :             if (mask_count > 1)
    1000             :             {
    1001             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
    1002             :                 unsigned int num_bytes_needed =
    1003             :                     nb_pixels * dst_nbands * (td->td_bitspersample / 8);
    1004             :                 if (sp->uncompressed_buffer_multiband_alloc < num_bytes_needed)
    1005             :                 {
    1006             :                     _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
    1007             :                     sp->uncompressed_buffer_multiband =
    1008             :                         _TIFFmallocExt(tif, num_bytes_needed);
    1009             :                     if (!sp->uncompressed_buffer_multiband)
    1010             :                     {
    1011             :                         sp->uncompressed_buffer_multiband_alloc = 0;
    1012             :                         return 0;
    1013             :                     }
    1014             :                     sp->uncompressed_buffer_multiband_alloc = num_bytes_needed;
    1015             :                 }
    1016             : 
    1017             :                 unsigned k = 0;
    1018             :                 if (td->td_bitspersample == 32)
    1019             :                 {
    1020             :                     for (i = 0; i < nb_pixels; i++)
    1021             :                     {
    1022             :                         for (int j = 0; j < td->td_samplesperpixel; ++j)
    1023             :                         {
    1024             :                             const float val =
    1025             :                                 ((float *)sp->uncompressed_buffer)[k];
    1026             :                             ((float *)sp->uncompressed_buffer_multiband)
    1027             :                                 [i + j * nb_pixels] = val;
    1028             :                             ++k;
    1029             :                             sp->mask_buffer[i + j * nb_pixels] =
    1030             :                                 (val == val) ? 255 : 0;
    1031             :                         }
    1032             :                     }
    1033             :                 }
    1034             :                 else
    1035             :                 {
    1036             :                     for (i = 0; i < nb_pixels; i++)
    1037             :                     {
    1038             :                         for (int j = 0; j < td->td_samplesperpixel; ++j)
    1039             :                         {
    1040             :                             const double val =
    1041             :                                 ((double *)sp->uncompressed_buffer)[k];
    1042             :                             ((double *)sp->uncompressed_buffer_multiband)
    1043             :                                 [i + j * nb_pixels] = val;
    1044             :                             ++k;
    1045             :                             sp->mask_buffer[i + j * nb_pixels] =
    1046             :                                 (val == val) ? 255 : 0;
    1047             :                         }
    1048             :                     }
    1049             :                 }
    1050             : #else
    1051           2 :                 TIFFErrorExtR(tif, module,
    1052             :                               "lerc_encode() would need to create one mask per "
    1053             :                               "sample, but this requires liblerc >= 3.0");
    1054           2 :                 return 0;
    1055             : #endif
    1056             :             }
    1057          16 :             else if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
    1058             :                      dst_nbands > 1)
    1059             :             {
    1060           0 :                 if (td->td_bitspersample == 32)
    1061             :                 {
    1062           0 :                     for (i = 0; i < nb_pixels; i++)
    1063             :                     {
    1064           0 :                         const float val =
    1065           0 :                             ((float *)sp->uncompressed_buffer)[i * dst_nbands];
    1066           0 :                         sp->mask_buffer[i] = (val == val) ? 255 : 0;
    1067             :                     }
    1068             :                 }
    1069             :                 else
    1070             :                 {
    1071           0 :                     for (i = 0; i < nb_pixels; i++)
    1072             :                     {
    1073           0 :                         const double val =
    1074           0 :                             ((double *)sp->uncompressed_buffer)[i * dst_nbands];
    1075           0 :                         sp->mask_buffer[i] = (val == val) ? 255 : 0;
    1076             :                     }
    1077             :                 }
    1078             :             }
    1079             :             else
    1080             :             {
    1081          16 :                 if (td->td_bitspersample == 32)
    1082             :                 {
    1083         614 :                     for (i = 0; i < nb_pixels; i++)
    1084             :                     {
    1085         606 :                         const float val = ((float *)sp->uncompressed_buffer)[i];
    1086         606 :                         sp->mask_buffer[i] = (val == val) ? 255 : 0;
    1087             :                     }
    1088             :                 }
    1089             :                 else
    1090             :                 {
    1091         614 :                     for (i = 0; i < nb_pixels; i++)
    1092             :                     {
    1093         606 :                         const double val =
    1094         606 :                             ((double *)sp->uncompressed_buffer)[i];
    1095         606 :                         sp->mask_buffer[i] = (val == val) ? 255 : 0;
    1096             :                     }
    1097             :                 }
    1098             :             }
    1099             :         }
    1100             :     }
    1101             : 
    1102         369 :     unsigned int estimated_compressed_size = sp->uncompressed_alloc;
    1103             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
    1104             :     if (mask_count > 1)
    1105             :     {
    1106             :         estimated_compressed_size += nb_pixels * mask_count / 8;
    1107             :     }
    1108             : #endif
    1109             : 
    1110         369 :     if (sp->compressed_size < estimated_compressed_size)
    1111             :     {
    1112         155 :         _TIFFfreeExt(tif, sp->compressed_buffer);
    1113         155 :         sp->compressed_buffer = _TIFFmallocExt(tif, estimated_compressed_size);
    1114         155 :         if (!sp->compressed_buffer)
    1115             :         {
    1116           0 :             sp->compressed_size = 0;
    1117           0 :             return 0;
    1118             :         }
    1119         155 :         sp->compressed_size = estimated_compressed_size;
    1120             :     }
    1121             : 
    1122             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
    1123             :     if (mask_count > 1)
    1124             :     {
    1125             :         lerc_ret = lerc_encodeForVersion(
    1126             :             sp->uncompressed_buffer_multiband, sp->lerc_version,
    1127             :             GetLercDataType(tif), 1, sp->segment_width, sp->segment_height,
    1128             :             dst_nbands, dst_nbands, sp->mask_buffer, sp->maxzerror,
    1129             :             sp->compressed_buffer, sp->compressed_size, &numBytesWritten);
    1130             :     }
    1131             :     else
    1132             : #endif
    1133             :     {
    1134         738 :         lerc_ret = lerc_encodeForVersion(
    1135         369 :             sp->uncompressed_buffer, sp->lerc_version, GetLercDataType(tif),
    1136         369 :             td->td_planarconfig == PLANARCONFIG_CONTIG ? dst_nbands : 1,
    1137         369 :             sp->segment_width, sp->segment_height, 1,
    1138             : #if LERC_AT_LEAST_VERSION(3, 0, 0)
    1139             :             use_mask ? 1 : 0,
    1140             : #endif
    1141             :             use_mask ? sp->mask_buffer : NULL, sp->maxzerror,
    1142         369 :             sp->compressed_buffer, sp->compressed_size, &numBytesWritten);
    1143             :     }
    1144         369 :     if (lerc_ret != 0)
    1145             :     {
    1146           0 :         TIFFErrorExtR(tif, module, "lerc_encode() failed");
    1147           0 :         return 0;
    1148             :     }
    1149         369 :     assert(numBytesWritten < estimated_compressed_size);
    1150             : 
    1151         369 :     if (sp->additional_compression == LERC_ADD_COMPRESSION_DEFLATE)
    1152             :     {
    1153             : #if LIBDEFLATE_SUPPORT
    1154         108 :         if (sp->libdeflate_enc == NULL)
    1155             :         {
    1156             :             /* To get results as good as zlib, we ask for an extra */
    1157             :             /* level of compression */
    1158          38 :             sp->libdeflate_enc = libdeflate_alloc_compressor(
    1159          38 :                 sp->zipquality == Z_DEFAULT_COMPRESSION ? 7
    1160           3 :                 : sp->zipquality >= 6 && sp->zipquality <= 9
    1161           3 :                     ? sp->zipquality + 1
    1162          11 :                     : sp->zipquality);
    1163          38 :             if (sp->libdeflate_enc == NULL)
    1164             :             {
    1165           0 :                 TIFFErrorExtR(tif, module, "Cannot allocate compressor");
    1166           0 :                 return 0;
    1167             :             }
    1168             :         }
    1169             : 
    1170             :         /* Should not happen normally */
    1171         108 :         if (libdeflate_zlib_compress_bound(
    1172         108 :                 sp->libdeflate_enc, numBytesWritten) > sp->uncompressed_alloc)
    1173             :         {
    1174           0 :             TIFFErrorExtR(tif, module,
    1175             :                           "Output buffer for libdeflate too small");
    1176           0 :             return 0;
    1177             :         }
    1178             : 
    1179         216 :         tif->tif_rawcc = libdeflate_zlib_compress(
    1180         108 :             sp->libdeflate_enc, sp->compressed_buffer, numBytesWritten,
    1181         108 :             sp->uncompressed_buffer, sp->uncompressed_alloc);
    1182             : 
    1183         108 :         if (tif->tif_rawcc == 0)
    1184             :         {
    1185           0 :             TIFFErrorExtR(tif, module, "Encoder error at scanline %lu",
    1186           0 :                           (unsigned long)tif->tif_row);
    1187           0 :             return 0;
    1188             :         }
    1189             : #else
    1190             :         z_stream strm;
    1191             :         int zlib_ret;
    1192             :         int cappedQuality = sp->zipquality;
    1193             :         if (cappedQuality > Z_BEST_COMPRESSION)
    1194             :             cappedQuality = Z_BEST_COMPRESSION;
    1195             : 
    1196             :         memset(&strm, 0, sizeof(strm));
    1197             :         strm.zalloc = NULL;
    1198             :         strm.zfree = NULL;
    1199             :         strm.opaque = NULL;
    1200             :         zlib_ret = deflateInit(&strm, cappedQuality);
    1201             :         if (zlib_ret != Z_OK)
    1202             :         {
    1203             :             TIFFErrorExtR(tif, module, "deflateInit() failed");
    1204             :             return 0;
    1205             :         }
    1206             : 
    1207             :         strm.avail_in = numBytesWritten;
    1208             :         strm.next_in = sp->compressed_buffer;
    1209             :         strm.avail_out = sp->uncompressed_alloc;
    1210             :         strm.next_out = sp->uncompressed_buffer;
    1211             :         zlib_ret = deflate(&strm, Z_FINISH);
    1212             :         if (zlib_ret == Z_STREAM_END)
    1213             :         {
    1214             :             tif->tif_rawcc = sp->uncompressed_alloc - strm.avail_out;
    1215             :         }
    1216             :         deflateEnd(&strm);
    1217             :         if (zlib_ret != Z_STREAM_END)
    1218             :         {
    1219             :             TIFFErrorExtR(tif, module, "deflate() failed");
    1220             :             return 0;
    1221             :         }
    1222             : #endif
    1223             :         {
    1224             :             int ret;
    1225         108 :             uint8_t *tif_rawdata_backup = tif->tif_rawdata;
    1226         108 :             tif->tif_rawdata = sp->uncompressed_buffer;
    1227         108 :             ret = TIFFFlushData1(tif);
    1228         108 :             tif->tif_rawdata = tif_rawdata_backup;
    1229         108 :             if (!ret)
    1230             :             {
    1231           0 :                 return 0;
    1232             :             }
    1233             :         }
    1234             :     }
    1235         261 :     else if (sp->additional_compression == LERC_ADD_COMPRESSION_ZSTD)
    1236             :     {
    1237             : #ifdef ZSTD_SUPPORT
    1238         104 :         size_t zstd_ret = ZSTD_compress(
    1239         104 :             sp->uncompressed_buffer, sp->uncompressed_alloc,
    1240         104 :             sp->compressed_buffer, numBytesWritten, sp->zstd_compress_level);
    1241         104 :         if (ZSTD_isError(zstd_ret))
    1242             :         {
    1243           0 :             TIFFErrorExtR(tif, module, "Error in ZSTD_compress(): %s",
    1244             :                           ZSTD_getErrorName(zstd_ret));
    1245           0 :             return 0;
    1246             :         }
    1247             : 
    1248             :         {
    1249             :             int ret;
    1250         104 :             uint8_t *tif_rawdata_backup = tif->tif_rawdata;
    1251         104 :             tif->tif_rawdata = sp->uncompressed_buffer;
    1252         104 :             tif->tif_rawcc = zstd_ret;
    1253         104 :             ret = TIFFFlushData1(tif);
    1254         104 :             tif->tif_rawdata = tif_rawdata_backup;
    1255         104 :             if (!ret)
    1256             :             {
    1257           0 :                 return 0;
    1258             :             }
    1259             :         }
    1260             : #else
    1261             :         TIFFErrorExtR(tif, module, "ZSTD support missing");
    1262             :         return 0;
    1263             : #endif
    1264             :     }
    1265         157 :     else if (sp->additional_compression != LERC_ADD_COMPRESSION_NONE)
    1266             :     {
    1267           0 :         TIFFErrorExtR(tif, module, "Unhandled additional compression");
    1268           0 :         return 0;
    1269             :     }
    1270             :     else
    1271             :     {
    1272             :         int ret;
    1273         157 :         uint8_t *tif_rawdata_backup = tif->tif_rawdata;
    1274         157 :         tif->tif_rawdata = sp->compressed_buffer;
    1275         157 :         tif->tif_rawcc = numBytesWritten;
    1276         157 :         ret = TIFFFlushData1(tif);
    1277         156 :         tif->tif_rawdata = tif_rawdata_backup;
    1278         156 :         if (!ret)
    1279           0 :             return 0;
    1280             :     }
    1281             : 
    1282         368 :     return 1;
    1283             : }
    1284             : 
    1285         988 : static void LERCCleanup(TIFF *tif)
    1286             : {
    1287         988 :     LERCState *sp = GetLERCState(tif);
    1288             : 
    1289         988 :     assert(sp != 0);
    1290             : 
    1291         988 :     tif->tif_tagmethods.vgetfield = sp->vgetparent;
    1292         988 :     tif->tif_tagmethods.vsetfield = sp->vsetparent;
    1293             : 
    1294         988 :     _TIFFfreeExt(tif, sp->uncompressed_buffer);
    1295         988 :     _TIFFfreeExt(tif, sp->uncompressed_buffer_multiband);
    1296         987 :     _TIFFfreeExt(tif, sp->compressed_buffer);
    1297         988 :     _TIFFfreeExt(tif, sp->mask_buffer);
    1298             : 
    1299             : #if LIBDEFLATE_SUPPORT
    1300         988 :     if (sp->libdeflate_dec)
    1301          47 :         libdeflate_free_decompressor(sp->libdeflate_dec);
    1302         988 :     if (sp->libdeflate_enc)
    1303          38 :         libdeflate_free_compressor(sp->libdeflate_enc);
    1304             : #endif
    1305             : 
    1306         988 :     _TIFFfreeExt(tif, sp);
    1307         987 :     tif->tif_data = NULL;
    1308             : 
    1309         987 :     _TIFFSetDefaultCompressionState(tif);
    1310         987 : }
    1311             : 
    1312             : static const TIFFField LERCFields[] = {
    1313             :     {TIFFTAG_LERC_PARAMETERS, TIFF_VARIABLE2, TIFF_VARIABLE2, TIFF_LONG, 0,
    1314             :      TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, FALSE, TRUE,
    1315             :      "LercParameters", NULL},
    1316             :     {TIFFTAG_LERC_MAXZERROR, 0, 0, TIFF_ANY, 0, TIFF_SETGET_DOUBLE,
    1317             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "LercMaximumError",
    1318             :      NULL},
    1319             :     {TIFFTAG_LERC_VERSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
    1320             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "LercVersion", NULL},
    1321             :     {TIFFTAG_LERC_ADD_COMPRESSION, 0, 0, TIFF_ANY, 0, TIFF_SETGET_UINT32,
    1322             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE,
    1323             :      "LercAdditionalCompression", NULL},
    1324             :     {TIFFTAG_ZSTD_LEVEL, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
    1325             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE,
    1326             :      "ZSTD zstd_compress_level", NULL},
    1327             :     {TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT,
    1328             :      TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL},
    1329             : };
    1330             : 
    1331        2897 : static int LERCVSetFieldBase(TIFF *tif, uint32_t tag, ...)
    1332             : {
    1333        2897 :     LERCState *sp = GetLERCState(tif);
    1334             :     int ret;
    1335             :     va_list ap;
    1336        2897 :     va_start(ap, tag);
    1337        2897 :     ret = (*sp->vsetparent)(tif, tag, ap);
    1338        2897 :     va_end(ap);
    1339        2897 :     return ret;
    1340             : }
    1341             : 
    1342       11589 : static int LERCVSetField(TIFF *tif, uint32_t tag, va_list ap)
    1343             : {
    1344             :     static const char module[] = "LERCVSetField";
    1345       11589 :     LERCState *sp = GetLERCState(tif);
    1346             : 
    1347       11589 :     switch (tag)
    1348             :     {
    1349         891 :         case TIFFTAG_LERC_PARAMETERS:
    1350             :         {
    1351         891 :             uint32_t count = va_arg(ap, int);
    1352         891 :             int *params = va_arg(ap, int *);
    1353         891 :             if (count < 2)
    1354             :             {
    1355           0 :                 TIFFErrorExtR(tif, module,
    1356             :                               "Invalid count for LercParameters: %u", count);
    1357           0 :                 return 0;
    1358             :             }
    1359         891 :             sp->lerc_version = params[0];
    1360         891 :             sp->additional_compression = params[1];
    1361         891 :             return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, count,
    1362             :                                      params);
    1363             :         }
    1364         363 :         case TIFFTAG_LERC_MAXZERROR:
    1365         363 :             sp->maxzerror = va_arg(ap, double);
    1366         363 :             return 1;
    1367         988 :         case TIFFTAG_LERC_VERSION:
    1368             :         {
    1369         988 :             int params[2] = {0, 0};
    1370         988 :             int version = va_arg(ap, int);
    1371         988 :             if (version != LERC_VERSION_2_4)
    1372             :             {
    1373           0 :                 TIFFErrorExtR(tif, module, "Invalid value for LercVersion: %d",
    1374             :                               version);
    1375           0 :                 return 0;
    1376             :             }
    1377         988 :             sp->lerc_version = version;
    1378         988 :             params[0] = sp->lerc_version;
    1379         988 :             params[1] = sp->additional_compression;
    1380         988 :             return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
    1381             :         }
    1382        1018 :         case TIFFTAG_LERC_ADD_COMPRESSION:
    1383             :         {
    1384        1018 :             int params[2] = {0, 0};
    1385        1018 :             int additional_compression = va_arg(ap, int);
    1386             : #ifndef ZSTD_SUPPORT
    1387             :             if (additional_compression == LERC_ADD_COMPRESSION_ZSTD)
    1388             :             {
    1389             :                 TIFFErrorExtR(tif, module,
    1390             :                               "LERC_ZSTD requested, but ZSTD not available");
    1391             :                 return 0;
    1392             :             }
    1393             : #endif
    1394        1018 :             if (additional_compression != LERC_ADD_COMPRESSION_NONE &&
    1395          14 :                 additional_compression != LERC_ADD_COMPRESSION_DEFLATE &&
    1396             :                 additional_compression != LERC_ADD_COMPRESSION_ZSTD)
    1397             :             {
    1398           0 :                 TIFFErrorExtR(tif, module,
    1399             :                               "Invalid value for LercAdditionalCompression: %d",
    1400             :                               additional_compression);
    1401           0 :                 return 0;
    1402             :             }
    1403        1018 :             sp->additional_compression = additional_compression;
    1404        1018 :             params[0] = sp->lerc_version;
    1405        1018 :             params[1] = sp->additional_compression;
    1406        1018 :             return LERCVSetFieldBase(tif, TIFFTAG_LERC_PARAMETERS, 2, params);
    1407             :         }
    1408             : #ifdef ZSTD_SUPPORT
    1409          14 :         case TIFFTAG_ZSTD_LEVEL:
    1410             :         {
    1411          14 :             sp->zstd_compress_level = (int)va_arg(ap, int);
    1412          28 :             if (sp->zstd_compress_level <= 0 ||
    1413          14 :                 sp->zstd_compress_level > ZSTD_maxCLevel())
    1414             :             {
    1415           0 :                 TIFFWarningExtR(tif, module,
    1416             :                                 "ZSTD_LEVEL should be between 1 and %d",
    1417             :                                 ZSTD_maxCLevel());
    1418             :             }
    1419          14 :             return 1;
    1420             :         }
    1421             : #endif
    1422          14 :         case TIFFTAG_ZIPQUALITY:
    1423             :         {
    1424          14 :             sp->zipquality = (int)va_arg(ap, int);
    1425          14 :             if (sp->zipquality < Z_DEFAULT_COMPRESSION ||
    1426          14 :                 sp->zipquality > LIBDEFLATE_MAX_COMPRESSION_LEVEL)
    1427             :             {
    1428           0 :                 TIFFErrorExtR(
    1429             :                     tif, module,
    1430             :                     "Invalid ZipQuality value. Should be in [-1,%d] range",
    1431             :                     LIBDEFLATE_MAX_COMPRESSION_LEVEL);
    1432           0 :                 return 0;
    1433             :             }
    1434             : 
    1435             : #if LIBDEFLATE_SUPPORT
    1436          14 :             if (sp->libdeflate_enc)
    1437             :             {
    1438           0 :                 libdeflate_free_compressor(sp->libdeflate_enc);
    1439           0 :                 sp->libdeflate_enc = NULL;
    1440             :             }
    1441             : #endif
    1442             : 
    1443          14 :             return (1);
    1444             :         }
    1445        8301 :         default:
    1446        8301 :             return (*sp->vsetparent)(tif, tag, ap);
    1447             :     }
    1448             :     /*NOTREACHED*/
    1449             : }
    1450             : 
    1451       11452 : static int LERCVGetField(TIFF *tif, uint32_t tag, va_list ap)
    1452             : {
    1453       11452 :     LERCState *sp = GetLERCState(tif);
    1454             : 
    1455       11452 :     switch (tag)
    1456             :     {
    1457           0 :         case TIFFTAG_LERC_MAXZERROR:
    1458           0 :             *va_arg(ap, double *) = sp->maxzerror;
    1459           0 :             break;
    1460         317 :         case TIFFTAG_LERC_VERSION:
    1461         317 :             *va_arg(ap, int *) = sp->lerc_version;
    1462         317 :             break;
    1463         317 :         case TIFFTAG_LERC_ADD_COMPRESSION:
    1464         317 :             *va_arg(ap, int *) = sp->additional_compression;
    1465         317 :             break;
    1466           0 :         case TIFFTAG_ZSTD_LEVEL:
    1467           0 :             *va_arg(ap, int *) = sp->zstd_compress_level;
    1468           0 :             break;
    1469           0 :         case TIFFTAG_ZIPQUALITY:
    1470           0 :             *va_arg(ap, int *) = sp->zipquality;
    1471           0 :             break;
    1472       10818 :         default:
    1473       10818 :             return (*sp->vgetparent)(tif, tag, ap);
    1474             :     }
    1475         634 :     return 1;
    1476             : }
    1477             : 
    1478         988 : int TIFFInitLERC(TIFF *tif, int scheme)
    1479             : {
    1480             :     static const char module[] = "TIFFInitLERC";
    1481             :     LERCState *sp;
    1482             : 
    1483             :     (void)scheme;
    1484         988 :     assert(scheme == COMPRESSION_LERC);
    1485             : 
    1486             :     /*
    1487             :      * Merge codec-specific tag information.
    1488             :      */
    1489         988 :     if (!_TIFFMergeFields(tif, LERCFields, TIFFArrayCount(LERCFields)))
    1490             :     {
    1491           0 :         TIFFErrorExtR(tif, module, "Merging LERC codec-specific tags failed");
    1492           0 :         return 0;
    1493             :     }
    1494             : 
    1495             :     /*
    1496             :      * Allocate state block so tag methods have storage to record values.
    1497             :      */
    1498         988 :     tif->tif_data = (uint8_t *)_TIFFcallocExt(tif, 1, sizeof(LERCState));
    1499         988 :     if (tif->tif_data == NULL)
    1500           0 :         goto bad;
    1501         988 :     sp = GetLERCState(tif);
    1502             : 
    1503             :     /*
    1504             :      * Override parent get/set field methods.
    1505             :      */
    1506         988 :     sp->vgetparent = tif->tif_tagmethods.vgetfield;
    1507         988 :     tif->tif_tagmethods.vgetfield = LERCVGetField; /* hook for codec tags */
    1508         988 :     sp->vsetparent = tif->tif_tagmethods.vsetfield;
    1509         988 :     tif->tif_tagmethods.vsetfield = LERCVSetField; /* hook for codec tags */
    1510             : 
    1511             :     /*
    1512             :      * Install codec methods.
    1513             :      */
    1514         988 :     tif->tif_fixuptags = LERCFixupTags;
    1515         988 :     tif->tif_setupdecode = LERCSetupDecode;
    1516         988 :     tif->tif_predecode = LERCPreDecode;
    1517         988 :     tif->tif_decoderow = LERCDecode;
    1518         988 :     tif->tif_decodestrip = LERCDecode;
    1519         988 :     tif->tif_decodetile = LERCDecode;
    1520         988 :     tif->tif_setupencode = LERCSetupEncode;
    1521         988 :     tif->tif_preencode = LERCPreEncode;
    1522         988 :     tif->tif_postencode = LERCPostEncode;
    1523         988 :     tif->tif_encoderow = LERCEncode;
    1524         988 :     tif->tif_encodestrip = LERCEncode;
    1525         988 :     tif->tif_encodetile = LERCEncode;
    1526         988 :     tif->tif_cleanup = LERCCleanup;
    1527             : 
    1528             :     /* Default values for codec-specific fields */
    1529         988 :     TIFFSetField(tif, TIFFTAG_LERC_VERSION, LERC_VERSION_2_4);
    1530         988 :     TIFFSetField(tif, TIFFTAG_LERC_ADD_COMPRESSION, LERC_ADD_COMPRESSION_NONE);
    1531         988 :     sp->maxzerror = 0.0;
    1532         988 :     sp->zstd_compress_level = 9;            /* default comp. level */
    1533         988 :     sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
    1534         988 :     sp->state = 0;
    1535             : 
    1536         988 :     return 1;
    1537           0 : bad:
    1538           0 :     TIFFErrorExtR(tif, module, "No space for LERC state block");
    1539           0 :     return 0;
    1540             : }
    1541             : #endif /* LERC_SUPPORT */

Generated by: LCOV version 1.14