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 is_interlaced;///< video is interlaced
56 unsigned is_brush; ///< video is in ANBR format
57 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
58 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
59 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
60 unsigned transparency; ///< TODO: transparency color index in palette
61 unsigned masking; ///< TODO: masking method used
62 int init; // 1 if buffer and palette data already initialized, 0 otherwise
63 int16_t tvdc[16]; ///< TVDC lookup table
70 #define LUT8_PART(plane, v) \
71 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
72 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
79 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
80 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
81 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
82 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
83 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
84 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
85 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
86 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
88 #define LUT8(plane) { \
89 LUT8_PART(plane, 0x0000000), \
90 LUT8_PART(plane, 0x1000000), \
91 LUT8_PART(plane, 0x0010000), \
92 LUT8_PART(plane, 0x1010000), \
93 LUT8_PART(plane, 0x0000100), \
94 LUT8_PART(plane, 0x1000100), \
95 LUT8_PART(plane, 0x0010100), \
96 LUT8_PART(plane, 0x1010100), \
97 LUT8_PART(plane, 0x0000001), \
98 LUT8_PART(plane, 0x1000001), \
99 LUT8_PART(plane, 0x0010001), \
100 LUT8_PART(plane, 0x1010001), \
101 LUT8_PART(plane, 0x0000101), \
102 LUT8_PART(plane, 0x1000101), \
103 LUT8_PART(plane, 0x0010101), \
104 LUT8_PART(plane, 0x1010101), \
107 // 8 planes * 8-bit mask
108 static const uint64_t plane8_lut[8][256] = {
109 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
110 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
113 #define LUT32(plane) { \
115 0, 0, 0, 1 << plane, \
116 0, 0, 1 << plane, 0, \
117 0, 0, 1 << plane, 1 << plane, \
118 0, 1 << plane, 0, 0, \
119 0, 1 << plane, 0, 1 << plane, \
120 0, 1 << plane, 1 << plane, 0, \
121 0, 1 << plane, 1 << plane, 1 << plane, \
122 1 << plane, 0, 0, 0, \
123 1 << plane, 0, 0, 1 << plane, \
124 1 << plane, 0, 1 << plane, 0, \
125 1 << plane, 0, 1 << plane, 1 << plane, \
126 1 << plane, 1 << plane, 0, 0, \
127 1 << plane, 1 << plane, 0, 1 << plane, \
128 1 << plane, 1 << plane, 1 << plane, 0, \
129 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
132 // 32 planes * 4-bit mask * 4 lookup tables each
133 static const uint32_t plane32_lut[32][16*4] = {
134 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
135 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
136 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
137 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
138 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
139 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
140 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
141 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
144 // Gray to RGB, required for palette table of grayscale images with bpp < 8
145 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
146 return x << 16 | x << 8 | x;
150 * Convert CMAP buffer (stored in extradata) to lavc palette format
152 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
154 IffContext *s = avctx->priv_data;
156 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
157 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
159 if (avctx->bits_per_coded_sample > 8) {
160 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
161 return AVERROR_INVALIDDATA;
164 count = 1 << avctx->bits_per_coded_sample;
165 // If extradata is smaller than actually needed, fill the remaining with black.
166 count = FFMIN(palette_size / 3, count);
168 for (i = 0; i < count; i++)
169 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
170 if (s->flags && count >= 32) { // EHB
171 for (i = 0; i < 32; i++)
172 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
173 count = FFMAX(count, 64);
175 } else { // Create gray-scale color palette for bps < 8
176 count = 1 << avctx->bits_per_coded_sample;
178 for (i = 0; i < count; i++)
179 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
181 if (s->masking == MASK_HAS_MASK) {
182 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
183 for (i = 0; i < count; i++)
185 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
186 s->transparency < 1 << avctx->bits_per_coded_sample)
187 pal[s->transparency] &= 0xFFFFFF;
192 * Extracts the IFF extra context and updates internal
193 * decoder structures.
195 * @param avctx the AVCodecContext where to extract extra context to
196 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
197 * @return >= 0 in case of success, a negative error code otherwise
199 static int extract_header(AVCodecContext *const avctx,
200 const AVPacket *const avpkt)
202 IffContext *s = avctx->priv_data;
204 unsigned buf_size = 0;
207 if (avctx->extradata_size < 2) {
208 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
209 return AVERROR_INVALIDDATA;
211 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
213 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
216 GetByteContext *gb = &s->gb;
218 bytestream2_skip(gb, 4);
219 while (bytestream2_get_bytes_left(gb) >= 1) {
220 chunk_id = bytestream2_get_le32(gb);
221 data_size = bytestream2_get_be32(gb);
223 if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
224 bytestream2_skip(gb, data_size + (data_size & 1));
225 } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
228 return AVERROR_INVALIDDATA;
230 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
231 bytestream2_skip(gb, 19);
232 extra = bytestream2_get_be32(gb);
233 s->is_short = !(extra & 1);
234 s->is_brush = extra == 2;
235 s->is_interlaced = !!(extra & 0x40);
237 bytestream2_skip(gb, data_size + (data_size & 1));
238 } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
239 chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
240 if (chunk_id == MKTAG('B','O','D','Y'))
241 s->compression &= 0xFF;
243 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
244 int count = data_size / 3;
245 uint32_t *pal = s->pal[0];
248 return AVERROR_INVALIDDATA;
250 for (i = 0; i < count; i++)
251 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
253 for (i = 0; i < count; i++)
254 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
256 bytestream2_skip(gb, data_size & 1);
258 bytestream2_skip(gb, data_size + (data_size&1));
262 buf = avctx->extradata;
263 buf_size = bytestream_get_be16(&buf);
264 if (buf_size <= 1 || palette_size < 0) {
265 av_log(avctx, AV_LOG_ERROR,
266 "Invalid palette size received: %u -> palette data offset: %d\n",
267 buf_size, palette_size);
268 return AVERROR_INVALIDDATA;
272 if (buf_size >= 41) {
273 s->compression = bytestream_get_byte(&buf);
274 s->bpp = bytestream_get_byte(&buf);
275 s->ham = bytestream_get_byte(&buf);
276 s->flags = bytestream_get_byte(&buf);
277 s->transparency = bytestream_get_be16(&buf);
278 s->masking = bytestream_get_byte(&buf);
279 for (i = 0; i < 16; i++)
280 s->tvdc[i] = bytestream_get_be16(&buf);
282 if (s->masking == MASK_HAS_MASK) {
283 if (s->bpp >= 8 && !s->ham) {
284 avctx->pix_fmt = AV_PIX_FMT_RGB32;
285 av_freep(&s->mask_buf);
286 av_freep(&s->mask_palbuf);
287 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
289 return AVERROR(ENOMEM);
291 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
292 av_freep(&s->mask_buf);
293 return AVERROR(ENOMEM);
295 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
296 if (!s->mask_palbuf) {
297 av_freep(&s->mask_buf);
298 return AVERROR(ENOMEM);
302 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
303 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
304 return AVERROR_PATCHWELCOME;
306 if (!s->bpp || s->bpp > 32) {
307 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
308 return AVERROR_INVALIDDATA;
309 } else if (s->ham >= 8) {
310 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
311 return AVERROR_INVALIDDATA;
314 av_freep(&s->ham_buf);
315 av_freep(&s->ham_palbuf);
318 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
320 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
322 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
324 return AVERROR(ENOMEM);
326 ham_count = 8 * (1 << s->ham);
327 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
328 if (!s->ham_palbuf) {
329 av_freep(&s->ham_buf);
330 return AVERROR(ENOMEM);
333 if (count) { // HAM with color palette attached
334 // prefill with black and palette and set HAM take direct value mask to zero
335 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
336 for (i=0; i < count; i++) {
337 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
340 } else { // HAM with grayscale color palette
342 for (i=0; i < count; i++) {
343 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
344 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
347 for (i=0; i < count; i++) {
348 uint32_t tmp = i << (8 - s->ham);
349 tmp |= tmp >> s->ham;
350 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
351 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
352 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
353 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
354 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
355 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
357 if (s->masking == MASK_HAS_MASK) {
358 for (i = 0; i < ham_count; i++)
359 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
367 static av_cold int decode_end(AVCodecContext *avctx)
369 IffContext *s = avctx->priv_data;
370 av_freep(&s->planebuf);
371 av_freep(&s->ham_buf);
372 av_freep(&s->ham_palbuf);
373 av_freep(&s->video[0]);
374 av_freep(&s->video[1]);
375 av_freep(&s->pal[0]);
376 av_freep(&s->pal[1]);
380 static av_cold int decode_init(AVCodecContext *avctx)
382 IffContext *s = avctx->priv_data;
385 if (avctx->bits_per_coded_sample <= 8) {
388 if (avctx->extradata_size >= 2)
389 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
392 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
393 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
394 } else if (avctx->bits_per_coded_sample <= 32) {
395 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
396 avctx->pix_fmt = AV_PIX_FMT_RGB32;
397 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
398 avctx->pix_fmt = AV_PIX_FMT_RGB444;
399 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
400 if (avctx->bits_per_coded_sample == 24) {
401 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
402 } else if (avctx->bits_per_coded_sample == 32) {
403 avctx->pix_fmt = AV_PIX_FMT_BGR32;
405 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
406 return AVERROR_PATCHWELCOME;
410 return AVERROR_INVALIDDATA;
413 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
415 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
416 s->planebuf = av_malloc(s->planesize + AV_INPUT_BUFFER_PADDING_SIZE);
418 return AVERROR(ENOMEM);
420 s->bpp = avctx->bits_per_coded_sample;
422 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
423 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
424 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
425 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
426 s->pal[0] = av_calloc(256, sizeof(*s->pal[0]));
427 s->pal[1] = av_calloc(256, sizeof(*s->pal[1]));
428 if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
429 return AVERROR(ENOMEM);
432 if ((err = extract_header(avctx, NULL)) < 0)
439 * Decode interleaved plane buffer up to 8bpp
440 * @param dst Destination buffer
441 * @param buf Source buffer
443 * @param plane plane number to decode as
445 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
447 const uint64_t *lut = plane8_lut[plane];
449 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
453 uint64_t v = AV_RN64A(dst) | lut[*buf++];
456 } while (--buf_size);
460 * Decode interleaved plane buffer up to 24bpp
461 * @param dst Destination buffer
462 * @param buf Source buffer
464 * @param plane plane number to decode as
466 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
468 const uint32_t *lut = plane32_lut[plane];
470 unsigned mask = (*buf >> 2) & ~3;
471 dst[0] |= lut[mask++];
472 dst[1] |= lut[mask++];
473 dst[2] |= lut[mask++];
475 mask = (*buf++ << 2) & 0x3F;
476 dst[4] |= lut[mask++];
477 dst[5] |= lut[mask++];
478 dst[6] |= lut[mask++];
481 } while (--buf_size);
484 #define DECODE_HAM_PLANE32(x) \
485 first = buf[x] << 1; \
486 second = buf[(x)+1] << 1; \
487 delta &= pal[first++]; \
488 delta |= pal[first]; \
490 delta &= pal[second++]; \
491 delta |= pal[second]; \
495 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
497 * @param dst the destination 24bpp buffer
498 * @param buf the source 8bpp chunky buffer
499 * @param pal the HAM decode table
500 * @param buf_size the plane size in bytes
502 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
503 const uint32_t *const pal, unsigned buf_size)
505 uint32_t delta = pal[1]; /* first palette entry */
507 uint32_t first, second;
508 DECODE_HAM_PLANE32(0);
509 DECODE_HAM_PLANE32(2);
510 DECODE_HAM_PLANE32(4);
511 DECODE_HAM_PLANE32(6);
514 } while (--buf_size);
517 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
518 const uint32_t *const pal, unsigned width)
521 *dst++ = pal[*buf++];
526 * Decode one complete byterun1 encoded line.
528 * @param dst the destination buffer where to store decompressed bitstream
529 * @param dst_size the destination plane size in bytes
530 * @param buf the source byterun1 compressed bitstream
531 * @param buf_end the EOF of source byterun1 compressed bitstream
532 * @return number of consumed bytes in byterun1 compressed bitstream
534 static int decode_byterun(uint8_t *dst, int dst_size,
538 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
540 const int8_t value = bytestream2_get_byte(gb);
542 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
543 bytestream2_get_buffer(gb, dst + x, length);
544 } else if (value > -128) {
545 length = FFMIN(-value + 1, dst_size - x);
546 memset(dst + x, bytestream2_get_byte(gb), length);
553 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
554 memset(dst+x, 0, dst_size - x);
556 return bytestream2_tell(gb);
559 #define DECODE_RGBX_COMMON(type) \
561 length = bytestream2_get_byte(gb); \
563 length = bytestream2_get_be16(gb); \
568 for (i = 0; i < length; i++) { \
569 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
581 * @param[out] dst Destination buffer
582 * @param width Width of destination buffer (pixels)
583 * @param height Height of destination buffer (pixels)
584 * @param linesize Line size of destination buffer (bytes)
586 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
588 int x = 0, y = 0, i, length;
589 while (bytestream2_get_bytes_left(gb) >= 4) {
590 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
591 length = bytestream2_get_byte(gb) & 0x7F;
592 DECODE_RGBX_COMMON(uint32_t)
598 * @param[out] dst Destination buffer
599 * @param width Width of destination buffer (pixels)
600 * @param height Height of destination buffer (pixels)
601 * @param linesize Line size of destination buffer (bytes)
603 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
605 int x = 0, y = 0, i, length;
606 while (bytestream2_get_bytes_left(gb) >= 2) {
607 uint32_t pixel = bytestream2_get_be16u(gb);
608 length = pixel & 0x7;
610 DECODE_RGBX_COMMON(uint16_t)
615 * Decode DEEP RLE 32-bit buffer
616 * @param[out] dst Destination buffer
617 * @param[in] src Source buffer
618 * @param src_size Source buffer size (bytes)
619 * @param width Width of destination buffer (pixels)
620 * @param height Height of destination buffer (pixels)
621 * @param linesize Line size of destination buffer (bytes)
623 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
625 const uint8_t *src_end = src + src_size;
627 while (src + 5 <= src_end) {
629 opcode = *(int8_t *)src++;
631 int size = opcode + 1;
632 for (i = 0; i < size; i++) {
633 int length = FFMIN(size - i, width);
634 memcpy(dst + y*linesize + x * 4, src, length * 4);
646 int size = -opcode + 1;
647 uint32_t pixel = AV_RN32(src);
648 for (i = 0; i < size; i++) {
649 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
664 * Decode DEEP TVDC 32-bit buffer
665 * @param[out] dst Destination buffer
666 * @param[in] src Source buffer
667 * @param src_size Source buffer size (bytes)
668 * @param width Width of destination buffer (pixels)
669 * @param height Height of destination buffer (pixels)
670 * @param linesize Line size of destination buffer (bytes)
671 * @param[int] tvdc TVDC lookup table
673 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)
675 int x = 0, y = 0, plane = 0;
679 for (i = 0; i < src_size * 2;) {
680 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
681 int d = tvdc[GETNIBBLE];
685 dst[y * linesize + x*4 + plane] = pixel;
688 if (i >= src_size * 2)
692 d = FFMIN(d, width - x);
693 for (j = 0; j < d; j++) {
694 dst[y * linesize + x*4 + plane] = pixel;
713 static void decode_short_horizontal_delta(uint8_t *dst,
714 const uint8_t *buf, const uint8_t *buf_end,
715 int w, int bpp, int dst_size)
717 int planepitch = FFALIGN(w, 16) >> 3;
718 int pitch = planepitch * bpp;
719 GetByteContext ptrs, gb;
721 unsigned ofssrc, pos;
724 bytestream2_init(&ptrs, buf, buf_end - buf);
725 bytestream2_init_writer(&pb, dst, dst_size);
727 for (k = 0; k < bpp; k++) {
728 ofssrc = bytestream2_get_be32(&ptrs);
734 if (ofssrc >= buf_end - buf)
737 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
738 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
739 int16_t offset = bytestream2_get_be16(&gb);
743 unsigned data = bytestream2_get_be16(&gb);
746 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
747 bytestream2_seek_p(&pb, noffset, SEEK_SET);
748 bytestream2_put_be16(&pb, data);
750 uint16_t count = bytestream2_get_be16(&gb);
752 pos += 2 * -(offset + 2);
753 for (i = 0; i < count; i++) {
754 uint16_t data = bytestream2_get_be16(&gb);
757 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
758 bytestream2_seek_p(&pb, noffset, SEEK_SET);
759 bytestream2_put_be16(&pb, data);
766 static void decode_byte_vertical_delta(uint8_t *dst,
767 const uint8_t *buf, const uint8_t *buf_end,
768 int w, int xor, int bpp, int dst_size)
770 int ncolumns = ((w + 15) / 16) * 2;
771 int dstpitch = ncolumns * bpp;
772 unsigned ofsdst, ofssrc, opcode, x;
773 GetByteContext ptrs, gb;
777 bytestream2_init(&ptrs, buf, buf_end - buf);
778 bytestream2_init_writer(&pb, dst, dst_size);
780 for (k = 0; k < bpp; k++) {
781 ofssrc = bytestream2_get_be32(&ptrs);
786 if (ofssrc >= buf_end - buf)
789 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
790 for (j = 0; j < ncolumns; j++) {
791 ofsdst = j + k * ncolumns;
793 i = bytestream2_get_byte(&gb);
795 opcode = bytestream2_get_byte(&gb);
798 opcode = bytestream2_get_byte(&gb);
799 x = bytestream2_get_byte(&gb);
802 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
803 if (xor && ofsdst < dst_size) {
804 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
806 bytestream2_put_byte(&pb, x);
811 } else if (opcode < 0x80) {
812 ofsdst += opcode * dstpitch;
817 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
818 if (xor && ofsdst < dst_size) {
819 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
821 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
833 static void decode_delta_j(uint8_t *dst,
834 const uint8_t *buf, const uint8_t *buf_end,
835 int w, int h, int bpp, int dst_size)
839 uint32_t type, flag, cols, groups, rows, bytes;
841 int planepitch_byte = (w + 7) / 8;
842 int planepitch = ((w + 15) / 16) * 2;
843 int kludge_j, b, g, r, d;
846 pitch = planepitch * bpp;
847 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
849 bytestream2_init(&gb, buf, buf_end - buf);
851 while (bytestream2_get_bytes_left(&gb) >= 2) {
852 type = bytestream2_get_be16(&gb);
858 flag = bytestream2_get_be16(&gb);
859 cols = bytestream2_get_be16(&gb);
860 groups = bytestream2_get_be16(&gb);
862 for (g = 0; g < groups; g++) {
863 offset = bytestream2_get_be16(&gb);
865 if (bytestream2_get_bytes_left(&gb) < 1)
869 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
871 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
873 for (b = 0; b < cols; b++) {
874 for (d = 0; d < bpp; d++) {
875 uint8_t value = bytestream2_get_byte(&gb);
877 if (offset >= dst_size)
886 offset += planepitch;
889 if ((cols * bpp) & 1)
890 bytestream2_skip(&gb, 1);
894 flag = bytestream2_get_be16(&gb);
895 rows = bytestream2_get_be16(&gb);
896 bytes = bytestream2_get_be16(&gb);
897 groups = bytestream2_get_be16(&gb);
899 for (g = 0; g < groups; g++) {
900 offset = bytestream2_get_be16(&gb);
903 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
905 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
907 for (r = 0; r < rows; r++) {
908 for (d = 0; d < bpp; d++) {
909 unsigned noffset = offset + (r * pitch) + d * planepitch;
911 if (bytestream2_get_bytes_left(&gb) < 1)
914 for (b = 0; b < bytes; b++) {
915 uint8_t value = bytestream2_get_byte(&gb);
917 if (noffset >= dst_size)
930 if ((rows * bytes * bpp) & 1)
931 bytestream2_skip(&gb, 1);
940 static void decode_short_vertical_delta(uint8_t *dst,
941 const uint8_t *buf, const uint8_t *buf_end,
942 int w, int bpp, int dst_size)
944 int ncolumns = (w + 15) >> 4;
945 int dstpitch = ncolumns * bpp * 2;
946 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
947 GetByteContext ptrs, gb, dptrs, dgb;
951 if (buf_end - buf <= 64)
954 bytestream2_init(&ptrs, buf, buf_end - buf);
955 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
956 bytestream2_init_writer(&pb, dst, dst_size);
958 for (k = 0; k < bpp; k++) {
959 ofssrc = bytestream2_get_be32(&ptrs);
960 ofsdata = bytestream2_get_be32(&dptrs);
965 if (ofssrc >= buf_end - buf)
968 if (ofsdata >= buf_end - buf)
971 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
972 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
973 for (j = 0; j < ncolumns; j++) {
974 ofsdst = (j + k * ncolumns) * 2;
976 i = bytestream2_get_byte(&gb);
978 opcode = bytestream2_get_byte(&gb);
981 opcode = bytestream2_get_byte(&gb);
982 x = bytestream2_get_be16(&dgb);
985 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
986 bytestream2_put_be16(&pb, x);
990 } else if (opcode < 0x80) {
991 ofsdst += opcode * dstpitch;
996 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
997 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1008 static void decode_long_vertical_delta(uint8_t *dst,
1009 const uint8_t *buf, const uint8_t *buf_end,
1010 int w, int bpp, int dst_size)
1012 int ncolumns = (w + 31) >> 5;
1013 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1014 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1015 GetByteContext ptrs, gb, dptrs, dgb;
1019 if (buf_end - buf <= 64)
1022 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1023 bytestream2_init(&ptrs, buf, buf_end - buf);
1024 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1025 bytestream2_init_writer(&pb, dst, dst_size);
1027 for (k = 0; k < bpp; k++) {
1028 ofssrc = bytestream2_get_be32(&ptrs);
1029 ofsdata = bytestream2_get_be32(&dptrs);
1034 if (ofssrc >= buf_end - buf)
1037 if (ofsdata >= buf_end - buf)
1040 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1041 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1042 for (j = 0; j < ncolumns; j++) {
1043 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1045 i = bytestream2_get_byte(&gb);
1047 opcode = bytestream2_get_byte(&gb);
1050 opcode = bytestream2_get_byte(&gb);
1051 if (h && (j == (ncolumns - 1))) {
1052 x = bytestream2_get_be16(&dgb);
1053 bytestream2_skip(&dgb, 2);
1055 x = bytestream2_get_be32(&dgb);
1059 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1060 if (h && (j == (ncolumns - 1))) {
1061 bytestream2_put_be16(&pb, x);
1063 bytestream2_put_be32(&pb, x);
1068 } else if (opcode < 0x80) {
1069 ofsdst += opcode * dstpitch;
1074 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1075 if (h && (j == (ncolumns - 1))) {
1076 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1077 bytestream2_skip(&dgb, 2);
1079 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1091 static void decode_short_vertical_delta2(uint8_t *dst,
1092 const uint8_t *buf, const uint8_t *buf_end,
1093 int w, int bpp, int dst_size)
1095 int ncolumns = (w + 15) >> 4;
1096 int dstpitch = ncolumns * bpp * 2;
1097 unsigned ofsdst, ofssrc, opcode, x;
1098 GetByteContext ptrs, gb;
1102 bytestream2_init(&ptrs, buf, buf_end - buf);
1103 bytestream2_init_writer(&pb, dst, dst_size);
1105 for (k = 0; k < bpp; k++) {
1106 ofssrc = bytestream2_get_be32(&ptrs);
1111 if (ofssrc >= buf_end - buf)
1114 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1115 for (j = 0; j < ncolumns; j++) {
1116 ofsdst = (j + k * ncolumns) * 2;
1118 i = bytestream2_get_be16(&gb);
1119 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1120 opcode = bytestream2_get_be16(&gb);
1123 opcode = bytestream2_get_be16(&gb);
1124 x = bytestream2_get_be16(&gb);
1126 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1127 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1128 bytestream2_put_be16(&pb, x);
1132 } else if (opcode < 0x8000) {
1133 ofsdst += opcode * dstpitch;
1137 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1138 bytestream2_get_bytes_left_p(&pb) > 1) {
1139 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1140 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1151 static void decode_long_vertical_delta2(uint8_t *dst,
1152 const uint8_t *buf, const uint8_t *buf_end,
1153 int w, int bpp, int dst_size)
1155 int ncolumns = (w + 31) >> 5;
1156 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1157 unsigned ofsdst, ofssrc, opcode, x;
1158 unsigned skip = 0x80000000, mask = skip - 1;
1159 GetByteContext ptrs, gb;
1163 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1164 bytestream2_init(&ptrs, buf, buf_end - buf);
1165 bytestream2_init_writer(&pb, dst, dst_size);
1167 for (k = 0; k < bpp; k++) {
1168 ofssrc = bytestream2_get_be32(&ptrs);
1173 if (ofssrc >= buf_end - buf)
1176 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1177 for (j = 0; j < ncolumns; j++) {
1178 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1180 if (h && (j == (ncolumns - 1))) {
1185 i = bytestream2_get_be32(&gb);
1186 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1187 opcode = bytestream2_get_be32(&gb);
1190 if (h && (j == ncolumns - 1)) {
1191 opcode = bytestream2_get_be16(&gb);
1192 x = bytestream2_get_be16(&gb);
1194 opcode = bytestream2_get_be32(&gb);
1195 x = bytestream2_get_be32(&gb);
1198 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1199 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1200 if (h && (j == ncolumns - 1))
1201 bytestream2_put_be16(&pb, x);
1203 bytestream2_put_be32(&pb, x);
1207 } else if (opcode < skip) {
1208 ofsdst += opcode * dstpitch;
1212 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1213 bytestream2_get_bytes_left_p(&pb) > 1) {
1214 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1215 if (h && (j == ncolumns - 1)) {
1216 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1218 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1230 static void decode_delta_d(uint8_t *dst,
1231 const uint8_t *buf, const uint8_t *buf_end,
1232 int w, int flag, int bpp, int dst_size)
1234 int planepitch = FFALIGN(w, 16) >> 3;
1235 int pitch = planepitch * bpp;
1236 int planepitch_byte = (w + 7) / 8;
1237 unsigned entries, ofssrc;
1238 GetByteContext gb, ptrs;
1242 if (buf_end - buf <= 4 * bpp)
1245 bytestream2_init_writer(&pb, dst, dst_size);
1246 bytestream2_init(&ptrs, buf, bpp * 4);
1248 for (k = 0; k < bpp; k++) {
1249 ofssrc = bytestream2_get_be32(&ptrs);
1254 if (ofssrc >= buf_end - buf)
1257 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1259 entries = bytestream2_get_be32(&gb);
1260 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1261 int32_t opcode = bytestream2_get_be32(&gb);
1262 unsigned offset = bytestream2_get_be32(&gb);
1264 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1266 uint32_t x = bytestream2_get_be32(&gb);
1267 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1268 bytestream2_put_be32(&pb, x);
1269 bytestream2_skip_p(&pb, pitch - 4);
1274 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1275 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1276 bytestream2_skip_p(&pb, pitch - 4);
1285 static void decode_delta_e(uint8_t *dst,
1286 const uint8_t *buf, const uint8_t *buf_end,
1287 int w, int flag, int bpp, int dst_size)
1289 int planepitch = FFALIGN(w, 16) >> 3;
1290 int pitch = planepitch * bpp;
1291 int planepitch_byte = (w + 7) / 8;
1292 unsigned entries, ofssrc;
1293 GetByteContext gb, ptrs;
1297 if (buf_end - buf <= 4 * bpp)
1300 bytestream2_init_writer(&pb, dst, dst_size);
1301 bytestream2_init(&ptrs, buf, bpp * 4);
1303 for (k = 0; k < bpp; k++) {
1304 ofssrc = bytestream2_get_be32(&ptrs);
1309 if (ofssrc >= buf_end - buf)
1312 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1314 entries = bytestream2_get_be16(&gb);
1315 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1316 int16_t opcode = bytestream2_get_be16(&gb);
1317 unsigned offset = bytestream2_get_be32(&gb);
1319 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1321 uint16_t x = bytestream2_get_be16(&gb);
1322 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1323 bytestream2_put_be16(&pb, x);
1324 bytestream2_skip_p(&pb, pitch - 2);
1329 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1330 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1331 bytestream2_skip_p(&pb, pitch - 2);
1340 static void decode_delta_l(uint8_t *dst,
1341 const uint8_t *buf, const uint8_t *buf_end,
1342 int w, int flag, int bpp, int dst_size)
1344 GetByteContext off0, off1, dgb, ogb;
1346 unsigned poff0, poff1;
1348 int planepitch_byte = (w + 7) / 8;
1349 int planepitch = ((w + 15) / 16) * 2;
1350 int pitch = planepitch * bpp;
1352 if (buf_end - buf <= 64)
1355 bytestream2_init(&off0, buf, buf_end - buf);
1356 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1357 bytestream2_init_writer(&pb, dst, dst_size);
1359 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1361 for (k = 0; k < bpp; k++) {
1362 poff0 = bytestream2_get_be32(&off0);
1363 poff1 = bytestream2_get_be32(&off1);
1368 if (2LL * poff0 >= buf_end - buf)
1371 if (2LL * poff1 >= buf_end - buf)
1374 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1375 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1377 while ((bytestream2_peek_be16(&ogb)) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1378 uint32_t offset = bytestream2_get_be16(&ogb);
1379 int16_t cnt = bytestream2_get_be16(&ogb);
1382 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1384 bytestream2_seek_p(&pb, offset, SEEK_SET);
1386 data = bytestream2_get_be16(&dgb);
1387 for (i = 0; i < cnt; i++) {
1388 bytestream2_put_be16(&pb, data);
1389 bytestream2_skip_p(&pb, dstpitch - 2);
1392 bytestream2_seek_p(&pb, offset, SEEK_SET);
1393 for (i = 0; i < cnt; i++) {
1394 data = bytestream2_get_be16(&dgb);
1395 bytestream2_put_be16(&pb, data);
1396 bytestream2_skip_p(&pb, dstpitch - 2);
1403 static int unsupported(AVCodecContext *avctx)
1405 IffContext *s = avctx->priv_data;
1406 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1407 return AVERROR_INVALIDDATA;
1410 static int decode_frame(AVCodecContext *avctx,
1411 void *data, int *got_frame,
1414 IffContext *s = avctx->priv_data;
1415 AVFrame *frame = data;
1416 const uint8_t *buf = avpkt->data;
1417 int buf_size = avpkt->size;
1418 const uint8_t *buf_end = buf + buf_size;
1420 GetByteContext *gb = &s->gb;
1421 const AVPixFmtDescriptor *desc;
1423 bytestream2_init(gb, avpkt->data, avpkt->size);
1425 if ((res = extract_header(avctx, avpkt)) < 0)
1428 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1432 buf += bytestream2_tell(gb);
1433 buf_size -= bytestream2_tell(gb);
1434 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1436 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1437 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1438 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1440 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1441 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1442 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1447 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1448 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1449 memcpy(s->pal[0], s->frame->data[1], 256 * 4);
1452 switch (s->compression) {
1454 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1455 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1456 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1457 for (plane = 0; plane < s->bpp; plane++) {
1458 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1459 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1460 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1461 buf += s->planesize;
1464 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1465 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1466 for (y = 0; y < avctx->height; y++) {
1467 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1468 memset(s->ham_buf, 0, s->planesize * 8);
1469 for (plane = 0; plane < s->bpp; plane++) {
1470 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1471 if (start >= buf_end)
1473 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1475 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1478 return unsupported(avctx);
1479 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1480 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1482 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1483 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1484 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1486 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1487 for (x = 0; x < avctx->width; x++)
1488 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1491 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1492 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1493 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1494 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1495 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1496 for (y = 0; y < avctx->height; y++) {
1497 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1498 memset(row, 0, avctx->width);
1499 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1500 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1501 buf += s->planesize;
1504 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1505 for (y = 0; y < avctx->height; y++) {
1506 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1507 memset(s->ham_buf, 0, s->planesize * 8);
1508 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1509 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1510 buf += s->planesize;
1512 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1514 } else { // AV_PIX_FMT_BGR32
1515 for (y = 0; y < avctx->height; y++) {
1516 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1517 memset(row, 0, avctx->width << 2);
1518 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1519 decodeplane32((uint32_t *)row, buf,
1520 FFMIN(s->planesize, buf_end - buf), plane);
1521 buf += s->planesize;
1525 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1526 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1527 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1528 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1529 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1530 buf += avctx->width + (avctx->width % 2); // padding if odd
1532 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1533 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1534 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1535 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1536 buf += avctx->width + (avctx->width & 1); // padding if odd
1537 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1540 return unsupported(avctx);
1544 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1545 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1546 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1547 uint8_t *video = s->video[0];
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 buf += decode_byterun(s->planebuf, s->planesize, gb);
1554 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1555 memcpy(video, s->planebuf, s->planesize);
1556 video += s->planesize;
1558 decodeplane8(row, s->planebuf, s->planesize, plane);
1561 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1562 for (y = 0; y < avctx->height; y++) {
1563 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1564 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1565 for (plane = 0; plane < s->bpp; plane++) {
1566 buf += decode_byterun(s->planebuf, s->planesize, gb);
1567 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1569 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1571 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1572 uint8_t *video = s->video[0];
1573 for (y = 0; y < avctx->height; y++) {
1574 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1575 memset(s->ham_buf, 0, s->planesize * 8);
1576 for (plane = 0; plane < s->bpp; plane++) {
1577 buf += decode_byterun(s->planebuf, s->planesize, gb);
1578 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1579 memcpy(video, s->planebuf, s->planesize);
1580 video += s->planesize;
1582 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1584 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1586 } else { // AV_PIX_FMT_BGR32
1587 for (y = 0; y < avctx->height; y++) {
1588 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1589 memset(row, 0, avctx->width << 2);
1590 for (plane = 0; plane < s->bpp; plane++) {
1591 buf += decode_byterun(s->planebuf, s->planesize, gb);
1592 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1596 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1597 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1598 for (y = 0; y < avctx->height; y++) {
1599 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1600 buf += decode_byterun(row, avctx->width, gb);
1602 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1603 for (y = 0; y < avctx->height; y++) {
1604 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1605 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1606 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1609 return unsupported(avctx);
1610 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1611 if (av_get_bits_per_pixel(desc) == 32)
1612 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1614 return unsupported(avctx);
1618 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1619 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1620 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1621 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1623 return unsupported(avctx);
1626 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1627 if (av_get_bits_per_pixel(desc) == 32)
1628 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1630 return unsupported(avctx);
1632 return unsupported(avctx);
1636 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1640 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1645 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1647 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1652 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1654 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1658 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1662 if (s->is_interlaced)
1663 return unsupported(avctx);
1664 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1668 if (s->is_interlaced)
1669 return unsupported(avctx);
1670 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1674 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1677 return unsupported(avctx);
1680 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1681 memcpy(s->pal[1], s->pal[0], 256 * 4);
1682 memcpy(s->video[1], s->video[0], s->video_size);
1685 if (s->compression > 0xff) {
1686 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1688 for (y = 0; y < avctx->height; y++) {
1689 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1690 memset(row, 0, avctx->width);
1691 for (plane = 0; plane < s->bpp; plane++) {
1692 decodeplane8(row, buf, s->planesize, plane);
1693 buf += s->planesize;
1696 memcpy(frame->data[1], s->pal[0], 256 * 4);
1697 } else if (s->ham) {
1698 int i, count = 1 << s->ham;
1701 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1702 for (i = 0; i < count; i++) {
1703 s->ham_palbuf[i*2+1] = s->pal[0][i];
1705 for (i = 0; i < count; i++) {
1706 uint32_t tmp = i << (8 - s->ham);
1707 tmp |= tmp >> s->ham;
1708 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1709 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1710 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1711 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1712 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1713 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1715 if (s->masking == MASK_HAS_MASK) {
1716 for (i = 0; i < 8 * (1 << s->ham); i++)
1717 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1719 for (y = 0; y < avctx->height; y++) {
1720 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1721 memset(s->ham_buf, 0, s->planesize * 8);
1722 for (plane = 0; plane < s->bpp; plane++) {
1723 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1724 buf += s->planesize;
1726 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1729 return unsupported(avctx);
1733 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1734 FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
1738 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1739 frame->key_frame = 1;
1740 frame->pict_type = AV_PICTURE_TYPE_I;
1742 frame->key_frame = 0;
1743 frame->pict_type = AV_PICTURE_TYPE_P;
1751 #if CONFIG_IFF_ILBM_DECODER
1752 AVCodec ff_iff_ilbm_decoder = {
1754 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM"),
1755 .type = AVMEDIA_TYPE_VIDEO,
1756 .id = AV_CODEC_ID_IFF_ILBM,
1757 .priv_data_size = sizeof(IffContext),
1758 .init = decode_init,
1759 .close = decode_end,
1760 .decode = decode_frame,
1761 .capabilities = AV_CODEC_CAP_DR1,