Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/tiff/libtiff/tif_next.c
4391 views
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
#define SETPIXEL(op, v) \
34
{ \
35
switch (npixels++ & 3) \
36
{ \
37
case 0: \
38
op[0] = (unsigned char)((v) << 6); \
39
break; \
40
case 1: \
41
op[0] |= (v) << 4; \
42
break; \
43
case 2: \
44
op[0] |= (v) << 2; \
45
break; \
46
case 3: \
47
*op++ |= (v); \
48
op_offset++; \
49
break; \
50
} \
51
}
52
53
#define LITERALROW 0x00
54
#define LITERALSPAN 0x40
55
#define WHITE ((1 << 2) - 1)
56
57
static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
58
{
59
static const char module[] = "NeXTDecode";
60
unsigned char *bp, *op;
61
tmsize_t cc;
62
uint8_t *row;
63
tmsize_t scanline, n;
64
65
(void)s;
66
/*
67
* Each scanline is assumed to start off as all
68
* white (we assume a PhotometricInterpretation
69
* of ``min-is-black'').
70
*/
71
for (op = (unsigned char *)buf, cc = occ; cc-- > 0;)
72
*op++ = 0xff;
73
74
bp = (unsigned char *)tif->tif_rawcp;
75
cc = tif->tif_rawcc;
76
scanline = tif->tif_scanlinesize;
77
if (occ % scanline)
78
{
79
TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
80
return (0);
81
}
82
for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)
83
{
84
n = *bp++;
85
cc--;
86
switch (n)
87
{
88
case LITERALROW:
89
/*
90
* The entire scanline is given as literal values.
91
*/
92
if (cc < scanline)
93
goto bad;
94
_TIFFmemcpy(row, bp, scanline);
95
bp += scanline;
96
cc -= scanline;
97
break;
98
case LITERALSPAN:
99
{
100
tmsize_t off;
101
/*
102
* The scanline has a literal span that begins at some
103
* offset.
104
*/
105
if (cc < 4)
106
goto bad;
107
off = (bp[0] * 256) + bp[1];
108
n = (bp[2] * 256) + bp[3];
109
if (cc < 4 + n || off + n > scanline)
110
goto bad;
111
_TIFFmemcpy(row + off, bp + 4, n);
112
bp += 4 + n;
113
cc -= 4 + n;
114
break;
115
}
116
default:
117
{
118
uint32_t npixels = 0, grey;
119
tmsize_t op_offset = 0;
120
uint32_t imagewidth = tif->tif_dir.td_imagewidth;
121
if (isTiled(tif))
122
imagewidth = tif->tif_dir.td_tilewidth;
123
124
/*
125
* The scanline is composed of a sequence of constant
126
* color ``runs''. We shift into ``run mode'' and
127
* interpret bytes as codes of the form
128
* <color><npixels> until we've filled the scanline.
129
*/
130
op = row;
131
for (;;)
132
{
133
grey = (uint32_t)((n >> 6) & 0x3);
134
n &= 0x3f;
135
/*
136
* Ensure the run does not exceed the scanline
137
* bounds, potentially resulting in a security
138
* issue.
139
*/
140
while (n-- > 0 && npixels < imagewidth &&
141
op_offset < scanline)
142
SETPIXEL(op, grey);
143
if (npixels >= imagewidth)
144
break;
145
if (op_offset >= scanline)
146
{
147
TIFFErrorExtR(tif, module,
148
"Invalid data for scanline %" PRIu32,
149
tif->tif_row);
150
return (0);
151
}
152
if (cc == 0)
153
goto bad;
154
n = *bp++;
155
cc--;
156
}
157
break;
158
}
159
}
160
}
161
tif->tif_rawcp = (uint8_t *)bp;
162
tif->tif_rawcc = cc;
163
return (1);
164
bad:
165
TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
166
tif->tif_row);
167
return (0);
168
}
169
170
static int NeXTPreDecode(TIFF *tif, uint16_t s)
171
{
172
static const char module[] = "NeXTPreDecode";
173
TIFFDirectory *td = &tif->tif_dir;
174
(void)s;
175
176
if (td->td_bitspersample != 2)
177
{
178
TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,
179
td->td_bitspersample);
180
return (0);
181
}
182
return (1);
183
}
184
185
int TIFFInitNeXT(TIFF *tif, int scheme)
186
{
187
(void)scheme;
188
tif->tif_predecode = NeXTPreDecode;
189
tif->tif_decoderow = NeXTDecode;
190
tif->tif_decodestrip = NeXTDecode;
191
tif->tif_decodetile = NeXTDecode;
192
return (1);
193
}
194
#endif /* NEXT_SUPPORT */
195
196