LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_lerc.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 470 599 78.5 %
Date: 2026-04-03 14:38:35 Functions: 22 26 84.6 %

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

Generated by: LCOV version 1.14