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
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/RGB8/RGBN bitmap decoder
31 #include "libavutil/imgutils.h"
33 #include "bytestream.h"
42 MASK_HAS_TRANSPARENT_COLOR,
46 typedef struct IffContext {
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
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
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), \
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),
114 #define LUT32(plane) { \
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, \
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),
145 // Gray to RGB, required for palette table of grayscale images with bpp < 8
146 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
147 return x << 16 | x << 8 | x;
151 * Convert CMAP buffer (stored in extradata) to lavc palette format
153 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
155 IffContext *s = avctx->priv_data;
157 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
158 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
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;
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);
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);
176 } else { // Create gray-scale color palette for bps < 8
177 count = 1 << avctx->bits_per_coded_sample;
179 for (i = 0; i < count; i++)
180 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
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;
187 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
188 for (i = 0; i < count; i++)
190 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
191 s->transparency < 1 << avctx->bits_per_coded_sample)
192 pal[s->transparency] &= 0xFFFFFF;
197 * Extracts the IFF extra context and updates internal
198 * decoder structures.
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
204 static int extract_header(AVCodecContext *const avctx,
205 const AVPacket *const avpkt)
207 IffContext *s = avctx->priv_data;
209 unsigned buf_size = 0;
212 if (avctx->extradata_size < 2) {
213 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
214 return AVERROR_INVALIDDATA;
216 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
218 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
221 GetByteContext *gb = &s->gb;
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);
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')) {
233 return AVERROR_INVALIDDATA;
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);
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;
248 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
249 int count = data_size / 3;
250 uint32_t *pal = s->pal;
253 return AVERROR_INVALIDDATA;
255 for (i = 0; i < count; i++)
256 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
258 for (i = 0; i < count; i++)
259 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
261 bytestream2_skip(gb, data_size & 1);
263 bytestream2_skip(gb, data_size + (data_size&1));
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;
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);
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;
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);
304 return AVERROR(ENOMEM);
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);
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);
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;
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;
326 av_freep(&s->ham_buf);
327 av_freep(&s->ham_palbuf);
330 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
332 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
334 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
336 return AVERROR(ENOMEM);
338 ham_count = 8 * (1 << s->ham);
339 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
340 if (!s->ham_palbuf) {
341 av_freep(&s->ham_buf);
342 return AVERROR(ENOMEM);
345 if (count) { // HAM with color palette attached
346 // prefill with black and palette and set HAM take direct value mask to zero
347 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
348 for (i=0; i < count; i++) {
349 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
352 } else { // HAM with grayscale color palette
354 for (i=0; i < count; i++) {
355 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
356 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
359 for (i=0; i < count; i++) {
360 uint32_t tmp = i << (8 - s->ham);
361 tmp |= tmp >> s->ham;
362 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
363 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
364 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
365 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
366 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
367 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
369 if (s->masking == MASK_HAS_MASK) {
370 for (i = 0; i < ham_count; i++)
371 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
379 static av_cold int decode_end(AVCodecContext *avctx)
381 IffContext *s = avctx->priv_data;
382 av_freep(&s->planebuf);
383 av_freep(&s->ham_buf);
384 av_freep(&s->ham_palbuf);
385 av_freep(&s->mask_buf);
386 av_freep(&s->mask_palbuf);
387 av_freep(&s->video[0]);
388 av_freep(&s->video[1]);
393 static av_cold int decode_init(AVCodecContext *avctx)
395 IffContext *s = avctx->priv_data;
398 if (avctx->bits_per_coded_sample <= 8) {
401 if (avctx->extradata_size >= 2)
402 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
405 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
406 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
407 } else if (avctx->bits_per_coded_sample <= 32) {
408 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
409 avctx->pix_fmt = AV_PIX_FMT_RGB32;
410 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
411 avctx->pix_fmt = AV_PIX_FMT_RGB444;
412 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
413 if (avctx->bits_per_coded_sample == 24) {
414 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
415 } else if (avctx->bits_per_coded_sample == 32) {
416 avctx->pix_fmt = AV_PIX_FMT_BGR32;
418 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
419 return AVERROR_PATCHWELCOME;
423 return AVERROR_INVALIDDATA;
426 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
428 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
429 s->planebuf = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
431 return AVERROR(ENOMEM);
433 s->bpp = avctx->bits_per_coded_sample;
435 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
436 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
437 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
438 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
439 s->pal = av_calloc(256, sizeof(*s->pal));
440 if (!s->video[0] || !s->video[1] || !s->pal)
441 return AVERROR(ENOMEM);
444 if ((err = extract_header(avctx, NULL)) < 0)
451 * Decode interleaved plane buffer up to 8bpp
452 * @param dst Destination buffer
453 * @param buf Source buffer
455 * @param plane plane number to decode as
457 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
459 const uint64_t *lut = plane8_lut[plane];
461 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
465 uint64_t v = AV_RN64A(dst) | lut[*buf++];
468 } while (--buf_size);
472 * Decode interleaved plane buffer up to 24bpp
473 * @param dst Destination buffer
474 * @param buf Source buffer
476 * @param plane plane number to decode as
478 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
480 const uint32_t *lut = plane32_lut[plane];
482 unsigned mask = (*buf >> 2) & ~3;
483 dst[0] |= lut[mask++];
484 dst[1] |= lut[mask++];
485 dst[2] |= lut[mask++];
487 mask = (*buf++ << 2) & 0x3F;
488 dst[4] |= lut[mask++];
489 dst[5] |= lut[mask++];
490 dst[6] |= lut[mask++];
493 } while (--buf_size);
496 #define DECODE_HAM_PLANE32(x) \
497 first = buf[x] << 1; \
498 second = buf[(x)+1] << 1; \
499 delta &= pal[first++]; \
500 delta |= pal[first]; \
502 delta &= pal[second++]; \
503 delta |= pal[second]; \
507 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
509 * @param dst the destination 24bpp buffer
510 * @param buf the source 8bpp chunky buffer
511 * @param pal the HAM decode table
512 * @param buf_size the plane size in bytes
514 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
515 const uint32_t *const pal, unsigned buf_size)
517 uint32_t delta = pal[1]; /* first palette entry */
519 uint32_t first, second;
520 DECODE_HAM_PLANE32(0);
521 DECODE_HAM_PLANE32(2);
522 DECODE_HAM_PLANE32(4);
523 DECODE_HAM_PLANE32(6);
526 } while (--buf_size);
529 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
530 const uint32_t *const pal, unsigned width)
533 *dst++ = pal[*buf++];
538 * Decode one complete byterun1 encoded line.
540 * @param dst the destination buffer where to store decompressed bitstream
541 * @param dst_size the destination plane size in bytes
542 * @param buf the source byterun1 compressed bitstream
543 * @param buf_end the EOF of source byterun1 compressed bitstream
544 * @return number of consumed bytes in byterun1 compressed bitstream
546 static int decode_byterun(uint8_t *dst, int dst_size,
550 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
552 const int8_t value = bytestream2_get_byte(gb);
554 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
555 bytestream2_get_buffer(gb, dst + x, length);
556 if (length < value + 1)
557 bytestream2_skip(gb, value + 1 - length);
558 } else if (value > -128) {
559 length = FFMIN(-value + 1, dst_size - x);
560 memset(dst + x, bytestream2_get_byte(gb), length);
567 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
568 memset(dst+x, 0, dst_size - x);
570 return bytestream2_tell(gb);
573 static int decode_byterun2(uint8_t *dst, int height, int line_size,
578 int i, y_pos = 0, x_pos = 0;
580 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
583 bytestream2_skip(gb, 4);
584 count = bytestream2_get_be16(gb) - 2;
585 if (bytestream2_get_bytes_left(gb) < count)
588 bytestream2_init(&cmds, gb->buffer, count);
589 bytestream2_skip(gb, count);
591 for (i = 0; i < count && x_pos < line_size; i++) {
592 int8_t cmd = bytestream2_get_byte(&cmds);
596 l = bytestream2_get_be16(gb);
597 while (l-- > 0 && x_pos < line_size) {
598 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
599 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
600 if (y_pos >= height) {
605 } else if (cmd < 0) {
607 while (l-- > 0 && x_pos < line_size) {
608 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
609 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
610 if (y_pos >= height) {
615 } else if (cmd == 1) {
616 l = bytestream2_get_be16(gb);
617 r = bytestream2_get_be16(gb);
618 while (l-- > 0 && x_pos < line_size) {
619 dst[x_pos + y_pos * line_size ] = r >> 8;
620 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
621 if (y_pos >= height) {
628 r = bytestream2_get_be16(gb);
629 while (l-- > 0 && x_pos < line_size) {
630 dst[x_pos + y_pos * line_size ] = r >> 8;
631 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
632 if (y_pos >= height) {
640 return bytestream2_tell(gb);
643 #define DECODE_RGBX_COMMON(type) \
645 length = bytestream2_get_byte(gb); \
647 length = bytestream2_get_be16(gb); \
652 for (i = 0; i < length; i++) { \
653 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
665 * @param[out] dst Destination buffer
666 * @param width Width of destination buffer (pixels)
667 * @param height Height of destination buffer (pixels)
668 * @param linesize Line size of destination buffer (bytes)
670 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
672 int x = 0, y = 0, i, length;
673 while (bytestream2_get_bytes_left(gb) >= 4) {
674 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
675 length = bytestream2_get_byte(gb) & 0x7F;
676 DECODE_RGBX_COMMON(uint32_t)
682 * @param[out] dst Destination buffer
683 * @param width Width of destination buffer (pixels)
684 * @param height Height of destination buffer (pixels)
685 * @param linesize Line size of destination buffer (bytes)
687 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
689 int x = 0, y = 0, i, length;
690 while (bytestream2_get_bytes_left(gb) >= 2) {
691 uint32_t pixel = bytestream2_get_be16u(gb);
692 length = pixel & 0x7;
694 DECODE_RGBX_COMMON(uint16_t)
699 * Decode DEEP RLE 32-bit buffer
700 * @param[out] dst Destination buffer
701 * @param[in] src Source buffer
702 * @param src_size Source buffer size (bytes)
703 * @param width Width of destination buffer (pixels)
704 * @param height Height of destination buffer (pixels)
705 * @param linesize Line size of destination buffer (bytes)
707 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
709 const uint8_t *src_end = src + src_size;
711 while (src + 5 <= src_end) {
713 opcode = *(int8_t *)src++;
715 int size = opcode + 1;
716 for (i = 0; i < size; i++) {
717 int length = FFMIN(size - i, width);
718 memcpy(dst + y*linesize + x * 4, src, length * 4);
730 int size = -opcode + 1;
731 uint32_t pixel = AV_RN32(src);
732 for (i = 0; i < size; i++) {
733 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
748 * Decode DEEP TVDC 32-bit buffer
749 * @param[out] dst Destination buffer
750 * @param[in] src Source buffer
751 * @param src_size Source buffer size (bytes)
752 * @param width Width of destination buffer (pixels)
753 * @param height Height of destination buffer (pixels)
754 * @param linesize Line size of destination buffer (bytes)
755 * @param[int] tvdc TVDC lookup table
757 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)
759 int x = 0, y = 0, plane = 0;
763 for (i = 0; i < src_size * 2;) {
764 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
765 int d = tvdc[GETNIBBLE];
769 dst[y * linesize + x*4 + plane] = pixel;
772 if (i >= src_size * 2)
776 d = FFMIN(d, width - x);
777 for (j = 0; j < d; j++) {
778 dst[y * linesize + x*4 + plane] = pixel;
797 static void decode_short_horizontal_delta(uint8_t *dst,
798 const uint8_t *buf, const uint8_t *buf_end,
799 int w, int bpp, int dst_size)
801 int planepitch = FFALIGN(w, 16) >> 3;
802 int pitch = planepitch * bpp;
803 GetByteContext ptrs, gb;
805 unsigned ofssrc, pos;
808 bytestream2_init(&ptrs, buf, buf_end - buf);
809 bytestream2_init_writer(&pb, dst, dst_size);
811 for (k = 0; k < bpp; k++) {
812 ofssrc = bytestream2_get_be32(&ptrs);
818 if (ofssrc >= buf_end - buf)
821 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
822 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
823 int16_t offset = bytestream2_get_be16(&gb);
827 unsigned data = bytestream2_get_be16(&gb);
830 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
831 bytestream2_seek_p(&pb, noffset, SEEK_SET);
832 bytestream2_put_be16(&pb, data);
834 uint16_t count = bytestream2_get_be16(&gb);
836 pos += 2 * -(offset + 2);
837 for (i = 0; i < count; i++) {
838 uint16_t data = bytestream2_get_be16(&gb);
841 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
842 bytestream2_seek_p(&pb, noffset, SEEK_SET);
843 bytestream2_put_be16(&pb, data);
850 static void decode_byte_vertical_delta(uint8_t *dst,
851 const uint8_t *buf, const uint8_t *buf_end,
852 int w, int xor, int bpp, int dst_size)
854 int ncolumns = ((w + 15) / 16) * 2;
855 int dstpitch = ncolumns * bpp;
856 unsigned ofsdst, ofssrc, opcode, x;
857 GetByteContext ptrs, gb;
861 bytestream2_init(&ptrs, buf, buf_end - buf);
862 bytestream2_init_writer(&pb, dst, dst_size);
864 for (k = 0; k < bpp; k++) {
865 ofssrc = bytestream2_get_be32(&ptrs);
870 if (ofssrc >= buf_end - buf)
873 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
874 for (j = 0; j < ncolumns; j++) {
875 ofsdst = j + k * ncolumns;
877 i = bytestream2_get_byte(&gb);
879 opcode = bytestream2_get_byte(&gb);
882 opcode = bytestream2_get_byte(&gb);
883 x = bytestream2_get_byte(&gb);
886 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
887 if (xor && ofsdst < dst_size) {
888 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
890 bytestream2_put_byte(&pb, x);
895 } else if (opcode < 0x80) {
896 ofsdst += opcode * dstpitch;
901 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
902 if (xor && ofsdst < dst_size) {
903 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
905 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
917 static void decode_delta_j(uint8_t *dst,
918 const uint8_t *buf, const uint8_t *buf_end,
919 int w, int h, int bpp, int dst_size)
923 uint32_t type, flag, cols, groups, rows, bytes;
925 int planepitch_byte = (w + 7) / 8;
926 int planepitch = ((w + 15) / 16) * 2;
927 int kludge_j, b, g, r, d;
930 pitch = planepitch * bpp;
931 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
933 bytestream2_init(&gb, buf, buf_end - buf);
935 while (bytestream2_get_bytes_left(&gb) >= 2) {
936 type = bytestream2_get_be16(&gb);
942 flag = bytestream2_get_be16(&gb);
943 cols = bytestream2_get_be16(&gb);
944 groups = bytestream2_get_be16(&gb);
946 for (g = 0; g < groups; g++) {
947 offset = bytestream2_get_be16(&gb);
949 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
950 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
955 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
957 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
959 for (b = 0; b < cols; b++) {
960 for (d = 0; d < bpp; d++) {
961 uint8_t value = bytestream2_get_byte(&gb);
963 if (offset >= dst_size)
972 offset += planepitch;
975 if ((cols * bpp) & 1)
976 bytestream2_skip(&gb, 1);
980 flag = bytestream2_get_be16(&gb);
981 rows = bytestream2_get_be16(&gb);
982 bytes = bytestream2_get_be16(&gb);
983 groups = bytestream2_get_be16(&gb);
985 for (g = 0; g < groups; g++) {
986 offset = bytestream2_get_be16(&gb);
989 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
991 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
993 for (r = 0; r < rows; r++) {
994 for (d = 0; d < bpp; d++) {
995 unsigned noffset = offset + (r * pitch) + d * planepitch;
997 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
998 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1002 for (b = 0; b < bytes; b++) {
1003 uint8_t value = bytestream2_get_byte(&gb);
1005 if (noffset >= dst_size)
1007 ptr = dst + noffset;
1018 if ((rows * bytes * bpp) & 1)
1019 bytestream2_skip(&gb, 1);
1028 static void decode_short_vertical_delta(uint8_t *dst,
1029 const uint8_t *buf, const uint8_t *buf_end,
1030 int w, int bpp, int dst_size)
1032 int ncolumns = (w + 15) >> 4;
1033 int dstpitch = ncolumns * bpp * 2;
1034 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1035 GetByteContext ptrs, gb, dptrs, dgb;
1039 if (buf_end - buf <= 64)
1042 bytestream2_init(&ptrs, buf, buf_end - buf);
1043 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1044 bytestream2_init_writer(&pb, dst, dst_size);
1046 for (k = 0; k < bpp; k++) {
1047 ofssrc = bytestream2_get_be32(&ptrs);
1048 ofsdata = bytestream2_get_be32(&dptrs);
1053 if (ofssrc >= buf_end - buf)
1056 if (ofsdata >= buf_end - buf)
1059 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1060 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1061 for (j = 0; j < ncolumns; j++) {
1062 ofsdst = (j + k * ncolumns) * 2;
1064 i = bytestream2_get_byte(&gb);
1066 opcode = bytestream2_get_byte(&gb);
1069 opcode = bytestream2_get_byte(&gb);
1070 x = bytestream2_get_be16(&dgb);
1073 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1074 bytestream2_put_be16(&pb, x);
1078 } else if (opcode < 0x80) {
1079 ofsdst += opcode * dstpitch;
1084 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1085 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1096 static void decode_long_vertical_delta(uint8_t *dst,
1097 const uint8_t *buf, const uint8_t *buf_end,
1098 int w, int bpp, int dst_size)
1100 int ncolumns = (w + 31) >> 5;
1101 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1102 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1103 GetByteContext ptrs, gb, dptrs, dgb;
1107 if (buf_end - buf <= 64)
1110 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1111 bytestream2_init(&ptrs, buf, buf_end - buf);
1112 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1113 bytestream2_init_writer(&pb, dst, dst_size);
1115 for (k = 0; k < bpp; k++) {
1116 ofssrc = bytestream2_get_be32(&ptrs);
1117 ofsdata = bytestream2_get_be32(&dptrs);
1122 if (ofssrc >= buf_end - buf)
1125 if (ofsdata >= buf_end - buf)
1128 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1129 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1130 for (j = 0; j < ncolumns; j++) {
1131 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1133 i = bytestream2_get_byte(&gb);
1135 opcode = bytestream2_get_byte(&gb);
1138 opcode = bytestream2_get_byte(&gb);
1139 if (h && (j == (ncolumns - 1))) {
1140 x = bytestream2_get_be16(&dgb);
1141 bytestream2_skip(&dgb, 2);
1143 x = bytestream2_get_be32(&dgb);
1147 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1148 if (h && (j == (ncolumns - 1))) {
1149 bytestream2_put_be16(&pb, x);
1151 bytestream2_put_be32(&pb, x);
1156 } else if (opcode < 0x80) {
1157 ofsdst += opcode * dstpitch;
1162 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1163 if (h && (j == (ncolumns - 1))) {
1164 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1165 bytestream2_skip(&dgb, 2);
1167 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1179 static void decode_short_vertical_delta2(uint8_t *dst,
1180 const uint8_t *buf, const uint8_t *buf_end,
1181 int w, int bpp, int dst_size)
1183 int ncolumns = (w + 15) >> 4;
1184 int dstpitch = ncolumns * bpp * 2;
1185 unsigned ofsdst, ofssrc, opcode, x;
1186 GetByteContext ptrs, gb;
1190 bytestream2_init(&ptrs, buf, buf_end - buf);
1191 bytestream2_init_writer(&pb, dst, dst_size);
1193 for (k = 0; k < bpp; k++) {
1194 ofssrc = bytestream2_get_be32(&ptrs);
1199 if (ofssrc >= buf_end - buf)
1202 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1203 for (j = 0; j < ncolumns; j++) {
1204 ofsdst = (j + k * ncolumns) * 2;
1206 i = bytestream2_get_be16(&gb);
1207 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1208 opcode = bytestream2_get_be16(&gb);
1211 opcode = bytestream2_get_be16(&gb);
1212 x = bytestream2_get_be16(&gb);
1214 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1215 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1216 bytestream2_put_be16(&pb, x);
1220 } else if (opcode < 0x8000) {
1221 ofsdst += opcode * dstpitch;
1225 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1226 bytestream2_get_bytes_left_p(&pb) > 1) {
1227 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1228 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1239 static void decode_long_vertical_delta2(uint8_t *dst,
1240 const uint8_t *buf, const uint8_t *buf_end,
1241 int w, int bpp, int dst_size)
1243 int ncolumns = (w + 31) >> 5;
1244 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1245 unsigned ofsdst, ofssrc, opcode, x;
1246 unsigned skip = 0x80000000, mask = skip - 1;
1247 GetByteContext ptrs, gb;
1251 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1252 bytestream2_init(&ptrs, buf, buf_end - buf);
1253 bytestream2_init_writer(&pb, dst, dst_size);
1255 for (k = 0; k < bpp; k++) {
1256 ofssrc = bytestream2_get_be32(&ptrs);
1261 if (ofssrc >= buf_end - buf)
1264 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1265 for (j = 0; j < ncolumns; j++) {
1266 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1268 if (h && (j == (ncolumns - 1))) {
1273 i = bytestream2_get_be32(&gb);
1274 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1275 opcode = bytestream2_get_be32(&gb);
1278 if (h && (j == ncolumns - 1)) {
1279 opcode = bytestream2_get_be16(&gb);
1280 x = bytestream2_get_be16(&gb);
1282 opcode = bytestream2_get_be32(&gb);
1283 x = bytestream2_get_be32(&gb);
1286 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1287 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1288 if (h && (j == ncolumns - 1))
1289 bytestream2_put_be16(&pb, x);
1291 bytestream2_put_be32(&pb, x);
1295 } else if (opcode < skip) {
1296 ofsdst += opcode * dstpitch;
1300 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1301 bytestream2_get_bytes_left_p(&pb) > 1) {
1302 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1303 if (h && (j == ncolumns - 1)) {
1304 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1306 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1318 static void decode_delta_d(uint8_t *dst,
1319 const uint8_t *buf, const uint8_t *buf_end,
1320 int w, int flag, int bpp, int dst_size)
1322 int planepitch = FFALIGN(w, 16) >> 3;
1323 int pitch = planepitch * bpp;
1324 int planepitch_byte = (w + 7) / 8;
1325 unsigned entries, ofssrc;
1326 GetByteContext gb, ptrs;
1330 if (buf_end - buf <= 4 * bpp)
1333 bytestream2_init_writer(&pb, dst, dst_size);
1334 bytestream2_init(&ptrs, buf, bpp * 4);
1336 for (k = 0; k < bpp; k++) {
1337 ofssrc = bytestream2_get_be32(&ptrs);
1342 if (ofssrc >= buf_end - buf)
1345 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1347 entries = bytestream2_get_be32(&gb);
1348 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1349 int32_t opcode = bytestream2_get_be32(&gb);
1350 unsigned offset = bytestream2_get_be32(&gb);
1352 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1354 uint32_t x = bytestream2_get_be32(&gb);
1355 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1356 bytestream2_put_be32(&pb, x);
1357 bytestream2_skip_p(&pb, pitch - 4);
1362 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1363 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1364 bytestream2_skip_p(&pb, pitch - 4);
1373 static void decode_delta_e(uint8_t *dst,
1374 const uint8_t *buf, const uint8_t *buf_end,
1375 int w, int flag, int bpp, int dst_size)
1377 int planepitch = FFALIGN(w, 16) >> 3;
1378 int pitch = planepitch * bpp;
1379 int planepitch_byte = (w + 7) / 8;
1380 unsigned entries, ofssrc;
1381 GetByteContext gb, ptrs;
1385 if (buf_end - buf <= 4 * bpp)
1388 bytestream2_init_writer(&pb, dst, dst_size);
1389 bytestream2_init(&ptrs, buf, bpp * 4);
1391 for (k = 0; k < bpp; k++) {
1392 ofssrc = bytestream2_get_be32(&ptrs);
1397 if (ofssrc >= buf_end - buf)
1400 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1402 entries = bytestream2_get_be16(&gb);
1403 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1404 int16_t opcode = bytestream2_get_be16(&gb);
1405 unsigned offset = bytestream2_get_be32(&gb);
1407 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1409 uint16_t x = bytestream2_get_be16(&gb);
1410 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1411 bytestream2_put_be16(&pb, x);
1412 bytestream2_skip_p(&pb, pitch - 2);
1417 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1418 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1419 bytestream2_skip_p(&pb, pitch - 2);
1428 static void decode_delta_l(uint8_t *dst,
1429 const uint8_t *buf, const uint8_t *buf_end,
1430 int w, int flag, int bpp, int dst_size)
1432 GetByteContext off0, off1, dgb, ogb;
1434 unsigned poff0, poff1;
1436 int planepitch_byte = (w + 7) / 8;
1437 int planepitch = ((w + 15) / 16) * 2;
1438 int pitch = planepitch * bpp;
1440 if (buf_end - buf <= 64)
1443 bytestream2_init(&off0, buf, buf_end - buf);
1444 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1445 bytestream2_init_writer(&pb, dst, dst_size);
1447 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1449 for (k = 0; k < bpp; k++) {
1450 poff0 = bytestream2_get_be32(&off0);
1451 poff1 = bytestream2_get_be32(&off1);
1456 if (2LL * poff0 >= buf_end - buf)
1459 if (2LL * poff1 >= buf_end - buf)
1462 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1463 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1465 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1466 uint32_t offset = bytestream2_get_be16(&ogb);
1467 int16_t cnt = bytestream2_get_be16(&ogb);
1470 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1472 if (bytestream2_get_bytes_left(&dgb) < 2)
1474 bytestream2_seek_p(&pb, offset, SEEK_SET);
1476 data = bytestream2_get_be16(&dgb);
1477 for (i = 0; i < cnt; i++) {
1478 bytestream2_put_be16(&pb, data);
1479 bytestream2_skip_p(&pb, dstpitch - 2);
1482 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1484 bytestream2_seek_p(&pb, offset, SEEK_SET);
1485 for (i = 0; i < cnt; i++) {
1486 data = bytestream2_get_be16(&dgb);
1487 bytestream2_put_be16(&pb, data);
1488 bytestream2_skip_p(&pb, dstpitch - 2);
1495 static int unsupported(AVCodecContext *avctx)
1497 IffContext *s = avctx->priv_data;
1498 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1499 return AVERROR_INVALIDDATA;
1502 static int decode_frame(AVCodecContext *avctx,
1503 void *data, int *got_frame,
1506 IffContext *s = avctx->priv_data;
1507 AVFrame *frame = data;
1508 const uint8_t *buf = avpkt->data;
1509 int buf_size = avpkt->size;
1510 const uint8_t *buf_end = buf + buf_size;
1512 GetByteContext *gb = &s->gb;
1513 const AVPixFmtDescriptor *desc;
1515 bytestream2_init(gb, avpkt->data, avpkt->size);
1517 if ((res = extract_header(avctx, avpkt)) < 0)
1520 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1524 buf += bytestream2_tell(gb);
1525 buf_size -= bytestream2_tell(gb);
1526 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1528 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1529 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1530 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1532 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1533 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1534 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1539 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1540 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1541 memcpy(s->pal, s->frame->data[1], 256 * 4);
1544 switch (s->compression) {
1546 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1547 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1548 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1549 for (plane = 0; plane < s->bpp; plane++) {
1550 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1551 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1552 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1553 buf += s->planesize;
1556 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1557 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1558 for (y = 0; y < avctx->height; y++) {
1559 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1560 memset(s->ham_buf, 0, s->planesize * 8);
1561 for (plane = 0; plane < s->bpp; plane++) {
1562 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1563 if (start >= buf_end)
1565 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1567 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1570 return unsupported(avctx);
1571 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1572 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1574 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1575 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1576 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1578 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1579 for (x = 0; x < avctx->width; x++)
1580 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1583 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1584 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1585 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1586 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1587 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1588 for (y = 0; y < avctx->height; y++) {
1589 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1590 memset(row, 0, avctx->width);
1591 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1592 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1593 buf += s->planesize;
1596 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1597 for (y = 0; y < avctx->height; y++) {
1598 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1599 memset(s->ham_buf, 0, s->planesize * 8);
1600 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1601 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1602 buf += s->planesize;
1604 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1606 } else { // AV_PIX_FMT_BGR32
1607 for (y = 0; y < avctx->height; y++) {
1608 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1609 memset(row, 0, avctx->width << 2);
1610 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1611 decodeplane32((uint32_t *)row, buf,
1612 FFMIN(s->planesize, buf_end - buf), plane);
1613 buf += s->planesize;
1617 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1618 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1619 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1620 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1621 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1622 buf += avctx->width + (avctx->width % 2); // padding if odd
1624 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1625 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1626 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1627 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1628 buf += avctx->width + (avctx->width & 1); // padding if odd
1629 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1632 return unsupported(avctx);
1634 return unsupported(avctx);
1638 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1639 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1640 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1641 uint8_t *video = s->video[0];
1643 for (y = 0; y < avctx->height; y++) {
1644 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1645 memset(row, 0, avctx->width);
1646 for (plane = 0; plane < s->bpp; plane++) {
1647 buf += decode_byterun(s->planebuf, s->planesize, gb);
1648 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1649 memcpy(video, s->planebuf, s->planesize);
1650 video += s->planesize;
1652 decodeplane8(row, s->planebuf, s->planesize, plane);
1655 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1656 for (y = 0; y < avctx->height; y++) {
1657 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1658 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1659 for (plane = 0; plane < s->bpp; plane++) {
1660 buf += decode_byterun(s->planebuf, s->planesize, gb);
1661 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1663 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1665 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1666 uint8_t *video = s->video[0];
1667 for (y = 0; y < avctx->height; y++) {
1668 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1669 memset(s->ham_buf, 0, s->planesize * 8);
1670 for (plane = 0; plane < s->bpp; plane++) {
1671 buf += decode_byterun(s->planebuf, s->planesize, gb);
1672 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1673 memcpy(video, s->planebuf, s->planesize);
1674 video += s->planesize;
1676 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1678 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1680 } else { // AV_PIX_FMT_BGR32
1681 for (y = 0; y < avctx->height; y++) {
1682 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1683 memset(row, 0, avctx->width << 2);
1684 for (plane = 0; plane < s->bpp; plane++) {
1685 buf += decode_byterun(s->planebuf, s->planesize, gb);
1686 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1690 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1691 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1692 for (y = 0; y < avctx->height; y++) {
1693 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1694 buf += decode_byterun(row, avctx->width, gb);
1696 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1697 for (y = 0; y < avctx->height; y++) {
1698 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1699 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1700 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1703 return unsupported(avctx);
1704 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1705 if (av_get_bits_per_pixel(desc) == 32)
1706 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1708 return unsupported(avctx);
1709 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1710 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1711 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1712 for (plane = 0; plane < s->bpp; plane++) {
1713 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1714 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1715 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1716 buf += s->planesize;
1719 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1720 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1721 for (y = 0; y < avctx->height; y++) {
1722 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1723 memset(s->ham_buf, 0, s->planesize * 8);
1724 for (plane = 0; plane < s->bpp; plane++) {
1725 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1726 if (start >= buf_end)
1728 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1730 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1733 return unsupported(avctx);
1736 return unsupported(avctx);
1740 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1741 for (plane = 0; plane < s->bpp; plane++) {
1742 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1743 for (y = 0; y < avctx->height; y++) {
1744 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1745 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1749 return unsupported(avctx);
1753 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1754 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1755 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1756 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1758 return unsupported(avctx);
1761 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1762 if (av_get_bits_per_pixel(desc) == 32)
1763 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1765 return unsupported(avctx);
1767 return unsupported(avctx);
1771 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1775 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1780 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1782 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1787 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1789 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1793 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1797 if (s->is_interlaced)
1798 return unsupported(avctx);
1799 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1803 if (s->is_interlaced)
1804 return unsupported(avctx);
1805 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1809 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1812 return unsupported(avctx);
1815 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1816 memcpy(s->video[1], s->video[0], s->video_size);
1819 if (s->compression > 0xff) {
1820 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1822 for (y = 0; y < avctx->height; y++) {
1823 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1824 memset(row, 0, avctx->width);
1825 for (plane = 0; plane < s->bpp; plane++) {
1826 decodeplane8(row, buf, s->planesize, plane);
1827 buf += s->planesize;
1830 memcpy(frame->data[1], s->pal, 256 * 4);
1831 } else if (s->ham) {
1832 int i, count = 1 << s->ham;
1835 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1836 for (i = 0; i < count; i++) {
1837 s->ham_palbuf[i*2+1] = s->pal[i];
1839 for (i = 0; i < count; i++) {
1840 uint32_t tmp = i << (8 - s->ham);
1841 tmp |= tmp >> s->ham;
1842 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1843 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1844 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1845 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1846 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1847 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1849 if (s->masking == MASK_HAS_MASK) {
1850 for (i = 0; i < 8 * (1 << s->ham); i++)
1851 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1853 for (y = 0; y < avctx->height; y++) {
1854 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1855 memset(s->ham_buf, 0, s->planesize * 8);
1856 for (plane = 0; plane < s->bpp; plane++) {
1857 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1858 buf += s->planesize;
1860 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1863 return unsupported(avctx);
1867 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1871 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1872 frame->key_frame = 1;
1873 frame->pict_type = AV_PICTURE_TYPE_I;
1875 frame->key_frame = 0;
1876 frame->pict_type = AV_PICTURE_TYPE_P;
1884 #if CONFIG_IFF_ILBM_DECODER
1885 AVCodec ff_iff_ilbm_decoder = {
1887 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1888 .type = AVMEDIA_TYPE_VIDEO,
1889 .id = AV_CODEC_ID_IFF_ILBM,
1890 .priv_data_size = sizeof(IffContext),
1891 .init = decode_init,
1892 .close = decode_end,
1893 .decode = decode_frame,
1894 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1895 .capabilities = AV_CODEC_CAP_DR1,