1 : /* $Id: tif_next.c,v 1.13 2010-03-10 18:56:48 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 NEXT_SUPPORT
29 : /*
30 : * TIFF Library.
31 : *
32 : * NeXT 2-bit Grey Scale Compression Algorithm Support
33 : */
34 :
35 : #define SETPIXEL(op, v) { \
36 : switch (npixels++ & 3) { \
37 : case 0: op[0] = (unsigned char) ((v) << 6); break; \
38 : case 1: op[0] |= (v) << 4; break; \
39 : case 2: op[0] |= (v) << 2; break; \
40 : case 3: *op++ |= (v); break; \
41 : } \
42 : }
43 :
44 : #define LITERALROW 0x00
45 : #define LITERALSPAN 0x40
46 : #define WHITE ((1<<2)-1)
47 :
48 : static int
49 : NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
50 0 : {
51 : static const char module[] = "NeXTDecode";
52 : unsigned char *bp, *op;
53 : tmsize_t cc;
54 : uint8* row;
55 : tmsize_t scanline, n;
56 :
57 : (void) s;
58 : /*
59 : * Each scanline is assumed to start off as all
60 : * white (we assume a PhotometricInterpretation
61 : * of ``min-is-black'').
62 : */
63 0 : for (op = (unsigned char*) buf, cc = occ; cc-- > 0;)
64 0 : *op++ = 0xff;
65 :
66 0 : bp = (unsigned char *)tif->tif_rawcp;
67 0 : cc = tif->tif_rawcc;
68 0 : scanline = tif->tif_scanlinesize;
69 0 : if (occ % scanline)
70 : {
71 0 : TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
72 0 : return (0);
73 : }
74 0 : for (row = buf; occ > 0; occ -= scanline, row += scanline) {
75 0 : n = *bp++, cc--;
76 0 : switch (n) {
77 : case LITERALROW:
78 : /*
79 : * The entire scanline is given as literal values.
80 : */
81 0 : if (cc < scanline)
82 0 : goto bad;
83 0 : _TIFFmemcpy(row, bp, scanline);
84 0 : bp += scanline;
85 0 : cc -= scanline;
86 0 : break;
87 : case LITERALSPAN: {
88 : tmsize_t off;
89 : /*
90 : * The scanline has a literal span that begins at some
91 : * offset.
92 : */
93 0 : off = (bp[0] * 256) + bp[1];
94 0 : n = (bp[2] * 256) + bp[3];
95 0 : if (cc < 4+n || off+n > scanline)
96 : goto bad;
97 0 : _TIFFmemcpy(row+off, bp+4, n);
98 0 : bp += 4+n;
99 0 : cc -= 4+n;
100 0 : break;
101 : }
102 : default: {
103 0 : uint32 npixels = 0, grey;
104 0 : uint32 imagewidth = tif->tif_dir.td_imagewidth;
105 :
106 : /*
107 : * The scanline is composed of a sequence of constant
108 : * color ``runs''. We shift into ``run mode'' and
109 : * interpret bytes as codes of the form
110 : * <color><npixels> until we've filled the scanline.
111 : */
112 0 : op = row;
113 : for (;;) {
114 0 : grey = (uint32)((n>>6) & 0x3);
115 0 : n &= 0x3f;
116 : /*
117 : * Ensure the run does not exceed the scanline
118 : * bounds, potentially resulting in a security
119 : * issue.
120 : */
121 0 : while (n-- > 0 && npixels < imagewidth)
122 0 : SETPIXEL(op, grey);
123 0 : if (npixels >= imagewidth)
124 0 : break;
125 0 : if (cc == 0)
126 0 : goto bad;
127 0 : n = *bp++, cc--;
128 0 : }
129 : break;
130 : }
131 : }
132 : }
133 0 : tif->tif_rawcp = (uint8*) bp;
134 0 : tif->tif_rawcc = cc;
135 0 : return (1);
136 0 : bad:
137 0 : TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld",
138 : (long) tif->tif_row);
139 0 : return (0);
140 : }
141 :
142 : int
143 : TIFFInitNeXT(TIFF* tif, int scheme)
144 0 : {
145 : (void) scheme;
146 0 : tif->tif_decoderow = NeXTDecode;
147 0 : tif->tif_decodestrip = NeXTDecode;
148 0 : tif->tif_decodetile = NeXTDecode;
149 0 : return (1);
150 : }
151 : #endif /* NEXT_SUPPORT */
152 :
153 : /* vim: set ts=8 sts=8 sw=8 noet: */
154 : /*
155 : * Local Variables:
156 : * mode: c
157 : * c-basic-offset: 8
158 : * fill-column: 78
159 : * End:
160 : */
|