1 | /* $Header: /afs/dev.mit.edu/source/repository/third/tiff/libtiff/tif_thunder.c,v 1.1.1.1 2002-12-26 02:37:36 ghudson 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 | |
---|
27 | #include "tiffiop.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++ & 1) \ |
---|
61 | *op++ |= lastpixel; \ |
---|
62 | else \ |
---|
63 | op[0] = lastpixel << 4; \ |
---|
64 | } |
---|
65 | |
---|
66 | static int |
---|
67 | ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels) |
---|
68 | { |
---|
69 | register u_char *bp; |
---|
70 | register tsize_t cc; |
---|
71 | u_int lastpixel; |
---|
72 | tsize_t npixels; |
---|
73 | |
---|
74 | bp = (u_char *)tif->tif_rawcp; |
---|
75 | cc = tif->tif_rawcc; |
---|
76 | lastpixel = 0; |
---|
77 | npixels = 0; |
---|
78 | while (cc > 0 && npixels < maxpixels) { |
---|
79 | int n, delta; |
---|
80 | |
---|
81 | n = *bp++, cc--; |
---|
82 | switch (n & THUNDER_CODE) { |
---|
83 | case THUNDER_RUN: /* pixel run */ |
---|
84 | /* |
---|
85 | * Replicate the last pixel n times, |
---|
86 | * where n is the lower-order 6 bits. |
---|
87 | */ |
---|
88 | if (npixels & 1) { |
---|
89 | op[0] |= lastpixel; |
---|
90 | lastpixel = *op++; npixels++; n--; |
---|
91 | } else |
---|
92 | lastpixel |= lastpixel << 4; |
---|
93 | npixels += n; |
---|
94 | for (; n > 0; n -= 2) |
---|
95 | *op++ = lastpixel; |
---|
96 | if (n == -1) |
---|
97 | *--op &= 0xf0; |
---|
98 | lastpixel &= 0xf; |
---|
99 | break; |
---|
100 | case THUNDER_2BITDELTAS: /* 2-bit deltas */ |
---|
101 | if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) |
---|
102 | SETPIXEL(op, lastpixel + twobitdeltas[delta]); |
---|
103 | if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) |
---|
104 | SETPIXEL(op, lastpixel + twobitdeltas[delta]); |
---|
105 | if ((delta = (n & 3)) != DELTA2_SKIP) |
---|
106 | SETPIXEL(op, lastpixel + twobitdeltas[delta]); |
---|
107 | break; |
---|
108 | case THUNDER_3BITDELTAS: /* 3-bit deltas */ |
---|
109 | if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) |
---|
110 | SETPIXEL(op, lastpixel + threebitdeltas[delta]); |
---|
111 | if ((delta = (n & 7)) != DELTA3_SKIP) |
---|
112 | SETPIXEL(op, lastpixel + threebitdeltas[delta]); |
---|
113 | break; |
---|
114 | case THUNDER_RAW: /* raw data */ |
---|
115 | SETPIXEL(op, n); |
---|
116 | break; |
---|
117 | } |
---|
118 | } |
---|
119 | tif->tif_rawcp = (tidata_t) bp; |
---|
120 | tif->tif_rawcc = cc; |
---|
121 | if (npixels != maxpixels) { |
---|
122 | TIFFError(tif->tif_name, |
---|
123 | "ThunderDecode: %s data at scanline %ld (%lu != %lu)", |
---|
124 | npixels < maxpixels ? "Not enough" : "Too much", |
---|
125 | (long) tif->tif_row, (long) npixels, (long) maxpixels); |
---|
126 | return (0); |
---|
127 | } |
---|
128 | return (1); |
---|
129 | } |
---|
130 | |
---|
131 | static int |
---|
132 | ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) |
---|
133 | { |
---|
134 | tidata_t row = buf; |
---|
135 | |
---|
136 | (void) s; |
---|
137 | while ((long)occ > 0) { |
---|
138 | if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) |
---|
139 | return (0); |
---|
140 | occ -= tif->tif_scanlinesize; |
---|
141 | row += tif->tif_scanlinesize; |
---|
142 | } |
---|
143 | return (1); |
---|
144 | } |
---|
145 | |
---|
146 | int |
---|
147 | TIFFInitThunderScan(TIFF* tif, int scheme) |
---|
148 | { |
---|
149 | (void) scheme; |
---|
150 | tif->tif_decoderow = ThunderDecodeRow; |
---|
151 | tif->tif_decodestrip = ThunderDecodeRow; |
---|
152 | return (1); |
---|
153 | } |
---|
154 | #endif /* THUNDER_SUPPORT */ |
---|