LCOV - code coverage report
Current view: top level - frmts/gtiff/libtiff - tif_thunder.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 42 77 54.5 %
Date: 2024-11-21 22:18:42 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 *op0, 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           1 :     uint8_t *op = op0;
      93             : 
      94           1 :     bp = (unsigned char *)tif->tif_rawcp;
      95           1 :     cc = tif->tif_rawcc;
      96           1 :     lastpixel = 0;
      97           1 :     npixels = 0;
      98           3 :     while (cc > 0 && npixels < maxpixels)
      99             :     {
     100             :         int n, delta;
     101             : 
     102           2 :         n = *bp++;
     103           2 :         cc--;
     104           2 :         switch (n & THUNDER_CODE)
     105             :         {
     106           1 :             case THUNDER_RUN: /* pixel run */
     107             :                 /*
     108             :                  * Replicate the last pixel n times,
     109             :                  * where n is the lower-order 6 bits.
     110             :                  */
     111           1 :                 if (n == 0)
     112           1 :                     break;
     113           0 :                 if (npixels & 1)
     114             :                 {
     115           0 :                     op[0] |= lastpixel;
     116           0 :                     lastpixel = *op++;
     117           0 :                     npixels++;
     118           0 :                     n--;
     119             :                 }
     120             :                 else
     121           0 :                     lastpixel |= lastpixel << 4;
     122           0 :                 npixels += n;
     123           0 :                 if (npixels > maxpixels)
     124           0 :                     break;
     125           0 :                 for (; n > 0; n -= 2)
     126           0 :                     *op++ = (uint8_t)lastpixel;
     127           0 :                 if (n == -1)
     128           0 :                     *--op &= 0xf0;
     129           0 :                 lastpixel &= 0xf;
     130           0 :                 break;
     131           1 :             case THUNDER_2BITDELTAS: /* 2-bit deltas */
     132           1 :                 if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
     133           1 :                     SETPIXEL(op,
     134             :                              (unsigned)((int)lastpixel + twobitdeltas[delta]));
     135           1 :                 if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
     136           1 :                     SETPIXEL(op,
     137             :                              (unsigned)((int)lastpixel + twobitdeltas[delta]));
     138           1 :                 if ((delta = (n & 3)) != DELTA2_SKIP)
     139           1 :                     SETPIXEL(op,
     140             :                              (unsigned)((int)lastpixel + twobitdeltas[delta]));
     141           1 :                 break;
     142           0 :             case THUNDER_3BITDELTAS: /* 3-bit deltas */
     143           0 :                 if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
     144           0 :                     SETPIXEL(
     145             :                         op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
     146           0 :                 if ((delta = (n & 7)) != DELTA3_SKIP)
     147           0 :                     SETPIXEL(
     148             :                         op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
     149           0 :                 break;
     150           0 :             case THUNDER_RAW: /* raw data */
     151           0 :                 SETPIXEL(op, n);
     152           0 :                 break;
     153             :         }
     154           3 :     }
     155           1 :     tif->tif_rawcp = (uint8_t *)bp;
     156           1 :     tif->tif_rawcc = cc;
     157           1 :     if (npixels != maxpixels)
     158             :     {
     159           0 :         uint8_t *op_end = op0 + (maxpixels + 1) / 2;
     160           0 :         memset(op, 0, (size_t)(op_end - op));
     161           0 :         TIFFErrorExtR(tif, module,
     162             :                       "%s data at scanline %lu (%" PRIu64 " != %" PRIu64 ")",
     163             :                       npixels < maxpixels ? "Not enough" : "Too much",
     164           0 :                       (unsigned long)tif->tif_row, (uint64_t)npixels,
     165             :                       (uint64_t)maxpixels);
     166           0 :         return (0);
     167             :     }
     168             : 
     169           1 :     return (1);
     170             : }
     171             : 
     172           1 : static int ThunderDecodeRow(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
     173             : {
     174             :     static const char module[] = "ThunderDecodeRow";
     175           1 :     uint8_t *row = buf;
     176             : 
     177             :     (void)s;
     178           1 :     if (occ % tif->tif_scanlinesize)
     179             :     {
     180           0 :         TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
     181           0 :         return (0);
     182             :     }
     183           2 :     while (occ > 0)
     184             :     {
     185           1 :         if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
     186           0 :             return (0);
     187           1 :         occ -= tif->tif_scanlinesize;
     188           1 :         row += tif->tif_scanlinesize;
     189             :     }
     190           1 :     return (1);
     191             : }
     192             : 
     193           2 : int TIFFInitThunderScan(TIFF *tif, int scheme)
     194             : {
     195             :     (void)scheme;
     196             : 
     197           2 :     tif->tif_setupdecode = ThunderSetupDecode;
     198           2 :     tif->tif_decoderow = ThunderDecodeRow;
     199           2 :     tif->tif_decodestrip = ThunderDecodeRow;
     200           2 :     return (1);
     201             : }
     202             : #endif /* THUNDER_SUPPORT */

Generated by: LCOV version 1.14