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 593 78.9 %
Date: 2024-05-03 15:49:35 Functions: 15 15 100.0 %

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

Generated by: LCOV version 1.14