/src/opencv/3rdparty/libtiff/tif_next.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 1988-1997 Sam Leffler |
3 | | * Copyright (c) 1991-1997 Silicon Graphics, Inc. |
4 | | * |
5 | | * Permission to use, copy, modify, distribute, and sell this software and |
6 | | * its documentation for any purpose is hereby granted without fee, provided |
7 | | * that (i) the above copyright notices and this permission notice appear in |
8 | | * all copies of the software and related documentation, and (ii) the names of |
9 | | * Sam Leffler and Silicon Graphics may not be used in any advertising or |
10 | | * publicity relating to the software without the specific, prior written |
11 | | * permission of Sam Leffler and Silicon Graphics. |
12 | | * |
13 | | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, |
14 | | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY |
15 | | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. |
16 | | * |
17 | | * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR |
18 | | * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, |
19 | | * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, |
20 | | * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF |
21 | | * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
22 | | * OF THIS SOFTWARE. |
23 | | */ |
24 | | |
25 | | #include "tiffiop.h" |
26 | | #ifdef NEXT_SUPPORT |
27 | | /* |
28 | | * TIFF Library. |
29 | | * |
30 | | * NeXT 2-bit Grey Scale Compression Algorithm Support |
31 | | */ |
32 | | |
33 | 0 | #define SETPIXEL(op, v) { \ |
34 | 0 | switch (npixels++ & 3) { \ |
35 | 0 | case 0: op[0] = (unsigned char) ((v) << 6); break; \ |
36 | 0 | case 1: op[0] |= (v) << 4; break; \ |
37 | 0 | case 2: op[0] |= (v) << 2; break; \ |
38 | 0 | case 3: *op++ |= (v); op_offset++; break; \ |
39 | 0 | } \ |
40 | 0 | } |
41 | | |
42 | 0 | #define LITERALROW 0x00 |
43 | 0 | #define LITERALSPAN 0x40 |
44 | | #define WHITE ((1<<2)-1) |
45 | | |
46 | | static int |
47 | | NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s) |
48 | 0 | { |
49 | 0 | static const char module[] = "NeXTDecode"; |
50 | 0 | unsigned char *bp, *op; |
51 | 0 | tmsize_t cc; |
52 | 0 | uint8* row; |
53 | 0 | tmsize_t scanline, n; |
54 | |
|
55 | 0 | (void) s; |
56 | | /* |
57 | | * Each scanline is assumed to start off as all |
58 | | * white (we assume a PhotometricInterpretation |
59 | | * of ``min-is-black''). |
60 | | */ |
61 | 0 | for (op = (unsigned char*) buf, cc = occ; cc-- > 0;) |
62 | 0 | *op++ = 0xff; |
63 | |
|
64 | 0 | bp = (unsigned char *)tif->tif_rawcp; |
65 | 0 | cc = tif->tif_rawcc; |
66 | 0 | scanline = tif->tif_scanlinesize; |
67 | 0 | if (occ % scanline) |
68 | 0 | { |
69 | 0 | TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read"); |
70 | 0 | return (0); |
71 | 0 | } |
72 | 0 | for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) { |
73 | 0 | n = *bp++; |
74 | 0 | cc--; |
75 | 0 | switch (n) { |
76 | 0 | case LITERALROW: |
77 | | /* |
78 | | * The entire scanline is given as literal values. |
79 | | */ |
80 | 0 | if (cc < scanline) |
81 | 0 | goto bad; |
82 | 0 | _TIFFmemcpy(row, bp, scanline); |
83 | 0 | bp += scanline; |
84 | 0 | cc -= scanline; |
85 | 0 | break; |
86 | 0 | case LITERALSPAN: { |
87 | 0 | tmsize_t off; |
88 | | /* |
89 | | * The scanline has a literal span that begins at some |
90 | | * offset. |
91 | | */ |
92 | 0 | if( cc < 4 ) |
93 | 0 | goto bad; |
94 | 0 | off = (bp[0] * 256) + bp[1]; |
95 | 0 | n = (bp[2] * 256) + bp[3]; |
96 | 0 | if (cc < 4+n || off+n > scanline) |
97 | 0 | goto bad; |
98 | 0 | _TIFFmemcpy(row+off, bp+4, n); |
99 | 0 | bp += 4+n; |
100 | 0 | cc -= 4+n; |
101 | 0 | break; |
102 | 0 | } |
103 | 0 | default: { |
104 | 0 | uint32 npixels = 0, grey; |
105 | 0 | tmsize_t op_offset = 0; |
106 | 0 | uint32 imagewidth = tif->tif_dir.td_imagewidth; |
107 | 0 | if( isTiled(tif) ) |
108 | 0 | imagewidth = tif->tif_dir.td_tilewidth; |
109 | | |
110 | | /* |
111 | | * The scanline is composed of a sequence of constant |
112 | | * color ``runs''. We shift into ``run mode'' and |
113 | | * interpret bytes as codes of the form |
114 | | * <color><npixels> until we've filled the scanline. |
115 | | */ |
116 | 0 | op = row; |
117 | 0 | for (;;) { |
118 | 0 | grey = (uint32)((n>>6) & 0x3); |
119 | 0 | n &= 0x3f; |
120 | | /* |
121 | | * Ensure the run does not exceed the scanline |
122 | | * bounds, potentially resulting in a security |
123 | | * issue. |
124 | | */ |
125 | 0 | while (n-- > 0 && npixels < imagewidth && op_offset < scanline) |
126 | 0 | SETPIXEL(op, grey); |
127 | 0 | if (npixels >= imagewidth) |
128 | 0 | break; |
129 | 0 | if (op_offset >= scanline ) { |
130 | 0 | TIFFErrorExt(tif->tif_clientdata, module, "Invalid data for scanline %ld", |
131 | 0 | (long) tif->tif_row); |
132 | 0 | return (0); |
133 | 0 | } |
134 | 0 | if (cc == 0) |
135 | 0 | goto bad; |
136 | 0 | n = *bp++; |
137 | 0 | cc--; |
138 | 0 | } |
139 | 0 | break; |
140 | 0 | } |
141 | 0 | } |
142 | 0 | } |
143 | 0 | tif->tif_rawcp = (uint8*) bp; |
144 | 0 | tif->tif_rawcc = cc; |
145 | 0 | return (1); |
146 | 0 | bad: |
147 | 0 | TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld", |
148 | 0 | (long) tif->tif_row); |
149 | 0 | return (0); |
150 | 0 | } |
151 | | |
152 | | static int |
153 | | NeXTPreDecode(TIFF* tif, uint16 s) |
154 | 1 | { |
155 | 1 | static const char module[] = "NeXTPreDecode"; |
156 | 1 | TIFFDirectory *td = &tif->tif_dir; |
157 | 1 | (void)s; |
158 | | |
159 | 1 | if( td->td_bitspersample != 2 ) |
160 | 1 | { |
161 | 1 | TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d", |
162 | 1 | td->td_bitspersample); |
163 | 1 | return (0); |
164 | 1 | } |
165 | 0 | return (1); |
166 | 1 | } |
167 | | |
168 | | int |
169 | | TIFFInitNeXT(TIFF* tif, int scheme) |
170 | 1 | { |
171 | 1 | (void) scheme; |
172 | 1 | tif->tif_predecode = NeXTPreDecode; |
173 | 1 | tif->tif_decoderow = NeXTDecode; |
174 | 1 | tif->tif_decodestrip = NeXTDecode; |
175 | 1 | tif->tif_decodetile = NeXTDecode; |
176 | 1 | return (1); |
177 | 1 | } |
178 | | #endif /* NEXT_SUPPORT */ |
179 | | |
180 | | /* vim: set ts=8 sts=8 sw=8 noet: */ |
181 | | /* |
182 | | * Local Variables: |
183 | | * mode: c |
184 | | * c-basic-offset: 8 |
185 | | * fill-column: 78 |
186 | | * End: |
187 | | */ |