1 /*
2 * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5 * Copyright (c) 2016 Paul B Mahol
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 /**
25 * @file
26 * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
27 */
28
29 #include <stdint.h>
30
31 #include "libavutil/imgutils.h"
32
33 #include "bytestream.h"
34 #include "avcodec.h"
35 #include "internal.h"
36 #include "mathops.h"
37
38 // TODO: masking bits
39 typedef enum {
40 MASK_NONE,
41 MASK_HAS_MASK,
42 MASK_HAS_TRANSPARENT_COLOR,
43 MASK_LASSO
44 } mask_type;
45
46 typedef struct IffContext {
47 AVFrame *frame;
48 int planesize;
49 uint8_t * planebuf;
50 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
51 uint32_t *ham_palbuf; ///< HAM decode table
52 uint32_t *mask_buf; ///< temporary buffer for palette indices
53 uint32_t *mask_palbuf; ///< masking palette table
54 unsigned compression; ///< delta compression method used
55 unsigned is_short; ///< short compression method used
56 unsigned is_interlaced;///< video is interlaced
57 unsigned is_brush; ///< video is in ANBR format
58 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
59 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
60 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
61 unsigned transparency; ///< TODO: transparency color index in palette
62 unsigned masking; ///< TODO: masking method used
63 int init; // 1 if buffer and palette data already initialized, 0 otherwise
64 int16_t tvdc[16]; ///< TVDC lookup table
65 GetByteContext gb;
66 uint8_t *video[2];
67 unsigned video_size;
68 uint32_t *pal;
69 } IffContext;
70
71 #define LUT8_PART(plane, v) \
72 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
79 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
80 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
81 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
82 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
83 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
84 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
85 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
86 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
87 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
88
89 #define LUT8(plane) { \
90 LUT8_PART(plane, 0x0000000), \
91 LUT8_PART(plane, 0x1000000), \
92 LUT8_PART(plane, 0x0010000), \
93 LUT8_PART(plane, 0x1010000), \
94 LUT8_PART(plane, 0x0000100), \
95 LUT8_PART(plane, 0x1000100), \
96 LUT8_PART(plane, 0x0010100), \
97 LUT8_PART(plane, 0x1010100), \
98 LUT8_PART(plane, 0x0000001), \
99 LUT8_PART(plane, 0x1000001), \
100 LUT8_PART(plane, 0x0010001), \
101 LUT8_PART(plane, 0x1010001), \
102 LUT8_PART(plane, 0x0000101), \
103 LUT8_PART(plane, 0x1000101), \
104 LUT8_PART(plane, 0x0010101), \
105 LUT8_PART(plane, 0x1010101), \
106 }
107
108 // 8 planes * 8-bit mask
109 static const uint64_t plane8_lut[8][256] = {
110 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
111 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
112 };
113
114 #define LUT32(plane) { \
115 0, 0, 0, 0, \
116 0, 0, 0, 1U << plane, \
117 0, 0, 1U << plane, 0, \
118 0, 0, 1U << plane, 1U << plane, \
119 0, 1U << plane, 0, 0, \
120 0, 1U << plane, 0, 1U << plane, \
121 0, 1U << plane, 1U << plane, 0, \
122 0, 1U << plane, 1U << plane, 1U << plane, \
123 1U << plane, 0, 0, 0, \
124 1U << plane, 0, 0, 1U << plane, \
125 1U << plane, 0, 1U << plane, 0, \
126 1U << plane, 0, 1U << plane, 1U << plane, \
127 1U << plane, 1U << plane, 0, 0, \
128 1U << plane, 1U << plane, 0, 1U << plane, \
129 1U << plane, 1U << plane, 1U << plane, 0, \
130 1U << plane, 1U << plane, 1U << plane, 1U << plane, \
131 }
132
133 // 32 planes * 4-bit mask * 4 lookup tables each
134 static const uint32_t plane32_lut[32][16*4] = {
135 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
136 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
137 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
138 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
139 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
140 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
141 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
142 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
143 };
144
145 // Gray to RGB, required for palette table of grayscale images with bpp < 8
gray2rgb(const uint32_t x)146 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
147 return x << 16 | x << 8 | x;
148 }
149
150 /**
151 * Convert CMAP buffer (stored in extradata) to lavc palette format
152 */
cmap_read_palette(AVCodecContext * avctx,uint32_t * pal)153 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
154 {
155 IffContext *s = avctx->priv_data;
156 int count, i;
157 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
158 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
159
160 if (avctx->bits_per_coded_sample > 8) {
161 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
162 return AVERROR_INVALIDDATA;
163 }
164
165 count = 1 << avctx->bits_per_coded_sample;
166 // If extradata is smaller than actually needed, fill the remaining with black.
167 count = FFMIN(palette_size / 3, count);
168 if (count) {
169 for (i = 0; i < count; i++)
170 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
171 if (s->flags && count >= 32) { // EHB
172 for (i = 0; i < 32; i++)
173 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
174 count = FFMAX(count, 64);
175 }
176 } else { // Create gray-scale color palette for bps < 8
177 count = 1 << avctx->bits_per_coded_sample;
178
179 for (i = 0; i < count; i++)
180 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
181 }
182 if (s->masking == MASK_HAS_MASK) {
183 if ((1 << avctx->bits_per_coded_sample) < count) {
184 avpriv_request_sample(avctx, "overlapping mask");
185 return AVERROR_PATCHWELCOME;
186 }
187 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
188 for (i = 0; i < count; i++)
189 pal[i] &= 0xFFFFFF;
190 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
191 s->transparency < 1 << avctx->bits_per_coded_sample)
192 pal[s->transparency] &= 0xFFFFFF;
193 return 0;
194 }
195
196 /**
197 * Extracts the IFF extra context and updates internal
198 * decoder structures.
199 *
200 * @param avctx the AVCodecContext where to extract extra context to
201 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
202 * @return >= 0 in case of success, a negative error code otherwise
203 */
extract_header(AVCodecContext * const avctx,const AVPacket * const avpkt)204 static int extract_header(AVCodecContext *const avctx,
205 const AVPacket *const avpkt)
206 {
207 IffContext *s = avctx->priv_data;
208 const uint8_t *buf;
209 unsigned buf_size = 0;
210 int i, palette_size;
211
212 if (avctx->extradata_size < 2) {
213 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
214 return AVERROR_INVALIDDATA;
215 }
216 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
217
218 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
219 uint32_t chunk_id;
220 uint64_t data_size;
221 GetByteContext *gb = &s->gb;
222
223 bytestream2_skip(gb, 4);
224 while (bytestream2_get_bytes_left(gb) >= 1) {
225 chunk_id = bytestream2_get_le32(gb);
226 data_size = bytestream2_get_be32(gb);
227
228 if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
229 bytestream2_skip(gb, data_size + (data_size & 1));
230 } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
231 unsigned extra;
232 if (data_size < 40)
233 return AVERROR_INVALIDDATA;
234
235 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
236 bytestream2_skip(gb, 19);
237 extra = bytestream2_get_be32(gb);
238 s->is_short = !(extra & 1);
239 s->is_brush = extra == 2;
240 s->is_interlaced = !!(extra & 0x40);
241 data_size -= 24;
242 bytestream2_skip(gb, data_size + (data_size & 1));
243 } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
244 chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
245 if (chunk_id == MKTAG('B','O','D','Y'))
246 s->compression &= 0xFF;
247 break;
248 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
249 int count = data_size / 3;
250 uint32_t *pal = s->pal;
251
252 if (count > 256)
253 return AVERROR_INVALIDDATA;
254 if (s->ham) {
255 for (i = 0; i < count; i++)
256 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
257 } else {
258 for (i = 0; i < count; i++)
259 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
260 }
261 bytestream2_skip(gb, data_size & 1);
262 } else {
263 bytestream2_skip(gb, data_size + (data_size&1));
264 }
265 }
266 } else if (!avpkt) {
267 buf = avctx->extradata;
268 buf_size = bytestream_get_be16(&buf);
269 if (buf_size <= 1 || palette_size < 0) {
270 av_log(avctx, AV_LOG_ERROR,
271 "Invalid palette size received: %u -> palette data offset: %d\n",
272 buf_size, palette_size);
273 return AVERROR_INVALIDDATA;
274 }
275 }
276
277 if (buf_size >= 41) {
278 s->compression = bytestream_get_byte(&buf);
279 s->bpp = bytestream_get_byte(&buf);
280 s->ham = bytestream_get_byte(&buf);
281 s->flags = bytestream_get_byte(&buf);
282 s->transparency = bytestream_get_be16(&buf);
283 s->masking = bytestream_get_byte(&buf);
284 for (i = 0; i < 16; i++)
285 s->tvdc[i] = bytestream_get_be16(&buf);
286
287 if (s->ham) {
288 if (s->bpp > 8) {
289 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
290 return AVERROR_INVALIDDATA;
291 } else if (s->ham != (s->bpp > 6 ? 6 : 4)) {
292 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
293 return AVERROR_INVALIDDATA;
294 }
295 }
296
297 if (s->masking == MASK_HAS_MASK) {
298 if (s->bpp >= 8 && !s->ham) {
299 avctx->pix_fmt = AV_PIX_FMT_RGB32;
300 av_freep(&s->mask_buf);
301 av_freep(&s->mask_palbuf);
302 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
303 if (!s->mask_buf)
304 return AVERROR(ENOMEM);
305 if (s->bpp > 16) {
306 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
307 av_freep(&s->mask_buf);
308 return AVERROR(ENOMEM);
309 }
310 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
311 if (!s->mask_palbuf) {
312 av_freep(&s->mask_buf);
313 return AVERROR(ENOMEM);
314 }
315 }
316 s->bpp++;
317 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
318 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
319 return AVERROR_PATCHWELCOME;
320 }
321 if (!s->bpp || s->bpp > 32) {
322 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
323 return AVERROR_INVALIDDATA;
324 }
325 if (s->video_size && s->planesize * s->bpp * avctx->height > s->video_size)
326 return AVERROR_INVALIDDATA;
327
328 av_freep(&s->ham_buf);
329 av_freep(&s->ham_palbuf);
330
331 if (s->ham) {
332 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
333 int ham_count;
334 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
335 int extra_space = 1;
336
337 if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ') && s->ham == 4)
338 extra_space = 4;
339
340 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
341 if (!s->ham_buf)
342 return AVERROR(ENOMEM);
343
344 ham_count = 8 * (1 << s->ham);
345 s->ham_palbuf = av_malloc(extra_space * (ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
346 if (!s->ham_palbuf) {
347 av_freep(&s->ham_buf);
348 return AVERROR(ENOMEM);
349 }
350
351 if (count) { // HAM with color palette attached
352 // prefill with black and palette and set HAM take direct value mask to zero
353 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
354 for (i=0; i < count; i++) {
355 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
356 }
357 count = 1 << s->ham;
358 } else { // HAM with grayscale color palette
359 count = 1 << s->ham;
360 for (i=0; i < count; i++) {
361 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
362 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
363 }
364 }
365 for (i=0; i < count; i++) {
366 uint32_t tmp = i << (8 - s->ham);
367 tmp |= tmp >> s->ham;
368 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
369 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
370 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
371 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
372 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
373 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
374 }
375 if (s->masking == MASK_HAS_MASK) {
376 for (i = 0; i < ham_count; i++)
377 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
378 }
379 }
380 }
381
382 return 0;
383 }
384
decode_end(AVCodecContext * avctx)385 static av_cold int decode_end(AVCodecContext *avctx)
386 {
387 IffContext *s = avctx->priv_data;
388 av_freep(&s->planebuf);
389 av_freep(&s->ham_buf);
390 av_freep(&s->ham_palbuf);
391 av_freep(&s->mask_buf);
392 av_freep(&s->mask_palbuf);
393 av_freep(&s->video[0]);
394 av_freep(&s->video[1]);
395 av_freep(&s->pal);
396 return 0;
397 }
398
decode_init(AVCodecContext * avctx)399 static av_cold int decode_init(AVCodecContext *avctx)
400 {
401 IffContext *s = avctx->priv_data;
402 int err;
403
404 if (avctx->bits_per_coded_sample <= 8) {
405 int palette_size;
406
407 if (avctx->extradata_size >= 2)
408 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
409 else
410 palette_size = 0;
411 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
412 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
413 } else if (avctx->bits_per_coded_sample <= 32) {
414 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
415 avctx->pix_fmt = AV_PIX_FMT_RGB32;
416 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
417 avctx->pix_fmt = AV_PIX_FMT_RGB444;
418 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
419 if (avctx->bits_per_coded_sample == 24) {
420 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
421 } else if (avctx->bits_per_coded_sample == 32) {
422 avctx->pix_fmt = AV_PIX_FMT_BGR32;
423 } else {
424 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
425 return AVERROR_PATCHWELCOME;
426 }
427 }
428 } else {
429 return AVERROR_INVALIDDATA;
430 }
431
432 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
433 return err;
434 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
435 s->planebuf = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
436 if (!s->planebuf)
437 return AVERROR(ENOMEM);
438
439 s->bpp = avctx->bits_per_coded_sample;
440
441 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
442 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
443 if (!s->video_size)
444 return AVERROR_INVALIDDATA;
445 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
446 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
447 s->pal = av_calloc(256, sizeof(*s->pal));
448 if (!s->video[0] || !s->video[1] || !s->pal)
449 return AVERROR(ENOMEM);
450 }
451
452 if ((err = extract_header(avctx, NULL)) < 0)
453 return err;
454
455 return 0;
456 }
457
458 /**
459 * Decode interleaved plane buffer up to 8bpp
460 * @param dst Destination buffer
461 * @param buf Source buffer
462 * @param buf_size
463 * @param plane plane number to decode as
464 */
decodeplane8(uint8_t * dst,const uint8_t * buf,int buf_size,int plane)465 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
466 {
467 const uint64_t *lut;
468 if (plane >= 8) {
469 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
470 return;
471 }
472 lut = plane8_lut[plane];
473 do {
474 uint64_t v = AV_RN64A(dst) | lut[*buf++];
475 AV_WN64A(dst, v);
476 dst += 8;
477 } while (--buf_size);
478 }
479
480 /**
481 * Decode interleaved plane buffer up to 24bpp
482 * @param dst Destination buffer
483 * @param buf Source buffer
484 * @param buf_size
485 * @param plane plane number to decode as
486 */
decodeplane32(uint32_t * dst,const uint8_t * buf,int buf_size,int plane)487 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
488 {
489 const uint32_t *lut = plane32_lut[plane];
490 do {
491 unsigned mask = (*buf >> 2) & ~3;
492 dst[0] |= lut[mask++];
493 dst[1] |= lut[mask++];
494 dst[2] |= lut[mask++];
495 dst[3] |= lut[mask];
496 mask = (*buf++ << 2) & 0x3F;
497 dst[4] |= lut[mask++];
498 dst[5] |= lut[mask++];
499 dst[6] |= lut[mask++];
500 dst[7] |= lut[mask];
501 dst += 8;
502 } while (--buf_size);
503 }
504
505 #define DECODE_HAM_PLANE32(x) \
506 first = buf[x] << 1; \
507 second = buf[(x)+1] << 1; \
508 delta &= pal[first++]; \
509 delta |= pal[first]; \
510 dst[x] = delta; \
511 delta &= pal[second++]; \
512 delta |= pal[second]; \
513 dst[(x)+1] = delta
514
515 /**
516 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
517 *
518 * @param dst the destination 24bpp buffer
519 * @param buf the source 8bpp chunky buffer
520 * @param pal the HAM decode table
521 * @param buf_size the plane size in bytes
522 */
decode_ham_plane32(uint32_t * dst,const uint8_t * buf,const uint32_t * const pal,unsigned buf_size)523 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
524 const uint32_t *const pal, unsigned buf_size)
525 {
526 uint32_t delta = pal[1]; /* first palette entry */
527 do {
528 uint32_t first, second;
529 DECODE_HAM_PLANE32(0);
530 DECODE_HAM_PLANE32(2);
531 DECODE_HAM_PLANE32(4);
532 DECODE_HAM_PLANE32(6);
533 buf += 8;
534 dst += 8;
535 } while (--buf_size);
536 }
537
lookup_pal_indicies(uint32_t * dst,const uint32_t * buf,const uint32_t * const pal,unsigned width)538 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
539 const uint32_t *const pal, unsigned width)
540 {
541 do {
542 *dst++ = pal[*buf++];
543 } while (--width);
544 }
545
546 /**
547 * Decode one complete byterun1 encoded line.
548 *
549 * @param dst the destination buffer where to store decompressed bitstream
550 * @param dst_size the destination plane size in bytes
551 * @param buf the source byterun1 compressed bitstream
552 * @param buf_end the EOF of source byterun1 compressed bitstream
553 * @return number of consumed bytes in byterun1 compressed bitstream
554 */
decode_byterun(uint8_t * dst,int dst_size,GetByteContext * gb)555 static int decode_byterun(uint8_t *dst, int dst_size,
556 GetByteContext *gb)
557 {
558 unsigned x;
559 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
560 unsigned length;
561 const int8_t value = bytestream2_get_byte(gb);
562 if (value >= 0) {
563 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
564 bytestream2_get_buffer(gb, dst + x, length);
565 if (length < value + 1)
566 bytestream2_skip(gb, value + 1 - length);
567 } else if (value > -128) {
568 length = FFMIN(-value + 1, dst_size - x);
569 memset(dst + x, bytestream2_get_byte(gb), length);
570 } else { // noop
571 continue;
572 }
573 x += length;
574 }
575 if (x < dst_size) {
576 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
577 memset(dst+x, 0, dst_size - x);
578 }
579 return bytestream2_tell(gb);
580 }
581
decode_byterun2(uint8_t * dst,int height,int line_size,GetByteContext * gb)582 static int decode_byterun2(uint8_t *dst, int height, int line_size,
583 GetByteContext *gb)
584 {
585 GetByteContext cmds;
586 unsigned count;
587 int i, y_pos = 0, x_pos = 0;
588
589 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
590 return 0;
591
592 bytestream2_skip(gb, 4);
593 count = bytestream2_get_be16(gb) - 2;
594 if (bytestream2_get_bytes_left(gb) < count)
595 return 0;
596
597 bytestream2_init(&cmds, gb->buffer, count);
598 bytestream2_skip(gb, count);
599
600 for (i = 0; i < count && x_pos < line_size; i++) {
601 int8_t cmd = bytestream2_get_byte(&cmds);
602 int l, r;
603
604 if (cmd == 0) {
605 l = bytestream2_get_be16(gb);
606 while (l-- > 0 && x_pos < line_size) {
607 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
608 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
609 if (y_pos >= height) {
610 y_pos = 0;
611 x_pos += 2;
612 }
613 }
614 } else if (cmd < 0) {
615 l = -cmd;
616 while (l-- > 0 && x_pos < line_size) {
617 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
618 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
619 if (y_pos >= height) {
620 y_pos = 0;
621 x_pos += 2;
622 }
623 }
624 } else if (cmd == 1) {
625 l = bytestream2_get_be16(gb);
626 r = bytestream2_get_be16(gb);
627 while (l-- > 0 && x_pos < line_size) {
628 dst[x_pos + y_pos * line_size ] = r >> 8;
629 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
630 if (y_pos >= height) {
631 y_pos = 0;
632 x_pos += 2;
633 }
634 }
635 } else {
636 l = cmd;
637 r = bytestream2_get_be16(gb);
638 while (l-- > 0 && x_pos < line_size) {
639 dst[x_pos + y_pos * line_size ] = r >> 8;
640 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
641 if (y_pos >= height) {
642 y_pos = 0;
643 x_pos += 2;
644 }
645 }
646 }
647 }
648
649 return bytestream2_tell(gb);
650 }
651
652 #define DECODE_RGBX_COMMON(type) \
653 if (!length) { \
654 length = bytestream2_get_byte(gb); \
655 if (!length) { \
656 length = bytestream2_get_be16(gb); \
657 if (!length) \
658 return; \
659 } \
660 } \
661 for (i = 0; i < length; i++) { \
662 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
663 x += 1; \
664 if (x >= width) { \
665 y += 1; \
666 if (y >= height) \
667 return; \
668 x = 0; \
669 } \
670 }
671
672 /**
673 * Decode RGB8 buffer
674 * @param[out] dst Destination buffer
675 * @param width Width of destination buffer (pixels)
676 * @param height Height of destination buffer (pixels)
677 * @param linesize Line size of destination buffer (bytes)
678 */
decode_rgb8(GetByteContext * gb,uint8_t * dst,int width,int height,int linesize)679 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
680 {
681 int x = 0, y = 0, i, length;
682 while (bytestream2_get_bytes_left(gb) >= 4) {
683 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
684 length = bytestream2_get_byte(gb) & 0x7F;
685 DECODE_RGBX_COMMON(uint32_t)
686 }
687 }
688
689 /**
690 * Decode RGBN buffer
691 * @param[out] dst Destination buffer
692 * @param width Width of destination buffer (pixels)
693 * @param height Height of destination buffer (pixels)
694 * @param linesize Line size of destination buffer (bytes)
695 */
decode_rgbn(GetByteContext * gb,uint8_t * dst,int width,int height,int linesize)696 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
697 {
698 int x = 0, y = 0, i, length;
699 while (bytestream2_get_bytes_left(gb) >= 2) {
700 uint32_t pixel = bytestream2_get_be16u(gb);
701 length = pixel & 0x7;
702 pixel >>= 4;
703 DECODE_RGBX_COMMON(uint16_t)
704 }
705 }
706
707 /**
708 * Decode DEEP RLE 32-bit buffer
709 * @param[out] dst Destination buffer
710 * @param[in] src Source buffer
711 * @param src_size Source buffer size (bytes)
712 * @param width Width of destination buffer (pixels)
713 * @param height Height of destination buffer (pixels)
714 * @param linesize Line size of destination buffer (bytes)
715 */
decode_deep_rle32(uint8_t * dst,const uint8_t * src,int src_size,int width,int height,int linesize)716 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
717 {
718 const uint8_t *src_end = src + src_size;
719 int x = 0, y = 0, i;
720 while (src_end - src >= 5) {
721 int opcode;
722 opcode = *(int8_t *)src++;
723 if (opcode >= 0) {
724 int size = opcode + 1;
725 for (i = 0; i < size; i++) {
726 int length = FFMIN(size - i, width - x);
727 if (src_end - src < length * 4)
728 return;
729 memcpy(dst + y*linesize + x * 4, src, length * 4);
730 src += length * 4;
731 x += length;
732 i += length;
733 if (x >= width) {
734 x = 0;
735 y += 1;
736 if (y >= height)
737 return;
738 }
739 }
740 } else {
741 int size = -opcode + 1;
742 uint32_t pixel = AV_RN32(src);
743 for (i = 0; i < size; i++) {
744 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
745 x += 1;
746 if (x >= width) {
747 x = 0;
748 y += 1;
749 if (y >= height)
750 return;
751 }
752 }
753 src += 4;
754 }
755 }
756 }
757
758 /**
759 * Decode DEEP TVDC 32-bit buffer
760 * @param[out] dst Destination buffer
761 * @param[in] src Source buffer
762 * @param src_size Source buffer size (bytes)
763 * @param width Width of destination buffer (pixels)
764 * @param height Height of destination buffer (pixels)
765 * @param linesize Line size of destination buffer (bytes)
766 * @param[int] tvdc TVDC lookup table
767 */
decode_deep_tvdc32(uint8_t * dst,const uint8_t * src,int src_size,int width,int height,int linesize,const int16_t * tvdc)768 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)
769 {
770 int x = 0, y = 0, plane = 0;
771 int8_t pixel = 0;
772 int i, j;
773
774 for (i = 0; i < src_size * 2;) {
775 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
776 int d = tvdc[GETNIBBLE];
777 i++;
778 if (d) {
779 pixel += d;
780 dst[y * linesize + x*4 + plane] = pixel;
781 x++;
782 } else {
783 if (i >= src_size * 2)
784 return;
785 d = GETNIBBLE + 1;
786 i++;
787 d = FFMIN(d, width - x);
788 for (j = 0; j < d; j++) {
789 dst[y * linesize + x*4 + plane] = pixel;
790 x++;
791 }
792 }
793 if (x >= width) {
794 plane++;
795 if (plane >= 4) {
796 y++;
797 if (y >= height)
798 return;
799 plane = 0;
800 }
801 x = 0;
802 pixel = 0;
803 i = (i + 1) & ~1;
804 }
805 }
806 }
807
decode_short_horizontal_delta(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int bpp,int dst_size)808 static void decode_short_horizontal_delta(uint8_t *dst,
809 const uint8_t *buf, const uint8_t *buf_end,
810 int w, int bpp, int dst_size)
811 {
812 int planepitch = FFALIGN(w, 16) >> 3;
813 int pitch = planepitch * bpp;
814 GetByteContext ptrs, gb;
815 PutByteContext pb;
816 unsigned ofssrc, pos;
817 int i, k;
818
819 bytestream2_init(&ptrs, buf, buf_end - buf);
820 bytestream2_init_writer(&pb, dst, dst_size);
821
822 for (k = 0; k < bpp; k++) {
823 ofssrc = bytestream2_get_be32(&ptrs);
824 pos = 0;
825
826 if (!ofssrc)
827 continue;
828
829 if (ofssrc >= buf_end - buf)
830 continue;
831
832 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
833 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
834 int16_t offset = bytestream2_get_be16(&gb);
835 unsigned noffset;
836
837 if (offset >= 0) {
838 unsigned data = bytestream2_get_be16(&gb);
839
840 pos += offset * 2;
841 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
842 bytestream2_seek_p(&pb, noffset, SEEK_SET);
843 bytestream2_put_be16(&pb, data);
844 } else {
845 uint16_t count = bytestream2_get_be16(&gb);
846
847 pos += 2 * -(offset + 2);
848 for (i = 0; i < count; i++) {
849 uint16_t data = bytestream2_get_be16(&gb);
850
851 pos += 2;
852 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
853 bytestream2_seek_p(&pb, noffset, SEEK_SET);
854 bytestream2_put_be16(&pb, data);
855 }
856 }
857 }
858 }
859 }
860
decode_byte_vertical_delta(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int xor,int bpp,int dst_size)861 static void decode_byte_vertical_delta(uint8_t *dst,
862 const uint8_t *buf, const uint8_t *buf_end,
863 int w, int xor, int bpp, int dst_size)
864 {
865 int ncolumns = ((w + 15) / 16) * 2;
866 int dstpitch = ncolumns * bpp;
867 unsigned ofsdst, ofssrc, opcode, x;
868 GetByteContext ptrs, gb;
869 PutByteContext pb;
870 int i, j, k;
871
872 bytestream2_init(&ptrs, buf, buf_end - buf);
873 bytestream2_init_writer(&pb, dst, dst_size);
874
875 for (k = 0; k < bpp; k++) {
876 ofssrc = bytestream2_get_be32(&ptrs);
877
878 if (!ofssrc)
879 continue;
880
881 if (ofssrc >= buf_end - buf)
882 continue;
883
884 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
885 for (j = 0; j < ncolumns; j++) {
886 ofsdst = j + k * ncolumns;
887
888 i = bytestream2_get_byte(&gb);
889 while (i > 0) {
890 opcode = bytestream2_get_byte(&gb);
891
892 if (opcode == 0) {
893 opcode = bytestream2_get_byte(&gb);
894 x = bytestream2_get_byte(&gb);
895
896 while (opcode) {
897 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
898 if (xor && ofsdst < dst_size) {
899 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
900 } else {
901 bytestream2_put_byte(&pb, x);
902 }
903 ofsdst += dstpitch;
904 opcode--;
905 }
906 } else if (opcode < 0x80) {
907 ofsdst += opcode * dstpitch;
908 } else {
909 opcode &= 0x7f;
910
911 while (opcode) {
912 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
913 if (xor && ofsdst < dst_size) {
914 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
915 } else {
916 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
917 }
918 ofsdst += dstpitch;
919 opcode--;
920 }
921 }
922 i--;
923 }
924 }
925 }
926 }
927
decode_delta_j(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int h,int bpp,int dst_size)928 static void decode_delta_j(uint8_t *dst,
929 const uint8_t *buf, const uint8_t *buf_end,
930 int w, int h, int bpp, int dst_size)
931 {
932 int32_t pitch;
933 uint8_t *ptr;
934 uint32_t type, flag, cols, groups, rows, bytes;
935 uint32_t offset;
936 int planepitch_byte = (w + 7) / 8;
937 int planepitch = ((w + 15) / 16) * 2;
938 int kludge_j, b, g, r, d;
939 GetByteContext gb;
940
941 pitch = planepitch * bpp;
942 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
943
944 bytestream2_init(&gb, buf, buf_end - buf);
945
946 while (bytestream2_get_bytes_left(&gb) >= 2) {
947 type = bytestream2_get_be16(&gb);
948
949 switch (type) {
950 case 0:
951 return;
952 case 1:
953 flag = bytestream2_get_be16(&gb);
954 cols = bytestream2_get_be16(&gb);
955 groups = bytestream2_get_be16(&gb);
956
957 for (g = 0; g < groups; g++) {
958 offset = bytestream2_get_be16(&gb);
959
960 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
961 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
962 return;
963 }
964
965 if (kludge_j)
966 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
967 else
968 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
969
970 for (b = 0; b < cols; b++) {
971 for (d = 0; d < bpp; d++) {
972 uint8_t value = bytestream2_get_byte(&gb);
973
974 if (offset >= dst_size)
975 return;
976 ptr = dst + offset;
977
978 if (flag)
979 ptr[0] ^= value;
980 else
981 ptr[0] = value;
982
983 offset += planepitch;
984 }
985 }
986 if ((cols * bpp) & 1)
987 bytestream2_skip(&gb, 1);
988 }
989 break;
990 case 2:
991 flag = bytestream2_get_be16(&gb);
992 rows = bytestream2_get_be16(&gb);
993 bytes = bytestream2_get_be16(&gb);
994 groups = bytestream2_get_be16(&gb);
995
996 for (g = 0; g < groups; g++) {
997 offset = bytestream2_get_be16(&gb);
998
999 if (kludge_j)
1000 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
1001 else
1002 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
1003
1004 for (r = 0; r < rows; r++) {
1005 for (d = 0; d < bpp; d++) {
1006 unsigned noffset = offset + (r * pitch) + d * planepitch;
1007
1008 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1009 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1010 return;
1011 }
1012
1013 for (b = 0; b < bytes; b++) {
1014 uint8_t value = bytestream2_get_byte(&gb);
1015
1016 if (noffset >= dst_size)
1017 return;
1018 ptr = dst + noffset;
1019
1020 if (flag)
1021 ptr[0] ^= value;
1022 else
1023 ptr[0] = value;
1024
1025 noffset++;
1026 }
1027 }
1028 }
1029 if ((rows * bytes * bpp) & 1)
1030 bytestream2_skip(&gb, 1);
1031 }
1032 break;
1033 default:
1034 return;
1035 }
1036 }
1037 }
1038
decode_short_vertical_delta(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int bpp,int dst_size)1039 static void decode_short_vertical_delta(uint8_t *dst,
1040 const uint8_t *buf, const uint8_t *buf_end,
1041 int w, int bpp, int dst_size)
1042 {
1043 int ncolumns = (w + 15) >> 4;
1044 int dstpitch = ncolumns * bpp * 2;
1045 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1046 GetByteContext ptrs, gb, dptrs, dgb;
1047 PutByteContext pb;
1048 int i, j, k;
1049
1050 if (buf_end - buf <= 64)
1051 return;
1052
1053 bytestream2_init(&ptrs, buf, buf_end - buf);
1054 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1055 bytestream2_init_writer(&pb, dst, dst_size);
1056
1057 for (k = 0; k < bpp; k++) {
1058 ofssrc = bytestream2_get_be32(&ptrs);
1059 ofsdata = bytestream2_get_be32(&dptrs);
1060
1061 if (!ofssrc)
1062 continue;
1063
1064 if (ofssrc >= buf_end - buf)
1065 return;
1066
1067 if (ofsdata >= buf_end - buf)
1068 return;
1069
1070 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1071 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1072 for (j = 0; j < ncolumns; j++) {
1073 ofsdst = (j + k * ncolumns) * 2;
1074
1075 i = bytestream2_get_byte(&gb);
1076 while (i > 0) {
1077 opcode = bytestream2_get_byte(&gb);
1078
1079 if (opcode == 0) {
1080 opcode = bytestream2_get_byte(&gb);
1081 x = bytestream2_get_be16(&dgb);
1082
1083 while (opcode) {
1084 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1085 bytestream2_put_be16(&pb, x);
1086 ofsdst += dstpitch;
1087 opcode--;
1088 }
1089 } else if (opcode < 0x80) {
1090 ofsdst += opcode * dstpitch;
1091 } else {
1092 opcode &= 0x7f;
1093
1094 while (opcode) {
1095 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1096 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1097 ofsdst += dstpitch;
1098 opcode--;
1099 }
1100 }
1101 i--;
1102 }
1103 }
1104 }
1105 }
1106
decode_long_vertical_delta(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int bpp,int dst_size)1107 static void decode_long_vertical_delta(uint8_t *dst,
1108 const uint8_t *buf, const uint8_t *buf_end,
1109 int w, int bpp, int dst_size)
1110 {
1111 int ncolumns = (w + 31) >> 5;
1112 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1113 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1114 GetByteContext ptrs, gb, dptrs, dgb;
1115 PutByteContext pb;
1116 int i, j, k, h;
1117
1118 if (buf_end - buf <= 64)
1119 return;
1120
1121 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1122 bytestream2_init(&ptrs, buf, buf_end - buf);
1123 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1124 bytestream2_init_writer(&pb, dst, dst_size);
1125
1126 for (k = 0; k < bpp; k++) {
1127 ofssrc = bytestream2_get_be32(&ptrs);
1128 ofsdata = bytestream2_get_be32(&dptrs);
1129
1130 if (!ofssrc)
1131 continue;
1132
1133 if (ofssrc >= buf_end - buf)
1134 return;
1135
1136 if (ofsdata >= buf_end - buf)
1137 return;
1138
1139 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1140 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1141 for (j = 0; j < ncolumns; j++) {
1142 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1143
1144 i = bytestream2_get_byte(&gb);
1145 while (i > 0) {
1146 opcode = bytestream2_get_byte(&gb);
1147
1148 if (opcode == 0) {
1149 opcode = bytestream2_get_byte(&gb);
1150 if (h && (j == (ncolumns - 1))) {
1151 x = bytestream2_get_be16(&dgb);
1152 bytestream2_skip(&dgb, 2);
1153 } else {
1154 x = bytestream2_get_be32(&dgb);
1155 }
1156
1157 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1158 return;
1159
1160 while (opcode) {
1161 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1162 if (h && (j == (ncolumns - 1))) {
1163 bytestream2_put_be16(&pb, x);
1164 } else {
1165 bytestream2_put_be32(&pb, x);
1166 }
1167 ofsdst += dstpitch;
1168 opcode--;
1169 }
1170 } else if (opcode < 0x80) {
1171 ofsdst += opcode * dstpitch;
1172 } else {
1173 opcode &= 0x7f;
1174
1175 while (opcode) {
1176 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1177 if (h && (j == (ncolumns - 1))) {
1178 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1179 bytestream2_skip(&dgb, 2);
1180 } else {
1181 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1182 }
1183 ofsdst += dstpitch;
1184 opcode--;
1185 }
1186 }
1187 i--;
1188 }
1189 }
1190 }
1191 }
1192
decode_short_vertical_delta2(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int bpp,int dst_size)1193 static void decode_short_vertical_delta2(uint8_t *dst,
1194 const uint8_t *buf, const uint8_t *buf_end,
1195 int w, int bpp, int dst_size)
1196 {
1197 int ncolumns = (w + 15) >> 4;
1198 int dstpitch = ncolumns * bpp * 2;
1199 unsigned ofsdst, ofssrc, opcode, x;
1200 GetByteContext ptrs, gb;
1201 PutByteContext pb;
1202 int i, j, k;
1203
1204 bytestream2_init(&ptrs, buf, buf_end - buf);
1205 bytestream2_init_writer(&pb, dst, dst_size);
1206
1207 for (k = 0; k < bpp; k++) {
1208 ofssrc = bytestream2_get_be32(&ptrs);
1209
1210 if (!ofssrc)
1211 continue;
1212
1213 if (ofssrc >= buf_end - buf)
1214 continue;
1215
1216 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1217 for (j = 0; j < ncolumns; j++) {
1218 ofsdst = (j + k * ncolumns) * 2;
1219
1220 i = bytestream2_get_be16(&gb);
1221 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1222 opcode = bytestream2_get_be16(&gb);
1223
1224 if (opcode == 0) {
1225 opcode = bytestream2_get_be16(&gb);
1226 x = bytestream2_get_be16(&gb);
1227
1228 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1229 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1230 bytestream2_put_be16(&pb, x);
1231 ofsdst += dstpitch;
1232 opcode--;
1233 }
1234 } else if (opcode < 0x8000) {
1235 ofsdst += opcode * dstpitch;
1236 } else {
1237 opcode &= 0x7fff;
1238
1239 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1240 bytestream2_get_bytes_left_p(&pb) > 1) {
1241 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1242 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1243 ofsdst += dstpitch;
1244 opcode--;
1245 }
1246 }
1247 i--;
1248 }
1249 }
1250 }
1251 }
1252
decode_long_vertical_delta2(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int bpp,int dst_size)1253 static void decode_long_vertical_delta2(uint8_t *dst,
1254 const uint8_t *buf, const uint8_t *buf_end,
1255 int w, int bpp, int dst_size)
1256 {
1257 int ncolumns = (w + 31) >> 5;
1258 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1259 unsigned ofsdst, ofssrc, opcode, x;
1260 unsigned skip = 0x80000000, mask = skip - 1;
1261 GetByteContext ptrs, gb;
1262 PutByteContext pb;
1263 int i, j, k, h;
1264
1265 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1266 bytestream2_init(&ptrs, buf, buf_end - buf);
1267 bytestream2_init_writer(&pb, dst, dst_size);
1268
1269 for (k = 0; k < bpp; k++) {
1270 ofssrc = bytestream2_get_be32(&ptrs);
1271
1272 if (!ofssrc)
1273 continue;
1274
1275 if (ofssrc >= buf_end - buf)
1276 continue;
1277
1278 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1279 for (j = 0; j < ncolumns; j++) {
1280 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1281
1282 if (h && (j == (ncolumns - 1))) {
1283 skip = 0x8000;
1284 mask = skip - 1;
1285 }
1286
1287 i = bytestream2_get_be32(&gb);
1288 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1289 opcode = bytestream2_get_be32(&gb);
1290
1291 if (opcode == 0) {
1292 if (h && (j == ncolumns - 1)) {
1293 opcode = bytestream2_get_be16(&gb);
1294 x = bytestream2_get_be16(&gb);
1295 } else {
1296 opcode = bytestream2_get_be32(&gb);
1297 x = bytestream2_get_be32(&gb);
1298 }
1299
1300 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1301 return;
1302
1303 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1304 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1305 if (h && (j == ncolumns - 1))
1306 bytestream2_put_be16(&pb, x);
1307 else
1308 bytestream2_put_be32(&pb, x);
1309 ofsdst += dstpitch;
1310 opcode--;
1311 }
1312 } else if (opcode < skip) {
1313 ofsdst += opcode * dstpitch;
1314 } else {
1315 opcode &= mask;
1316
1317 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1318 bytestream2_get_bytes_left_p(&pb) > 1) {
1319 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1320 if (h && (j == ncolumns - 1)) {
1321 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1322 } else {
1323 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1324 }
1325 ofsdst += dstpitch;
1326 opcode--;
1327 }
1328 }
1329 i--;
1330 }
1331 }
1332 }
1333 }
1334
decode_delta_d(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int flag,int bpp,int dst_size)1335 static void decode_delta_d(uint8_t *dst,
1336 const uint8_t *buf, const uint8_t *buf_end,
1337 int w, int flag, int bpp, int dst_size)
1338 {
1339 int planepitch = FFALIGN(w, 16) >> 3;
1340 int pitch = planepitch * bpp;
1341 int planepitch_byte = (w + 7) / 8;
1342 unsigned entries, ofssrc;
1343 GetByteContext gb, ptrs;
1344 PutByteContext pb;
1345 int k;
1346
1347 if (buf_end - buf <= 4 * bpp)
1348 return;
1349
1350 bytestream2_init_writer(&pb, dst, dst_size);
1351 bytestream2_init(&ptrs, buf, bpp * 4);
1352
1353 for (k = 0; k < bpp; k++) {
1354 ofssrc = bytestream2_get_be32(&ptrs);
1355
1356 if (!ofssrc)
1357 continue;
1358
1359 if (ofssrc >= buf_end - buf)
1360 continue;
1361
1362 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1363
1364 entries = bytestream2_get_be32(&gb);
1365 if (entries * 8LL > bytestream2_get_bytes_left(&gb))
1366 return;
1367
1368 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1369 int32_t opcode = bytestream2_get_be32(&gb);
1370 unsigned offset = bytestream2_get_be32(&gb);
1371
1372 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1373 if (opcode >= 0) {
1374 uint32_t x = bytestream2_get_be32(&gb);
1375 if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1376 continue;
1377 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1378 bytestream2_put_be32(&pb, x);
1379 bytestream2_skip_p(&pb, pitch - 4);
1380 opcode--;
1381 }
1382 } else {
1383 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1384 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1385 bytestream2_skip_p(&pb, pitch - 4);
1386 opcode++;
1387 }
1388 }
1389 entries--;
1390 }
1391 }
1392 }
1393
decode_delta_e(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int flag,int bpp,int dst_size)1394 static void decode_delta_e(uint8_t *dst,
1395 const uint8_t *buf, const uint8_t *buf_end,
1396 int w, int flag, int bpp, int dst_size)
1397 {
1398 int planepitch = FFALIGN(w, 16) >> 3;
1399 int pitch = planepitch * bpp;
1400 int planepitch_byte = (w + 7) / 8;
1401 unsigned entries, ofssrc;
1402 GetByteContext gb, ptrs;
1403 PutByteContext pb;
1404 int k;
1405
1406 if (buf_end - buf <= 4 * bpp)
1407 return;
1408
1409 bytestream2_init_writer(&pb, dst, dst_size);
1410 bytestream2_init(&ptrs, buf, bpp * 4);
1411
1412 for (k = 0; k < bpp; k++) {
1413 ofssrc = bytestream2_get_be32(&ptrs);
1414
1415 if (!ofssrc)
1416 continue;
1417
1418 if (ofssrc >= buf_end - buf)
1419 continue;
1420
1421 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1422
1423 entries = bytestream2_get_be16(&gb);
1424 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1425 int16_t opcode = bytestream2_get_be16(&gb);
1426 unsigned offset = bytestream2_get_be32(&gb);
1427
1428 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1429 if (opcode >= 0) {
1430 uint16_t x = bytestream2_get_be16(&gb);
1431 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1432 bytestream2_put_be16(&pb, x);
1433 bytestream2_skip_p(&pb, pitch - 2);
1434 opcode--;
1435 }
1436 } else {
1437 opcode = -opcode;
1438 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1439 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1440 bytestream2_skip_p(&pb, pitch - 2);
1441 opcode--;
1442 }
1443 }
1444 entries--;
1445 }
1446 }
1447 }
1448
decode_delta_l(uint8_t * dst,const uint8_t * buf,const uint8_t * buf_end,int w,int flag,int bpp,int dst_size)1449 static void decode_delta_l(uint8_t *dst,
1450 const uint8_t *buf, const uint8_t *buf_end,
1451 int w, int flag, int bpp, int dst_size)
1452 {
1453 GetByteContext off0, off1, dgb, ogb;
1454 PutByteContext pb;
1455 unsigned poff0, poff1;
1456 int i, k, dstpitch;
1457 int planepitch_byte = (w + 7) / 8;
1458 int planepitch = ((w + 15) / 16) * 2;
1459 int pitch = planepitch * bpp;
1460
1461 if (buf_end - buf <= 64)
1462 return;
1463
1464 bytestream2_init(&off0, buf, buf_end - buf);
1465 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1466 bytestream2_init_writer(&pb, dst, dst_size);
1467
1468 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1469
1470 for (k = 0; k < bpp; k++) {
1471 poff0 = bytestream2_get_be32(&off0);
1472 poff1 = bytestream2_get_be32(&off1);
1473
1474 if (!poff0)
1475 continue;
1476
1477 if (2LL * poff0 >= buf_end - buf)
1478 return;
1479
1480 if (2LL * poff1 >= buf_end - buf)
1481 return;
1482
1483 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1484 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1485
1486 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1487 uint32_t offset = bytestream2_get_be16(&ogb);
1488 int16_t cnt = bytestream2_get_be16(&ogb);
1489 uint16_t data;
1490
1491 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1492 if (cnt < 0) {
1493 if (bytestream2_get_bytes_left(&dgb) < 2)
1494 break;
1495 bytestream2_seek_p(&pb, offset, SEEK_SET);
1496 cnt = -cnt;
1497 data = bytestream2_get_be16(&dgb);
1498 for (i = 0; i < cnt; i++) {
1499 bytestream2_put_be16(&pb, data);
1500 bytestream2_skip_p(&pb, dstpitch - 2);
1501 }
1502 } else {
1503 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1504 break;
1505 bytestream2_seek_p(&pb, offset, SEEK_SET);
1506 for (i = 0; i < cnt; i++) {
1507 data = bytestream2_get_be16(&dgb);
1508 bytestream2_put_be16(&pb, data);
1509 bytestream2_skip_p(&pb, dstpitch - 2);
1510 }
1511 }
1512 }
1513 }
1514 }
1515
unsupported(AVCodecContext * avctx)1516 static int unsupported(AVCodecContext *avctx)
1517 {
1518 IffContext *s = avctx->priv_data;
1519 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1520 return AVERROR_INVALIDDATA;
1521 }
1522
decode_frame(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * avpkt)1523 static int decode_frame(AVCodecContext *avctx,
1524 void *data, int *got_frame,
1525 AVPacket *avpkt)
1526 {
1527 IffContext *s = avctx->priv_data;
1528 AVFrame *frame = data;
1529 const uint8_t *buf = avpkt->data;
1530 int buf_size = avpkt->size;
1531 const uint8_t *buf_end = buf + buf_size;
1532 int y, plane, res;
1533 GetByteContext *gb = &s->gb;
1534 const AVPixFmtDescriptor *desc;
1535
1536 bytestream2_init(gb, avpkt->data, avpkt->size);
1537
1538 if ((res = extract_header(avctx, avpkt)) < 0)
1539 return res;
1540
1541 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1542 return res;
1543 s->frame = frame;
1544
1545 buf += bytestream2_tell(gb);
1546 buf_size -= bytestream2_tell(gb);
1547 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1548
1549 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1550 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1551 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1552 return res;
1553 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1554 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1555 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1556 return res;
1557 }
1558 s->init = 1;
1559
1560 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1561 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1562 memcpy(s->pal, s->frame->data[1], 256 * 4);
1563 }
1564
1565 switch (s->compression) {
1566 case 0x0:
1567 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1568 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1569 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1570 for (plane = 0; plane < s->bpp; plane++) {
1571 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1572 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1573 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1574 buf += s->planesize;
1575 }
1576 }
1577 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1578 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1579 for (y = 0; y < avctx->height; y++) {
1580 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1581 memset(s->ham_buf, 0, s->planesize * 8);
1582 for (plane = 0; plane < s->bpp; plane++) {
1583 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1584 if (start >= buf_end)
1585 break;
1586 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1587 }
1588 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1589 }
1590 } else
1591 return unsupported(avctx);
1592 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1593 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1594 int x;
1595 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1596 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1597 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1598 buf += raw_width;
1599 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1600 for (x = 0; x < avctx->width; x++)
1601 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1602 }
1603 }
1604 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1605 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1606 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1607 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1608 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1609 for (y = 0; y < avctx->height; y++) {
1610 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1611 memset(row, 0, avctx->width);
1612 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1613 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1614 buf += s->planesize;
1615 }
1616 }
1617 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1618 for (y = 0; y < avctx->height; y++) {
1619 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1620 memset(s->ham_buf, 0, s->planesize * 8);
1621 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1622 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1623 buf += s->planesize;
1624 }
1625 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1626 }
1627 } else { // AV_PIX_FMT_BGR32
1628 for (y = 0; y < avctx->height; y++) {
1629 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1630 memset(row, 0, avctx->width << 2);
1631 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1632 decodeplane32((uint32_t *)row, buf,
1633 FFMIN(s->planesize, buf_end - buf), plane);
1634 buf += s->planesize;
1635 }
1636 }
1637 }
1638 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1639 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1640 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1641 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1642 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1643 buf += avctx->width + (avctx->width % 2); // padding if odd
1644 }
1645 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1646 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1647 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1648 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1649 buf += avctx->width + (avctx->width & 1); // padding if odd
1650 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1651 }
1652 } else
1653 return unsupported(avctx);
1654 } else {
1655 return unsupported(avctx);
1656 }
1657 break;
1658 case 0x1:
1659 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1660 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1661 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1662 uint8_t *video = s->video[0];
1663
1664 for (y = 0; y < avctx->height; y++) {
1665 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1666 memset(row, 0, avctx->width);
1667 for (plane = 0; plane < s->bpp; plane++) {
1668 buf += decode_byterun(s->planebuf, s->planesize, gb);
1669 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1670 memcpy(video, s->planebuf, s->planesize);
1671 video += s->planesize;
1672 }
1673 decodeplane8(row, s->planebuf, s->planesize, plane);
1674 }
1675 }
1676 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1677 for (y = 0; y < avctx->height; y++) {
1678 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1679 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1680 for (plane = 0; plane < s->bpp; plane++) {
1681 buf += decode_byterun(s->planebuf, s->planesize, gb);
1682 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1683 }
1684 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1685 }
1686 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1687 uint8_t *video = s->video[0];
1688 for (y = 0; y < avctx->height; y++) {
1689 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1690 memset(s->ham_buf, 0, s->planesize * 8);
1691 for (plane = 0; plane < s->bpp; plane++) {
1692 buf += decode_byterun(s->planebuf, s->planesize, gb);
1693 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1694 memcpy(video, s->planebuf, s->planesize);
1695 video += s->planesize;
1696 }
1697 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1698 }
1699 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1700 }
1701 } else { // AV_PIX_FMT_BGR32
1702 for (y = 0; y < avctx->height; y++) {
1703 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1704 memset(row, 0, avctx->width << 2);
1705 for (plane = 0; plane < s->bpp; plane++) {
1706 buf += decode_byterun(s->planebuf, s->planesize, gb);
1707 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1708 }
1709 }
1710 }
1711 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1712 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1713 for (y = 0; y < avctx->height; y++) {
1714 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1715 buf += decode_byterun(row, avctx->width, gb);
1716 }
1717 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1718 for (y = 0; y < avctx->height; y++) {
1719 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1720 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1721 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1722 }
1723 } else
1724 return unsupported(avctx);
1725 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1726 if (av_get_bits_per_pixel(desc) == 32)
1727 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1728 else
1729 return unsupported(avctx);
1730 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1731 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1732 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1733 for (plane = 0; plane < s->bpp; plane++) {
1734 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1735 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1736 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1737 buf += s->planesize;
1738 }
1739 }
1740 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1741 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1742 for (y = 0; y < avctx->height; y++) {
1743 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1744 memset(s->ham_buf, 0, s->planesize * 8);
1745 for (plane = 0; plane < s->bpp; plane++) {
1746 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1747 if (start >= buf_end)
1748 break;
1749 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1750 }
1751 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1752 }
1753 } else {
1754 return unsupported(avctx);
1755 }
1756 } else {
1757 return unsupported(avctx);
1758 }
1759 break;
1760 case 0x2:
1761 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1762 for (plane = 0; plane < s->bpp; plane++) {
1763 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1764 for (y = 0; y < avctx->height; y++) {
1765 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1766 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1767 }
1768 }
1769 } else {
1770 return unsupported(avctx);
1771 }
1772 break;
1773 case 0x4:
1774 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1775 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1776 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1777 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1778 else
1779 return unsupported(avctx);
1780 break;
1781 case 0x5:
1782 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1783 if (av_get_bits_per_pixel(desc) == 32)
1784 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1785 else
1786 return unsupported(avctx);
1787 } else
1788 return unsupported(avctx);
1789 break;
1790 case 0x300:
1791 case 0x301:
1792 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1793 break;
1794 case 0x500:
1795 case 0x501:
1796 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1797 break;
1798 case 0x700:
1799 case 0x701:
1800 if (s->is_short)
1801 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1802 else
1803 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1804 break;
1805 case 0x800:
1806 case 0x801:
1807 if (s->is_short)
1808 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1809 else
1810 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1811 break;
1812 case 0x4a00:
1813 case 0x4a01:
1814 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1815 break;
1816 case 0x6400:
1817 case 0x6401:
1818 if (s->is_interlaced)
1819 return unsupported(avctx);
1820 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1821 break;
1822 case 0x6500:
1823 case 0x6501:
1824 if (s->is_interlaced)
1825 return unsupported(avctx);
1826 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1827 break;
1828 case 0x6c00:
1829 case 0x6c01:
1830 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1831 break;
1832 default:
1833 return unsupported(avctx);
1834 }
1835
1836 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1837 memcpy(s->video[1], s->video[0], s->video_size);
1838 }
1839
1840 if (s->compression > 0xff) {
1841 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1842 buf = s->video[0];
1843 for (y = 0; y < avctx->height; y++) {
1844 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1845 memset(row, 0, avctx->width);
1846 for (plane = 0; plane < s->bpp; plane++) {
1847 decodeplane8(row, buf, s->planesize, plane);
1848 buf += s->planesize;
1849 }
1850 }
1851 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1852 memcpy(frame->data[1], s->pal, 256 * 4);
1853 } else if (s->ham) {
1854 int i, count = 1 << s->ham;
1855
1856 buf = s->video[0];
1857 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1858 for (i = 0; i < count; i++) {
1859 s->ham_palbuf[i*2+1] = s->pal[i];
1860 }
1861 for (i = 0; i < count; i++) {
1862 uint32_t tmp = i << (8 - s->ham);
1863 tmp |= tmp >> s->ham;
1864 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1865 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1866 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1867 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1868 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1869 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1870 }
1871 if (s->masking == MASK_HAS_MASK) {
1872 for (i = 0; i < 8 * (1 << s->ham); i++)
1873 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1874 }
1875 for (y = 0; y < avctx->height; y++) {
1876 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1877 memset(s->ham_buf, 0, s->planesize * 8);
1878 for (plane = 0; plane < s->bpp; plane++) {
1879 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1880 buf += s->planesize;
1881 }
1882 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1883 }
1884 } else {
1885 return unsupported(avctx);
1886 }
1887
1888 if (!s->is_brush) {
1889 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1890 }
1891 }
1892
1893 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1894 frame->key_frame = 1;
1895 frame->pict_type = AV_PICTURE_TYPE_I;
1896 } else {
1897 frame->key_frame = 0;
1898 frame->pict_type = AV_PICTURE_TYPE_P;
1899 }
1900
1901 *got_frame = 1;
1902
1903 return buf_size;
1904 }
1905
1906 #if CONFIG_IFF_ILBM_DECODER
1907 AVCodec ff_iff_ilbm_decoder = {
1908 .name = "iff",
1909 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1910 .type = AVMEDIA_TYPE_VIDEO,
1911 .id = AV_CODEC_ID_IFF_ILBM,
1912 .priv_data_size = sizeof(IffContext),
1913 .init = decode_init,
1914 .close = decode_end,
1915 .decode = decode_frame,
1916 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1917 .capabilities = AV_CODEC_CAP_DR1,
1918 };
1919 #endif
1920