Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/tiff/libtiff/tif_thunder.c
Line
Count
Source (jump to first uncovered line)
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
0
#define THUNDER_CODE    0xc0  /* mask for 2-bit code word */
46
/* code values */
47
0
#define THUNDER_RUN   0x00  /* run of pixels w/ encoded count */
48
0
#define THUNDER_2BITDELTAS  0x40  /* 3 pixels w/ encoded 2-bit deltas */
49
0
#define     DELTA2_SKIP   2  /* skip code for 2-bit deltas */
50
0
#define THUNDER_3BITDELTAS  0x80  /* 2 pixels w/ encoded 3-bit deltas */
51
0
#define     DELTA3_SKIP   4  /* skip code for 3-bit deltas */
52
0
#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
0
#define SETPIXEL(op, v) {                     \
58
0
  lastpixel = (v) & 0xf;                \
59
0
        if ( npixels < maxpixels )         \
60
0
        {                                     \
61
0
    if (npixels++ & 1)                  \
62
0
      *op++ |= lastpixel;               \
63
0
    else                                \
64
0
      op[0] = (uint8_t) (lastpixel << 4); \
65
0
        }                                     \
66
0
}
67
68
static int
69
ThunderSetupDecode(TIFF* tif)
70
0
{
71
0
  static const char module[] = "ThunderSetupDecode";
72
73
0
        if( tif->tif_dir.td_bitspersample != 4 )
74
0
        {
75
0
                TIFFErrorExt(tif->tif_clientdata, module,
76
0
                             "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.",
77
0
                             (int) tif->tif_dir.td_bitspersample );
78
0
                return 0;
79
0
        }
80
        
81
82
0
  return (1);
83
0
}
84
85
static int
86
ThunderDecode(TIFF* tif, uint8_t* op, tmsize_t maxpixels)
87
0
{
88
0
  static const char module[] = "ThunderDecode";
89
0
  register unsigned char *bp;
90
0
  register tmsize_t cc;
91
0
  unsigned int lastpixel;
92
0
  tmsize_t npixels;
93
94
0
  bp = (unsigned char *)tif->tif_rawcp;
95
0
  cc = tif->tif_rawcc;
96
0
  lastpixel = 0;
97
0
  npixels = 0;
98
0
  while (cc > 0 && npixels < maxpixels) {
99
0
    int n, delta;
100
101
0
    n = *bp++;
102
0
    cc--;
103
0
    switch (n & THUNDER_CODE) {
104
0
    case THUNDER_RUN:   /* pixel run */
105
      /*
106
       * Replicate the last pixel n times,
107
       * where n is the lower-order 6 bits.
108
       */
109
0
      if (npixels & 1) {
110
0
        op[0] |= lastpixel;
111
0
        lastpixel = *op++; npixels++; n--;
112
0
      } else
113
0
        lastpixel |= lastpixel << 4;
114
0
      npixels += n;
115
0
      if (npixels < maxpixels) {
116
0
        for (; n > 0; n -= 2)
117
0
          *op++ = (uint8_t) lastpixel;
118
0
      }
119
0
      if (n == -1)
120
0
        *--op &= 0xf0;
121
0
      lastpixel &= 0xf;
122
0
      break;
123
0
    case THUNDER_2BITDELTAS: /* 2-bit deltas */
124
0
      if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
125
0
        SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
126
0
      if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
127
0
        SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
128
0
      if ((delta = (n & 3)) != DELTA2_SKIP)
129
0
        SETPIXEL(op, (unsigned)((int)lastpixel + twobitdeltas[delta]));
130
0
      break;
131
0
    case THUNDER_3BITDELTAS: /* 3-bit deltas */
132
0
      if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
133
0
        SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
134
0
      if ((delta = (n & 7)) != DELTA3_SKIP)
135
0
        SETPIXEL(op, (unsigned)((int)lastpixel + threebitdeltas[delta]));
136
0
      break;
137
0
    case THUNDER_RAW:   /* raw data */
138
0
      SETPIXEL(op, n);
139
0
      break;
140
0
    }
141
0
  }
142
0
  tif->tif_rawcp = (uint8_t*) bp;
143
0
  tif->tif_rawcc = cc;
144
0
  if (npixels != maxpixels) {
145
0
    TIFFErrorExt(tif->tif_clientdata, module,
146
0
           "%s data at scanline %lu (%"PRIu64" != %"PRIu64")",
147
0
           npixels < maxpixels ? "Not enough" : "Too much",
148
0
           (unsigned long) tif->tif_row,
149
0
           (uint64_t) npixels,
150
0
           (uint64_t) maxpixels);
151
0
    return (0);
152
0
  }
153
154
0
        return (1);
155
0
}
156
157
static int
158
ThunderDecodeRow(TIFF* tif, uint8_t* buf, tmsize_t occ, uint16_t s)
159
0
{
160
0
  static const char module[] = "ThunderDecodeRow";
161
0
  uint8_t* row = buf;
162
  
163
0
  (void) s;
164
0
  if (occ % tif->tif_scanlinesize)
165
0
  {
166
0
    TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
167
0
    return (0);
168
0
  }
169
0
  while (occ > 0) {
170
0
    if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
171
0
      return (0);
172
0
    occ -= tif->tif_scanlinesize;
173
0
    row += tif->tif_scanlinesize;
174
0
  }
175
0
  return (1);
176
0
}
177
178
int
179
TIFFInitThunderScan(TIFF* tif, int scheme)
180
0
{
181
0
  (void) scheme;
182
183
0
        tif->tif_setupdecode = ThunderSetupDecode;
184
0
  tif->tif_decoderow = ThunderDecodeRow;
185
0
  tif->tif_decodestrip = ThunderDecodeRow; 
186
0
  return (1);
187
0
}
188
#endif /* THUNDER_SUPPORT */
189
190
/* vim: set ts=8 sts=8 sw=8 noet: */
191
/*
192
 * Local Variables:
193
 * mode: c
194
 * c-basic-offset: 8
195
 * fill-column: 78
196
 * End:
197
 */