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

Generated by: LCOV version 1.14