OLD | NEW |
| (Empty) |
1 /* $Id: tif_thunder.c,v 1.12 2011-04-02 20:54:09 bfriesen Exp $ */ | |
2 | |
3 /* | |
4 * Copyright (c) 1988-1997 Sam Leffler | |
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc. | |
6 * | |
7 * Permission to use, copy, modify, distribute, and sell this software and | |
8 * its documentation for any purpose is hereby granted without fee, provided | |
9 * that (i) the above copyright notices and this permission notice appear in | |
10 * all copies of the software and related documentation, and (ii) the names of | |
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or | |
12 * publicity relating to the software without the specific, prior written | |
13 * permission of Sam Leffler and Silicon Graphics. | |
14 * | |
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
18 * | |
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
24 * OF THIS SOFTWARE. | |
25 */ | |
26 #include "tiffiop.h" | |
27 #include <assert.h> | |
28 #ifdef THUNDER_SUPPORT | |
29 /* | |
30 * TIFF Library. | |
31 * | |
32 * ThunderScan 4-bit Compression Algorithm Support | |
33 */ | |
34 | |
35 /* | |
36 * ThunderScan uses an encoding scheme designed for | |
37 * 4-bit pixel values. Data is encoded in bytes, with | |
38 * each byte split into a 2-bit code word and a 6-bit | |
39 * data value. The encoding gives raw data, runs of | |
40 * pixels, or pixel values encoded as a delta from the | |
41 * previous pixel value. For the latter, either 2-bit | |
42 * or 3-bit delta values are used, with the deltas packed | |
43 * into a single byte. | |
44 */ | |
45 #define THUNDER_DATA 0x3f /* mask for 6-bit data */ | |
46 #define THUNDER_CODE 0xc0 /* mask for 2-bit code word */ | |
47 /* code values */ | |
48 #define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */ | |
49 #define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */ | |
50 #define DELTA2_SKIP 2 /* skip code for 2-bit deltas */ | |
51 #define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */ | |
52 #define DELTA3_SKIP 4 /* skip code for 3-bit deltas */ | |
53 #define THUNDER_RAW 0xc0 /* raw data encoded */ | |
54 | |
55 static const int twobitdeltas[4] = { 0, 1, 0, -1 }; | |
56 static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 }; | |
57 | |
58 #define SETPIXEL(op, v) { \ | |
59 lastpixel = (v) & 0xf; \ | |
60 if ( npixels < maxpixels ) \ | |
61 { \ | |
62 if (npixels++ & 1) \ | |
63 *op++ |= lastpixel; \ | |
64 else \ | |
65 op[0] = (uint8) (lastpixel << 4); \ | |
66 } \ | |
67 } | |
68 | |
69 static int | |
70 ThunderSetupDecode(TIFF* tif) | |
71 { | |
72 static const char module[] = "ThunderSetupDecode"; | |
73 | |
74 if( tif->tif_dir.td_bitspersample != 4 ) | |
75 { | |
76 TIFFErrorExt(tif->tif_clientdata, module, | |
77 "Wrong bitspersample value (%d), Thunder decoder on
ly supports 4bits per sample.", | |
78 (int) tif->tif_dir.td_bitspersample ); | |
79 return 0; | |
80 } | |
81 | |
82 | |
83 return (1); | |
84 } | |
85 | |
86 static int | |
87 ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels) | |
88 { | |
89 static const char module[] = "ThunderDecode"; | |
90 register unsigned char *bp; | |
91 register tmsize_t cc; | |
92 unsigned int lastpixel; | |
93 tmsize_t npixels; | |
94 | |
95 bp = (unsigned char *)tif->tif_rawcp; | |
96 cc = tif->tif_rawcc; | |
97 lastpixel = 0; | |
98 npixels = 0; | |
99 while (cc > 0 && npixels < maxpixels) { | |
100 int n, delta; | |
101 | |
102 n = *bp++, cc--; | |
103 switch (n & THUNDER_CODE) { | |
104 case THUNDER_RUN: /* pixel run */ | |
105 /* | |
106 * Replicate the last pixel n times, | |
107 * where n is the lower-order 6 bits. | |
108 */ | |
109 if (npixels & 1) { | |
110 op[0] |= lastpixel; | |
111 lastpixel = *op++; npixels++; n--; | |
112 } else | |
113 lastpixel |= lastpixel << 4; | |
114 npixels += n; | |
115 if (npixels < maxpixels) { | |
116 for (; n > 0; n -= 2) | |
117 *op++ = (uint8) lastpixel; | |
118 } | |
119 if (n == -1) | |
120 *--op &= 0xf0; | |
121 lastpixel &= 0xf; | |
122 break; | |
123 case THUNDER_2BITDELTAS: /* 2-bit deltas */ | |
124 if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) | |
125 SETPIXEL(op, lastpixel + twobitdeltas[delta]); | |
126 if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) | |
127 SETPIXEL(op, lastpixel + twobitdeltas[delta]); | |
128 if ((delta = (n & 3)) != DELTA2_SKIP) | |
129 SETPIXEL(op, lastpixel + twobitdeltas[delta]); | |
130 break; | |
131 case THUNDER_3BITDELTAS: /* 3-bit deltas */ | |
132 if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) | |
133 SETPIXEL(op, lastpixel + threebitdeltas[delta]); | |
134 if ((delta = (n & 7)) != DELTA3_SKIP) | |
135 SETPIXEL(op, lastpixel + threebitdeltas[delta]); | |
136 break; | |
137 case THUNDER_RAW: /* raw data */ | |
138 SETPIXEL(op, n); | |
139 break; | |
140 } | |
141 } | |
142 tif->tif_rawcp = (uint8*) bp; | |
143 tif->tif_rawcc = cc; | |
144 if (npixels != maxpixels) { | |
145 #if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__)) | |
146 TIFFErrorExt(tif->tif_clientdata, module, | |
147 "%s data at scanline %lu (%I64u != %I64u)", | |
148 npixels < maxpixels ? "Not enough" : "Too much", | |
149 (unsigned long) tif->tif_row, | |
150 (unsigned __int64) npixels, | |
151 (unsigned __int64) maxpixels); | |
152 #else | |
153 TIFFErrorExt(tif->tif_clientdata, module, | |
154 "%s data at scanline %lu (%llu != %llu)", | |
155 npixels < maxpixels ? "Not enough" : "Too much", | |
156 (unsigned long) tif->tif_row, | |
157 (unsigned long long) npixels, | |
158 (unsigned long long) maxpixels); | |
159 #endif | |
160 return (0); | |
161 } | |
162 | |
163 return (1); | |
164 } | |
165 | |
166 static int | |
167 ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) | |
168 { | |
169 static const char module[] = "ThunderDecodeRow"; | |
170 uint8* row = buf; | |
171 | |
172 (void) s; | |
173 if (occ % tif->tif_scanlinesize) | |
174 { | |
175 TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines
cannot be read"); | |
176 return (0); | |
177 } | |
178 while (occ > 0) { | |
179 if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) | |
180 return (0); | |
181 occ -= tif->tif_scanlinesize; | |
182 row += tif->tif_scanlinesize; | |
183 } | |
184 return (1); | |
185 } | |
186 | |
187 int | |
188 TIFFInitThunderScan(TIFF* tif, int scheme) | |
189 { | |
190 (void) scheme; | |
191 | |
192 tif->tif_setupdecode = ThunderSetupDecode; | |
193 tif->tif_decoderow = ThunderDecodeRow; | |
194 tif->tif_decodestrip = ThunderDecodeRow; | |
195 return (1); | |
196 } | |
197 #endif /* THUNDER_SUPPORT */ | |
198 | |
199 /* vim: set ts=8 sts=8 sw=8 noet: */ | |
200 /* | |
201 * Local Variables: | |
202 * mode: c | |
203 * c-basic-offset: 8 | |
204 * fill-column: 78 | |
205 * End: | |
206 */ | |
207 | |
208 | |
OLD | NEW |