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);
285 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
286 return AVERROR_INVALIDDATA;
287 } if (s->ham != (s->bpp > 6 ? 6 : 4)) {
288 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
289 return AVERROR_INVALIDDATA;
293 if (s->masking == MASK_HAS_MASK) {
294 if (s->bpp >= 8 && !s->ham) {
295 avctx->pix_fmt = AV_PIX_FMT_RGB32;
296 av_freep(&s->mask_buf);
297 av_freep(&s->mask_palbuf);
298 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
300 return AVERROR(ENOMEM);
302 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
303 av_freep(&s->mask_buf);
304 return AVERROR(ENOMEM);
306 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
307 if (!s->mask_palbuf) {
308 av_freep(&s->mask_buf);
309 return AVERROR(ENOMEM);
313 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
314 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
315 return AVERROR_PATCHWELCOME;
317 if (!s->bpp || s->bpp > 32) {
318 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
319 return AVERROR_INVALIDDATA;
322 av_freep(&s->ham_buf);
323 av_freep(&s->ham_palbuf);
326 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
328 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
330 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
332 return AVERROR(ENOMEM);
334 ham_count = 8 * (1 << s->ham);
335 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
336 if (!s->ham_palbuf) {
337 av_freep(&s->ham_buf);
338 return AVERROR(ENOMEM);
341 if (count) { // HAM with color palette attached
342 // prefill with black and palette and set HAM take direct value mask to zero
343 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
344 for (i=0; i < count; i++) {
345 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
348 } else { // HAM with grayscale color palette
350 for (i=0; i < count; i++) {
351 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
352 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
355 for (i=0; i < count; i++) {
356 uint32_t tmp = i << (8 - s->ham);
357 tmp |= tmp >> s->ham;
358 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
359 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
360 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
361 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
362 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
363 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
365 if (s->masking == MASK_HAS_MASK) {
366 for (i = 0; i < ham_count; i++)
367 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
375 static av_cold int decode_end(AVCodecContext *avctx)
377 IffContext *s = avctx->priv_data;
378 av_freep(&s->planebuf);
379 av_freep(&s->ham_buf);
380 av_freep(&s->ham_palbuf);
381 av_freep(&s->mask_buf);
382 av_freep(&s->mask_palbuf);
383 av_freep(&s->video[0]);
384 av_freep(&s->video[1]);
389 static av_cold int decode_init(AVCodecContext *avctx)
391 IffContext *s = avctx->priv_data;
394 if (avctx->bits_per_coded_sample <= 8) {
397 if (avctx->extradata_size >= 2)
398 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
401 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
402 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
403 } else if (avctx->bits_per_coded_sample <= 32) {
404 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
405 avctx->pix_fmt = AV_PIX_FMT_RGB32;
406 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
407 avctx->pix_fmt = AV_PIX_FMT_RGB444;
408 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
409 if (avctx->bits_per_coded_sample == 24) {
410 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
411 } else if (avctx->bits_per_coded_sample == 32) {
412 avctx->pix_fmt = AV_PIX_FMT_BGR32;
414 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
415 return AVERROR_PATCHWELCOME;
419 return AVERROR_INVALIDDATA;
422 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
424 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
425 s->planebuf = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
427 return AVERROR(ENOMEM);
429 s->bpp = avctx->bits_per_coded_sample;
431 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
432 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
433 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
434 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
435 s->pal = av_calloc(256, sizeof(*s->pal));
436 if (!s->video[0] || !s->video[1] || !s->pal)
437 return AVERROR(ENOMEM);
440 if ((err = extract_header(avctx, NULL)) < 0)
447 * Decode interleaved plane buffer up to 8bpp
448 * @param dst Destination buffer
449 * @param buf Source buffer
451 * @param plane plane number to decode as
453 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
455 const uint64_t *lut = plane8_lut[plane];
457 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
461 uint64_t v = AV_RN64A(dst) | lut[*buf++];
464 } while (--buf_size);
468 * Decode interleaved plane buffer up to 24bpp
469 * @param dst Destination buffer
470 * @param buf Source buffer
472 * @param plane plane number to decode as
474 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
476 const uint32_t *lut = plane32_lut[plane];
478 unsigned mask = (*buf >> 2) & ~3;
479 dst[0] |= lut[mask++];
480 dst[1] |= lut[mask++];
481 dst[2] |= lut[mask++];
483 mask = (*buf++ << 2) & 0x3F;
484 dst[4] |= lut[mask++];
485 dst[5] |= lut[mask++];
486 dst[6] |= lut[mask++];
489 } while (--buf_size);
492 #define DECODE_HAM_PLANE32(x) \
493 first = buf[x] << 1; \
494 second = buf[(x)+1] << 1; \
495 delta &= pal[first++]; \
496 delta |= pal[first]; \
498 delta &= pal[second++]; \
499 delta |= pal[second]; \
503 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
505 * @param dst the destination 24bpp buffer
506 * @param buf the source 8bpp chunky buffer
507 * @param pal the HAM decode table
508 * @param buf_size the plane size in bytes
510 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
511 const uint32_t *const pal, unsigned buf_size)
513 uint32_t delta = pal[1]; /* first palette entry */
515 uint32_t first, second;
516 DECODE_HAM_PLANE32(0);
517 DECODE_HAM_PLANE32(2);
518 DECODE_HAM_PLANE32(4);
519 DECODE_HAM_PLANE32(6);
522 } while (--buf_size);
525 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
526 const uint32_t *const pal, unsigned width)
529 *dst++ = pal[*buf++];
534 * Decode one complete byterun1 encoded line.
536 * @param dst the destination buffer where to store decompressed bitstream
537 * @param dst_size the destination plane size in bytes
538 * @param buf the source byterun1 compressed bitstream
539 * @param buf_end the EOF of source byterun1 compressed bitstream
540 * @return number of consumed bytes in byterun1 compressed bitstream
542 static int decode_byterun(uint8_t *dst, int dst_size,
546 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
548 const int8_t value = bytestream2_get_byte(gb);
550 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
551 bytestream2_get_buffer(gb, dst + x, length);
552 if (length < value + 1)
553 bytestream2_skip(gb, value + 1 - length);
554 } else if (value > -128) {
555 length = FFMIN(-value + 1, dst_size - x);
556 memset(dst + x, bytestream2_get_byte(gb), length);
563 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
564 memset(dst+x, 0, dst_size - x);
566 return bytestream2_tell(gb);
569 static int decode_byterun2(uint8_t *dst, int height, int line_size,
574 int i, y_pos = 0, x_pos = 0;
576 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
579 bytestream2_skip(gb, 4);
580 count = bytestream2_get_be16(gb) - 2;
581 if (bytestream2_get_bytes_left(gb) < count)
584 bytestream2_init(&cmds, gb->buffer, count);
585 bytestream2_skip(gb, count);
587 for (i = 0; i < count && x_pos < line_size; i++) {
588 int8_t cmd = bytestream2_get_byte(&cmds);
592 l = bytestream2_get_be16(gb);
593 while (l-- > 0 && x_pos < line_size) {
594 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
595 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
596 if (y_pos >= height) {
601 } else if (cmd < 0) {
603 while (l-- > 0 && x_pos < line_size) {
604 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
605 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
606 if (y_pos >= height) {
611 } else if (cmd == 1) {
612 l = bytestream2_get_be16(gb);
613 r = bytestream2_get_be16(gb);
614 while (l-- > 0 && x_pos < line_size) {
615 dst[x_pos + y_pos * line_size ] = r >> 8;
616 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
617 if (y_pos >= height) {
624 r = bytestream2_get_be16(gb);
625 while (l-- > 0 && x_pos < line_size) {
626 dst[x_pos + y_pos * line_size ] = r >> 8;
627 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
628 if (y_pos >= height) {
636 return bytestream2_tell(gb);
639 #define DECODE_RGBX_COMMON(type) \
641 length = bytestream2_get_byte(gb); \
643 length = bytestream2_get_be16(gb); \
648 for (i = 0; i < length; i++) { \
649 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
661 * @param[out] dst Destination buffer
662 * @param width Width of destination buffer (pixels)
663 * @param height Height of destination buffer (pixels)
664 * @param linesize Line size of destination buffer (bytes)
666 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
668 int x = 0, y = 0, i, length;
669 while (bytestream2_get_bytes_left(gb) >= 4) {
670 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
671 length = bytestream2_get_byte(gb) & 0x7F;
672 DECODE_RGBX_COMMON(uint32_t)
678 * @param[out] dst Destination buffer
679 * @param width Width of destination buffer (pixels)
680 * @param height Height of destination buffer (pixels)
681 * @param linesize Line size of destination buffer (bytes)
683 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
685 int x = 0, y = 0, i, length;
686 while (bytestream2_get_bytes_left(gb) >= 2) {
687 uint32_t pixel = bytestream2_get_be16u(gb);
688 length = pixel & 0x7;
690 DECODE_RGBX_COMMON(uint16_t)
695 * Decode DEEP RLE 32-bit buffer
696 * @param[out] dst Destination buffer
697 * @param[in] src Source buffer
698 * @param src_size Source buffer size (bytes)
699 * @param width Width of destination buffer (pixels)
700 * @param height Height of destination buffer (pixels)
701 * @param linesize Line size of destination buffer (bytes)
703 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
705 const uint8_t *src_end = src + src_size;
707 while (src + 5 <= src_end) {
709 opcode = *(int8_t *)src++;
711 int size = opcode + 1;
712 for (i = 0; i < size; i++) {
713 int length = FFMIN(size - i, width);
714 memcpy(dst + y*linesize + x * 4, src, length * 4);
726 int size = -opcode + 1;
727 uint32_t pixel = AV_RN32(src);
728 for (i = 0; i < size; i++) {
729 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
744 * Decode DEEP TVDC 32-bit buffer
745 * @param[out] dst Destination buffer
746 * @param[in] src Source buffer
747 * @param src_size Source buffer size (bytes)
748 * @param width Width of destination buffer (pixels)
749 * @param height Height of destination buffer (pixels)
750 * @param linesize Line size of destination buffer (bytes)
751 * @param[int] tvdc TVDC lookup table
753 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)
755 int x = 0, y = 0, plane = 0;
759 for (i = 0; i < src_size * 2;) {
760 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
761 int d = tvdc[GETNIBBLE];
765 dst[y * linesize + x*4 + plane] = pixel;
768 if (i >= src_size * 2)
772 d = FFMIN(d, width - x);
773 for (j = 0; j < d; j++) {
774 dst[y * linesize + x*4 + plane] = pixel;
793 static void decode_short_horizontal_delta(uint8_t *dst,
794 const uint8_t *buf, const uint8_t *buf_end,
795 int w, int bpp, int dst_size)
797 int planepitch = FFALIGN(w, 16) >> 3;
798 int pitch = planepitch * bpp;
799 GetByteContext ptrs, gb;
801 unsigned ofssrc, pos;
804 bytestream2_init(&ptrs, buf, buf_end - buf);
805 bytestream2_init_writer(&pb, dst, dst_size);
807 for (k = 0; k < bpp; k++) {
808 ofssrc = bytestream2_get_be32(&ptrs);
814 if (ofssrc >= buf_end - buf)
817 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
818 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
819 int16_t offset = bytestream2_get_be16(&gb);
823 unsigned data = bytestream2_get_be16(&gb);
826 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
827 bytestream2_seek_p(&pb, noffset, SEEK_SET);
828 bytestream2_put_be16(&pb, data);
830 uint16_t count = bytestream2_get_be16(&gb);
832 pos += 2 * -(offset + 2);
833 for (i = 0; i < count; i++) {
834 uint16_t data = bytestream2_get_be16(&gb);
837 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
838 bytestream2_seek_p(&pb, noffset, SEEK_SET);
839 bytestream2_put_be16(&pb, data);
846 static void decode_byte_vertical_delta(uint8_t *dst,
847 const uint8_t *buf, const uint8_t *buf_end,
848 int w, int xor, int bpp, int dst_size)
850 int ncolumns = ((w + 15) / 16) * 2;
851 int dstpitch = ncolumns * bpp;
852 unsigned ofsdst, ofssrc, opcode, x;
853 GetByteContext ptrs, gb;
857 bytestream2_init(&ptrs, buf, buf_end - buf);
858 bytestream2_init_writer(&pb, dst, dst_size);
860 for (k = 0; k < bpp; k++) {
861 ofssrc = bytestream2_get_be32(&ptrs);
866 if (ofssrc >= buf_end - buf)
869 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
870 for (j = 0; j < ncolumns; j++) {
871 ofsdst = j + k * ncolumns;
873 i = bytestream2_get_byte(&gb);
875 opcode = bytestream2_get_byte(&gb);
878 opcode = bytestream2_get_byte(&gb);
879 x = bytestream2_get_byte(&gb);
882 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
883 if (xor && ofsdst < dst_size) {
884 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
886 bytestream2_put_byte(&pb, x);
891 } else if (opcode < 0x80) {
892 ofsdst += opcode * dstpitch;
897 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
898 if (xor && ofsdst < dst_size) {
899 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
901 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
913 static void decode_delta_j(uint8_t *dst,
914 const uint8_t *buf, const uint8_t *buf_end,
915 int w, int h, int bpp, int dst_size)
919 uint32_t type, flag, cols, groups, rows, bytes;
921 int planepitch_byte = (w + 7) / 8;
922 int planepitch = ((w + 15) / 16) * 2;
923 int kludge_j, b, g, r, d;
926 pitch = planepitch * bpp;
927 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
929 bytestream2_init(&gb, buf, buf_end - buf);
931 while (bytestream2_get_bytes_left(&gb) >= 2) {
932 type = bytestream2_get_be16(&gb);
938 flag = bytestream2_get_be16(&gb);
939 cols = bytestream2_get_be16(&gb);
940 groups = bytestream2_get_be16(&gb);
942 for (g = 0; g < groups; g++) {
943 offset = bytestream2_get_be16(&gb);
945 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
946 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
951 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
953 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
955 for (b = 0; b < cols; b++) {
956 for (d = 0; d < bpp; d++) {
957 uint8_t value = bytestream2_get_byte(&gb);
959 if (offset >= dst_size)
968 offset += planepitch;
971 if ((cols * bpp) & 1)
972 bytestream2_skip(&gb, 1);
976 flag = bytestream2_get_be16(&gb);
977 rows = bytestream2_get_be16(&gb);
978 bytes = bytestream2_get_be16(&gb);
979 groups = bytestream2_get_be16(&gb);
981 for (g = 0; g < groups; g++) {
982 offset = bytestream2_get_be16(&gb);
985 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
987 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
989 for (r = 0; r < rows; r++) {
990 for (d = 0; d < bpp; d++) {
991 unsigned noffset = offset + (r * pitch) + d * planepitch;
993 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
994 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
998 for (b = 0; b < bytes; b++) {
999 uint8_t value = bytestream2_get_byte(&gb);
1001 if (noffset >= dst_size)
1003 ptr = dst + noffset;
1014 if ((rows * bytes * bpp) & 1)
1015 bytestream2_skip(&gb, 1);
1024 static void decode_short_vertical_delta(uint8_t *dst,
1025 const uint8_t *buf, const uint8_t *buf_end,
1026 int w, int bpp, int dst_size)
1028 int ncolumns = (w + 15) >> 4;
1029 int dstpitch = ncolumns * bpp * 2;
1030 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1031 GetByteContext ptrs, gb, dptrs, dgb;
1035 if (buf_end - buf <= 64)
1038 bytestream2_init(&ptrs, buf, buf_end - buf);
1039 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1040 bytestream2_init_writer(&pb, dst, dst_size);
1042 for (k = 0; k < bpp; k++) {
1043 ofssrc = bytestream2_get_be32(&ptrs);
1044 ofsdata = bytestream2_get_be32(&dptrs);
1049 if (ofssrc >= buf_end - buf)
1052 if (ofsdata >= buf_end - buf)
1055 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1056 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1057 for (j = 0; j < ncolumns; j++) {
1058 ofsdst = (j + k * ncolumns) * 2;
1060 i = bytestream2_get_byte(&gb);
1062 opcode = bytestream2_get_byte(&gb);
1065 opcode = bytestream2_get_byte(&gb);
1066 x = bytestream2_get_be16(&dgb);
1069 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1070 bytestream2_put_be16(&pb, x);
1074 } else if (opcode < 0x80) {
1075 ofsdst += opcode * dstpitch;
1080 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1081 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1092 static void decode_long_vertical_delta(uint8_t *dst,
1093 const uint8_t *buf, const uint8_t *buf_end,
1094 int w, int bpp, int dst_size)
1096 int ncolumns = (w + 31) >> 5;
1097 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1098 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1099 GetByteContext ptrs, gb, dptrs, dgb;
1103 if (buf_end - buf <= 64)
1106 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1107 bytestream2_init(&ptrs, buf, buf_end - buf);
1108 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1109 bytestream2_init_writer(&pb, dst, dst_size);
1111 for (k = 0; k < bpp; k++) {
1112 ofssrc = bytestream2_get_be32(&ptrs);
1113 ofsdata = bytestream2_get_be32(&dptrs);
1118 if (ofssrc >= buf_end - buf)
1121 if (ofsdata >= buf_end - buf)
1124 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1125 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1126 for (j = 0; j < ncolumns; j++) {
1127 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1129 i = bytestream2_get_byte(&gb);
1131 opcode = bytestream2_get_byte(&gb);
1134 opcode = bytestream2_get_byte(&gb);
1135 if (h && (j == (ncolumns - 1))) {
1136 x = bytestream2_get_be16(&dgb);
1137 bytestream2_skip(&dgb, 2);
1139 x = bytestream2_get_be32(&dgb);
1143 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1144 if (h && (j == (ncolumns - 1))) {
1145 bytestream2_put_be16(&pb, x);
1147 bytestream2_put_be32(&pb, x);
1152 } else if (opcode < 0x80) {
1153 ofsdst += opcode * dstpitch;
1158 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1159 if (h && (j == (ncolumns - 1))) {
1160 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1161 bytestream2_skip(&dgb, 2);
1163 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1175 static void decode_short_vertical_delta2(uint8_t *dst,
1176 const uint8_t *buf, const uint8_t *buf_end,
1177 int w, int bpp, int dst_size)
1179 int ncolumns = (w + 15) >> 4;
1180 int dstpitch = ncolumns * bpp * 2;
1181 unsigned ofsdst, ofssrc, opcode, x;
1182 GetByteContext ptrs, gb;
1186 bytestream2_init(&ptrs, buf, buf_end - buf);
1187 bytestream2_init_writer(&pb, dst, dst_size);
1189 for (k = 0; k < bpp; k++) {
1190 ofssrc = bytestream2_get_be32(&ptrs);
1195 if (ofssrc >= buf_end - buf)
1198 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1199 for (j = 0; j < ncolumns; j++) {
1200 ofsdst = (j + k * ncolumns) * 2;
1202 i = bytestream2_get_be16(&gb);
1203 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1204 opcode = bytestream2_get_be16(&gb);
1207 opcode = bytestream2_get_be16(&gb);
1208 x = bytestream2_get_be16(&gb);
1210 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1211 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1212 bytestream2_put_be16(&pb, x);
1216 } else if (opcode < 0x8000) {
1217 ofsdst += opcode * dstpitch;
1221 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1222 bytestream2_get_bytes_left_p(&pb) > 1) {
1223 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1224 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1235 static void decode_long_vertical_delta2(uint8_t *dst,
1236 const uint8_t *buf, const uint8_t *buf_end,
1237 int w, int bpp, int dst_size)
1239 int ncolumns = (w + 31) >> 5;
1240 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1241 unsigned ofsdst, ofssrc, opcode, x;
1242 unsigned skip = 0x80000000, mask = skip - 1;
1243 GetByteContext ptrs, gb;
1247 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1248 bytestream2_init(&ptrs, buf, buf_end - buf);
1249 bytestream2_init_writer(&pb, dst, dst_size);
1251 for (k = 0; k < bpp; k++) {
1252 ofssrc = bytestream2_get_be32(&ptrs);
1257 if (ofssrc >= buf_end - buf)
1260 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1261 for (j = 0; j < ncolumns; j++) {
1262 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1264 if (h && (j == (ncolumns - 1))) {
1269 i = bytestream2_get_be32(&gb);
1270 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1271 opcode = bytestream2_get_be32(&gb);
1274 if (h && (j == ncolumns - 1)) {
1275 opcode = bytestream2_get_be16(&gb);
1276 x = bytestream2_get_be16(&gb);
1278 opcode = bytestream2_get_be32(&gb);
1279 x = bytestream2_get_be32(&gb);
1282 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1283 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1284 if (h && (j == ncolumns - 1))
1285 bytestream2_put_be16(&pb, x);
1287 bytestream2_put_be32(&pb, x);
1291 } else if (opcode < skip) {
1292 ofsdst += opcode * dstpitch;
1296 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1297 bytestream2_get_bytes_left_p(&pb) > 1) {
1298 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1299 if (h && (j == ncolumns - 1)) {
1300 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1302 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1314 static void decode_delta_d(uint8_t *dst,
1315 const uint8_t *buf, const uint8_t *buf_end,
1316 int w, int flag, int bpp, int dst_size)
1318 int planepitch = FFALIGN(w, 16) >> 3;
1319 int pitch = planepitch * bpp;
1320 int planepitch_byte = (w + 7) / 8;
1321 unsigned entries, ofssrc;
1322 GetByteContext gb, ptrs;
1326 if (buf_end - buf <= 4 * bpp)
1329 bytestream2_init_writer(&pb, dst, dst_size);
1330 bytestream2_init(&ptrs, buf, bpp * 4);
1332 for (k = 0; k < bpp; k++) {
1333 ofssrc = bytestream2_get_be32(&ptrs);
1338 if (ofssrc >= buf_end - buf)
1341 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1343 entries = bytestream2_get_be32(&gb);
1344 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1345 int32_t opcode = bytestream2_get_be32(&gb);
1346 unsigned offset = bytestream2_get_be32(&gb);
1348 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1350 uint32_t x = bytestream2_get_be32(&gb);
1351 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1352 bytestream2_put_be32(&pb, x);
1353 bytestream2_skip_p(&pb, pitch - 4);
1358 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1359 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1360 bytestream2_skip_p(&pb, pitch - 4);
1369 static void decode_delta_e(uint8_t *dst,
1370 const uint8_t *buf, const uint8_t *buf_end,
1371 int w, int flag, int bpp, int dst_size)
1373 int planepitch = FFALIGN(w, 16) >> 3;
1374 int pitch = planepitch * bpp;
1375 int planepitch_byte = (w + 7) / 8;
1376 unsigned entries, ofssrc;
1377 GetByteContext gb, ptrs;
1381 if (buf_end - buf <= 4 * bpp)
1384 bytestream2_init_writer(&pb, dst, dst_size);
1385 bytestream2_init(&ptrs, buf, bpp * 4);
1387 for (k = 0; k < bpp; k++) {
1388 ofssrc = bytestream2_get_be32(&ptrs);
1393 if (ofssrc >= buf_end - buf)
1396 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1398 entries = bytestream2_get_be16(&gb);
1399 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1400 int16_t opcode = bytestream2_get_be16(&gb);
1401 unsigned offset = bytestream2_get_be32(&gb);
1403 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1405 uint16_t x = bytestream2_get_be16(&gb);
1406 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1407 bytestream2_put_be16(&pb, x);
1408 bytestream2_skip_p(&pb, pitch - 2);
1413 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1414 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1415 bytestream2_skip_p(&pb, pitch - 2);
1424 static void decode_delta_l(uint8_t *dst,
1425 const uint8_t *buf, const uint8_t *buf_end,
1426 int w, int flag, int bpp, int dst_size)
1428 GetByteContext off0, off1, dgb, ogb;
1430 unsigned poff0, poff1;
1432 int planepitch_byte = (w + 7) / 8;
1433 int planepitch = ((w + 15) / 16) * 2;
1434 int pitch = planepitch * bpp;
1436 if (buf_end - buf <= 64)
1439 bytestream2_init(&off0, buf, buf_end - buf);
1440 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1441 bytestream2_init_writer(&pb, dst, dst_size);
1443 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1445 for (k = 0; k < bpp; k++) {
1446 poff0 = bytestream2_get_be32(&off0);
1447 poff1 = bytestream2_get_be32(&off1);
1452 if (2LL * poff0 >= buf_end - buf)
1455 if (2LL * poff1 >= buf_end - buf)
1458 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1459 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1461 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1462 uint32_t offset = bytestream2_get_be16(&ogb);
1463 int16_t cnt = bytestream2_get_be16(&ogb);
1466 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1468 if (bytestream2_get_bytes_left(&dgb) < 2)
1470 bytestream2_seek_p(&pb, offset, SEEK_SET);
1472 data = bytestream2_get_be16(&dgb);
1473 for (i = 0; i < cnt; i++) {
1474 bytestream2_put_be16(&pb, data);
1475 bytestream2_skip_p(&pb, dstpitch - 2);
1478 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1480 bytestream2_seek_p(&pb, offset, SEEK_SET);
1481 for (i = 0; i < cnt; i++) {
1482 data = bytestream2_get_be16(&dgb);
1483 bytestream2_put_be16(&pb, data);
1484 bytestream2_skip_p(&pb, dstpitch - 2);
1491 static int unsupported(AVCodecContext *avctx)
1493 IffContext *s = avctx->priv_data;
1494 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1495 return AVERROR_INVALIDDATA;
1498 static int decode_frame(AVCodecContext *avctx,
1499 void *data, int *got_frame,
1502 IffContext *s = avctx->priv_data;
1503 AVFrame *frame = data;
1504 const uint8_t *buf = avpkt->data;
1505 int buf_size = avpkt->size;
1506 const uint8_t *buf_end = buf + buf_size;
1508 GetByteContext *gb = &s->gb;
1509 const AVPixFmtDescriptor *desc;
1511 bytestream2_init(gb, avpkt->data, avpkt->size);
1513 if ((res = extract_header(avctx, avpkt)) < 0)
1516 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1520 buf += bytestream2_tell(gb);
1521 buf_size -= bytestream2_tell(gb);
1522 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1524 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1525 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1526 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1528 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1529 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1530 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1535 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1536 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1537 memcpy(s->pal, s->frame->data[1], 256 * 4);
1540 switch (s->compression) {
1542 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1543 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1544 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1545 for (plane = 0; plane < s->bpp; plane++) {
1546 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1547 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1548 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1549 buf += s->planesize;
1552 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1553 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1554 for (y = 0; y < avctx->height; y++) {
1555 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1556 memset(s->ham_buf, 0, s->planesize * 8);
1557 for (plane = 0; plane < s->bpp; plane++) {
1558 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1559 if (start >= buf_end)
1561 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1563 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1566 return unsupported(avctx);
1567 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1568 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1570 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1571 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1572 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1574 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1575 for (x = 0; x < avctx->width; x++)
1576 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1579 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1580 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1581 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1582 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1583 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1584 for (y = 0; y < avctx->height; y++) {
1585 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1586 memset(row, 0, avctx->width);
1587 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1588 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1589 buf += s->planesize;
1592 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1593 for (y = 0; y < avctx->height; y++) {
1594 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1595 memset(s->ham_buf, 0, s->planesize * 8);
1596 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1597 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1598 buf += s->planesize;
1600 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1602 } else { // AV_PIX_FMT_BGR32
1603 for (y = 0; y < avctx->height; y++) {
1604 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1605 memset(row, 0, avctx->width << 2);
1606 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1607 decodeplane32((uint32_t *)row, buf,
1608 FFMIN(s->planesize, buf_end - buf), plane);
1609 buf += s->planesize;
1613 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1614 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1615 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1616 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1617 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1618 buf += avctx->width + (avctx->width % 2); // padding if odd
1620 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1621 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1622 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1623 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1624 buf += avctx->width + (avctx->width & 1); // padding if odd
1625 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1628 return unsupported(avctx);
1630 return unsupported(avctx);
1634 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1635 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1636 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1637 uint8_t *video = s->video[0];
1639 for (y = 0; y < avctx->height; y++) {
1640 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1641 memset(row, 0, avctx->width);
1642 for (plane = 0; plane < s->bpp; plane++) {
1643 buf += decode_byterun(s->planebuf, s->planesize, gb);
1644 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1645 memcpy(video, s->planebuf, s->planesize);
1646 video += s->planesize;
1648 decodeplane8(row, s->planebuf, s->planesize, plane);
1651 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1652 for (y = 0; y < avctx->height; y++) {
1653 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1654 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1655 for (plane = 0; plane < s->bpp; plane++) {
1656 buf += decode_byterun(s->planebuf, s->planesize, gb);
1657 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1659 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1661 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1662 uint8_t *video = s->video[0];
1663 for (y = 0; y < avctx->height; y++) {
1664 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1665 memset(s->ham_buf, 0, s->planesize * 8);
1666 for (plane = 0; plane < s->bpp; plane++) {
1667 buf += decode_byterun(s->planebuf, s->planesize, gb);
1668 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1669 memcpy(video, s->planebuf, s->planesize);
1670 video += s->planesize;
1672 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1674 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1676 } else { // AV_PIX_FMT_BGR32
1677 for (y = 0; y < avctx->height; y++) {
1678 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1679 memset(row, 0, avctx->width << 2);
1680 for (plane = 0; plane < s->bpp; plane++) {
1681 buf += decode_byterun(s->planebuf, s->planesize, gb);
1682 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1686 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1687 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1688 for (y = 0; y < avctx->height; y++) {
1689 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1690 buf += decode_byterun(row, avctx->width, gb);
1692 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1693 for (y = 0; y < avctx->height; y++) {
1694 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1695 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1696 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1699 return unsupported(avctx);
1700 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1701 if (av_get_bits_per_pixel(desc) == 32)
1702 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1704 return unsupported(avctx);
1705 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1706 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1707 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1708 for (plane = 0; plane < s->bpp; plane++) {
1709 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1710 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1711 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1712 buf += s->planesize;
1715 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1716 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1717 for (y = 0; y < avctx->height; y++) {
1718 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1719 memset(s->ham_buf, 0, s->planesize * 8);
1720 for (plane = 0; plane < s->bpp; plane++) {
1721 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1722 if (start >= buf_end)
1724 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1726 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1729 return unsupported(avctx);
1732 return unsupported(avctx);
1736 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1737 for (plane = 0; plane < s->bpp; plane++) {
1738 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1739 for (y = 0; y < avctx->height; y++) {
1740 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1741 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1745 return unsupported(avctx);
1749 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1750 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1751 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1752 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1754 return unsupported(avctx);
1757 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1758 if (av_get_bits_per_pixel(desc) == 32)
1759 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1761 return unsupported(avctx);
1763 return unsupported(avctx);
1767 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1771 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1776 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1778 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1783 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1785 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1789 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1793 if (s->is_interlaced)
1794 return unsupported(avctx);
1795 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1799 if (s->is_interlaced)
1800 return unsupported(avctx);
1801 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1805 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1808 return unsupported(avctx);
1811 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1812 memcpy(s->video[1], s->video[0], s->video_size);
1815 if (s->compression > 0xff) {
1816 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1818 for (y = 0; y < avctx->height; y++) {
1819 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1820 memset(row, 0, avctx->width);
1821 for (plane = 0; plane < s->bpp; plane++) {
1822 decodeplane8(row, buf, s->planesize, plane);
1823 buf += s->planesize;
1826 memcpy(frame->data[1], s->pal, 256 * 4);
1827 } else if (s->ham) {
1828 int i, count = 1 << s->ham;
1831 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1832 for (i = 0; i < count; i++) {
1833 s->ham_palbuf[i*2+1] = s->pal[i];
1835 for (i = 0; i < count; i++) {
1836 uint32_t tmp = i << (8 - s->ham);
1837 tmp |= tmp >> s->ham;
1838 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1839 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1840 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1841 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1842 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1843 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1845 if (s->masking == MASK_HAS_MASK) {
1846 for (i = 0; i < 8 * (1 << s->ham); i++)
1847 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1849 for (y = 0; y < avctx->height; y++) {
1850 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1851 memset(s->ham_buf, 0, s->planesize * 8);
1852 for (plane = 0; plane < s->bpp; plane++) {
1853 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1854 buf += s->planesize;
1856 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1859 return unsupported(avctx);
1863 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1867 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1868 frame->key_frame = 1;
1869 frame->pict_type = AV_PICTURE_TYPE_I;
1871 frame->key_frame = 0;
1872 frame->pict_type = AV_PICTURE_TYPE_P;
1880 #if CONFIG_IFF_ILBM_DECODER
1881 AVCodec ff_iff_ilbm_decoder = {
1883 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1884 .type = AVMEDIA_TYPE_VIDEO,
1885 .id = AV_CODEC_ID_IFF_ILBM,
1886 .priv_data_size = sizeof(IffContext),
1887 .init = decode_init,
1888 .close = decode_end,
1889 .decode = decode_frame,
1890 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1891 .capabilities = AV_CODEC_CAP_DR1,