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

Generated by: LCOV version 1.14