source: trunk/third/tiff/libtiff/tif_thunder.c @ 18174

Revision 18174, 4.7 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18173, which included commits to RCS files with non-trunk default branches.
Line 
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
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] = lastpixel << 4; \
64}
65
66static int
67ThunderDecode(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
131static int
132ThunderDecodeRow(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
146int
147TIFFInitThunderScan(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 */
Note: See TracBrowser for help on using the repository browser.