| 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 |