2 * IFF ACBM/ANIM/DEEP/ILBM/PBM 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
7 * This file is part of FFmpeg.
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.
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.
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
26 * IFF ACBM/ANIM/DEEP/ILBM/PBM bitmap decoder
31 #include "libavutil/imgutils.h"
32 #include "bytestream.h"
41 MASK_HAS_TRANSPARENT_COLOR,
45 typedef struct IffContext {
49 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
50 uint32_t *ham_palbuf; ///< HAM decode table
51 uint32_t *mask_buf; ///< temporary buffer for palette indices
52 uint32_t *mask_palbuf; ///< masking palette table
53 unsigned compression; ///< delta compression method used
54 unsigned is_short; ///< short compression method used
55 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
56 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
57 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
58 unsigned transparency; ///< TODO: transparency color index in palette
59 unsigned masking; ///< TODO: masking method used
60 int init; // 1 if buffer and palette data already initialized, 0 otherwise
61 int16_t tvdc[16]; ///< TVDC lookup table
69 #define LUT8_PART(plane, v) \
70 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
71 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
72 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
79 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
80 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
81 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
82 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
83 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
84 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
85 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
87 #define LUT8(plane) { \
88 LUT8_PART(plane, 0x0000000), \
89 LUT8_PART(plane, 0x1000000), \
90 LUT8_PART(plane, 0x0010000), \
91 LUT8_PART(plane, 0x1010000), \
92 LUT8_PART(plane, 0x0000100), \
93 LUT8_PART(plane, 0x1000100), \
94 LUT8_PART(plane, 0x0010100), \
95 LUT8_PART(plane, 0x1010100), \
96 LUT8_PART(plane, 0x0000001), \
97 LUT8_PART(plane, 0x1000001), \
98 LUT8_PART(plane, 0x0010001), \
99 LUT8_PART(plane, 0x1010001), \
100 LUT8_PART(plane, 0x0000101), \
101 LUT8_PART(plane, 0x1000101), \
102 LUT8_PART(plane, 0x0010101), \
103 LUT8_PART(plane, 0x1010101), \
106 // 8 planes * 8-bit mask
107 static const uint64_t plane8_lut[8][256] = {
108 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
109 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
112 #define LUT32(plane) { \
114 0, 0, 0, 1 << plane, \
115 0, 0, 1 << plane, 0, \
116 0, 0, 1 << plane, 1 << plane, \
117 0, 1 << plane, 0, 0, \
118 0, 1 << plane, 0, 1 << plane, \
119 0, 1 << plane, 1 << plane, 0, \
120 0, 1 << plane, 1 << plane, 1 << plane, \
121 1 << plane, 0, 0, 0, \
122 1 << plane, 0, 0, 1 << plane, \
123 1 << plane, 0, 1 << plane, 0, \
124 1 << plane, 0, 1 << plane, 1 << plane, \
125 1 << plane, 1 << plane, 0, 0, \
126 1 << plane, 1 << plane, 0, 1 << plane, \
127 1 << plane, 1 << plane, 1 << plane, 0, \
128 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
131 // 32 planes * 4-bit mask * 4 lookup tables each
132 static const uint32_t plane32_lut[32][16*4] = {
133 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
134 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
135 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
136 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
137 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
138 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
139 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
140 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
143 // Gray to RGB, required for palette table of grayscale images with bpp < 8
144 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
145 return x << 16 | x << 8 | x;
149 * Convert CMAP buffer (stored in extradata) to lavc palette format
151 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
153 IffContext *s = avctx->priv_data;
155 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
156 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
158 if (avctx->bits_per_coded_sample > 8) {
159 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
160 return AVERROR_INVALIDDATA;
163 count = 1 << avctx->bits_per_coded_sample;
164 // If extradata is smaller than actually needed, fill the remaining with black.
165 count = FFMIN(palette_size / 3, count);
167 for (i = 0; i < count; i++)
168 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
169 if (s->flags && count >= 32) { // EHB
170 for (i = 0; i < 32; i++)
171 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
172 count = FFMAX(count, 64);
174 } else { // Create gray-scale color palette for bps < 8
175 count = 1 << avctx->bits_per_coded_sample;
177 for (i = 0; i < count; i++)
178 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
180 if (s->masking == MASK_HAS_MASK) {
181 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
182 for (i = 0; i < count; i++)
184 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
185 s->transparency < 1 << avctx->bits_per_coded_sample)
186 pal[s->transparency] &= 0xFFFFFF;
191 * Extracts the IFF extra context and updates internal
192 * decoder structures.
194 * @param avctx the AVCodecContext where to extract extra context to
195 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
196 * @return >= 0 in case of success, a negative error code otherwise
198 static int extract_header(AVCodecContext *const avctx,
199 const AVPacket *const avpkt)
201 IffContext *s = avctx->priv_data;
203 unsigned buf_size = 0;
206 if (avctx->extradata_size < 2) {
207 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
208 return AVERROR_INVALIDDATA;
210 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
212 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
215 GetByteContext *gb = &s->gb;
217 bytestream2_skip(gb, 4);
218 while (bytestream2_get_bytes_left(gb) >= 1) {
219 chunk_id = bytestream2_get_le32(gb);
220 data_size = bytestream2_get_be32(gb);
222 if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
223 bytestream2_skip(gb, data_size + (data_size & 1));
224 } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
226 return AVERROR_INVALIDDATA;
228 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
229 bytestream2_skip(gb, 19);
230 s->is_short = !(bytestream2_get_be32(gb) & 1);
232 bytestream2_skip(gb, data_size + (data_size & 1));
233 } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
234 chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
235 if (chunk_id == MKTAG('B','O','D','Y'))
236 s->compression &= 0xFF;
238 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
239 int count = data_size / 3;
240 uint32_t *pal = s->pal[0];
243 return AVERROR_INVALIDDATA;
245 for (i = 0; i < count; i++)
246 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
248 for (i = 0; i < count; i++)
249 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
251 bytestream2_skip(gb, data_size & 1);
253 bytestream2_skip(gb, data_size + (data_size&1));
257 buf = avctx->extradata;
258 buf_size = bytestream_get_be16(&buf);
259 if (buf_size <= 1 || palette_size < 0) {
260 av_log(avctx, AV_LOG_ERROR,
261 "Invalid palette size received: %u -> palette data offset: %d\n",
262 buf_size, palette_size);
263 return AVERROR_INVALIDDATA;
267 if (buf_size >= 41) {
268 s->compression = bytestream_get_byte(&buf);
269 s->bpp = bytestream_get_byte(&buf);
270 s->ham = bytestream_get_byte(&buf);
271 s->flags = bytestream_get_byte(&buf);
272 s->transparency = bytestream_get_be16(&buf);
273 s->masking = bytestream_get_byte(&buf);
274 for (i = 0; i < 16; i++)
275 s->tvdc[i] = bytestream_get_be16(&buf);
277 if (s->masking == MASK_HAS_MASK) {
278 if (s->bpp >= 8 && !s->ham) {
279 avctx->pix_fmt = AV_PIX_FMT_RGB32;
280 av_freep(&s->mask_buf);
281 av_freep(&s->mask_palbuf);
282 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
284 return AVERROR(ENOMEM);
286 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
287 av_freep(&s->mask_buf);
288 return AVERROR(ENOMEM);
290 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
291 if (!s->mask_palbuf) {
292 av_freep(&s->mask_buf);
293 return AVERROR(ENOMEM);
297 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
298 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
299 return AVERROR_PATCHWELCOME;
301 if (!s->bpp || s->bpp > 32) {
302 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
303 return AVERROR_INVALIDDATA;
304 } else if (s->ham >= 8) {
305 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
306 return AVERROR_INVALIDDATA;
309 av_freep(&s->ham_buf);
310 av_freep(&s->ham_palbuf);
313 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
315 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
317 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
319 return AVERROR(ENOMEM);
321 ham_count = 8 * (1 << s->ham);
322 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
323 if (!s->ham_palbuf) {
324 av_freep(&s->ham_buf);
325 return AVERROR(ENOMEM);
328 if (count) { // HAM with color palette attached
329 // prefill with black and palette and set HAM take direct value mask to zero
330 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
331 for (i=0; i < count; i++) {
332 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
335 } else { // HAM with grayscale color palette
337 for (i=0; i < count; i++) {
338 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
339 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
342 for (i=0; i < count; i++) {
343 uint32_t tmp = i << (8 - s->ham);
344 tmp |= tmp >> s->ham;
345 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
346 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
347 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
348 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
349 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
350 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
352 if (s->masking == MASK_HAS_MASK) {
353 for (i = 0; i < ham_count; i++)
354 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
362 static av_cold int decode_end(AVCodecContext *avctx)
364 IffContext *s = avctx->priv_data;
365 av_freep(&s->planebuf);
366 av_freep(&s->ham_buf);
367 av_freep(&s->ham_palbuf);
368 av_freep(&s->video[0]);
369 av_freep(&s->video[1]);
370 av_freep(&s->pal[0]);
371 av_freep(&s->pal[1]);
375 static av_cold int decode_init(AVCodecContext *avctx)
377 IffContext *s = avctx->priv_data;
380 if (avctx->bits_per_coded_sample <= 8) {
383 if (avctx->extradata_size >= 2)
384 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
387 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
388 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
389 } else if (avctx->bits_per_coded_sample <= 32) {
390 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
391 avctx->pix_fmt = AV_PIX_FMT_RGB32;
392 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
393 avctx->pix_fmt = AV_PIX_FMT_RGB444;
394 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
395 if (avctx->bits_per_coded_sample == 24) {
396 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
397 } else if (avctx->bits_per_coded_sample == 32) {
398 avctx->pix_fmt = AV_PIX_FMT_BGR32;
400 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
401 return AVERROR_PATCHWELCOME;
405 return AVERROR_INVALIDDATA;
408 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
410 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
411 s->planebuf = av_malloc(s->planesize + AV_INPUT_BUFFER_PADDING_SIZE);
413 return AVERROR(ENOMEM);
415 s->bpp = avctx->bits_per_coded_sample;
417 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
418 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
419 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
420 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
421 s->pal[0] = av_calloc(256, sizeof(*s->pal[0]));
422 s->pal[1] = av_calloc(256, sizeof(*s->pal[1]));
423 if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
424 return AVERROR(ENOMEM);
428 if ((err = extract_header(avctx, NULL)) < 0)
435 * Decode interleaved plane buffer up to 8bpp
436 * @param dst Destination buffer
437 * @param buf Source buffer
439 * @param plane plane number to decode as
441 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
443 const uint64_t *lut = plane8_lut[plane];
445 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
449 uint64_t v = AV_RN64A(dst) | lut[*buf++];
452 } while (--buf_size);
456 * Decode interleaved plane buffer up to 24bpp
457 * @param dst Destination buffer
458 * @param buf Source buffer
460 * @param plane plane number to decode as
462 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
464 const uint32_t *lut = plane32_lut[plane];
466 unsigned mask = (*buf >> 2) & ~3;
467 dst[0] |= lut[mask++];
468 dst[1] |= lut[mask++];
469 dst[2] |= lut[mask++];
471 mask = (*buf++ << 2) & 0x3F;
472 dst[4] |= lut[mask++];
473 dst[5] |= lut[mask++];
474 dst[6] |= lut[mask++];
477 } while (--buf_size);
480 #define DECODE_HAM_PLANE32(x) \
481 first = buf[x] << 1; \
482 second = buf[(x)+1] << 1; \
483 delta &= pal[first++]; \
484 delta |= pal[first]; \
486 delta &= pal[second++]; \
487 delta |= pal[second]; \
491 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
493 * @param dst the destination 24bpp buffer
494 * @param buf the source 8bpp chunky buffer
495 * @param pal the HAM decode table
496 * @param buf_size the plane size in bytes
498 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
499 const uint32_t *const pal, unsigned buf_size)
501 uint32_t delta = pal[1]; /* first palette entry */
503 uint32_t first, second;
504 DECODE_HAM_PLANE32(0);
505 DECODE_HAM_PLANE32(2);
506 DECODE_HAM_PLANE32(4);
507 DECODE_HAM_PLANE32(6);
510 } while (--buf_size);
513 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
514 const uint32_t *const pal, unsigned width)
517 *dst++ = pal[*buf++];
522 * Decode one complete byterun1 encoded line.
524 * @param dst the destination buffer where to store decompressed bitstream
525 * @param dst_size the destination plane size in bytes
526 * @param buf the source byterun1 compressed bitstream
527 * @param buf_end the EOF of source byterun1 compressed bitstream
528 * @return number of consumed bytes in byterun1 compressed bitstream
530 static int decode_byterun(uint8_t *dst, int dst_size,
534 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
536 const int8_t value = bytestream2_get_byte(gb);
538 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
539 bytestream2_get_buffer(gb, dst + x, length);
540 } else if (value > -128) {
541 length = FFMIN(-value + 1, dst_size - x);
542 memset(dst + x, bytestream2_get_byte(gb), length);
549 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
550 memset(dst+x, 0, dst_size - x);
552 return bytestream2_tell(gb);
555 #define DECODE_RGBX_COMMON(type) \
557 length = bytestream2_get_byte(gb); \
559 length = bytestream2_get_be16(gb); \
564 for (i = 0; i < length; i++) { \
565 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
577 * @param[out] dst Destination buffer
578 * @param width Width of destination buffer (pixels)
579 * @param height Height of destination buffer (pixels)
580 * @param linesize Line size of destination buffer (bytes)
582 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
584 int x = 0, y = 0, i, length;
585 while (bytestream2_get_bytes_left(gb) >= 4) {
586 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
587 length = bytestream2_get_byte(gb) & 0x7F;
588 DECODE_RGBX_COMMON(uint32_t)
594 * @param[out] dst Destination buffer
595 * @param width Width of destination buffer (pixels)
596 * @param height Height of destination buffer (pixels)
597 * @param linesize Line size of destination buffer (bytes)
599 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
601 int x = 0, y = 0, i, length;
602 while (bytestream2_get_bytes_left(gb) >= 2) {
603 uint32_t pixel = bytestream2_get_be16u(gb);
604 length = pixel & 0x7;
606 DECODE_RGBX_COMMON(uint16_t)
611 * Decode DEEP RLE 32-bit buffer
612 * @param[out] dst Destination buffer
613 * @param[in] src Source buffer
614 * @param src_size Source buffer size (bytes)
615 * @param width Width of destination buffer (pixels)
616 * @param height Height of destination buffer (pixels)
617 * @param linesize Line size of destination buffer (bytes)
619 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
621 const uint8_t *src_end = src + src_size;
623 while (src + 5 <= src_end) {
625 opcode = *(int8_t *)src++;
627 int size = opcode + 1;
628 for (i = 0; i < size; i++) {
629 int length = FFMIN(size - i, width);
630 memcpy(dst + y*linesize + x * 4, src, length * 4);
642 int size = -opcode + 1;
643 uint32_t pixel = AV_RN32(src);
644 for (i = 0; i < size; i++) {
645 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
660 * Decode DEEP TVDC 32-bit buffer
661 * @param[out] dst Destination buffer
662 * @param[in] src Source buffer
663 * @param src_size Source buffer size (bytes)
664 * @param width Width of destination buffer (pixels)
665 * @param height Height of destination buffer (pixels)
666 * @param linesize Line size of destination buffer (bytes)
667 * @param[int] tvdc TVDC lookup table
669 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)
671 int x = 0, y = 0, plane = 0;
675 for (i = 0; i < src_size * 2;) {
676 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
677 int d = tvdc[GETNIBBLE];
681 dst[y * linesize + x*4 + plane] = pixel;
684 if (i >= src_size * 2)
688 d = FFMIN(d, width - x);
689 for (j = 0; j < d; j++) {
690 dst[y * linesize + x*4 + plane] = pixel;
709 static void decode_short_horizontal_delta(uint8_t *dst,
710 const uint8_t *buf, const uint8_t *buf_end,
711 int w, int bpp, int dst_size)
713 int planepitch = FFALIGN(w, 16) >> 3;
714 int pitch = planepitch * bpp;
715 GetByteContext ptrs, gb;
717 unsigned ofssrc, pos;
720 bytestream2_init(&ptrs, buf, buf_end - buf);
721 bytestream2_init_writer(&pb, dst, dst_size);
723 for (k = 0; k < bpp; k++) {
724 ofssrc = bytestream2_get_be32(&ptrs);
730 if (ofssrc >= buf_end - buf)
733 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
734 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
735 int16_t offset = bytestream2_get_be16(&gb);
739 unsigned data = bytestream2_get_be16(&gb);
742 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
743 bytestream2_seek_p(&pb, noffset, SEEK_SET);
744 bytestream2_put_be16(&pb, data);
746 uint16_t count = bytestream2_get_be16(&gb);
748 pos += 2 * -(offset + 2);
749 for (i = 0; i < count; i++) {
750 uint16_t data = bytestream2_get_be16(&gb);
753 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
754 bytestream2_seek_p(&pb, noffset, SEEK_SET);
755 bytestream2_put_be16(&pb, data);
762 static void decode_byte_vertical_delta(uint8_t *dst,
763 const uint8_t *buf, const uint8_t *buf_end,
764 int w, int bpp, int dst_size)
766 int ncolumns = ((w + 15) / 16) * 2;
767 int dstpitch = ncolumns * bpp;
768 unsigned ofsdst, ofssrc, opcode, x;
769 GetByteContext ptrs, gb;
773 bytestream2_init(&ptrs, buf, buf_end - buf);
774 bytestream2_init_writer(&pb, dst, dst_size);
776 for (k = 0; k < bpp; k++) {
777 ofssrc = bytestream2_get_be32(&ptrs);
782 if (ofssrc >= buf_end - buf)
785 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
786 for (j = 0; j < ncolumns; j++) {
787 ofsdst = j + k * ncolumns;
789 i = bytestream2_get_byte(&gb);
791 opcode = bytestream2_get_byte(&gb);
794 opcode = bytestream2_get_byte(&gb);
795 x = bytestream2_get_byte(&gb);
798 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
799 bytestream2_put_byte(&pb, x);
803 } else if (opcode < 0x80) {
804 ofsdst += opcode * dstpitch;
809 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
810 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
821 static void decode_delta_j(uint8_t *dst,
822 const uint8_t *buf, const uint8_t *buf_end,
823 int w, int h, int bpp, int dst_size)
827 uint32_t type, flag, cols, groups, rows, bytes;
829 int planepitch_byte = (w + 7) / 8;
830 int planepitch = ((w + 15) / 16) * 2;
831 int kludge_j, b, g, r, d;
834 pitch = planepitch * bpp;
835 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
837 bytestream2_init(&gb, buf, buf_end - buf);
839 while (bytestream2_get_bytes_left(&gb) >= 2) {
840 type = bytestream2_get_be16(&gb);
846 flag = bytestream2_get_be16(&gb);
847 cols = bytestream2_get_be16(&gb);
848 groups = bytestream2_get_be16(&gb);
850 for (g = 0; g < groups; g++) {
851 offset = bytestream2_get_be16(&gb);
854 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
856 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
858 for (b = 0; b < cols; b++) {
859 for (d = 0; d < bpp; d++) {
860 uint8_t value = bytestream2_get_byte(&gb);
862 if (offset >= dst_size)
871 offset += planepitch;
874 if ((cols * bpp) & 1)
875 bytestream2_skip(&gb, 1);
879 flag = bytestream2_get_be16(&gb);
880 rows = bytestream2_get_be16(&gb);
881 bytes = bytestream2_get_be16(&gb);
882 groups = bytestream2_get_be16(&gb);
884 for (g = 0; g < groups; g++) {
885 offset = bytestream2_get_be16(&gb);
888 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
890 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
892 for (r = 0; r < rows; r++) {
893 for (d = 0; d < bpp; d++) {
894 unsigned noffset = offset + (r * pitch) + d * planepitch;
896 for (b = 0; b < bytes; b++) {
897 uint8_t value = bytestream2_get_byte(&gb);
899 if (noffset >= dst_size)
912 if ((rows * bytes * bpp) & 1)
913 bytestream2_skip(&gb, 1);
922 static void decode_short_vertical_delta(uint8_t *dst,
923 const uint8_t *buf, const uint8_t *buf_end,
924 int w, int bpp, int dst_size)
926 int ncolumns = (w + 15) >> 4;
927 int dstpitch = ncolumns * bpp * 2;
928 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
929 GetByteContext ptrs, gb, dptrs, dgb;
933 if (buf_end - buf <= 64)
936 bytestream2_init(&ptrs, buf, buf_end - buf);
937 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
938 bytestream2_init_writer(&pb, dst, dst_size);
940 for (k = 0; k < bpp; k++) {
941 ofssrc = bytestream2_get_be32(&ptrs);
942 ofsdata = bytestream2_get_be32(&dptrs);
947 if (ofssrc >= buf_end - buf)
950 if (ofsdata >= buf_end - buf)
953 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
954 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
955 for (j = 0; j < ncolumns; j++) {
956 ofsdst = (j + k * ncolumns) * 2;
958 i = bytestream2_get_byte(&gb);
960 opcode = bytestream2_get_byte(&gb);
963 opcode = bytestream2_get_byte(&gb);
964 x = bytestream2_get_be16(&dgb);
967 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
968 bytestream2_put_be16(&pb, x);
972 } else if (opcode < 0x80) {
973 ofsdst += opcode * dstpitch;
978 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
979 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
990 static void decode_long_vertical_delta(uint8_t *dst,
991 const uint8_t *buf, const uint8_t *buf_end,
992 int w, int bpp, int dst_size)
994 int ncolumns = (w + 31) >> 5;
995 int dstpitch = ((w + 15) / 16 * 2) * bpp;
996 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
997 GetByteContext ptrs, gb, dptrs, dgb;
1001 if (buf_end - buf <= 64)
1004 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1005 bytestream2_init(&ptrs, buf, buf_end - buf);
1006 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1007 bytestream2_init_writer(&pb, dst, dst_size);
1009 for (k = 0; k < bpp; k++) {
1010 ofssrc = bytestream2_get_be32(&ptrs);
1011 ofsdata = bytestream2_get_be32(&dptrs);
1016 if (ofssrc >= buf_end - buf)
1019 if (ofsdata >= buf_end - buf)
1022 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1023 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1024 for (j = 0; j < ncolumns; j++) {
1025 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1027 i = bytestream2_get_byte(&gb);
1029 opcode = bytestream2_get_byte(&gb);
1032 opcode = bytestream2_get_byte(&gb);
1033 if (h && (j == (ncolumns - 1))) {
1034 x = bytestream2_get_be16(&dgb);
1035 bytestream2_skip(&dgb, 2);
1037 x = bytestream2_get_be32(&dgb);
1041 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1042 if (h && (j == (ncolumns - 1))) {
1043 bytestream2_put_be16(&pb, x);
1045 bytestream2_put_be32(&pb, x);
1050 } else if (opcode < 0x80) {
1051 ofsdst += opcode * dstpitch;
1056 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1057 if (h && (j == (ncolumns - 1))) {
1058 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1059 bytestream2_skip(&dgb, 2);
1061 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1073 static void decode_short_vertical_delta2(uint8_t *dst,
1074 const uint8_t *buf, const uint8_t *buf_end,
1075 int w, int bpp, int dst_size)
1077 int ncolumns = (w + 15) >> 4;
1078 int dstpitch = ncolumns * bpp * 2;
1079 unsigned ofsdst, ofssrc, opcode, x;
1080 GetByteContext ptrs, gb;
1084 bytestream2_init(&ptrs, buf, buf_end - buf);
1085 bytestream2_init_writer(&pb, dst, dst_size);
1087 for (k = 0; k < bpp; k++) {
1088 ofssrc = bytestream2_get_be32(&ptrs);
1093 if (ofssrc >= buf_end - buf)
1096 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1097 for (j = 0; j < ncolumns; j++) {
1098 ofsdst = (j + k * ncolumns) * 2;
1100 i = bytestream2_get_be16(&gb);
1101 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1102 opcode = bytestream2_get_be16(&gb);
1105 opcode = bytestream2_get_be16(&gb);
1106 x = bytestream2_get_be16(&gb);
1108 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1109 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1110 bytestream2_put_be16(&pb, x);
1114 } else if (opcode < 0x8000) {
1115 ofsdst += opcode * dstpitch;
1119 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1120 bytestream2_get_bytes_left_p(&pb) > 1) {
1121 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1122 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1133 static void decode_long_vertical_delta2(uint8_t *dst,
1134 const uint8_t *buf, const uint8_t *buf_end,
1135 int w, int bpp, int dst_size)
1137 int ncolumns = (w + 31) >> 5;
1138 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1139 unsigned ofsdst, ofssrc, opcode, x;
1140 unsigned skip = 0x80000000, mask = skip - 1;
1141 GetByteContext ptrs, gb;
1145 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1146 bytestream2_init(&ptrs, buf, buf_end - buf);
1147 bytestream2_init_writer(&pb, dst, dst_size);
1149 for (k = 0; k < bpp; k++) {
1150 ofssrc = bytestream2_get_be32(&ptrs);
1155 if (ofssrc >= buf_end - buf)
1158 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1159 for (j = 0; j < ncolumns; j++) {
1160 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1162 if (h && (j == (ncolumns - 1))) {
1167 i = bytestream2_get_be32(&gb);
1168 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1169 opcode = bytestream2_get_be32(&gb);
1172 if (h && (j == ncolumns - 1)) {
1173 opcode = bytestream2_get_be16(&gb);
1174 x = bytestream2_get_be16(&gb);
1176 opcode = bytestream2_get_be32(&gb);
1177 x = bytestream2_get_be32(&gb);
1180 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1181 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1182 if (h && (j == ncolumns - 1))
1183 bytestream2_put_be16(&pb, x);
1185 bytestream2_put_be32(&pb, x);
1189 } else if (opcode < skip) {
1190 ofsdst += opcode * dstpitch;
1194 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1195 bytestream2_get_bytes_left_p(&pb) > 1) {
1196 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1197 if (h && (j == ncolumns - 1)) {
1198 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1200 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1212 static void decode_delta_l(uint8_t *dst,
1213 const uint8_t *buf, const uint8_t *buf_end,
1214 int w, int flag, int bpp, int dst_size)
1216 GetByteContext off0, off1, dgb, ogb;
1218 unsigned poff0, poff1;
1220 int planepitch_byte = (w + 7) / 8;
1221 int planepitch = ((w + 15) / 16) * 2;
1222 int pitch = planepitch * bpp;
1224 if (buf_end - buf <= 64)
1227 bytestream2_init(&off0, buf, buf_end - buf);
1228 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1229 bytestream2_init_writer(&pb, dst, dst_size);
1231 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1233 for (k = 0; k < bpp; k++) {
1234 poff0 = bytestream2_get_be32(&off0);
1235 poff1 = bytestream2_get_be32(&off1);
1240 if (2LL * poff0 >= buf_end - buf)
1243 if (2LL * poff1 >= buf_end - buf)
1246 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1247 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1249 while ((bytestream2_peek_be16(&ogb)) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1250 uint32_t offset = bytestream2_get_be16(&ogb);
1251 int16_t cnt = bytestream2_get_be16(&ogb);
1254 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1256 bytestream2_seek_p(&pb, offset, SEEK_SET);
1258 data = bytestream2_get_be16(&dgb);
1259 for (i = 0; i < cnt; i++) {
1260 bytestream2_put_be16(&pb, data);
1261 bytestream2_skip_p(&pb, dstpitch - 2);
1264 bytestream2_seek_p(&pb, offset, SEEK_SET);
1265 for (i = 0; i < cnt; i++) {
1266 data = bytestream2_get_be16(&dgb);
1267 bytestream2_put_be16(&pb, data);
1268 bytestream2_skip_p(&pb, dstpitch - 2);
1275 static int unsupported(AVCodecContext *avctx)
1277 IffContext *s = avctx->priv_data;
1278 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
1279 return AVERROR_INVALIDDATA;
1282 static int decode_frame(AVCodecContext *avctx,
1283 void *data, int *got_frame,
1286 IffContext *s = avctx->priv_data;
1287 AVFrame *frame = data;
1288 const uint8_t *buf = avpkt->data;
1289 int buf_size = avpkt->size;
1290 const uint8_t *buf_end = buf + buf_size;
1292 GetByteContext *gb = &s->gb;
1293 const AVPixFmtDescriptor *desc;
1295 bytestream2_init(gb, avpkt->data, avpkt->size);
1297 if ((res = extract_header(avctx, avpkt)) < 0)
1300 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1304 buf += bytestream2_tell(gb);
1305 buf_size -= bytestream2_tell(gb);
1306 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1308 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1309 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1310 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1312 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1313 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1314 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1319 if (s->compression <= 0xff && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1320 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1321 memcpy(s->pal[0], s->frame->data[1], 256 * 4);
1324 if (s->compression > 0xff && s->first) {
1325 memcpy(s->video[1], s->video[0], s->video_size);
1326 memcpy(s->pal[1], s->pal[0], 256 * 4);
1330 switch (s->compression) {
1332 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1333 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1334 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1335 for (plane = 0; plane < s->bpp; plane++) {
1336 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1337 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1338 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1339 buf += s->planesize;
1342 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1343 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1344 for (y = 0; y < avctx->height; y++) {
1345 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1346 memset(s->ham_buf, 0, s->planesize * 8);
1347 for (plane = 0; plane < s->bpp; plane++) {
1348 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1349 if (start >= buf_end)
1351 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1353 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1356 return unsupported(avctx);
1357 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1358 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1360 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1361 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1362 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1364 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1365 for (x = 0; x < avctx->width; x++)
1366 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1369 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1370 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1371 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1372 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1373 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1374 for (y = 0; y < avctx->height; y++) {
1375 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1376 memset(row, 0, avctx->width);
1377 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1378 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1379 buf += s->planesize;
1382 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1383 for (y = 0; y < avctx->height; y++) {
1384 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1385 memset(s->ham_buf, 0, s->planesize * 8);
1386 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1387 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1388 buf += s->planesize;
1390 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1392 } else { // AV_PIX_FMT_BGR32
1393 for (y = 0; y < avctx->height; y++) {
1394 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1395 memset(row, 0, avctx->width << 2);
1396 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1397 decodeplane32((uint32_t *)row, buf,
1398 FFMIN(s->planesize, buf_end - buf), plane);
1399 buf += s->planesize;
1403 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1404 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1405 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1406 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1407 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1408 buf += avctx->width + (avctx->width % 2); // padding if odd
1410 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1411 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1412 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1413 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1414 buf += avctx->width + (avctx->width & 1); // padding if odd
1415 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1418 return unsupported(avctx);
1422 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1423 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1424 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1425 uint8_t *video = s->video[0];
1427 for (y = 0; y < avctx->height; y++) {
1428 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1429 memset(row, 0, avctx->width);
1430 for (plane = 0; plane < s->bpp; plane++) {
1431 buf += decode_byterun(s->planebuf, s->planesize, gb);
1432 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1433 memcpy(video, s->planebuf, s->planesize);
1434 video += s->planesize;
1436 decodeplane8(row, s->planebuf, s->planesize, plane);
1439 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1440 for (y = 0; y < avctx->height; y++) {
1441 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1442 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1443 for (plane = 0; plane < s->bpp; plane++) {
1444 buf += decode_byterun(s->planebuf, s->planesize, gb);
1445 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1447 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1449 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1450 uint8_t *video = s->video[0];
1451 for (y = 0; y < avctx->height; y++) {
1452 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1453 memset(s->ham_buf, 0, s->planesize * 8);
1454 for (plane = 0; plane < s->bpp; plane++) {
1455 buf += decode_byterun(s->planebuf, s->planesize, gb);
1456 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1457 memcpy(video, s->planebuf, s->planesize);
1458 video += s->planesize;
1460 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1462 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1464 } else { // AV_PIX_FMT_BGR32
1465 for (y = 0; y < avctx->height; y++) {
1466 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1467 memset(row, 0, avctx->width << 2);
1468 for (plane = 0; plane < s->bpp; plane++) {
1469 buf += decode_byterun(s->planebuf, s->planesize, gb);
1470 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1474 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1475 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1476 for (y = 0; y < avctx->height; y++) {
1477 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1478 buf += decode_byterun(row, avctx->width, gb);
1480 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1481 for (y = 0; y < avctx->height; y++) {
1482 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1483 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1484 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1487 return unsupported(avctx);
1488 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1489 if (av_get_bits_per_pixel(desc) == 32)
1490 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1492 return unsupported(avctx);
1496 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1497 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1498 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1499 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1501 return unsupported(avctx);
1504 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1505 if (av_get_bits_per_pixel(desc) == 32)
1506 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1508 return unsupported(avctx);
1510 return unsupported(avctx);
1514 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1518 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1523 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1525 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1530 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1532 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1536 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1540 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1543 return unsupported(avctx);
1546 if (s->compression > 0xff) {
1547 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1549 for (y = 0; y < avctx->height; y++) {
1550 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1551 memset(row, 0, avctx->width);
1552 for (plane = 0; plane < s->bpp; plane++) {
1553 decodeplane8(row, buf, s->planesize, plane);
1554 buf += s->planesize;
1557 memcpy(frame->data[1], s->pal[0], 256 * 4);
1558 } else if (s->ham) {
1559 int i, count = 1 << s->ham;
1562 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1563 for (i = 0; i < count; i++) {
1564 s->ham_palbuf[i*2+1] = s->pal[0][i];
1566 for (i = 0; i < count; i++) {
1567 uint32_t tmp = i << (8 - s->ham);
1568 tmp |= tmp >> s->ham;
1569 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1570 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1571 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1572 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1573 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1574 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1576 if (s->masking == MASK_HAS_MASK) {
1577 for (i = 0; i < 8 * (1 << s->ham); i++)
1578 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1580 for (y = 0; y < avctx->height; y++) {
1581 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1582 memset(s->ham_buf, 0, s->planesize * 8);
1583 for (plane = 0; plane < s->bpp; plane++) {
1584 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1585 buf += s->planesize;
1587 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1590 return unsupported(avctx);
1593 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1594 FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
1597 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1598 frame->key_frame = 1;
1599 frame->pict_type = AV_PICTURE_TYPE_I;
1601 frame->key_frame = 0;
1602 frame->pict_type = AV_PICTURE_TYPE_P;
1610 #if CONFIG_IFF_ILBM_DECODER
1611 AVCodec ff_iff_ilbm_decoder = {
1613 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM"),
1614 .type = AVMEDIA_TYPE_VIDEO,
1615 .id = AV_CODEC_ID_IFF_ILBM,
1616 .priv_data_size = sizeof(IffContext),
1617 .init = decode_init,
1618 .close = decode_end,
1619 .decode = decode_frame,
1620 .capabilities = AV_CODEC_CAP_DR1,