1/* $Id: tif_thunder.c,v 1.5.2.1 2010-06-08 18:50:43 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 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 55static const int twobitdeltas[4] = { 0, 1, 0, -1 }; 56static 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] = (tidataval_t) (lastpixel << 4); \ 64} 65 66static int 67ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels) 68{ 69 register unsigned char *bp; 70 register tsize_t cc; 71 unsigned int lastpixel; 72 tsize_t npixels; 73 74 bp = (unsigned 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 if (npixels < maxpixels) { 95 for (; n > 0; n -= 2) 96 *op++ = (tidataval_t) lastpixel; 97 } 98 if (n == -1) 99 *--op &= 0xf0; 100 lastpixel &= 0xf; 101 break; 102 case THUNDER_2BITDELTAS: /* 2-bit deltas */ 103 if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP) 104 SETPIXEL(op, lastpixel + twobitdeltas[delta]); 105 if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP) 106 SETPIXEL(op, lastpixel + twobitdeltas[delta]); 107 if ((delta = (n & 3)) != DELTA2_SKIP) 108 SETPIXEL(op, lastpixel + twobitdeltas[delta]); 109 break; 110 case THUNDER_3BITDELTAS: /* 3-bit deltas */ 111 if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP) 112 SETPIXEL(op, lastpixel + threebitdeltas[delta]); 113 if ((delta = (n & 7)) != DELTA3_SKIP) 114 SETPIXEL(op, lastpixel + threebitdeltas[delta]); 115 break; 116 case THUNDER_RAW: /* raw data */ 117 SETPIXEL(op, n); 118 break; 119 } 120 } 121 tif->tif_rawcp = (tidata_t) bp; 122 tif->tif_rawcc = cc; 123 if (npixels != maxpixels) { 124 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 125 "ThunderDecode: %s data at scanline %ld (%lu != %lu)", 126 npixels < maxpixels ? "Not enough" : "Too much", 127 (long) tif->tif_row, (long) npixels, (long) maxpixels); 128 return (0); 129 } 130 return (1); 131} 132 133static int 134ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s) 135{ 136 tidata_t row = buf; 137 138 (void) s; 139 while ((long)occ > 0) { 140 if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth)) 141 return (0); 142 occ -= tif->tif_scanlinesize; 143 row += tif->tif_scanlinesize; 144 } 145 return (1); 146} 147 148int 149TIFFInitThunderScan(TIFF* tif, int scheme) 150{ 151 (void) scheme; 152 tif->tif_decoderow = ThunderDecodeRow; 153 tif->tif_decodestrip = ThunderDecodeRow; 154 return (1); 155} 156#endif /* THUNDER_SUPPORT */ 157 158/* vim: set ts=8 sts=8 sw=8 noet: */ 159/* 160 * Local Variables: 161 * mode: c 162 * c-basic-offset: 8 163 * fill-column: 78 164 * End: 165 */ 166