LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_compress.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 97 136 71.3 %
Date: 2026-04-03 14:38:35 Functions: 11 20 55.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1988-1997 Sam Leffler
       3             :  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
       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             : /*
      26             :  * TIFF Library
      27             :  *
      28             :  * Compression Scheme Configuration Support.
      29             :  */
      30             : #include "tiffiop.h"
      31             : 
      32           0 : static int TIFFNoEncode(TIFF *tif, const char *method)
      33             : {
      34           0 :     const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
      35             : 
      36           0 :     if (c)
      37             :     {
      38           0 :         TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented",
      39             :                       c->name, method);
      40             :     }
      41             :     else
      42             :     {
      43           0 :         TIFFErrorExtR(tif, tif->tif_name,
      44             :                       "Compression scheme %" PRIu16
      45             :                       " %s encoding is not implemented",
      46           0 :                       tif->tif_dir.td_compression, method);
      47             :     }
      48           0 :     return (-1);
      49             : }
      50             : 
      51           0 : int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
      52             : {
      53             :     (void)pp;
      54             :     (void)cc;
      55             :     (void)s;
      56           0 :     return (TIFFNoEncode(tif, "scanline"));
      57             : }
      58             : 
      59           0 : int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
      60             : {
      61             :     (void)pp;
      62             :     (void)cc;
      63             :     (void)s;
      64           0 :     return (TIFFNoEncode(tif, "strip"));
      65             : }
      66             : 
      67           0 : int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
      68             : {
      69             :     (void)pp;
      70             :     (void)cc;
      71             :     (void)s;
      72           0 :     return (TIFFNoEncode(tif, "tile"));
      73             : }
      74             : 
      75           0 : static int TIFFNoDecode(TIFF *tif, const char *method)
      76             : {
      77           0 :     const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
      78             : 
      79           0 :     if (c)
      80           0 :         TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented",
      81             :                       c->name, method);
      82             :     else
      83           0 :         TIFFErrorExtR(tif, tif->tif_name,
      84             :                       "Compression scheme %" PRIu16
      85             :                       " %s decoding is not implemented",
      86           0 :                       tif->tif_dir.td_compression, method);
      87           0 :     return (0);
      88             : }
      89             : 
      90          75 : static int _TIFFNoFixupTags(TIFF *tif)
      91             : {
      92             :     (void)tif;
      93          75 :     return (1);
      94             : }
      95             : 
      96           0 : int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
      97             : {
      98             :     (void)pp;
      99             :     (void)cc;
     100             :     (void)s;
     101           0 :     return (TIFFNoDecode(tif, "scanline"));
     102             : }
     103             : 
     104           0 : int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
     105             : {
     106             :     (void)pp;
     107             :     (void)cc;
     108             :     (void)s;
     109           0 :     return (TIFFNoDecode(tif, "strip"));
     110             : }
     111             : 
     112           0 : int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
     113             : {
     114             :     (void)pp;
     115             :     (void)cc;
     116             :     (void)s;
     117           0 :     return (TIFFNoDecode(tif, "tile"));
     118             : }
     119             : 
     120           0 : int _TIFFNoSeek(TIFF *tif, uint32_t off)
     121             : {
     122             :     (void)off;
     123           0 :     TIFFErrorExtR(tif, tif->tif_name,
     124             :                   "Compression algorithm does not support random access");
     125           0 :     return (0);
     126             : }
     127             : 
     128        2081 : int _TIFFNoPreCode(TIFF *tif, uint16_t s)
     129             : {
     130             :     (void)tif;
     131             :     (void)s;
     132        2081 :     return (1);
     133             : }
     134             : 
     135       17252 : static int _TIFFtrue(TIFF *tif)
     136             : {
     137             :     (void)tif;
     138       17252 :     return (1);
     139             : }
     140      250811 : static void _TIFFvoid(TIFF *tif) { (void)tif; }
     141             : 
     142      373720 : void _TIFFSetDefaultPostDecode(TIFF *tif)
     143             : {
     144      373720 :     tif->tif_postdecode = _TIFFNoPostDecode;
     145             :     /*
     146             :      * If the data require post-decoding processing to byte-swap
     147             :      * samples, set it up here.  Note that since tags are required
     148             :      * to be ordered, compression code can override this behavior
     149             :      * in the setup method if it wants to roll the post decoding
     150             :      * work in with its normal work.
     151             :      */
     152      373720 :     if (tif->tif_flags & TIFF_SWAB)
     153             :     {
     154        1857 :         TIFFDirectory *td = &tif->tif_dir;
     155        1857 :         if (td->td_bitspersample == 16)
     156         153 :             tif->tif_postdecode = _TIFFSwab16BitData;
     157        1704 :         else if (td->td_bitspersample == 24)
     158           0 :             tif->tif_postdecode = _TIFFSwab24BitData;
     159        1704 :         else if (td->td_bitspersample == 32)
     160         149 :             tif->tif_postdecode = _TIFFSwab32BitData;
     161        1555 :         else if (td->td_bitspersample == 64)
     162          21 :             tif->tif_postdecode = _TIFFSwab64BitData;
     163        1534 :         else if (td->td_bitspersample == 128)
     164             :         {
     165             :             // Used for Complex 64-bit floating point.
     166             :             // The real and imaginary parts are byte-swapped separately.
     167           7 :             tif->tif_postdecode = _TIFFSwab64BitData;
     168             :         }
     169             :     }
     170      373720 : }
     171             : 
     172      279413 : void _TIFFSetDefaultCompressionState(TIFF *tif)
     173             : {
     174      279413 :     tif->tif_fixuptags = _TIFFNoFixupTags;
     175      279413 :     tif->tif_decodestatus = TRUE;
     176      279413 :     tif->tif_setupdecode = _TIFFtrue;
     177      279413 :     tif->tif_predecode = _TIFFNoPreCode;
     178      279413 :     _TIFFSetDefaultPostDecode(tif);
     179      279370 :     tif->tif_decoderow = _TIFFNoRowDecode;
     180      279370 :     tif->tif_decodestrip = _TIFFNoStripDecode;
     181      279370 :     tif->tif_decodetile = _TIFFNoTileDecode;
     182      279370 :     tif->tif_encodestatus = TRUE;
     183      279370 :     tif->tif_setupencode = _TIFFtrue;
     184      279370 :     tif->tif_preencode = _TIFFNoPreCode;
     185      279370 :     tif->tif_postencode = _TIFFtrue;
     186      279370 :     tif->tif_encoderow = _TIFFNoRowEncode;
     187      279370 :     tif->tif_encodestrip = _TIFFNoStripEncode;
     188      279370 :     tif->tif_encodetile = _TIFFNoTileEncode;
     189      279370 :     tif->tif_close = _TIFFvoid;
     190      279370 :     tif->tif_seek = _TIFFNoSeek;
     191      279370 :     tif->tif_cleanup = _TIFFvoid;
     192      279370 :     tif->tif_defstripsize = _TIFFDefaultStripSize;
     193      279370 :     tif->tif_deftilesize = _TIFFDefaultTileSize;
     194      279370 :     tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
     195      279370 : }
     196             : 
     197      172537 : int TIFFSetCompressionScheme(TIFF *tif, int scheme)
     198             : {
     199      172537 :     const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
     200             : 
     201      172536 :     _TIFFSetDefaultCompressionState(tif);
     202             :     /*
     203             :      * Don't treat an unknown compression scheme as an error.
     204             :      * This permits applications to open files with data that
     205             :      * the library does not have builtin support for, but which
     206             :      * may still be meaningful.
     207             :      */
     208      172536 :     return (c ? (*c->init)(tif, scheme) : 1);
     209             : }
     210             : 
     211             : /*
     212             :  * Other compression schemes may be registered.  Registered
     213             :  * schemes can also override the builtin versions provided
     214             :  * by this library.
     215             :  */
     216             : typedef struct _codec
     217             : {
     218             :     struct _codec *next;
     219             :     TIFFCodec *info;
     220             : } codec_t;
     221             : static codec_t *registeredCODECS = NULL;
     222             : 
     223      268813 : const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
     224             : {
     225             :     const TIFFCodec *c;
     226             :     codec_t *cd;
     227             : 
     228      653793 :     for (cd = registeredCODECS; cd; cd = cd->next)
     229      385877 :         if (cd->info->scheme == scheme)
     230         897 :             return ((const TIFFCodec *)cd->info);
     231     1396220 :     for (c = _TIFFBuiltinCODECS; c->name; c++)
     232     1396200 :         if (c->scheme == scheme)
     233      267895 :             return (c);
     234          21 :     return ((const TIFFCodec *)0);
     235             : }
     236             : 
     237        1398 : TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
     238             :                              TIFFInitMethod init)
     239             : {
     240        1398 :     codec_t *cd = (codec_t *)_TIFFmallocExt(
     241             :         NULL,
     242        1398 :         (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
     243             : 
     244        1398 :     if (cd != NULL)
     245             :     {
     246             :         char *codec_name;
     247        1398 :         cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
     248        1398 :         codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
     249        1398 :         strcpy(codec_name, name);
     250        1398 :         cd->info->name = codec_name;
     251        1398 :         cd->info->scheme = scheme;
     252        1398 :         cd->info->init = init;
     253        1398 :         cd->next = registeredCODECS;
     254        1398 :         registeredCODECS = cd;
     255             :     }
     256             :     else
     257             :     {
     258           0 :         TIFFErrorExt(0, "TIFFRegisterCODEC",
     259             :                      "No space to register compression scheme %s", name);
     260           0 :         return NULL;
     261             :     }
     262        1398 :     return (cd->info);
     263             : }
     264             : 
     265         868 : void TIFFUnRegisterCODEC(TIFFCodec *c)
     266             : {
     267             :     codec_t *cd;
     268             :     codec_t **pcd;
     269             : 
     270        1302 :     for (pcd = &registeredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
     271        1302 :         if (cd->info == c)
     272             :         {
     273         868 :             *pcd = cd->next;
     274         868 :             _TIFFfreeExt(NULL, cd);
     275         868 :             return;
     276             :         }
     277           0 :     TIFFErrorExt(0, "TIFFUnRegisterCODEC",
     278             :                  "Cannot remove compression scheme %s; not registered",
     279             :                  c->name);
     280             : }
     281             : 
     282             : /************************************************************************/
     283             : /*                      TIFFGetConfiguredCODECs()                       */
     284             : /************************************************************************/
     285             : 
     286             : /**
     287             :  * Get list of configured codecs, both built-in and registered by user.
     288             :  * Caller is responsible to free this structure.
     289             :  *
     290             :  * @return returns array of TIFFCodec records (the last record should be NULL)
     291             :  * or NULL if function failed.
     292             :  */
     293             : 
     294        3837 : TIFFCodec *TIFFGetConfiguredCODECs(void)
     295             : {
     296        3837 :     int i = 1;
     297             :     codec_t *cd;
     298             :     const TIFFCodec *c;
     299        3837 :     TIFFCodec *codecs = NULL;
     300             :     TIFFCodec *new_codecs;
     301             : 
     302        4329 :     for (cd = registeredCODECS; cd; cd = cd->next)
     303             :     {
     304             :         new_codecs =
     305         492 :             (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
     306         492 :         if (!new_codecs)
     307             :         {
     308           0 :             _TIFFfreeExt(NULL, codecs);
     309           0 :             return NULL;
     310             :         }
     311         492 :         codecs = new_codecs;
     312         492 :         _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
     313         492 :         i++;
     314             :     }
     315       84414 :     for (c = _TIFFBuiltinCODECS; c->name; c++)
     316             :     {
     317       80577 :         if (TIFFIsCODECConfigured(c->scheme))
     318             :         {
     319       76740 :             new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
     320       76740 :                                                       i * sizeof(TIFFCodec));
     321       76740 :             if (!new_codecs)
     322             :             {
     323           0 :                 _TIFFfreeExt(NULL, codecs);
     324           0 :                 return NULL;
     325             :             }
     326       76740 :             codecs = new_codecs;
     327       76740 :             _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
     328       76740 :             i++;
     329             :         }
     330             :     }
     331             : 
     332             :     new_codecs =
     333        3837 :         (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
     334        3837 :     if (!new_codecs)
     335             :     {
     336           0 :         _TIFFfreeExt(NULL, codecs);
     337           0 :         return NULL;
     338             :     }
     339        3837 :     codecs = new_codecs;
     340        3837 :     _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
     341             : 
     342        3837 :     return codecs;
     343             : }

Generated by: LCOV version 1.14