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, 1 << plane, \
117 0, 0, 1 << plane, 0, \
118 0, 0, 1 << plane, 1 << plane, \
119 0, 1 << plane, 0, 0, \
120 0, 1 << plane, 0, 1 << plane, \
121 0, 1 << plane, 1 << plane, 0, \
122 0, 1 << plane, 1 << plane, 1 << plane, \
123 1 << plane, 0, 0, 0, \
124 1 << plane, 0, 0, 1 << plane, \
125 1 << plane, 0, 1 << plane, 0, \
126 1 << plane, 0, 1 << plane, 1 << plane, \
127 1 << plane, 1 << plane, 0, 0, \
128 1 << plane, 1 << plane, 0, 1 << plane, \
129 1 << plane, 1 << plane, 1 << plane, 0, \
130 1 << plane, 1 << plane, 1 << plane, 1 << 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 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
184 for (i = 0; i < count; i++)
186 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
187 s->transparency < 1 << avctx->bits_per_coded_sample)
188 pal[s->transparency] &= 0xFFFFFF;
193 * Extracts the IFF extra context and updates internal
194 * decoder structures.
196 * @param avctx the AVCodecContext where to extract extra context to
197 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
198 * @return >= 0 in case of success, a negative error code otherwise
200 static int extract_header(AVCodecContext *const avctx,
201 const AVPacket *const avpkt)
203 IffContext *s = avctx->priv_data;
205 unsigned buf_size = 0;
208 if (avctx->extradata_size < 2) {
209 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
210 return AVERROR_INVALIDDATA;
212 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
214 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
217 GetByteContext *gb = &s->gb;
219 bytestream2_skip(gb, 4);
220 while (bytestream2_get_bytes_left(gb) >= 1) {
221 chunk_id = bytestream2_get_le32(gb);
222 data_size = bytestream2_get_be32(gb);
224 if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
225 bytestream2_skip(gb, data_size + (data_size & 1));
226 } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
229 return AVERROR_INVALIDDATA;
231 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
232 bytestream2_skip(gb, 19);
233 extra = bytestream2_get_be32(gb);
234 s->is_short = !(extra & 1);
235 s->is_brush = extra == 2;
236 s->is_interlaced = !!(extra & 0x40);
238 bytestream2_skip(gb, data_size + (data_size & 1));
239 } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
240 chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
241 if (chunk_id == MKTAG('B','O','D','Y'))
242 s->compression &= 0xFF;
244 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
245 int count = data_size / 3;
246 uint32_t *pal = s->pal;
249 return AVERROR_INVALIDDATA;
251 for (i = 0; i < count; i++)
252 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
254 for (i = 0; i < count; i++)
255 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
257 bytestream2_skip(gb, data_size & 1);
259 bytestream2_skip(gb, data_size + (data_size&1));
263 buf = avctx->extradata;
264 buf_size = bytestream_get_be16(&buf);
265 if (buf_size <= 1 || palette_size < 0) {
266 av_log(avctx, AV_LOG_ERROR,
267 "Invalid palette size received: %u -> palette data offset: %d\n",
268 buf_size, palette_size);
269 return AVERROR_INVALIDDATA;
273 if (buf_size >= 41) {
274 s->compression = bytestream_get_byte(&buf);
275 s->bpp = bytestream_get_byte(&buf);
276 s->ham = bytestream_get_byte(&buf);
277 s->flags = bytestream_get_byte(&buf);
278 s->transparency = bytestream_get_be16(&buf);
279 s->masking = bytestream_get_byte(&buf);
280 for (i = 0; i < 16; i++)
281 s->tvdc[i] = bytestream_get_be16(&buf);
283 if (s->masking == MASK_HAS_MASK) {
284 if (s->bpp >= 8 && !s->ham) {
285 avctx->pix_fmt = AV_PIX_FMT_RGB32;
286 av_freep(&s->mask_buf);
287 av_freep(&s->mask_palbuf);
288 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
290 return AVERROR(ENOMEM);
292 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
293 av_freep(&s->mask_buf);
294 return AVERROR(ENOMEM);
296 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
297 if (!s->mask_palbuf) {
298 av_freep(&s->mask_buf);
299 return AVERROR(ENOMEM);
303 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
304 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
305 return AVERROR_PATCHWELCOME;
307 if (!s->bpp || s->bpp > 32) {
308 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
309 return AVERROR_INVALIDDATA;
310 } else if (s->ham >= 8) {
311 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
312 return AVERROR_INVALIDDATA;
315 av_freep(&s->ham_buf);
316 av_freep(&s->ham_palbuf);
319 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
321 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
323 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
325 return AVERROR(ENOMEM);
327 ham_count = 8 * (1 << s->ham);
328 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
329 if (!s->ham_palbuf) {
330 av_freep(&s->ham_buf);
331 return AVERROR(ENOMEM);
334 if (count) { // HAM with color palette attached
335 // prefill with black and palette and set HAM take direct value mask to zero
336 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
337 for (i=0; i < count; i++) {
338 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
341 } else { // HAM with grayscale color palette
343 for (i=0; i < count; i++) {
344 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
345 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
348 for (i=0; i < count; i++) {
349 uint32_t tmp = i << (8 - s->ham);
350 tmp |= tmp >> s->ham;
351 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
352 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
353 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
354 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
355 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
356 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
358 if (s->masking == MASK_HAS_MASK) {
359 for (i = 0; i < ham_count; i++)
360 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
368 static av_cold int decode_end(AVCodecContext *avctx)
370 IffContext *s = avctx->priv_data;
371 av_freep(&s->planebuf);
372 av_freep(&s->ham_buf);
373 av_freep(&s->ham_palbuf);
374 av_freep(&s->video[0]);
375 av_freep(&s->video[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 * avctx->height + 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 = av_calloc(256, sizeof(*s->pal));
427 if (!s->video[0] || !s->video[1] || !s->pal)
428 return AVERROR(ENOMEM);
431 if ((err = extract_header(avctx, NULL)) < 0)
438 * Decode interleaved plane buffer up to 8bpp
439 * @param dst Destination buffer
440 * @param buf Source buffer
442 * @param plane plane number to decode as
444 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
446 const uint64_t *lut = plane8_lut[plane];
448 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
452 uint64_t v = AV_RN64A(dst) | lut[*buf++];
455 } while (--buf_size);
459 * Decode interleaved plane buffer up to 24bpp
460 * @param dst Destination buffer
461 * @param buf Source buffer
463 * @param plane plane number to decode as
465 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
467 const uint32_t *lut = plane32_lut[plane];
469 unsigned mask = (*buf >> 2) & ~3;
470 dst[0] |= lut[mask++];
471 dst[1] |= lut[mask++];
472 dst[2] |= lut[mask++];
474 mask = (*buf++ << 2) & 0x3F;
475 dst[4] |= lut[mask++];
476 dst[5] |= lut[mask++];
477 dst[6] |= lut[mask++];
480 } while (--buf_size);
483 #define DECODE_HAM_PLANE32(x) \
484 first = buf[x] << 1; \
485 second = buf[(x)+1] << 1; \
486 delta &= pal[first++]; \
487 delta |= pal[first]; \
489 delta &= pal[second++]; \
490 delta |= pal[second]; \
494 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
496 * @param dst the destination 24bpp buffer
497 * @param buf the source 8bpp chunky buffer
498 * @param pal the HAM decode table
499 * @param buf_size the plane size in bytes
501 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
502 const uint32_t *const pal, unsigned buf_size)
504 uint32_t delta = pal[1]; /* first palette entry */
506 uint32_t first, second;
507 DECODE_HAM_PLANE32(0);
508 DECODE_HAM_PLANE32(2);
509 DECODE_HAM_PLANE32(4);
510 DECODE_HAM_PLANE32(6);
513 } while (--buf_size);
516 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
517 const uint32_t *const pal, unsigned width)
520 *dst++ = pal[*buf++];
525 * Decode one complete byterun1 encoded line.
527 * @param dst the destination buffer where to store decompressed bitstream
528 * @param dst_size the destination plane size in bytes
529 * @param buf the source byterun1 compressed bitstream
530 * @param buf_end the EOF of source byterun1 compressed bitstream
531 * @return number of consumed bytes in byterun1 compressed bitstream
533 static int decode_byterun(uint8_t *dst, int dst_size,
537 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
539 const int8_t value = bytestream2_get_byte(gb);
541 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
542 bytestream2_get_buffer(gb, dst + x, length);
543 if (length < value + 1)
544 bytestream2_skip(gb, value + 1 - length);
545 } else if (value > -128) {
546 length = FFMIN(-value + 1, dst_size - x);
547 memset(dst + x, bytestream2_get_byte(gb), length);
554 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
555 memset(dst+x, 0, dst_size - x);
557 return bytestream2_tell(gb);
560 static int decode_byterun2(uint8_t *dst, int height, int line_size,
565 int i, y_pos = 0, x_pos = 0;
567 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
570 bytestream2_skip(gb, 4);
571 count = bytestream2_get_be16(gb) - 2;
572 if (bytestream2_get_bytes_left(gb) < count)
575 bytestream2_init(&cmds, gb->buffer, count);
576 bytestream2_skip(gb, count);
578 for (i = 0; i < count && x_pos < line_size; i++) {
579 int8_t cmd = bytestream2_get_byte(&cmds);
583 l = bytestream2_get_be16(gb);
584 while (l-- > 0 && x_pos < line_size) {
585 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
586 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
587 if (y_pos >= height) {
592 } else if (cmd < 0) {
594 while (l-- > 0 && x_pos < line_size) {
595 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
596 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
597 if (y_pos >= height) {
602 } else if (cmd == 1) {
603 l = bytestream2_get_be16(gb);
604 r = bytestream2_get_be16(gb);
605 while (l-- > 0 && x_pos < line_size) {
606 dst[x_pos + y_pos * line_size ] = r >> 8;
607 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
608 if (y_pos >= height) {
615 r = bytestream2_get_be16(gb);
616 while (l-- > 0 && x_pos < line_size) {
617 dst[x_pos + y_pos * line_size ] = r >> 8;
618 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
619 if (y_pos >= height) {
627 return bytestream2_tell(gb);
630 #define DECODE_RGBX_COMMON(type) \
632 length = bytestream2_get_byte(gb); \
634 length = bytestream2_get_be16(gb); \
639 for (i = 0; i < length; i++) { \
640 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
652 * @param[out] dst Destination buffer
653 * @param width Width of destination buffer (pixels)
654 * @param height Height of destination buffer (pixels)
655 * @param linesize Line size of destination buffer (bytes)
657 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
659 int x = 0, y = 0, i, length;
660 while (bytestream2_get_bytes_left(gb) >= 4) {
661 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
662 length = bytestream2_get_byte(gb) & 0x7F;
663 DECODE_RGBX_COMMON(uint32_t)
669 * @param[out] dst Destination buffer
670 * @param width Width of destination buffer (pixels)
671 * @param height Height of destination buffer (pixels)
672 * @param linesize Line size of destination buffer (bytes)
674 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
676 int x = 0, y = 0, i, length;
677 while (bytestream2_get_bytes_left(gb) >= 2) {
678 uint32_t pixel = bytestream2_get_be16u(gb);
679 length = pixel & 0x7;
681 DECODE_RGBX_COMMON(uint16_t)
686 * Decode DEEP RLE 32-bit buffer
687 * @param[out] dst Destination buffer
688 * @param[in] src Source buffer
689 * @param src_size Source buffer size (bytes)
690 * @param width Width of destination buffer (pixels)
691 * @param height Height of destination buffer (pixels)
692 * @param linesize Line size of destination buffer (bytes)
694 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
696 const uint8_t *src_end = src + src_size;
698 while (src + 5 <= src_end) {
700 opcode = *(int8_t *)src++;
702 int size = opcode + 1;
703 for (i = 0; i < size; i++) {
704 int length = FFMIN(size - i, width);
705 memcpy(dst + y*linesize + x * 4, src, length * 4);
717 int size = -opcode + 1;
718 uint32_t pixel = AV_RN32(src);
719 for (i = 0; i < size; i++) {
720 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
735 * Decode DEEP TVDC 32-bit buffer
736 * @param[out] dst Destination buffer
737 * @param[in] src Source buffer
738 * @param src_size Source buffer size (bytes)
739 * @param width Width of destination buffer (pixels)
740 * @param height Height of destination buffer (pixels)
741 * @param linesize Line size of destination buffer (bytes)
742 * @param[int] tvdc TVDC lookup table
744 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)
746 int x = 0, y = 0, plane = 0;
750 for (i = 0; i < src_size * 2;) {
751 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
752 int d = tvdc[GETNIBBLE];
756 dst[y * linesize + x*4 + plane] = pixel;
759 if (i >= src_size * 2)
763 d = FFMIN(d, width - x);
764 for (j = 0; j < d; j++) {
765 dst[y * linesize + x*4 + plane] = pixel;
784 static void decode_short_horizontal_delta(uint8_t *dst,
785 const uint8_t *buf, const uint8_t *buf_end,
786 int w, int bpp, int dst_size)
788 int planepitch = FFALIGN(w, 16) >> 3;
789 int pitch = planepitch * bpp;
790 GetByteContext ptrs, gb;
792 unsigned ofssrc, pos;
795 bytestream2_init(&ptrs, buf, buf_end - buf);
796 bytestream2_init_writer(&pb, dst, dst_size);
798 for (k = 0; k < bpp; k++) {
799 ofssrc = bytestream2_get_be32(&ptrs);
805 if (ofssrc >= buf_end - buf)
808 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
809 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
810 int16_t offset = bytestream2_get_be16(&gb);
814 unsigned data = bytestream2_get_be16(&gb);
817 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
818 bytestream2_seek_p(&pb, noffset, SEEK_SET);
819 bytestream2_put_be16(&pb, data);
821 uint16_t count = bytestream2_get_be16(&gb);
823 pos += 2 * -(offset + 2);
824 for (i = 0; i < count; i++) {
825 uint16_t data = bytestream2_get_be16(&gb);
828 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
829 bytestream2_seek_p(&pb, noffset, SEEK_SET);
830 bytestream2_put_be16(&pb, data);
837 static void decode_byte_vertical_delta(uint8_t *dst,
838 const uint8_t *buf, const uint8_t *buf_end,
839 int w, int xor, int bpp, int dst_size)
841 int ncolumns = ((w + 15) / 16) * 2;
842 int dstpitch = ncolumns * bpp;
843 unsigned ofsdst, ofssrc, opcode, x;
844 GetByteContext ptrs, gb;
848 bytestream2_init(&ptrs, buf, buf_end - buf);
849 bytestream2_init_writer(&pb, dst, dst_size);
851 for (k = 0; k < bpp; k++) {
852 ofssrc = bytestream2_get_be32(&ptrs);
857 if (ofssrc >= buf_end - buf)
860 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
861 for (j = 0; j < ncolumns; j++) {
862 ofsdst = j + k * ncolumns;
864 i = bytestream2_get_byte(&gb);
866 opcode = bytestream2_get_byte(&gb);
869 opcode = bytestream2_get_byte(&gb);
870 x = bytestream2_get_byte(&gb);
873 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
874 if (xor && ofsdst < dst_size) {
875 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
877 bytestream2_put_byte(&pb, x);
882 } else if (opcode < 0x80) {
883 ofsdst += opcode * dstpitch;
888 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
889 if (xor && ofsdst < dst_size) {
890 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
892 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
904 static void decode_delta_j(uint8_t *dst,
905 const uint8_t *buf, const uint8_t *buf_end,
906 int w, int h, int bpp, int dst_size)
910 uint32_t type, flag, cols, groups, rows, bytes;
912 int planepitch_byte = (w + 7) / 8;
913 int planepitch = ((w + 15) / 16) * 2;
914 int kludge_j, b, g, r, d;
917 pitch = planepitch * bpp;
918 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
920 bytestream2_init(&gb, buf, buf_end - buf);
922 while (bytestream2_get_bytes_left(&gb) >= 2) {
923 type = bytestream2_get_be16(&gb);
929 flag = bytestream2_get_be16(&gb);
930 cols = bytestream2_get_be16(&gb);
931 groups = bytestream2_get_be16(&gb);
933 for (g = 0; g < groups; g++) {
934 offset = bytestream2_get_be16(&gb);
936 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
937 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
942 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
944 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
946 for (b = 0; b < cols; b++) {
947 for (d = 0; d < bpp; d++) {
948 uint8_t value = bytestream2_get_byte(&gb);
950 if (offset >= dst_size)
959 offset += planepitch;
962 if ((cols * bpp) & 1)
963 bytestream2_skip(&gb, 1);
967 flag = bytestream2_get_be16(&gb);
968 rows = bytestream2_get_be16(&gb);
969 bytes = bytestream2_get_be16(&gb);
970 groups = bytestream2_get_be16(&gb);
972 for (g = 0; g < groups; g++) {
973 offset = bytestream2_get_be16(&gb);
976 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
978 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
980 for (r = 0; r < rows; r++) {
981 for (d = 0; d < bpp; d++) {
982 unsigned noffset = offset + (r * pitch) + d * planepitch;
984 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
985 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
989 for (b = 0; b < bytes; b++) {
990 uint8_t value = bytestream2_get_byte(&gb);
992 if (noffset >= dst_size)
1005 if ((rows * bytes * bpp) & 1)
1006 bytestream2_skip(&gb, 1);
1015 static void decode_short_vertical_delta(uint8_t *dst,
1016 const uint8_t *buf, const uint8_t *buf_end,
1017 int w, int bpp, int dst_size)
1019 int ncolumns = (w + 15) >> 4;
1020 int dstpitch = ncolumns * bpp * 2;
1021 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1022 GetByteContext ptrs, gb, dptrs, dgb;
1026 if (buf_end - buf <= 64)
1029 bytestream2_init(&ptrs, buf, buf_end - buf);
1030 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1031 bytestream2_init_writer(&pb, dst, dst_size);
1033 for (k = 0; k < bpp; k++) {
1034 ofssrc = bytestream2_get_be32(&ptrs);
1035 ofsdata = bytestream2_get_be32(&dptrs);
1040 if (ofssrc >= buf_end - buf)
1043 if (ofsdata >= buf_end - buf)
1046 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1047 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1048 for (j = 0; j < ncolumns; j++) {
1049 ofsdst = (j + k * ncolumns) * 2;
1051 i = bytestream2_get_byte(&gb);
1053 opcode = bytestream2_get_byte(&gb);
1056 opcode = bytestream2_get_byte(&gb);
1057 x = bytestream2_get_be16(&dgb);
1060 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1061 bytestream2_put_be16(&pb, x);
1065 } else if (opcode < 0x80) {
1066 ofsdst += opcode * dstpitch;
1071 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1072 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1083 static void decode_long_vertical_delta(uint8_t *dst,
1084 const uint8_t *buf, const uint8_t *buf_end,
1085 int w, int bpp, int dst_size)
1087 int ncolumns = (w + 31) >> 5;
1088 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1089 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1090 GetByteContext ptrs, gb, dptrs, dgb;
1094 if (buf_end - buf <= 64)
1097 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1098 bytestream2_init(&ptrs, buf, buf_end - buf);
1099 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1100 bytestream2_init_writer(&pb, dst, dst_size);
1102 for (k = 0; k < bpp; k++) {
1103 ofssrc = bytestream2_get_be32(&ptrs);
1104 ofsdata = bytestream2_get_be32(&dptrs);
1109 if (ofssrc >= buf_end - buf)
1112 if (ofsdata >= buf_end - buf)
1115 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1116 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1117 for (j = 0; j < ncolumns; j++) {
1118 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1120 i = bytestream2_get_byte(&gb);
1122 opcode = bytestream2_get_byte(&gb);
1125 opcode = bytestream2_get_byte(&gb);
1126 if (h && (j == (ncolumns - 1))) {
1127 x = bytestream2_get_be16(&dgb);
1128 bytestream2_skip(&dgb, 2);
1130 x = bytestream2_get_be32(&dgb);
1134 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1135 if (h && (j == (ncolumns - 1))) {
1136 bytestream2_put_be16(&pb, x);
1138 bytestream2_put_be32(&pb, x);
1143 } else if (opcode < 0x80) {
1144 ofsdst += opcode * dstpitch;
1149 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1150 if (h && (j == (ncolumns - 1))) {
1151 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1152 bytestream2_skip(&dgb, 2);
1154 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1166 static void decode_short_vertical_delta2(uint8_t *dst,
1167 const uint8_t *buf, const uint8_t *buf_end,
1168 int w, int bpp, int dst_size)
1170 int ncolumns = (w + 15) >> 4;
1171 int dstpitch = ncolumns * bpp * 2;
1172 unsigned ofsdst, ofssrc, opcode, x;
1173 GetByteContext ptrs, gb;
1177 bytestream2_init(&ptrs, buf, buf_end - buf);
1178 bytestream2_init_writer(&pb, dst, dst_size);
1180 for (k = 0; k < bpp; k++) {
1181 ofssrc = bytestream2_get_be32(&ptrs);
1186 if (ofssrc >= buf_end - buf)
1189 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1190 for (j = 0; j < ncolumns; j++) {
1191 ofsdst = (j + k * ncolumns) * 2;
1193 i = bytestream2_get_be16(&gb);
1194 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1195 opcode = bytestream2_get_be16(&gb);
1198 opcode = bytestream2_get_be16(&gb);
1199 x = bytestream2_get_be16(&gb);
1201 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1202 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1203 bytestream2_put_be16(&pb, x);
1207 } else if (opcode < 0x8000) {
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 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1226 static void decode_long_vertical_delta2(uint8_t *dst,
1227 const uint8_t *buf, const uint8_t *buf_end,
1228 int w, int bpp, int dst_size)
1230 int ncolumns = (w + 31) >> 5;
1231 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1232 unsigned ofsdst, ofssrc, opcode, x;
1233 unsigned skip = 0x80000000, mask = skip - 1;
1234 GetByteContext ptrs, gb;
1238 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1239 bytestream2_init(&ptrs, buf, buf_end - buf);
1240 bytestream2_init_writer(&pb, dst, dst_size);
1242 for (k = 0; k < bpp; k++) {
1243 ofssrc = bytestream2_get_be32(&ptrs);
1248 if (ofssrc >= buf_end - buf)
1251 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1252 for (j = 0; j < ncolumns; j++) {
1253 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1255 if (h && (j == (ncolumns - 1))) {
1260 i = bytestream2_get_be32(&gb);
1261 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1262 opcode = bytestream2_get_be32(&gb);
1265 if (h && (j == ncolumns - 1)) {
1266 opcode = bytestream2_get_be16(&gb);
1267 x = bytestream2_get_be16(&gb);
1269 opcode = bytestream2_get_be32(&gb);
1270 x = bytestream2_get_be32(&gb);
1273 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1274 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1275 if (h && (j == ncolumns - 1))
1276 bytestream2_put_be16(&pb, x);
1278 bytestream2_put_be32(&pb, x);
1282 } else if (opcode < skip) {
1283 ofsdst += opcode * dstpitch;
1287 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1288 bytestream2_get_bytes_left_p(&pb) > 1) {
1289 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1290 if (h && (j == ncolumns - 1)) {
1291 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1293 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1305 static void decode_delta_d(uint8_t *dst,
1306 const uint8_t *buf, const uint8_t *buf_end,
1307 int w, int flag, int bpp, int dst_size)
1309 int planepitch = FFALIGN(w, 16) >> 3;
1310 int pitch = planepitch * bpp;
1311 int planepitch_byte = (w + 7) / 8;
1312 unsigned entries, ofssrc;
1313 GetByteContext gb, ptrs;
1317 if (buf_end - buf <= 4 * bpp)
1320 bytestream2_init_writer(&pb, dst, dst_size);
1321 bytestream2_init(&ptrs, buf, bpp * 4);
1323 for (k = 0; k < bpp; k++) {
1324 ofssrc = bytestream2_get_be32(&ptrs);
1329 if (ofssrc >= buf_end - buf)
1332 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1334 entries = bytestream2_get_be32(&gb);
1335 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1336 int32_t opcode = bytestream2_get_be32(&gb);
1337 unsigned offset = bytestream2_get_be32(&gb);
1339 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1341 uint32_t x = bytestream2_get_be32(&gb);
1342 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1343 bytestream2_put_be32(&pb, x);
1344 bytestream2_skip_p(&pb, pitch - 4);
1349 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1350 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1351 bytestream2_skip_p(&pb, pitch - 4);
1360 static void decode_delta_e(uint8_t *dst,
1361 const uint8_t *buf, const uint8_t *buf_end,
1362 int w, int flag, int bpp, int dst_size)
1364 int planepitch = FFALIGN(w, 16) >> 3;
1365 int pitch = planepitch * bpp;
1366 int planepitch_byte = (w + 7) / 8;
1367 unsigned entries, ofssrc;
1368 GetByteContext gb, ptrs;
1372 if (buf_end - buf <= 4 * bpp)
1375 bytestream2_init_writer(&pb, dst, dst_size);
1376 bytestream2_init(&ptrs, buf, bpp * 4);
1378 for (k = 0; k < bpp; k++) {
1379 ofssrc = bytestream2_get_be32(&ptrs);
1384 if (ofssrc >= buf_end - buf)
1387 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1389 entries = bytestream2_get_be16(&gb);
1390 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1391 int16_t opcode = bytestream2_get_be16(&gb);
1392 unsigned offset = bytestream2_get_be32(&gb);
1394 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1396 uint16_t x = bytestream2_get_be16(&gb);
1397 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1398 bytestream2_put_be16(&pb, x);
1399 bytestream2_skip_p(&pb, pitch - 2);
1404 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1405 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1406 bytestream2_skip_p(&pb, pitch - 2);
1415 static void decode_delta_l(uint8_t *dst,
1416 const uint8_t *buf, const uint8_t *buf_end,
1417 int w, int flag, int bpp, int dst_size)
1419 GetByteContext off0, off1, dgb, ogb;
1421 unsigned poff0, poff1;
1423 int planepitch_byte = (w + 7) / 8;
1424 int planepitch = ((w + 15) / 16) * 2;
1425 int pitch = planepitch * bpp;
1427 if (buf_end - buf <= 64)
1430 bytestream2_init(&off0, buf, buf_end - buf);
1431 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1432 bytestream2_init_writer(&pb, dst, dst_size);
1434 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1436 for (k = 0; k < bpp; k++) {
1437 poff0 = bytestream2_get_be32(&off0);
1438 poff1 = bytestream2_get_be32(&off1);
1443 if (2LL * poff0 >= buf_end - buf)
1446 if (2LL * poff1 >= buf_end - buf)
1449 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1450 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1452 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1453 uint32_t offset = bytestream2_get_be16(&ogb);
1454 int16_t cnt = bytestream2_get_be16(&ogb);
1457 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1459 if (bytestream2_get_bytes_left(&dgb) < 2)
1461 bytestream2_seek_p(&pb, offset, SEEK_SET);
1463 data = bytestream2_get_be16(&dgb);
1464 for (i = 0; i < cnt; i++) {
1465 bytestream2_put_be16(&pb, data);
1466 bytestream2_skip_p(&pb, dstpitch - 2);
1469 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1471 bytestream2_seek_p(&pb, offset, SEEK_SET);
1472 for (i = 0; i < cnt; i++) {
1473 data = bytestream2_get_be16(&dgb);
1474 bytestream2_put_be16(&pb, data);
1475 bytestream2_skip_p(&pb, dstpitch - 2);
1482 static int unsupported(AVCodecContext *avctx)
1484 IffContext *s = avctx->priv_data;
1485 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1486 return AVERROR_INVALIDDATA;
1489 static int decode_frame(AVCodecContext *avctx,
1490 void *data, int *got_frame,
1493 IffContext *s = avctx->priv_data;
1494 AVFrame *frame = data;
1495 const uint8_t *buf = avpkt->data;
1496 int buf_size = avpkt->size;
1497 const uint8_t *buf_end = buf + buf_size;
1499 GetByteContext *gb = &s->gb;
1500 const AVPixFmtDescriptor *desc;
1502 bytestream2_init(gb, avpkt->data, avpkt->size);
1504 if ((res = extract_header(avctx, avpkt)) < 0)
1507 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1511 buf += bytestream2_tell(gb);
1512 buf_size -= bytestream2_tell(gb);
1513 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1515 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1516 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1517 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1519 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1520 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1521 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1526 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1527 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1528 memcpy(s->pal, s->frame->data[1], 256 * 4);
1531 switch (s->compression) {
1533 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1534 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1535 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1536 for (plane = 0; plane < s->bpp; plane++) {
1537 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1538 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1539 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1540 buf += s->planesize;
1543 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1544 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1545 for (y = 0; y < avctx->height; y++) {
1546 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1547 memset(s->ham_buf, 0, s->planesize * 8);
1548 for (plane = 0; plane < s->bpp; plane++) {
1549 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1550 if (start >= buf_end)
1552 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1554 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1557 return unsupported(avctx);
1558 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1559 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1561 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1562 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1563 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1565 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1566 for (x = 0; x < avctx->width; x++)
1567 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1570 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1571 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1572 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1573 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1574 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1575 for (y = 0; y < avctx->height; y++) {
1576 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1577 memset(row, 0, avctx->width);
1578 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1579 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1580 buf += s->planesize;
1583 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1584 for (y = 0; y < avctx->height; y++) {
1585 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1586 memset(s->ham_buf, 0, s->planesize * 8);
1587 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1588 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1589 buf += s->planesize;
1591 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1593 } else { // AV_PIX_FMT_BGR32
1594 for (y = 0; y < avctx->height; y++) {
1595 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1596 memset(row, 0, avctx->width << 2);
1597 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1598 decodeplane32((uint32_t *)row, buf,
1599 FFMIN(s->planesize, buf_end - buf), plane);
1600 buf += s->planesize;
1604 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1605 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1606 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1607 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1608 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1609 buf += avctx->width + (avctx->width % 2); // padding if odd
1611 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1612 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1613 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1614 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1615 buf += avctx->width + (avctx->width & 1); // padding if odd
1616 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1619 return unsupported(avctx);
1621 return unsupported(avctx);
1625 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1626 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1627 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1628 uint8_t *video = s->video[0];
1630 for (y = 0; y < avctx->height; y++) {
1631 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1632 memset(row, 0, avctx->width);
1633 for (plane = 0; plane < s->bpp; plane++) {
1634 buf += decode_byterun(s->planebuf, s->planesize, gb);
1635 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1636 memcpy(video, s->planebuf, s->planesize);
1637 video += s->planesize;
1639 decodeplane8(row, s->planebuf, s->planesize, plane);
1642 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1643 for (y = 0; y < avctx->height; y++) {
1644 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1645 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1646 for (plane = 0; plane < s->bpp; plane++) {
1647 buf += decode_byterun(s->planebuf, s->planesize, gb);
1648 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1650 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1652 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1653 uint8_t *video = s->video[0];
1654 for (y = 0; y < avctx->height; y++) {
1655 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1656 memset(s->ham_buf, 0, s->planesize * 8);
1657 for (plane = 0; plane < s->bpp; plane++) {
1658 buf += decode_byterun(s->planebuf, s->planesize, gb);
1659 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1660 memcpy(video, s->planebuf, s->planesize);
1661 video += s->planesize;
1663 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1665 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1667 } else { // AV_PIX_FMT_BGR32
1668 for (y = 0; y < avctx->height; y++) {
1669 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1670 memset(row, 0, avctx->width << 2);
1671 for (plane = 0; plane < s->bpp; plane++) {
1672 buf += decode_byterun(s->planebuf, s->planesize, gb);
1673 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1677 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1678 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1679 for (y = 0; y < avctx->height; y++) {
1680 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1681 buf += decode_byterun(row, avctx->width, gb);
1683 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1684 for (y = 0; y < avctx->height; y++) {
1685 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1686 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1687 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1690 return unsupported(avctx);
1691 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1692 if (av_get_bits_per_pixel(desc) == 32)
1693 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1695 return unsupported(avctx);
1696 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1697 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1698 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1699 for (plane = 0; plane < s->bpp; plane++) {
1700 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1701 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1702 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1703 buf += s->planesize;
1706 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1707 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1708 for (y = 0; y < avctx->height; y++) {
1709 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1710 memset(s->ham_buf, 0, s->planesize * 8);
1711 for (plane = 0; plane < s->bpp; plane++) {
1712 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1713 if (start >= buf_end)
1715 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1717 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1720 return unsupported(avctx);
1723 return unsupported(avctx);
1727 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1728 for (plane = 0; plane < s->bpp; plane++) {
1729 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1730 for (y = 0; y < avctx->height; y++) {
1731 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1732 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1736 return unsupported(avctx);
1740 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1741 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1742 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1743 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1745 return unsupported(avctx);
1748 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1749 if (av_get_bits_per_pixel(desc) == 32)
1750 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1752 return unsupported(avctx);
1754 return unsupported(avctx);
1758 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1762 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1767 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1769 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1774 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1776 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1780 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1784 if (s->is_interlaced)
1785 return unsupported(avctx);
1786 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1790 if (s->is_interlaced)
1791 return unsupported(avctx);
1792 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1796 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1799 return unsupported(avctx);
1802 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1803 memcpy(s->video[1], s->video[0], s->video_size);
1806 if (s->compression > 0xff) {
1807 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1809 for (y = 0; y < avctx->height; y++) {
1810 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1811 memset(row, 0, avctx->width);
1812 for (plane = 0; plane < s->bpp; plane++) {
1813 decodeplane8(row, buf, s->planesize, plane);
1814 buf += s->planesize;
1817 memcpy(frame->data[1], s->pal, 256 * 4);
1818 } else if (s->ham) {
1819 int i, count = 1 << s->ham;
1822 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1823 for (i = 0; i < count; i++) {
1824 s->ham_palbuf[i*2+1] = s->pal[i];
1826 for (i = 0; i < count; i++) {
1827 uint32_t tmp = i << (8 - s->ham);
1828 tmp |= tmp >> s->ham;
1829 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1830 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1831 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1832 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1833 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1834 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1836 if (s->masking == MASK_HAS_MASK) {
1837 for (i = 0; i < 8 * (1 << s->ham); i++)
1838 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1840 for (y = 0; y < avctx->height; y++) {
1841 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1842 memset(s->ham_buf, 0, s->planesize * 8);
1843 for (plane = 0; plane < s->bpp; plane++) {
1844 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1845 buf += s->planesize;
1847 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1850 return unsupported(avctx);
1854 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1858 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1859 frame->key_frame = 1;
1860 frame->pict_type = AV_PICTURE_TYPE_I;
1862 frame->key_frame = 0;
1863 frame->pict_type = AV_PICTURE_TYPE_P;
1871 #if CONFIG_IFF_ILBM_DECODER
1872 AVCodec ff_iff_ilbm_decoder = {
1874 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1875 .type = AVMEDIA_TYPE_VIDEO,
1876 .id = AV_CODEC_ID_IFF_ILBM,
1877 .priv_data_size = sizeof(IffContext),
1878 .init = decode_init,
1879 .close = decode_end,
1880 .decode = decode_frame,
1881 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1882 .capabilities = AV_CODEC_CAP_DR1,