yading@10
|
1 /*
|
yading@10
|
2 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
|
yading@10
|
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
|
yading@10
|
4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
|
yading@10
|
5 *
|
yading@10
|
6 * This file is part of FFmpeg.
|
yading@10
|
7 *
|
yading@10
|
8 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
9 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
10 * License as published by the Free Software Foundation; either
|
yading@10
|
11 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
12 *
|
yading@10
|
13 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
16 * Lesser General Public License for more details.
|
yading@10
|
17 *
|
yading@10
|
18 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
19 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
21 */
|
yading@10
|
22
|
yading@10
|
23 /**
|
yading@10
|
24 * @file
|
yading@10
|
25 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
|
yading@10
|
26 */
|
yading@10
|
27
|
yading@10
|
28 #include "libavutil/imgutils.h"
|
yading@10
|
29 #include "bytestream.h"
|
yading@10
|
30 #include "avcodec.h"
|
yading@10
|
31 #include "get_bits.h"
|
yading@10
|
32 #include "internal.h"
|
yading@10
|
33
|
yading@10
|
34 // TODO: masking bits
|
yading@10
|
35 typedef enum {
|
yading@10
|
36 MASK_NONE,
|
yading@10
|
37 MASK_HAS_MASK,
|
yading@10
|
38 MASK_HAS_TRANSPARENT_COLOR,
|
yading@10
|
39 MASK_LASSO
|
yading@10
|
40 } mask_type;
|
yading@10
|
41
|
yading@10
|
42 typedef struct {
|
yading@10
|
43 AVFrame *frame;
|
yading@10
|
44 int planesize;
|
yading@10
|
45 uint8_t * planebuf;
|
yading@10
|
46 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
|
yading@10
|
47 uint32_t *ham_palbuf; ///< HAM decode table
|
yading@10
|
48 uint32_t *mask_buf; ///< temporary buffer for palette indices
|
yading@10
|
49 uint32_t *mask_palbuf; ///< masking palette table
|
yading@10
|
50 unsigned compression; ///< delta compression method used
|
yading@10
|
51 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
|
yading@10
|
52 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
|
yading@10
|
53 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
|
yading@10
|
54 unsigned transparency; ///< TODO: transparency color index in palette
|
yading@10
|
55 unsigned masking; ///< TODO: masking method used
|
yading@10
|
56 int init; // 1 if buffer and palette data already initialized, 0 otherwise
|
yading@10
|
57 int16_t tvdc[16]; ///< TVDC lookup table
|
yading@10
|
58 } IffContext;
|
yading@10
|
59
|
yading@10
|
60 #define LUT8_PART(plane, v) \
|
yading@10
|
61 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
|
yading@10
|
62 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
|
yading@10
|
63 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
|
yading@10
|
64 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
|
yading@10
|
65 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
|
yading@10
|
66 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
|
yading@10
|
67 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
|
yading@10
|
68 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
|
yading@10
|
69 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
|
yading@10
|
70 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
|
yading@10
|
71 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
|
yading@10
|
72 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
|
yading@10
|
73 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
|
yading@10
|
74 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
|
yading@10
|
75 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
|
yading@10
|
76 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
|
yading@10
|
77
|
yading@10
|
78 #define LUT8(plane) { \
|
yading@10
|
79 LUT8_PART(plane, 0x0000000), \
|
yading@10
|
80 LUT8_PART(plane, 0x1000000), \
|
yading@10
|
81 LUT8_PART(plane, 0x0010000), \
|
yading@10
|
82 LUT8_PART(plane, 0x1010000), \
|
yading@10
|
83 LUT8_PART(plane, 0x0000100), \
|
yading@10
|
84 LUT8_PART(plane, 0x1000100), \
|
yading@10
|
85 LUT8_PART(plane, 0x0010100), \
|
yading@10
|
86 LUT8_PART(plane, 0x1010100), \
|
yading@10
|
87 LUT8_PART(plane, 0x0000001), \
|
yading@10
|
88 LUT8_PART(plane, 0x1000001), \
|
yading@10
|
89 LUT8_PART(plane, 0x0010001), \
|
yading@10
|
90 LUT8_PART(plane, 0x1010001), \
|
yading@10
|
91 LUT8_PART(plane, 0x0000101), \
|
yading@10
|
92 LUT8_PART(plane, 0x1000101), \
|
yading@10
|
93 LUT8_PART(plane, 0x0010101), \
|
yading@10
|
94 LUT8_PART(plane, 0x1010101), \
|
yading@10
|
95 }
|
yading@10
|
96
|
yading@10
|
97 // 8 planes * 8-bit mask
|
yading@10
|
98 static const uint64_t plane8_lut[8][256] = {
|
yading@10
|
99 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
|
yading@10
|
100 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
|
yading@10
|
101 };
|
yading@10
|
102
|
yading@10
|
103 #define LUT32(plane) { \
|
yading@10
|
104 0, 0, 0, 0, \
|
yading@10
|
105 0, 0, 0, 1 << plane, \
|
yading@10
|
106 0, 0, 1 << plane, 0, \
|
yading@10
|
107 0, 0, 1 << plane, 1 << plane, \
|
yading@10
|
108 0, 1 << plane, 0, 0, \
|
yading@10
|
109 0, 1 << plane, 0, 1 << plane, \
|
yading@10
|
110 0, 1 << plane, 1 << plane, 0, \
|
yading@10
|
111 0, 1 << plane, 1 << plane, 1 << plane, \
|
yading@10
|
112 1 << plane, 0, 0, 0, \
|
yading@10
|
113 1 << plane, 0, 0, 1 << plane, \
|
yading@10
|
114 1 << plane, 0, 1 << plane, 0, \
|
yading@10
|
115 1 << plane, 0, 1 << plane, 1 << plane, \
|
yading@10
|
116 1 << plane, 1 << plane, 0, 0, \
|
yading@10
|
117 1 << plane, 1 << plane, 0, 1 << plane, \
|
yading@10
|
118 1 << plane, 1 << plane, 1 << plane, 0, \
|
yading@10
|
119 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
|
yading@10
|
120 }
|
yading@10
|
121
|
yading@10
|
122 // 32 planes * 4-bit mask * 4 lookup tables each
|
yading@10
|
123 static const uint32_t plane32_lut[32][16*4] = {
|
yading@10
|
124 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
|
yading@10
|
125 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
|
yading@10
|
126 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
|
yading@10
|
127 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
|
yading@10
|
128 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
|
yading@10
|
129 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
|
yading@10
|
130 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
|
yading@10
|
131 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
|
yading@10
|
132 };
|
yading@10
|
133
|
yading@10
|
134 // Gray to RGB, required for palette table of grayscale images with bpp < 8
|
yading@10
|
135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
|
yading@10
|
136 return x << 16 | x << 8 | x;
|
yading@10
|
137 }
|
yading@10
|
138
|
yading@10
|
139 /**
|
yading@10
|
140 * Convert CMAP buffer (stored in extradata) to lavc palette format
|
yading@10
|
141 */
|
yading@10
|
142 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
|
yading@10
|
143 {
|
yading@10
|
144 IffContext *s = avctx->priv_data;
|
yading@10
|
145 int count, i;
|
yading@10
|
146 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
|
yading@10
|
147 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
|
yading@10
|
148
|
yading@10
|
149 if (avctx->bits_per_coded_sample > 8) {
|
yading@10
|
150 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
|
yading@10
|
151 return AVERROR_INVALIDDATA;
|
yading@10
|
152 }
|
yading@10
|
153
|
yading@10
|
154 count = 1 << avctx->bits_per_coded_sample;
|
yading@10
|
155 // If extradata is smaller than actually needed, fill the remaining with black.
|
yading@10
|
156 count = FFMIN(palette_size / 3, count);
|
yading@10
|
157 if (count) {
|
yading@10
|
158 for (i=0; i < count; i++) {
|
yading@10
|
159 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
|
yading@10
|
160 }
|
yading@10
|
161 if (s->flags && count >= 32) { // EHB
|
yading@10
|
162 for (i = 0; i < 32; i++)
|
yading@10
|
163 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
|
yading@10
|
164 count = FFMAX(count, 64);
|
yading@10
|
165 }
|
yading@10
|
166 } else { // Create gray-scale color palette for bps < 8
|
yading@10
|
167 count = 1 << avctx->bits_per_coded_sample;
|
yading@10
|
168
|
yading@10
|
169 for (i=0; i < count; i++) {
|
yading@10
|
170 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
|
yading@10
|
171 }
|
yading@10
|
172 }
|
yading@10
|
173 if (s->masking == MASK_HAS_MASK) {
|
yading@10
|
174 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
|
yading@10
|
175 for (i = 0; i < count; i++)
|
yading@10
|
176 pal[i] &= 0xFFFFFF;
|
yading@10
|
177 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
|
yading@10
|
178 s->transparency < 1 << avctx->bits_per_coded_sample)
|
yading@10
|
179 pal[s->transparency] &= 0xFFFFFF;
|
yading@10
|
180 return 0;
|
yading@10
|
181 }
|
yading@10
|
182
|
yading@10
|
183 /**
|
yading@10
|
184 * Extracts the IFF extra context and updates internal
|
yading@10
|
185 * decoder structures.
|
yading@10
|
186 *
|
yading@10
|
187 * @param avctx the AVCodecContext where to extract extra context to
|
yading@10
|
188 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
|
yading@10
|
189 * @return 0 in case of success, a negative error code otherwise
|
yading@10
|
190 */
|
yading@10
|
191 static int extract_header(AVCodecContext *const avctx,
|
yading@10
|
192 const AVPacket *const avpkt) {
|
yading@10
|
193 const uint8_t *buf;
|
yading@10
|
194 unsigned buf_size;
|
yading@10
|
195 IffContext *s = avctx->priv_data;
|
yading@10
|
196 int i, palette_size;
|
yading@10
|
197
|
yading@10
|
198 if (avctx->extradata_size < 2) {
|
yading@10
|
199 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
|
yading@10
|
200 return AVERROR_INVALIDDATA;
|
yading@10
|
201 }
|
yading@10
|
202 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
|
yading@10
|
203
|
yading@10
|
204 if (avpkt) {
|
yading@10
|
205 int image_size;
|
yading@10
|
206 if (avpkt->size < 2)
|
yading@10
|
207 return AVERROR_INVALIDDATA;
|
yading@10
|
208 image_size = avpkt->size - AV_RB16(avpkt->data);
|
yading@10
|
209 buf = avpkt->data;
|
yading@10
|
210 buf_size = bytestream_get_be16(&buf);
|
yading@10
|
211 if (buf_size <= 1 || image_size <= 1) {
|
yading@10
|
212 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
213 "Invalid image size received: %u -> image data offset: %d\n",
|
yading@10
|
214 buf_size, image_size);
|
yading@10
|
215 return AVERROR_INVALIDDATA;
|
yading@10
|
216 }
|
yading@10
|
217 } else {
|
yading@10
|
218 buf = avctx->extradata;
|
yading@10
|
219 buf_size = bytestream_get_be16(&buf);
|
yading@10
|
220 if (buf_size <= 1 || palette_size < 0) {
|
yading@10
|
221 av_log(avctx, AV_LOG_ERROR,
|
yading@10
|
222 "Invalid palette size received: %u -> palette data offset: %d\n",
|
yading@10
|
223 buf_size, palette_size);
|
yading@10
|
224 return AVERROR_INVALIDDATA;
|
yading@10
|
225 }
|
yading@10
|
226 }
|
yading@10
|
227
|
yading@10
|
228 if (buf_size >= 41) {
|
yading@10
|
229 s->compression = bytestream_get_byte(&buf);
|
yading@10
|
230 s->bpp = bytestream_get_byte(&buf);
|
yading@10
|
231 s->ham = bytestream_get_byte(&buf);
|
yading@10
|
232 s->flags = bytestream_get_byte(&buf);
|
yading@10
|
233 s->transparency = bytestream_get_be16(&buf);
|
yading@10
|
234 s->masking = bytestream_get_byte(&buf);
|
yading@10
|
235 for (i = 0; i < 16; i++)
|
yading@10
|
236 s->tvdc[i] = bytestream_get_be16(&buf);
|
yading@10
|
237
|
yading@10
|
238 if (s->masking == MASK_HAS_MASK) {
|
yading@10
|
239 if (s->bpp >= 8 && !s->ham) {
|
yading@10
|
240 avctx->pix_fmt = AV_PIX_FMT_RGB32;
|
yading@10
|
241 av_freep(&s->mask_buf);
|
yading@10
|
242 av_freep(&s->mask_palbuf);
|
yading@10
|
243 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
244 if (!s->mask_buf)
|
yading@10
|
245 return AVERROR(ENOMEM);
|
yading@10
|
246 if (s->bpp > 16) {
|
yading@10
|
247 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
|
yading@10
|
248 av_freep(&s->mask_buf);
|
yading@10
|
249 return AVERROR(ENOMEM);
|
yading@10
|
250 }
|
yading@10
|
251 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
252 if (!s->mask_palbuf) {
|
yading@10
|
253 av_freep(&s->mask_buf);
|
yading@10
|
254 return AVERROR(ENOMEM);
|
yading@10
|
255 }
|
yading@10
|
256 }
|
yading@10
|
257 s->bpp++;
|
yading@10
|
258 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
|
yading@10
|
259 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
|
yading@10
|
260 return AVERROR_PATCHWELCOME;
|
yading@10
|
261 }
|
yading@10
|
262 if (!s->bpp || s->bpp > 32) {
|
yading@10
|
263 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
|
yading@10
|
264 return AVERROR_INVALIDDATA;
|
yading@10
|
265 } else if (s->ham >= 8) {
|
yading@10
|
266 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
|
yading@10
|
267 return AVERROR_INVALIDDATA;
|
yading@10
|
268 }
|
yading@10
|
269
|
yading@10
|
270 av_freep(&s->ham_buf);
|
yading@10
|
271 av_freep(&s->ham_palbuf);
|
yading@10
|
272
|
yading@10
|
273 if (s->ham) {
|
yading@10
|
274 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
|
yading@10
|
275 int ham_count;
|
yading@10
|
276 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
|
yading@10
|
277
|
yading@10
|
278 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
279 if (!s->ham_buf)
|
yading@10
|
280 return AVERROR(ENOMEM);
|
yading@10
|
281
|
yading@10
|
282 ham_count = 8 * (1 << s->ham);
|
yading@10
|
283 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
284 if (!s->ham_palbuf) {
|
yading@10
|
285 av_freep(&s->ham_buf);
|
yading@10
|
286 return AVERROR(ENOMEM);
|
yading@10
|
287 }
|
yading@10
|
288
|
yading@10
|
289 if (count) { // HAM with color palette attached
|
yading@10
|
290 // prefill with black and palette and set HAM take direct value mask to zero
|
yading@10
|
291 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
|
yading@10
|
292 for (i=0; i < count; i++) {
|
yading@10
|
293 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
|
yading@10
|
294 }
|
yading@10
|
295 count = 1 << s->ham;
|
yading@10
|
296 } else { // HAM with grayscale color palette
|
yading@10
|
297 count = 1 << s->ham;
|
yading@10
|
298 for (i=0; i < count; i++) {
|
yading@10
|
299 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
|
yading@10
|
300 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
|
yading@10
|
301 }
|
yading@10
|
302 }
|
yading@10
|
303 for (i=0; i < count; i++) {
|
yading@10
|
304 uint32_t tmp = i << (8 - s->ham);
|
yading@10
|
305 tmp |= tmp >> s->ham;
|
yading@10
|
306 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
|
yading@10
|
307 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
|
yading@10
|
308 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
|
yading@10
|
309 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
|
yading@10
|
310 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
|
yading@10
|
311 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
|
yading@10
|
312 }
|
yading@10
|
313 if (s->masking == MASK_HAS_MASK) {
|
yading@10
|
314 for (i = 0; i < ham_count; i++)
|
yading@10
|
315 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
|
yading@10
|
316 }
|
yading@10
|
317 }
|
yading@10
|
318 }
|
yading@10
|
319
|
yading@10
|
320 return 0;
|
yading@10
|
321 }
|
yading@10
|
322
|
yading@10
|
323 static av_cold int decode_init(AVCodecContext *avctx)
|
yading@10
|
324 {
|
yading@10
|
325 IffContext *s = avctx->priv_data;
|
yading@10
|
326 int err;
|
yading@10
|
327
|
yading@10
|
328 if (avctx->bits_per_coded_sample <= 8) {
|
yading@10
|
329 int palette_size;
|
yading@10
|
330
|
yading@10
|
331 if (avctx->extradata_size >= 2)
|
yading@10
|
332 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
|
yading@10
|
333 else
|
yading@10
|
334 palette_size = 0;
|
yading@10
|
335 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
|
yading@10
|
336 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
|
yading@10
|
337 } else if (avctx->bits_per_coded_sample <= 32) {
|
yading@10
|
338 if (avctx->codec_tag == MKTAG('R','G','B','8')) {
|
yading@10
|
339 avctx->pix_fmt = AV_PIX_FMT_RGB32;
|
yading@10
|
340 } else if (avctx->codec_tag == MKTAG('R','G','B','N')) {
|
yading@10
|
341 avctx->pix_fmt = AV_PIX_FMT_RGB444;
|
yading@10
|
342 } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
|
yading@10
|
343 if (avctx->bits_per_coded_sample == 24) {
|
yading@10
|
344 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
|
yading@10
|
345 } else if (avctx->bits_per_coded_sample == 32) {
|
yading@10
|
346 avctx->pix_fmt = AV_PIX_FMT_BGR32;
|
yading@10
|
347 } else {
|
yading@10
|
348 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
|
yading@10
|
349 return AVERROR_PATCHWELCOME;
|
yading@10
|
350 }
|
yading@10
|
351 }
|
yading@10
|
352 } else {
|
yading@10
|
353 return AVERROR_INVALIDDATA;
|
yading@10
|
354 }
|
yading@10
|
355
|
yading@10
|
356 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
|
yading@10
|
357 return err;
|
yading@10
|
358 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
|
yading@10
|
359 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@10
|
360 if (!s->planebuf)
|
yading@10
|
361 return AVERROR(ENOMEM);
|
yading@10
|
362
|
yading@10
|
363 s->bpp = avctx->bits_per_coded_sample;
|
yading@10
|
364 s->frame = av_frame_alloc();
|
yading@10
|
365 if (!s->frame)
|
yading@10
|
366 return AVERROR(ENOMEM);
|
yading@10
|
367
|
yading@10
|
368 if ((err = extract_header(avctx, NULL)) < 0)
|
yading@10
|
369 return err;
|
yading@10
|
370
|
yading@10
|
371 return 0;
|
yading@10
|
372 }
|
yading@10
|
373
|
yading@10
|
374 /**
|
yading@10
|
375 * Decode interleaved plane buffer up to 8bpp
|
yading@10
|
376 * @param dst Destination buffer
|
yading@10
|
377 * @param buf Source buffer
|
yading@10
|
378 * @param buf_size
|
yading@10
|
379 * @param plane plane number to decode as
|
yading@10
|
380 */
|
yading@10
|
381 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
|
yading@10
|
382 {
|
yading@10
|
383 const uint64_t *lut = plane8_lut[plane];
|
yading@10
|
384 if (plane >= 8) {
|
yading@10
|
385 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
|
yading@10
|
386 return;
|
yading@10
|
387 }
|
yading@10
|
388 do {
|
yading@10
|
389 uint64_t v = AV_RN64A(dst) | lut[*buf++];
|
yading@10
|
390 AV_WN64A(dst, v);
|
yading@10
|
391 dst += 8;
|
yading@10
|
392 } while (--buf_size);
|
yading@10
|
393 }
|
yading@10
|
394
|
yading@10
|
395 /**
|
yading@10
|
396 * Decode interleaved plane buffer up to 24bpp
|
yading@10
|
397 * @param dst Destination buffer
|
yading@10
|
398 * @param buf Source buffer
|
yading@10
|
399 * @param buf_size
|
yading@10
|
400 * @param plane plane number to decode as
|
yading@10
|
401 */
|
yading@10
|
402 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
|
yading@10
|
403 {
|
yading@10
|
404 const uint32_t *lut = plane32_lut[plane];
|
yading@10
|
405 do {
|
yading@10
|
406 unsigned mask = (*buf >> 2) & ~3;
|
yading@10
|
407 dst[0] |= lut[mask++];
|
yading@10
|
408 dst[1] |= lut[mask++];
|
yading@10
|
409 dst[2] |= lut[mask++];
|
yading@10
|
410 dst[3] |= lut[mask];
|
yading@10
|
411 mask = (*buf++ << 2) & 0x3F;
|
yading@10
|
412 dst[4] |= lut[mask++];
|
yading@10
|
413 dst[5] |= lut[mask++];
|
yading@10
|
414 dst[6] |= lut[mask++];
|
yading@10
|
415 dst[7] |= lut[mask];
|
yading@10
|
416 dst += 8;
|
yading@10
|
417 } while (--buf_size);
|
yading@10
|
418 }
|
yading@10
|
419
|
yading@10
|
420 #define DECODE_HAM_PLANE32(x) \
|
yading@10
|
421 first = buf[x] << 1; \
|
yading@10
|
422 second = buf[(x)+1] << 1; \
|
yading@10
|
423 delta &= pal[first++]; \
|
yading@10
|
424 delta |= pal[first]; \
|
yading@10
|
425 dst[x] = delta; \
|
yading@10
|
426 delta &= pal[second++]; \
|
yading@10
|
427 delta |= pal[second]; \
|
yading@10
|
428 dst[(x)+1] = delta
|
yading@10
|
429
|
yading@10
|
430 /**
|
yading@10
|
431 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
|
yading@10
|
432 *
|
yading@10
|
433 * @param dst the destination 24bpp buffer
|
yading@10
|
434 * @param buf the source 8bpp chunky buffer
|
yading@10
|
435 * @param pal the HAM decode table
|
yading@10
|
436 * @param buf_size the plane size in bytes
|
yading@10
|
437 */
|
yading@10
|
438 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
|
yading@10
|
439 const uint32_t *const pal, unsigned buf_size)
|
yading@10
|
440 {
|
yading@10
|
441 uint32_t delta = pal[1]; /* first palette entry */
|
yading@10
|
442 do {
|
yading@10
|
443 uint32_t first, second;
|
yading@10
|
444 DECODE_HAM_PLANE32(0);
|
yading@10
|
445 DECODE_HAM_PLANE32(2);
|
yading@10
|
446 DECODE_HAM_PLANE32(4);
|
yading@10
|
447 DECODE_HAM_PLANE32(6);
|
yading@10
|
448 buf += 8;
|
yading@10
|
449 dst += 8;
|
yading@10
|
450 } while (--buf_size);
|
yading@10
|
451 }
|
yading@10
|
452
|
yading@10
|
453 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
|
yading@10
|
454 const uint32_t *const pal, unsigned width)
|
yading@10
|
455 {
|
yading@10
|
456 do {
|
yading@10
|
457 *dst++ = pal[*buf++];
|
yading@10
|
458 } while (--width);
|
yading@10
|
459 }
|
yading@10
|
460
|
yading@10
|
461 /**
|
yading@10
|
462 * Decode one complete byterun1 encoded line.
|
yading@10
|
463 *
|
yading@10
|
464 * @param dst the destination buffer where to store decompressed bitstream
|
yading@10
|
465 * @param dst_size the destination plane size in bytes
|
yading@10
|
466 * @param buf the source byterun1 compressed bitstream
|
yading@10
|
467 * @param buf_end the EOF of source byterun1 compressed bitstream
|
yading@10
|
468 * @return number of consumed bytes in byterun1 compressed bitstream
|
yading@10
|
469 */
|
yading@10
|
470 static int decode_byterun(uint8_t *dst, int dst_size,
|
yading@10
|
471 const uint8_t *buf, const uint8_t *const buf_end) {
|
yading@10
|
472 const uint8_t *const buf_start = buf;
|
yading@10
|
473 unsigned x;
|
yading@10
|
474 for (x = 0; x < dst_size && buf < buf_end;) {
|
yading@10
|
475 unsigned length;
|
yading@10
|
476 const int8_t value = *buf++;
|
yading@10
|
477 if (value >= 0) {
|
yading@10
|
478 length = value + 1;
|
yading@10
|
479 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
|
yading@10
|
480 buf += length;
|
yading@10
|
481 } else if (value > -128) {
|
yading@10
|
482 length = -value + 1;
|
yading@10
|
483 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
|
yading@10
|
484 } else { // noop
|
yading@10
|
485 continue;
|
yading@10
|
486 }
|
yading@10
|
487 x += length;
|
yading@10
|
488 }
|
yading@10
|
489 return buf - buf_start;
|
yading@10
|
490 }
|
yading@10
|
491
|
yading@10
|
492 #define DECODE_RGBX_COMMON(type) \
|
yading@10
|
493 if (!length) { \
|
yading@10
|
494 length = bytestream2_get_byte(gb); \
|
yading@10
|
495 if (!length) { \
|
yading@10
|
496 length = bytestream2_get_be16(gb); \
|
yading@10
|
497 if (!length) \
|
yading@10
|
498 return; \
|
yading@10
|
499 } \
|
yading@10
|
500 } \
|
yading@10
|
501 for (i = 0; i < length; i++) { \
|
yading@10
|
502 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
|
yading@10
|
503 x += 1; \
|
yading@10
|
504 if (x >= width) { \
|
yading@10
|
505 y += 1; \
|
yading@10
|
506 if (y >= height) \
|
yading@10
|
507 return; \
|
yading@10
|
508 x = 0; \
|
yading@10
|
509 } \
|
yading@10
|
510 }
|
yading@10
|
511
|
yading@10
|
512 /**
|
yading@10
|
513 * Decode RGB8 buffer
|
yading@10
|
514 * @param[out] dst Destination buffer
|
yading@10
|
515 * @param width Width of destination buffer (pixels)
|
yading@10
|
516 * @param height Height of destination buffer (pixels)
|
yading@10
|
517 * @param linesize Line size of destination buffer (bytes)
|
yading@10
|
518 */
|
yading@10
|
519 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
|
yading@10
|
520 {
|
yading@10
|
521 int x = 0, y = 0, i, length;
|
yading@10
|
522 while (bytestream2_get_bytes_left(gb) >= 4) {
|
yading@10
|
523 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
|
yading@10
|
524 length = bytestream2_get_byte(gb) & 0x7F;
|
yading@10
|
525 DECODE_RGBX_COMMON(uint32_t)
|
yading@10
|
526 }
|
yading@10
|
527 }
|
yading@10
|
528
|
yading@10
|
529 /**
|
yading@10
|
530 * Decode RGBN buffer
|
yading@10
|
531 * @param[out] dst Destination buffer
|
yading@10
|
532 * @param width Width of destination buffer (pixels)
|
yading@10
|
533 * @param height Height of destination buffer (pixels)
|
yading@10
|
534 * @param linesize Line size of destination buffer (bytes)
|
yading@10
|
535 */
|
yading@10
|
536 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
|
yading@10
|
537 {
|
yading@10
|
538 int x = 0, y = 0, i, length;
|
yading@10
|
539 while (bytestream2_get_bytes_left(gb) >= 2) {
|
yading@10
|
540 uint32_t pixel = bytestream2_get_be16u(gb);
|
yading@10
|
541 length = pixel & 0x7;
|
yading@10
|
542 pixel >>= 4;
|
yading@10
|
543 DECODE_RGBX_COMMON(uint16_t)
|
yading@10
|
544 }
|
yading@10
|
545 }
|
yading@10
|
546
|
yading@10
|
547 /**
|
yading@10
|
548 * Decode DEEP RLE 32-bit buffer
|
yading@10
|
549 * @param[out] dst Destination buffer
|
yading@10
|
550 * @param[in] src Source buffer
|
yading@10
|
551 * @param src_size Source buffer size (bytes)
|
yading@10
|
552 * @param width Width of destination buffer (pixels)
|
yading@10
|
553 * @param height Height of destination buffer (pixels)
|
yading@10
|
554 * @param linesize Line size of destination buffer (bytes)
|
yading@10
|
555 */
|
yading@10
|
556 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
|
yading@10
|
557 {
|
yading@10
|
558 const uint8_t *src_end = src + src_size;
|
yading@10
|
559 int x = 0, y = 0, i;
|
yading@10
|
560 while (src + 5 <= src_end) {
|
yading@10
|
561 int opcode;
|
yading@10
|
562 opcode = *(int8_t *)src++;
|
yading@10
|
563 if (opcode >= 0) {
|
yading@10
|
564 int size = opcode + 1;
|
yading@10
|
565 for (i = 0; i < size; i++) {
|
yading@10
|
566 int length = FFMIN(size - i, width);
|
yading@10
|
567 memcpy(dst + y*linesize + x * 4, src, length * 4);
|
yading@10
|
568 src += length * 4;
|
yading@10
|
569 x += length;
|
yading@10
|
570 i += length;
|
yading@10
|
571 if (x >= width) {
|
yading@10
|
572 x = 0;
|
yading@10
|
573 y += 1;
|
yading@10
|
574 if (y >= height)
|
yading@10
|
575 return;
|
yading@10
|
576 }
|
yading@10
|
577 }
|
yading@10
|
578 } else {
|
yading@10
|
579 int size = -opcode + 1;
|
yading@10
|
580 uint32_t pixel = AV_RN32(src);
|
yading@10
|
581 for (i = 0; i < size; i++) {
|
yading@10
|
582 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
|
yading@10
|
583 x += 1;
|
yading@10
|
584 if (x >= width) {
|
yading@10
|
585 x = 0;
|
yading@10
|
586 y += 1;
|
yading@10
|
587 if (y >= height)
|
yading@10
|
588 return;
|
yading@10
|
589 }
|
yading@10
|
590 }
|
yading@10
|
591 src += 4;
|
yading@10
|
592 }
|
yading@10
|
593 }
|
yading@10
|
594 }
|
yading@10
|
595
|
yading@10
|
596 /**
|
yading@10
|
597 * Decode DEEP TVDC 32-bit buffer
|
yading@10
|
598 * @param[out] dst Destination buffer
|
yading@10
|
599 * @param[in] src Source buffer
|
yading@10
|
600 * @param src_size Source buffer size (bytes)
|
yading@10
|
601 * @param width Width of destination buffer (pixels)
|
yading@10
|
602 * @param height Height of destination buffer (pixels)
|
yading@10
|
603 * @param linesize Line size of destination buffer (bytes)
|
yading@10
|
604 * @param[int] tvdc TVDC lookup table
|
yading@10
|
605 */
|
yading@10
|
606 static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
|
yading@10
|
607 {
|
yading@10
|
608 int x = 0, y = 0, plane = 0;
|
yading@10
|
609 int8_t pixel = 0;
|
yading@10
|
610 int i, j;
|
yading@10
|
611
|
yading@10
|
612 for (i = 0; i < src_size * 2;) {
|
yading@10
|
613 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
|
yading@10
|
614 int d = tvdc[GETNIBBLE];
|
yading@10
|
615 i++;
|
yading@10
|
616 if (d) {
|
yading@10
|
617 pixel += d;
|
yading@10
|
618 dst[y * linesize + x*4 + plane] = pixel;
|
yading@10
|
619 x++;
|
yading@10
|
620 } else {
|
yading@10
|
621 if (i >= src_size * 2)
|
yading@10
|
622 return;
|
yading@10
|
623 d = GETNIBBLE + 1;
|
yading@10
|
624 i++;
|
yading@10
|
625 d = FFMIN(d, width - x);
|
yading@10
|
626 for (j = 0; j < d; j++) {
|
yading@10
|
627 dst[y * linesize + x*4 + plane] = pixel;
|
yading@10
|
628 x++;
|
yading@10
|
629 }
|
yading@10
|
630 }
|
yading@10
|
631 if (x >= width) {
|
yading@10
|
632 plane++;
|
yading@10
|
633 if (plane >= 4) {
|
yading@10
|
634 y++;
|
yading@10
|
635 if (y >= height)
|
yading@10
|
636 return;
|
yading@10
|
637 plane = 0;
|
yading@10
|
638 }
|
yading@10
|
639 x = 0;
|
yading@10
|
640 pixel = 0;
|
yading@10
|
641 i = (i + 1) & ~1;
|
yading@10
|
642 }
|
yading@10
|
643 }
|
yading@10
|
644 }
|
yading@10
|
645
|
yading@10
|
646 static int unsupported(AVCodecContext *avctx)
|
yading@10
|
647 {
|
yading@10
|
648 IffContext *s = avctx->priv_data;
|
yading@10
|
649 avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
|
yading@10
|
650 return AVERROR_INVALIDDATA;
|
yading@10
|
651 }
|
yading@10
|
652
|
yading@10
|
653 static int decode_frame(AVCodecContext *avctx,
|
yading@10
|
654 void *data, int *got_frame,
|
yading@10
|
655 AVPacket *avpkt)
|
yading@10
|
656 {
|
yading@10
|
657 IffContext *s = avctx->priv_data;
|
yading@10
|
658 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
|
yading@10
|
659 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
|
yading@10
|
660 const uint8_t *buf_end = buf+buf_size;
|
yading@10
|
661 int y, plane, res;
|
yading@10
|
662 GetByteContext gb;
|
yading@10
|
663
|
yading@10
|
664 if ((res = extract_header(avctx, avpkt)) < 0)
|
yading@10
|
665 return res;
|
yading@10
|
666 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
|
yading@10
|
667 return res;
|
yading@10
|
668 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
|
yading@10
|
669 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
|
yading@10
|
670 if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame->data[1])) < 0)
|
yading@10
|
671 return res;
|
yading@10
|
672 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
|
yading@10
|
673 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
|
yading@10
|
674 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
|
yading@10
|
675 return res;
|
yading@10
|
676 }
|
yading@10
|
677 s->init = 1;
|
yading@10
|
678
|
yading@10
|
679 switch (s->compression) {
|
yading@10
|
680 case 0:
|
yading@10
|
681 if (avctx->codec_tag == MKTAG('A','C','B','M')) {
|
yading@10
|
682 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
yading@10
|
683 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
|
yading@10
|
684 for (plane = 0; plane < s->bpp; plane++) {
|
yading@10
|
685 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
|
yading@10
|
686 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
|
yading@10
|
687 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
|
yading@10
|
688 buf += s->planesize;
|
yading@10
|
689 }
|
yading@10
|
690 }
|
yading@10
|
691 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
|
yading@10
|
692 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
|
yading@10
|
693 for(y = 0; y < avctx->height; y++) {
|
yading@10
|
694 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
|
yading@10
|
695 memset(s->ham_buf, 0, s->planesize * 8);
|
yading@10
|
696 for (plane = 0; plane < s->bpp; plane++) {
|
yading@10
|
697 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
|
yading@10
|
698 if (start >= buf_end)
|
yading@10
|
699 break;
|
yading@10
|
700 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
|
yading@10
|
701 }
|
yading@10
|
702 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
|
yading@10
|
703 }
|
yading@10
|
704 } else
|
yading@10
|
705 return unsupported(avctx);
|
yading@10
|
706 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
|
yading@10
|
707 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
|
yading@10
|
708 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
|
yading@10
|
709 int x;
|
yading@10
|
710 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
|
yading@10
|
711 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
|
yading@10
|
712 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
|
yading@10
|
713 buf += raw_width;
|
yading@10
|
714 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
|
yading@10
|
715 for(x = 0; x < avctx->width; x++)
|
yading@10
|
716 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
|
yading@10
|
717 }
|
yading@10
|
718 }
|
yading@10
|
719 } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
|
yading@10
|
720 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
yading@10
|
721 for(y = 0; y < avctx->height; y++ ) {
|
yading@10
|
722 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
|
yading@10
|
723 memset(row, 0, avctx->width);
|
yading@10
|
724 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
|
yading@10
|
725 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
|
yading@10
|
726 buf += s->planesize;
|
yading@10
|
727 }
|
yading@10
|
728 }
|
yading@10
|
729 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
|
yading@10
|
730 for (y = 0; y < avctx->height; y++) {
|
yading@10
|
731 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
|
yading@10
|
732 memset(s->ham_buf, 0, s->planesize * 8);
|
yading@10
|
733 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
|
yading@10
|
734 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
|
yading@10
|
735 buf += s->planesize;
|
yading@10
|
736 }
|
yading@10
|
737 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
|
yading@10
|
738 }
|
yading@10
|
739 } else { // AV_PIX_FMT_BGR32
|
yading@10
|
740 for(y = 0; y < avctx->height; y++ ) {
|
yading@10
|
741 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
|
yading@10
|
742 memset(row, 0, avctx->width << 2);
|
yading@10
|
743 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
|
yading@10
|
744 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
|
yading@10
|
745 buf += s->planesize;
|
yading@10
|
746 }
|
yading@10
|
747 }
|
yading@10
|
748 }
|
yading@10
|
749 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
|
yading@10
|
750 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
yading@10
|
751 for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
|
yading@10
|
752 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
|
yading@10
|
753 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
|
yading@10
|
754 buf += avctx->width + (avctx->width % 2); // padding if odd
|
yading@10
|
755 }
|
yading@10
|
756 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
|
yading@10
|
757 for (y = 0; y < avctx->height && buf_end > buf; y++) {
|
yading@10
|
758 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
|
yading@10
|
759 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
|
yading@10
|
760 buf += avctx->width + (avctx->width & 1); // padding if odd
|
yading@10
|
761 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
|
yading@10
|
762 }
|
yading@10
|
763 } else
|
yading@10
|
764 return unsupported(avctx);
|
yading@10
|
765 }
|
yading@10
|
766 break;
|
yading@10
|
767 case 1:
|
yading@10
|
768 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
|
yading@10
|
769 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
yading@10
|
770 for(y = 0; y < avctx->height ; y++ ) {
|
yading@10
|
771 uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
|
yading@10
|
772 memset(row, 0, avctx->width);
|
yading@10
|
773 for (plane = 0; plane < s->bpp; plane++) {
|
yading@10
|
774 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
|
yading@10
|
775 decodeplane8(row, s->planebuf, s->planesize, plane);
|
yading@10
|
776 }
|
yading@10
|
777 }
|
yading@10
|
778 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
|
yading@10
|
779 for (y = 0; y < avctx->height ; y++ ) {
|
yading@10
|
780 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
|
yading@10
|
781 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
|
yading@10
|
782 for (plane = 0; plane < s->bpp; plane++) {
|
yading@10
|
783 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
|
yading@10
|
784 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
|
yading@10
|
785 }
|
yading@10
|
786 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
|
yading@10
|
787 }
|
yading@10
|
788 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
|
yading@10
|
789 for (y = 0; y < avctx->height ; y++) {
|
yading@10
|
790 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
|
yading@10
|
791 memset(s->ham_buf, 0, s->planesize * 8);
|
yading@10
|
792 for (plane = 0; plane < s->bpp; plane++) {
|
yading@10
|
793 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
|
yading@10
|
794 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
|
yading@10
|
795 }
|
yading@10
|
796 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
|
yading@10
|
797 }
|
yading@10
|
798 } else { //AV_PIX_FMT_BGR32
|
yading@10
|
799 for(y = 0; y < avctx->height ; y++ ) {
|
yading@10
|
800 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
|
yading@10
|
801 memset(row, 0, avctx->width << 2);
|
yading@10
|
802 for (plane = 0; plane < s->bpp; plane++) {
|
yading@10
|
803 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
|
yading@10
|
804 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
|
yading@10
|
805 }
|
yading@10
|
806 }
|
yading@10
|
807 }
|
yading@10
|
808 } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
|
yading@10
|
809 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
|
yading@10
|
810 for(y = 0; y < avctx->height ; y++ ) {
|
yading@10
|
811 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
|
yading@10
|
812 buf += decode_byterun(row, avctx->width, buf, buf_end);
|
yading@10
|
813 }
|
yading@10
|
814 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
|
yading@10
|
815 for (y = 0; y < avctx->height ; y++) {
|
yading@10
|
816 uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
|
yading@10
|
817 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
|
yading@10
|
818 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
|
yading@10
|
819 }
|
yading@10
|
820 } else
|
yading@10
|
821 return unsupported(avctx);
|
yading@10
|
822 } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
|
yading@10
|
823 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
|
yading@10
|
824 if (av_get_bits_per_pixel(desc) == 32)
|
yading@10
|
825 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
|
yading@10
|
826 else
|
yading@10
|
827 return unsupported(avctx);
|
yading@10
|
828 }
|
yading@10
|
829 break;
|
yading@10
|
830 case 4:
|
yading@10
|
831 bytestream2_init(&gb, buf, buf_size);
|
yading@10
|
832 if (avctx->codec_tag == MKTAG('R','G','B','8'))
|
yading@10
|
833 decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
|
yading@10
|
834 else if (avctx->codec_tag == MKTAG('R','G','B','N'))
|
yading@10
|
835 decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
|
yading@10
|
836 else
|
yading@10
|
837 return unsupported(avctx);
|
yading@10
|
838 break;
|
yading@10
|
839 case 5:
|
yading@10
|
840 if (avctx->codec_tag == MKTAG('D','E','E','P')) {
|
yading@10
|
841 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
|
yading@10
|
842 if (av_get_bits_per_pixel(desc) == 32)
|
yading@10
|
843 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
|
yading@10
|
844 else
|
yading@10
|
845 return unsupported(avctx);
|
yading@10
|
846 } else
|
yading@10
|
847 return unsupported(avctx);
|
yading@10
|
848 break;
|
yading@10
|
849 default:
|
yading@10
|
850 return unsupported(avctx);
|
yading@10
|
851 }
|
yading@10
|
852
|
yading@10
|
853 if ((res = av_frame_ref(data, s->frame)) < 0)
|
yading@10
|
854 return res;
|
yading@10
|
855
|
yading@10
|
856 *got_frame = 1;
|
yading@10
|
857
|
yading@10
|
858 return buf_size;
|
yading@10
|
859 }
|
yading@10
|
860
|
yading@10
|
861 static av_cold int decode_end(AVCodecContext *avctx)
|
yading@10
|
862 {
|
yading@10
|
863 IffContext *s = avctx->priv_data;
|
yading@10
|
864 av_frame_free(&s->frame);
|
yading@10
|
865 av_freep(&s->planebuf);
|
yading@10
|
866 av_freep(&s->ham_buf);
|
yading@10
|
867 av_freep(&s->ham_palbuf);
|
yading@10
|
868 return 0;
|
yading@10
|
869 }
|
yading@10
|
870
|
yading@10
|
871 #if CONFIG_IFF_ILBM_DECODER
|
yading@10
|
872 AVCodec ff_iff_ilbm_decoder = {
|
yading@10
|
873 .name = "iff",
|
yading@10
|
874 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
875 .id = AV_CODEC_ID_IFF_ILBM,
|
yading@10
|
876 .priv_data_size = sizeof(IffContext),
|
yading@10
|
877 .init = decode_init,
|
yading@10
|
878 .close = decode_end,
|
yading@10
|
879 .decode = decode_frame,
|
yading@10
|
880 .capabilities = CODEC_CAP_DR1,
|
yading@10
|
881 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
|
yading@10
|
882 };
|
yading@10
|
883 #endif
|
yading@10
|
884 #if CONFIG_IFF_BYTERUN1_DECODER
|
yading@10
|
885 AVCodec ff_iff_byterun1_decoder = {
|
yading@10
|
886 .name = "iff",
|
yading@10
|
887 .type = AVMEDIA_TYPE_VIDEO,
|
yading@10
|
888 .id = AV_CODEC_ID_IFF_BYTERUN1,
|
yading@10
|
889 .priv_data_size = sizeof(IffContext),
|
yading@10
|
890 .init = decode_init,
|
yading@10
|
891 .close = decode_end,
|
yading@10
|
892 .decode = decode_frame,
|
yading@10
|
893 .capabilities = CODEC_CAP_DR1,
|
yading@10
|
894 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
|
yading@10
|
895 };
|
yading@10
|
896 #endif
|