PageRenderTime 56ms CodeModel.GetById 43ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/src/FreeImage/Source/LibTIFF/tif_thunder.c

https://bitbucket.org/cabalistic/ogredeps/
C | 189 lines | 119 code | 18 blank | 52 comment | 27 complexity | 2dc1cc1f0fb4ff2d11d330dd5b302b8d MD5 | raw file
  1/* $Id: tif_thunder.c,v 1.37 2011/04/10 17:14:09 drolon 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#include <assert.h>
 29#ifdef THUNDER_SUPPORT
 30/*
 31 * TIFF Library.
 32 *
 33 * ThunderScan 4-bit Compression Algorithm Support
 34 */
 35
 36/*
 37 * ThunderScan uses an encoding scheme designed for
 38 * 4-bit pixel values.  Data is encoded in bytes, with
 39 * each byte split into a 2-bit code word and a 6-bit
 40 * data value.  The encoding gives raw data, runs of
 41 * pixels, or pixel values encoded as a delta from the
 42 * previous pixel value.  For the latter, either 2-bit
 43 * or 3-bit delta values are used, with the deltas packed
 44 * into a single byte.
 45 */
 46#define	THUNDER_DATA		0x3f	/* mask for 6-bit data */
 47#define	THUNDER_CODE		0xc0	/* mask for 2-bit code word */
 48/* code values */
 49#define	THUNDER_RUN		0x00	/* run of pixels w/ encoded count */
 50#define	THUNDER_2BITDELTAS	0x40	/* 3 pixels w/ encoded 2-bit deltas */
 51#define	    DELTA2_SKIP		2	/* skip code for 2-bit deltas */
 52#define	THUNDER_3BITDELTAS	0x80	/* 2 pixels w/ encoded 3-bit deltas */
 53#define	    DELTA3_SKIP		4	/* skip code for 3-bit deltas */
 54#define	THUNDER_RAW		0xc0	/* raw data encoded */
 55
 56static const int twobitdeltas[4] = { 0, 1, 0, -1 };
 57static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
 58
 59#define	SETPIXEL(op, v) {                     \
 60	lastpixel = (v) & 0xf;                \
 61        if ( npixels < maxpixels )         \
 62        {                                     \
 63	  if (npixels++ & 1)                  \
 64	    *op++ |= lastpixel;               \
 65	  else                                \
 66	    op[0] = (tidataval_t) (lastpixel << 4); \
 67        }                                     \
 68}
 69
 70static int
 71ThunderSetupDecode(TIFF* tif)
 72{
 73	static const char module[] = "ThunderSetupDecode";
 74
 75        if( tif->tif_dir.td_bitspersample != 4 )
 76        {
 77                TIFFErrorExt(tif->tif_clientdata, module,
 78                             "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.",
 79                             (int) tif->tif_dir.td_bitspersample );
 80                return 0;
 81        }
 82        
 83
 84	return (1);
 85}
 86
 87static int
 88ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels)
 89{
 90	register unsigned char *bp;
 91	register tsize_t cc;
 92	unsigned int lastpixel;
 93	tsize_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++ = (tidataval_t) 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 = (tidata_t) bp;
143	tif->tif_rawcc = cc;
144	if (npixels != maxpixels) {
145		TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
146		    "ThunderDecode: %s data at scanline %ld (%lu != %lu)",
147		    npixels < maxpixels ? "Not enough" : "Too much",
148		    (long) tif->tif_row, (long) npixels, (long) maxpixels);
149		return (0);
150	}
151	return (1);
152}
153
154static int
155ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
156{
157	tidata_t row = buf;
158	
159	(void) s;
160	while ((long)occ > 0) {
161		if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
162			return (0);
163		occ -= tif->tif_scanlinesize;
164		row += tif->tif_scanlinesize;
165	}
166
167        return (1);
168}
169
170int
171TIFFInitThunderScan(TIFF* tif, int scheme)
172{
173	(void) scheme;
174	tif->tif_decoderow = ThunderDecodeRow;
175	tif->tif_decodestrip = ThunderDecodeRow;
176        tif->tif_setupdecode = ThunderSetupDecode;
177	return (1);
178}
179#endif /* THUNDER_SUPPORT */
180
181/* vim: set ts=8 sts=8 sw=8 noet: */
182/*
183 * Local Variables:
184 * mode: c
185 * c-basic-offset: 8
186 * fill-column: 78
187 * End:
188 */
189