LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_thunder.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 47 71 66.2 %
Date: 2024-05-04 12:52:34 Functions: 4 4 100.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             : #include "tiffiop.h"
      26             : #include <assert.h>
      27             : #ifdef THUNDER_SUPPORT
      28             : /*
      29             :  * TIFF Library.
      30             :  *
      31             :  * ThunderScan 4-bit Compression Algorithm Support
      32             :  */
      33             : 
      34             : /*
      35             :  * ThunderScan uses an encoding scheme designed for
      36             :  * 4-bit pixel values.  Data is encoded in bytes, with
      37             :  * each byte split into a 2-bit code word and a 6-bit
      38             :  * data value.  The encoding gives raw data, runs of
      39             :  * pixels, or pixel values encoded as a delta from the
      40             :  * previous pixel value.  For the latter, either 2-bit
      41             :  * or 3-bit delta values are used, with the deltas packed
      42             :  * into a single byte.
      43             :  */
      44             : #define THUNDER_DATA 0x3f /* mask for 6-bit data */
      45             : #define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
      46             : /* code values */
      47             : #define THUNDER_RUN 0x00        /* run of pixels w/ encoded count */
      48             : #define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */
      49             : #define DELTA2_SKIP 2           /* skip code for 2-bit deltas */
      50             : #define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */
      51             : #define DELTA3_SKIP 4           /* skip code for 3-bit deltas */
      52             : #define THUNDER_RAW 0xc0        /* raw data encoded */
      53             : 
      54             : static const int twobitdeltas[4] = {0, 1, 0, -1};
      55             : static const int threebitdeltas[8] = {0, 1, 2, 3, 0, -3, -2, -1};
      56             : 
      57             : #define SETPIXEL(op, v)                                                        \
      58             :     {                                                                          \
      59             :         lastpixel = (v)&0xf;                                                   \
      60             :         if (npixels < maxpixels)                                               \
      61             :         {                                                                      \
      62             :             if (npixels++ & 1)                                                 \
      63             :                 *op++ |= lastpixel;                                            \
      64             :             else                                                               \
      65             :                 op[0] = (uint8_t)(lastpixel << 4);                             \
      66             :         }                                                                      \
      67             :     }
      68             : 
      69           1 : static int ThunderSetupDecode(TIFF *tif)
      70             : {
      71             :     static const char module[] = "ThunderSetupDecode";
      72             : 
      73           1 :     if (tif->tif_dir.td_bitspersample != 4)
      74             :     {
      75           0 :         TIFFErrorExtR(tif, module,
      76             :                       "Wrong bitspersample value (%d), Thunder decoder only "
      77             :                       "supports 4bits per sample.",
      78           0 :                       (int)tif->tif_dir.td_bitspersample);
      79           0 :         return 0;
      80             :     }
      81             : 
      82           1 :     return (1);
      83             : }
      84             : 
      85           1 : static int ThunderDecode(TIFF *tif, uint8_t *op, tmsize_t maxpixels)
      86             : {
      87             :     static const char module[] = "ThunderDecode";
      88             :     register unsigned char *bp;
      89             :     register tmsize_t cc;
      90             :     unsigned int lastpixel;
      91             :     tmsize_t npixels;
      92             : 
      93           1 :     bp = (unsigned char *)tif->tif_rawcp;
      94           1 :     cc = tif->tif_rawcc;
      95           1 :     lastpixel = 0;
      96           1 :     npixels = 0;
      97           3 :     while (cc > 0 && npixels < maxpixels)
      98             :     {
      99             :         int n, delta;
     100             : 
     101           2 :         n = *bp++;
     102           2 :         cc--;
     103           2 :         switch (n & THUNDER_CODE)
     104             :         {
     105           1 :             case THUNDER_RUN: /* pixel run */
     106             :                 /*
     107             :                  * Replicate the last pixel n times,
     108             :                  * where n is the lower-order 6 bits.
     109             :                  */
     110           1 :                 if (npixels & 1)
     111             :                 {
     112           0 :                     op[0] |= lastpixel;
     113           0 :                     lastpixel = *op++;
     114           0 :                     npixels++;
     115           0 :                     n--;
     116             :                 }
     117             :                 else
     118           1 :                     lastpixel |= lastpixel << 4;
     119           1 :                 npixels += n;
     120           1 :                 if (npixels < maxpixels)
     121             :                 {
     122           1 :                     for (; n > 0; n -= 2)
     123           0 :                         *op++ = (uint8_t)lastpixel;
     124             :                 }
     125           1 :                 if (n == -1)
     126           0 :                     *--op &= 0xf0;
     127           1 :                 lastpixel &= 0xf;
     128           1 :                 break;
     129           1 :             case THUNDER_2BITDELTAS: /* 2-bit deltas */
     130           1 :                 if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
     131           1 :                     SETPIXEL(op,
     132             :                              (unsigned)((int)lastpixel + twobitdeltas[delta]));
     133           1 :                 if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
     134           1 :                     SETPIXEL(op,
     135             :                              (unsigned)((int)lastpixel + twobitdeltas[delta]));
     136           1 :                 if ((delta = (n & 3)) != DELTA2_SKIP)
     137           1 :                     SETPIXEL(op,
     138             :                              (unsigned)((int)lastpixel + twobitdeltas[delta]));
     139           1 :                 break;
     140           0 :             case THUNDER_3BITDELTAS: /* 3-bit deltas */
     141           0 :                 if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
     142           0 :                     SETPIXEL(
     143             :                         op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
     144           0 :                 if ((delta = (n & 7)) != DELTA3_SKIP)
     145           0 :                     SETPIXEL(
     146             :                         op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
     147           0 :                 break;
     148           0 :             case THUNDER_RAW: /* raw data */
     149           0 :                 SETPIXEL(op, n);
     150           0 :                 break;
     151             :         }
     152           3 :     }
     153           1 :     tif->tif_rawcp = (uint8_t *)bp;
     154           1 :     tif->tif_rawcc = cc;
     155           1 :     if (npixels != maxpixels)
     156             :     {
     157           0 :         TIFFErrorExtR(tif, module,
     158             :                       "%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
     159             :                       npixels < maxpixels ? "Not enough" : "Too much",
     160           0 :                       (unsigned long)tif->tif_row, (uint64_t)npixels,
     161             :                       (uint64_t)maxpixels);
     162           0 :         return (0);
     163             :     }
     164             : 
     165           1 :     return (1);
     166             : }
     167             : 
     168           1 : static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
     169             : {
     170             :     static const char module[] = "ThunderDecodeRow";
     171           1 :     uint8_t *row = buf;
     172             : 
     173             :     (void)s;
     174           1 :     if (occ % tif->tif_scanlinesize)
     175             :     {
     176           0 :         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
     177           0 :         return (0);
     178             :     }
     179           2 :     while (occ > 0)
     180             :     {
     181           1 :         if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
     182           0 :             return (0);
     183           1 :         occ -= tif->tif_scanlinesize;
     184           1 :         row += tif->tif_scanlinesize;
     185             :     }
     186           1 :     return (1);
     187             : }
     188             : 
     189           2 : int TIFFInitThunderScan(TIFF *tif, int scheme)
     190             : {
     191             :     (void)scheme;
     192             : 
     193           2 :     tif->tif_setupdecode = ThunderSetupDecode;
     194           2 :     tif->tif_decoderow = ThunderDecodeRow;
     195           2 :     tif->tif_decodestrip = ThunderDecodeRow;
     196           2 :     return (1);
     197             : }
     198             : #endif /* THUNDER_SUPPORT */

Generated by: LCOV version 1.14