1 /*
2 * SGI image decoder
3 * Todd Kirby <doubleshot@pacbell.net>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
28
38
39 /**
40 * Expand an RLE row into a channel.
41 * @param s the current image state
42 * @param out_buf Points to one line after the output buffer.
43 * @param len length of out_buf in bytes
44 * @param pixelstride pixel stride of input buffer
45 * @return size of output in bytes, else return error code.
46 */
48 int len,
int pixelstride)
49 {
51 unsigned char *orig = out_buf;
53
54 while (out_buf < out_end) {
57 pixel = bytestream2_get_byteu(&s->
g);
58 if (!(count = (pixel & 0x7f))) {
59 break;
60 }
61
62 /* Check for buffer overflow. */
63 if (out_end - out_buf <= pixelstride * (count - 1)) {
66 }
67
68 if (pixel & 0x80) {
69 while (count--) {
70 *out_buf = bytestream2_get_byte(&s->
g);
71 out_buf += pixelstride;
72 }
73 } else {
74 pixel = bytestream2_get_byte(&s->
g);
75
76 while (count--) {
78 out_buf += pixelstride;
79 }
80 }
81 }
82 return (out_buf - orig) / pixelstride;
83 }
84
86 int len,
int pixelstride)
87 {
90 unsigned short *orig = out_buf;
91 uint16_t *out_end = out_buf +
len;
92
93 while (out_buf < out_end) {
96 pixel = bytestream2_get_be16u(&s->
g);
97 if (!(count = (pixel & 0x7f)))
98 break;
99
100 /* Check for buffer overflow. */
101 if (out_end - out_buf <= pixelstride * (count - 1)) {
104 }
105
106 if (pixel & 0x80) {
107 while (count--) {
110 out_buf += pixelstride;
111 }
112 } else {
114
115 while (count--) {
117 out_buf += pixelstride;
118 }
119 }
120 }
121 return (out_buf - orig) / pixelstride;
122 }
123
124
125 /**
126 * Read a run length encoded SGI image.
127 * @param out_buf output buffer
128 * @param s the current image state
129 * @return 0 if no error, else return error code.
130 */
132 {
137 unsigned int start_offset;
139
140 /* size of RLE offset and length tables */
143 }
144
145 for (z = 0; z < s->
depth; z++) {
146 dest_row = out_buf;
147 for (y = 0; y < s->
height; y++) {
150 start_offset = bytestream2_get_be32(&g_table);
154 else
158 }
159 }
160 return 0;
161 }
162
163 /**
164 * Read an uncompressed SGI image.
165 * @param out_buf output buffer
166 * @param s the current image state
167 * @return 0 if read success, else return error code.
168 */
170 {
175
176 /* Test buffer size. */
179
180 /* Create a reader for each plane */
181 for (z = 0; z < s->
depth; z++) {
184 }
185
186 for (y = s->
height - 1; y >= 0; y--) {
187 out_end = out_buf + (y * s->
linesize);
189 for (x = s->
width; x > 0; x--)
190 for (z = 0; z < s->
depth; z++)
191 *out_end++ = bytestream2_get_byteu(&gp[z]);
192 } else {
193 uint16_t *out16 = (uint16_t *)out_end;
194 for (x = s->
width; x > 0; x--)
195 for (z = 0; z < s->
depth; z++)
197 }
198 }
199 return 0;
200 }
201
203 void *
data,
int *got_frame,
205 {
208 unsigned int dimension, rle;
211
216 }
217
218 /* Test for SGI magic. */
219 if (bytestream2_get_be16u(&s->
g) !=
SGI_MAGIC) {
222 }
223
224 rle = bytestream2_get_byteu(&s->
g);
226 dimension = bytestream2_get_be16u(&s->
g);
227 s->
width = bytestream2_get_be16u(&s->
g);
228 s->
height = bytestream2_get_be16u(&s->
g);
229 s->
depth = bytestream2_get_be16u(&s->
g);
230
234 }
235
236 /* Check for supported image dimensions. */
237 if (dimension != 2 && dimension != 3) {
240 }
241
248 } else {
251 }
252
254 if (ret < 0)
256
259
262 out_buf = p->
data[0];
263
265
267
268 /* Skip header. */
270 if (rle) {
272 } else {
274 }
275 if (ret)
277
278 *got_frame = 1;
280 }
281
283 {
285
287
288 return 0;
289 }
290
300 };