2 * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5 * Copyright (c) 2016 Paul B Mahol
7 * This file is part of FFmpeg.
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
31 #include "libavutil/imgutils.h"
33 #include "bytestream.h"
42 MASK_HAS_TRANSPARENT_COLOR,
46 typedef struct IffContext {
50 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
51 uint32_t *ham_palbuf; ///< HAM decode table
52 uint32_t *mask_buf; ///< temporary buffer for palette indices
53 uint32_t *mask_palbuf; ///< masking palette table
54 unsigned compression; ///< delta compression method used
55 unsigned is_short; ///< short compression method used
56 unsigned is_interlaced;///< video is interlaced
57 unsigned is_brush; ///< video is in ANBR format
58 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
59 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
60 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
61 unsigned transparency; ///< TODO: transparency color index in palette
62 unsigned masking; ///< TODO: masking method used
63 int init; // 1 if buffer and palette data already initialized, 0 otherwise
64 int16_t tvdc[16]; ///< TVDC lookup table
71 #define LUT8_PART(plane, v) \
72 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
79 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
80 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
81 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
82 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
83 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
84 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
85 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
86 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
87 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
89 #define LUT8(plane) { \
90 LUT8_PART(plane, 0x0000000), \
91 LUT8_PART(plane, 0x1000000), \
92 LUT8_PART(plane, 0x0010000), \
93 LUT8_PART(plane, 0x1010000), \
94 LUT8_PART(plane, 0x0000100), \
95 LUT8_PART(plane, 0x1000100), \
96 LUT8_PART(plane, 0x0010100), \
97 LUT8_PART(plane, 0x1010100), \
98 LUT8_PART(plane, 0x0000001), \
99 LUT8_PART(plane, 0x1000001), \
100 LUT8_PART(plane, 0x0010001), \
101 LUT8_PART(plane, 0x1010001), \
102 LUT8_PART(plane, 0x0000101), \
103 LUT8_PART(plane, 0x1000101), \
104 LUT8_PART(plane, 0x0010101), \
105 LUT8_PART(plane, 0x1010101), \
108 // 8 planes * 8-bit mask
109 static const uint64_t plane8_lut[8][256] = {
110 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
111 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
114 #define LUT32(plane) { \
116 0, 0, 0, 1U << plane, \
117 0, 0, 1U << plane, 0, \
118 0, 0, 1U << plane, 1U << plane, \
119 0, 1U << plane, 0, 0, \
120 0, 1U << plane, 0, 1U << plane, \
121 0, 1U << plane, 1U << plane, 0, \
122 0, 1U << plane, 1U << plane, 1U << plane, \
123 1U << plane, 0, 0, 0, \
124 1U << plane, 0, 0, 1U << plane, \
125 1U << plane, 0, 1U << plane, 0, \
126 1U << plane, 0, 1U << plane, 1U << plane, \
127 1U << plane, 1U << plane, 0, 0, \
128 1U << plane, 1U << plane, 0, 1U << plane, \
129 1U << plane, 1U << plane, 1U << plane, 0, \
130 1U << plane, 1U << plane, 1U << plane, 1U << plane, \
133 // 32 planes * 4-bit mask * 4 lookup tables each
134 static const uint32_t plane32_lut[32][16*4] = {
135 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
136 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
137 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
138 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
139 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
140 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
141 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
142 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
145 // Gray to RGB, required for palette table of grayscale images with bpp < 8
146 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
147 return x << 16 | x << 8 | x;
151 * Convert CMAP buffer (stored in extradata) to lavc palette format
153 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
155 IffContext *s = avctx->priv_data;
157 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
158 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
160 if (avctx->bits_per_coded_sample > 8) {
161 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
162 return AVERROR_INVALIDDATA;
165 count = 1 << avctx->bits_per_coded_sample;
166 // If extradata is smaller than actually needed, fill the remaining with black.
167 count = FFMIN(palette_size / 3, count);
169 for (i = 0; i < count; i++)
170 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
171 if (s->flags && count >= 32) { // EHB
172 for (i = 0; i < 32; i++)
173 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
174 count = FFMAX(count, 64);
176 } else { // Create gray-scale color palette for bps < 8
177 count = 1 << avctx->bits_per_coded_sample;
179 for (i = 0; i < count; i++)
180 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
182 if (s->masking == MASK_HAS_MASK) {
183 if ((1 << avctx->bits_per_coded_sample) < count) {
184 avpriv_request_sample(avctx, "overlapping mask");
185 return AVERROR_PATCHWELCOME;
187 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
188 for (i = 0; i < count; i++)
190 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
191 s->transparency < 1 << avctx->bits_per_coded_sample)
192 pal[s->transparency] &= 0xFFFFFF;
197 * Extracts the IFF extra context and updates internal
198 * decoder structures.
200 * @param avctx the AVCodecContext where to extract extra context to
201 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
202 * @return >= 0 in case of success, a negative error code otherwise
204 static int extract_header(AVCodecContext *const avctx,
205 const AVPacket *const avpkt)
207 IffContext *s = avctx->priv_data;
209 unsigned buf_size = 0;
212 if (avctx->extradata_size < 2) {
213 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
214 return AVERROR_INVALIDDATA;
216 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
218 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
221 GetByteContext *gb = &s->gb;
223 bytestream2_skip(gb, 4);
224 while (bytestream2_get_bytes_left(gb) >= 1) {
225 chunk_id = bytestream2_get_le32(gb);
226 data_size = bytestream2_get_be32(gb);
228 if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
229 bytestream2_skip(gb, data_size + (data_size & 1));
230 } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
233 return AVERROR_INVALIDDATA;
235 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
236 bytestream2_skip(gb, 19);
237 extra = bytestream2_get_be32(gb);
238 s->is_short = !(extra & 1);
239 s->is_brush = extra == 2;
240 s->is_interlaced = !!(extra & 0x40);
242 bytestream2_skip(gb, data_size + (data_size & 1));
243 } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
244 chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
245 if (chunk_id == MKTAG('B','O','D','Y'))
246 s->compression &= 0xFF;
248 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
249 int count = data_size / 3;
250 uint32_t *pal = s->pal;
253 return AVERROR_INVALIDDATA;
255 for (i = 0; i < count; i++)
256 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
258 for (i = 0; i < count; i++)
259 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
261 bytestream2_skip(gb, data_size & 1);
263 bytestream2_skip(gb, data_size + (data_size&1));
267 buf = avctx->extradata;
268 buf_size = bytestream_get_be16(&buf);
269 if (buf_size <= 1 || palette_size < 0) {
270 av_log(avctx, AV_LOG_ERROR,
271 "Invalid palette size received: %u -> palette data offset: %d\n",
272 buf_size, palette_size);
273 return AVERROR_INVALIDDATA;
277 if (buf_size >= 41) {
278 s->compression = bytestream_get_byte(&buf);
279 s->bpp = bytestream_get_byte(&buf);
280 s->ham = bytestream_get_byte(&buf);
281 s->flags = bytestream_get_byte(&buf);
282 s->transparency = bytestream_get_be16(&buf);
283 s->masking = bytestream_get_byte(&buf);
284 for (i = 0; i < 16; i++)
285 s->tvdc[i] = bytestream_get_be16(&buf);
289 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
290 return AVERROR_INVALIDDATA;
291 } else if (s->ham != (s->bpp > 6 ? 6 : 4)) {
292 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
293 return AVERROR_INVALIDDATA;
297 if (s->masking == MASK_HAS_MASK) {
298 if (s->bpp >= 8 && !s->ham) {
299 avctx->pix_fmt = AV_PIX_FMT_RGB32;
300 av_freep(&s->mask_buf);
301 av_freep(&s->mask_palbuf);
302 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
304 return AVERROR(ENOMEM);
306 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
307 av_freep(&s->mask_buf);
308 return AVERROR(ENOMEM);
310 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
311 if (!s->mask_palbuf) {
312 av_freep(&s->mask_buf);
313 return AVERROR(ENOMEM);
317 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
318 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
319 return AVERROR_PATCHWELCOME;
321 if (!s->bpp || s->bpp > 32) {
322 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
323 return AVERROR_INVALIDDATA;
326 av_freep(&s->ham_buf);
327 av_freep(&s->ham_palbuf);
330 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
332 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
334 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
336 return AVERROR(ENOMEM);
338 ham_count = 8 * (1 << s->ham);
339 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
340 if (!s->ham_palbuf) {
341 av_freep(&s->ham_buf);
342 return AVERROR(ENOMEM);
345 if (count) { // HAM with color palette attached
346 // prefill with black and palette and set HAM take direct value mask to zero
347 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
348 for (i=0; i < count; i++) {
349 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
352 } else { // HAM with grayscale color palette
354 for (i=0; i < count; i++) {
355 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
356 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
359 for (i=0; i < count; i++) {
360 uint32_t tmp = i << (8 - s->ham);
361 tmp |= tmp >> s->ham;
362 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
363 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
364 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
365 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
366 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
367 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
369 if (s->masking == MASK_HAS_MASK) {
370 for (i = 0; i < ham_count; i++)
371 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
379 static av_cold int decode_end(AVCodecContext *avctx)
381 IffContext *s = avctx->priv_data;
382 av_freep(&s->planebuf);
383 av_freep(&s->ham_buf);
384 av_freep(&s->ham_palbuf);
385 av_freep(&s->mask_buf);
386 av_freep(&s->mask_palbuf);
387 av_freep(&s->video[0]);
388 av_freep(&s->video[1]);
393 static av_cold int decode_init(AVCodecContext *avctx)
395 IffContext *s = avctx->priv_data;
398 if (avctx->bits_per_coded_sample <= 8) {
401 if (avctx->extradata_size >= 2)
402 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
405 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
406 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
407 } else if (avctx->bits_per_coded_sample <= 32) {
408 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
409 avctx->pix_fmt = AV_PIX_FMT_RGB32;
410 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
411 avctx->pix_fmt = AV_PIX_FMT_RGB444;
412 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
413 if (avctx->bits_per_coded_sample == 24) {
414 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
415 } else if (avctx->bits_per_coded_sample == 32) {
416 avctx->pix_fmt = AV_PIX_FMT_BGR32;
418 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
419 return AVERROR_PATCHWELCOME;
423 return AVERROR_INVALIDDATA;
426 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
428 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
429 s->planebuf = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
431 return AVERROR(ENOMEM);
433 s->bpp = avctx->bits_per_coded_sample;
435 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
436 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
437 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
438 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
439 s->pal = av_calloc(256, sizeof(*s->pal));
440 if (!s->video[0] || !s->video[1] || !s->pal)
441 return AVERROR(ENOMEM);
444 if ((err = extract_header(avctx, NULL)) < 0)
451 * Decode interleaved plane buffer up to 8bpp
452 * @param dst Destination buffer
453 * @param buf Source buffer
455 * @param plane plane number to decode as
457 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
461 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
464 lut = plane8_lut[plane];
466 uint64_t v = AV_RN64A(dst) | lut[*buf++];
469 } while (--buf_size);
473 * Decode interleaved plane buffer up to 24bpp
474 * @param dst Destination buffer
475 * @param buf Source buffer
477 * @param plane plane number to decode as
479 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
481 const uint32_t *lut = plane32_lut[plane];
483 unsigned mask = (*buf >> 2) & ~3;
484 dst[0] |= lut[mask++];
485 dst[1] |= lut[mask++];
486 dst[2] |= lut[mask++];
488 mask = (*buf++ << 2) & 0x3F;
489 dst[4] |= lut[mask++];
490 dst[5] |= lut[mask++];
491 dst[6] |= lut[mask++];
494 } while (--buf_size);
497 #define DECODE_HAM_PLANE32(x) \
498 first = buf[x] << 1; \
499 second = buf[(x)+1] << 1; \
500 delta &= pal[first++]; \
501 delta |= pal[first]; \
503 delta &= pal[second++]; \
504 delta |= pal[second]; \
508 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
510 * @param dst the destination 24bpp buffer
511 * @param buf the source 8bpp chunky buffer
512 * @param pal the HAM decode table
513 * @param buf_size the plane size in bytes
515 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
516 const uint32_t *const pal, unsigned buf_size)
518 uint32_t delta = pal[1]; /* first palette entry */
520 uint32_t first, second;
521 DECODE_HAM_PLANE32(0);
522 DECODE_HAM_PLANE32(2);
523 DECODE_HAM_PLANE32(4);
524 DECODE_HAM_PLANE32(6);
527 } while (--buf_size);
530 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
531 const uint32_t *const pal, unsigned width)
534 *dst++ = pal[*buf++];
539 * Decode one complete byterun1 encoded line.
541 * @param dst the destination buffer where to store decompressed bitstream
542 * @param dst_size the destination plane size in bytes
543 * @param buf the source byterun1 compressed bitstream
544 * @param buf_end the EOF of source byterun1 compressed bitstream
545 * @return number of consumed bytes in byterun1 compressed bitstream
547 static int decode_byterun(uint8_t *dst, int dst_size,
551 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
553 const int8_t value = bytestream2_get_byte(gb);
555 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
556 bytestream2_get_buffer(gb, dst + x, length);
557 if (length < value + 1)
558 bytestream2_skip(gb, value + 1 - length);
559 } else if (value > -128) {
560 length = FFMIN(-value + 1, dst_size - x);
561 memset(dst + x, bytestream2_get_byte(gb), length);
568 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
569 memset(dst+x, 0, dst_size - x);
571 return bytestream2_tell(gb);
574 static int decode_byterun2(uint8_t *dst, int height, int line_size,
579 int i, y_pos = 0, x_pos = 0;
581 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
584 bytestream2_skip(gb, 4);
585 count = bytestream2_get_be16(gb) - 2;
586 if (bytestream2_get_bytes_left(gb) < count)
589 bytestream2_init(&cmds, gb->buffer, count);
590 bytestream2_skip(gb, count);
592 for (i = 0; i < count && x_pos < line_size; i++) {
593 int8_t cmd = bytestream2_get_byte(&cmds);
597 l = bytestream2_get_be16(gb);
598 while (l-- > 0 && x_pos < line_size) {
599 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
600 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
601 if (y_pos >= height) {
606 } else if (cmd < 0) {
608 while (l-- > 0 && x_pos < line_size) {
609 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
610 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
611 if (y_pos >= height) {
616 } else if (cmd == 1) {
617 l = bytestream2_get_be16(gb);
618 r = bytestream2_get_be16(gb);
619 while (l-- > 0 && x_pos < line_size) {
620 dst[x_pos + y_pos * line_size ] = r >> 8;
621 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
622 if (y_pos >= height) {
629 r = bytestream2_get_be16(gb);
630 while (l-- > 0 && x_pos < line_size) {
631 dst[x_pos + y_pos * line_size ] = r >> 8;
632 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
633 if (y_pos >= height) {
641 return bytestream2_tell(gb);
644 #define DECODE_RGBX_COMMON(type) \
646 length = bytestream2_get_byte(gb); \
648 length = bytestream2_get_be16(gb); \
653 for (i = 0; i < length; i++) { \
654 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
666 * @param[out] dst Destination buffer
667 * @param width Width of destination buffer (pixels)
668 * @param height Height of destination buffer (pixels)
669 * @param linesize Line size of destination buffer (bytes)
671 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
673 int x = 0, y = 0, i, length;
674 while (bytestream2_get_bytes_left(gb) >= 4) {
675 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
676 length = bytestream2_get_byte(gb) & 0x7F;
677 DECODE_RGBX_COMMON(uint32_t)
683 * @param[out] dst Destination buffer
684 * @param width Width of destination buffer (pixels)
685 * @param height Height of destination buffer (pixels)
686 * @param linesize Line size of destination buffer (bytes)
688 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
690 int x = 0, y = 0, i, length;
691 while (bytestream2_get_bytes_left(gb) >= 2) {
692 uint32_t pixel = bytestream2_get_be16u(gb);
693 length = pixel & 0x7;
695 DECODE_RGBX_COMMON(uint16_t)
700 * Decode DEEP RLE 32-bit buffer
701 * @param[out] dst Destination buffer
702 * @param[in] src Source buffer
703 * @param src_size Source buffer size (bytes)
704 * @param width Width of destination buffer (pixels)
705 * @param height Height of destination buffer (pixels)
706 * @param linesize Line size of destination buffer (bytes)
708 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
710 const uint8_t *src_end = src + src_size;
712 while (src + 5 <= src_end) {
714 opcode = *(int8_t *)src++;
716 int size = opcode + 1;
717 for (i = 0; i < size; i++) {
718 int length = FFMIN(size - i, width);
719 memcpy(dst + y*linesize + x * 4, src, length * 4);
731 int size = -opcode + 1;
732 uint32_t pixel = AV_RN32(src);
733 for (i = 0; i < size; i++) {
734 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
749 * Decode DEEP TVDC 32-bit buffer
750 * @param[out] dst Destination buffer
751 * @param[in] src Source buffer
752 * @param src_size Source buffer size (bytes)
753 * @param width Width of destination buffer (pixels)
754 * @param height Height of destination buffer (pixels)
755 * @param linesize Line size of destination buffer (bytes)
756 * @param[int] tvdc TVDC lookup table
758 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)
760 int x = 0, y = 0, plane = 0;
764 for (i = 0; i < src_size * 2;) {
765 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
766 int d = tvdc[GETNIBBLE];
770 dst[y * linesize + x*4 + plane] = pixel;
773 if (i >= src_size * 2)
777 d = FFMIN(d, width - x);
778 for (j = 0; j < d; j++) {
779 dst[y * linesize + x*4 + plane] = pixel;
798 static void decode_short_horizontal_delta(uint8_t *dst,
799 const uint8_t *buf, const uint8_t *buf_end,
800 int w, int bpp, int dst_size)
802 int planepitch = FFALIGN(w, 16) >> 3;
803 int pitch = planepitch * bpp;
804 GetByteContext ptrs, gb;
806 unsigned ofssrc, pos;
809 bytestream2_init(&ptrs, buf, buf_end - buf);
810 bytestream2_init_writer(&pb, dst, dst_size);
812 for (k = 0; k < bpp; k++) {
813 ofssrc = bytestream2_get_be32(&ptrs);
819 if (ofssrc >= buf_end - buf)
822 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
823 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
824 int16_t offset = bytestream2_get_be16(&gb);
828 unsigned data = bytestream2_get_be16(&gb);
831 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
832 bytestream2_seek_p(&pb, noffset, SEEK_SET);
833 bytestream2_put_be16(&pb, data);
835 uint16_t count = bytestream2_get_be16(&gb);
837 pos += 2 * -(offset + 2);
838 for (i = 0; i < count; i++) {
839 uint16_t data = bytestream2_get_be16(&gb);
842 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
843 bytestream2_seek_p(&pb, noffset, SEEK_SET);
844 bytestream2_put_be16(&pb, data);
851 static void decode_byte_vertical_delta(uint8_t *dst,
852 const uint8_t *buf, const uint8_t *buf_end,
853 int w, int xor, int bpp, int dst_size)
855 int ncolumns = ((w + 15) / 16) * 2;
856 int dstpitch = ncolumns * bpp;
857 unsigned ofsdst, ofssrc, opcode, x;
858 GetByteContext ptrs, gb;
862 bytestream2_init(&ptrs, buf, buf_end - buf);
863 bytestream2_init_writer(&pb, dst, dst_size);
865 for (k = 0; k < bpp; k++) {
866 ofssrc = bytestream2_get_be32(&ptrs);
871 if (ofssrc >= buf_end - buf)
874 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
875 for (j = 0; j < ncolumns; j++) {
876 ofsdst = j + k * ncolumns;
878 i = bytestream2_get_byte(&gb);
880 opcode = bytestream2_get_byte(&gb);
883 opcode = bytestream2_get_byte(&gb);
884 x = bytestream2_get_byte(&gb);
887 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
888 if (xor && ofsdst < dst_size) {
889 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
891 bytestream2_put_byte(&pb, x);
896 } else if (opcode < 0x80) {
897 ofsdst += opcode * dstpitch;
902 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
903 if (xor && ofsdst < dst_size) {
904 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
906 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
918 static void decode_delta_j(uint8_t *dst,
919 const uint8_t *buf, const uint8_t *buf_end,
920 int w, int h, int bpp, int dst_size)
924 uint32_t type, flag, cols, groups, rows, bytes;
926 int planepitch_byte = (w + 7) / 8;
927 int planepitch = ((w + 15) / 16) * 2;
928 int kludge_j, b, g, r, d;
931 pitch = planepitch * bpp;
932 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
934 bytestream2_init(&gb, buf, buf_end - buf);
936 while (bytestream2_get_bytes_left(&gb) >= 2) {
937 type = bytestream2_get_be16(&gb);
943 flag = bytestream2_get_be16(&gb);
944 cols = bytestream2_get_be16(&gb);
945 groups = bytestream2_get_be16(&gb);
947 for (g = 0; g < groups; g++) {
948 offset = bytestream2_get_be16(&gb);
950 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
951 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
956 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
958 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
960 for (b = 0; b < cols; b++) {
961 for (d = 0; d < bpp; d++) {
962 uint8_t value = bytestream2_get_byte(&gb);
964 if (offset >= dst_size)
973 offset += planepitch;
976 if ((cols * bpp) & 1)
977 bytestream2_skip(&gb, 1);
981 flag = bytestream2_get_be16(&gb);
982 rows = bytestream2_get_be16(&gb);
983 bytes = bytestream2_get_be16(&gb);
984 groups = bytestream2_get_be16(&gb);
986 for (g = 0; g < groups; g++) {
987 offset = bytestream2_get_be16(&gb);
990 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
992 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
994 for (r = 0; r < rows; r++) {
995 for (d = 0; d < bpp; d++) {
996 unsigned noffset = offset + (r * pitch) + d * planepitch;
998 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
999 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1003 for (b = 0; b < bytes; b++) {
1004 uint8_t value = bytestream2_get_byte(&gb);
1006 if (noffset >= dst_size)
1008 ptr = dst + noffset;
1019 if ((rows * bytes * bpp) & 1)
1020 bytestream2_skip(&gb, 1);
1029 static void decode_short_vertical_delta(uint8_t *dst,
1030 const uint8_t *buf, const uint8_t *buf_end,
1031 int w, int bpp, int dst_size)
1033 int ncolumns = (w + 15) >> 4;
1034 int dstpitch = ncolumns * bpp * 2;
1035 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1036 GetByteContext ptrs, gb, dptrs, dgb;
1040 if (buf_end - buf <= 64)
1043 bytestream2_init(&ptrs, buf, buf_end - buf);
1044 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1045 bytestream2_init_writer(&pb, dst, dst_size);
1047 for (k = 0; k < bpp; k++) {
1048 ofssrc = bytestream2_get_be32(&ptrs);
1049 ofsdata = bytestream2_get_be32(&dptrs);
1054 if (ofssrc >= buf_end - buf)
1057 if (ofsdata >= buf_end - buf)
1060 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1061 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1062 for (j = 0; j < ncolumns; j++) {
1063 ofsdst = (j + k * ncolumns) * 2;
1065 i = bytestream2_get_byte(&gb);
1067 opcode = bytestream2_get_byte(&gb);
1070 opcode = bytestream2_get_byte(&gb);
1071 x = bytestream2_get_be16(&dgb);
1074 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1075 bytestream2_put_be16(&pb, x);
1079 } else if (opcode < 0x80) {
1080 ofsdst += opcode * dstpitch;
1085 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1086 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1097 static void decode_long_vertical_delta(uint8_t *dst,
1098 const uint8_t *buf, const uint8_t *buf_end,
1099 int w, int bpp, int dst_size)
1101 int ncolumns = (w + 31) >> 5;
1102 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1103 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1104 GetByteContext ptrs, gb, dptrs, dgb;
1108 if (buf_end - buf <= 64)
1111 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1112 bytestream2_init(&ptrs, buf, buf_end - buf);
1113 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1114 bytestream2_init_writer(&pb, dst, dst_size);
1116 for (k = 0; k < bpp; k++) {
1117 ofssrc = bytestream2_get_be32(&ptrs);
1118 ofsdata = bytestream2_get_be32(&dptrs);
1123 if (ofssrc >= buf_end - buf)
1126 if (ofsdata >= buf_end - buf)
1129 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1130 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1131 for (j = 0; j < ncolumns; j++) {
1132 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1134 i = bytestream2_get_byte(&gb);
1136 opcode = bytestream2_get_byte(&gb);
1139 opcode = bytestream2_get_byte(&gb);
1140 if (h && (j == (ncolumns - 1))) {
1141 x = bytestream2_get_be16(&dgb);
1142 bytestream2_skip(&dgb, 2);
1144 x = bytestream2_get_be32(&dgb);
1147 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1151 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1152 if (h && (j == (ncolumns - 1))) {
1153 bytestream2_put_be16(&pb, x);
1155 bytestream2_put_be32(&pb, x);
1160 } else if (opcode < 0x80) {
1161 ofsdst += opcode * dstpitch;
1166 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1167 if (h && (j == (ncolumns - 1))) {
1168 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1169 bytestream2_skip(&dgb, 2);
1171 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1183 static void decode_short_vertical_delta2(uint8_t *dst,
1184 const uint8_t *buf, const uint8_t *buf_end,
1185 int w, int bpp, int dst_size)
1187 int ncolumns = (w + 15) >> 4;
1188 int dstpitch = ncolumns * bpp * 2;
1189 unsigned ofsdst, ofssrc, opcode, x;
1190 GetByteContext ptrs, gb;
1194 bytestream2_init(&ptrs, buf, buf_end - buf);
1195 bytestream2_init_writer(&pb, dst, dst_size);
1197 for (k = 0; k < bpp; k++) {
1198 ofssrc = bytestream2_get_be32(&ptrs);
1203 if (ofssrc >= buf_end - buf)
1206 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1207 for (j = 0; j < ncolumns; j++) {
1208 ofsdst = (j + k * ncolumns) * 2;
1210 i = bytestream2_get_be16(&gb);
1211 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1212 opcode = bytestream2_get_be16(&gb);
1215 opcode = bytestream2_get_be16(&gb);
1216 x = bytestream2_get_be16(&gb);
1218 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1219 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1220 bytestream2_put_be16(&pb, x);
1224 } else if (opcode < 0x8000) {
1225 ofsdst += opcode * dstpitch;
1229 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1230 bytestream2_get_bytes_left_p(&pb) > 1) {
1231 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1232 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1243 static void decode_long_vertical_delta2(uint8_t *dst,
1244 const uint8_t *buf, const uint8_t *buf_end,
1245 int w, int bpp, int dst_size)
1247 int ncolumns = (w + 31) >> 5;
1248 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1249 unsigned ofsdst, ofssrc, opcode, x;
1250 unsigned skip = 0x80000000, mask = skip - 1;
1251 GetByteContext ptrs, gb;
1255 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1256 bytestream2_init(&ptrs, buf, buf_end - buf);
1257 bytestream2_init_writer(&pb, dst, dst_size);
1259 for (k = 0; k < bpp; k++) {
1260 ofssrc = bytestream2_get_be32(&ptrs);
1265 if (ofssrc >= buf_end - buf)
1268 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1269 for (j = 0; j < ncolumns; j++) {
1270 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1272 if (h && (j == (ncolumns - 1))) {
1277 i = bytestream2_get_be32(&gb);
1278 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1279 opcode = bytestream2_get_be32(&gb);
1282 if (h && (j == ncolumns - 1)) {
1283 opcode = bytestream2_get_be16(&gb);
1284 x = bytestream2_get_be16(&gb);
1286 opcode = bytestream2_get_be32(&gb);
1287 x = bytestream2_get_be32(&gb);
1290 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1293 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1294 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1295 if (h && (j == ncolumns - 1))
1296 bytestream2_put_be16(&pb, x);
1298 bytestream2_put_be32(&pb, x);
1302 } else if (opcode < skip) {
1303 ofsdst += opcode * dstpitch;
1307 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1308 bytestream2_get_bytes_left_p(&pb) > 1) {
1309 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1310 if (h && (j == ncolumns - 1)) {
1311 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1313 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1325 static void decode_delta_d(uint8_t *dst,
1326 const uint8_t *buf, const uint8_t *buf_end,
1327 int w, int flag, int bpp, int dst_size)
1329 int planepitch = FFALIGN(w, 16) >> 3;
1330 int pitch = planepitch * bpp;
1331 int planepitch_byte = (w + 7) / 8;
1332 unsigned entries, ofssrc;
1333 GetByteContext gb, ptrs;
1337 if (buf_end - buf <= 4 * bpp)
1340 bytestream2_init_writer(&pb, dst, dst_size);
1341 bytestream2_init(&ptrs, buf, bpp * 4);
1343 for (k = 0; k < bpp; k++) {
1344 ofssrc = bytestream2_get_be32(&ptrs);
1349 if (ofssrc >= buf_end - buf)
1352 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1354 entries = bytestream2_get_be32(&gb);
1355 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1356 int32_t opcode = bytestream2_get_be32(&gb);
1357 unsigned offset = bytestream2_get_be32(&gb);
1359 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1361 uint32_t x = bytestream2_get_be32(&gb);
1362 if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1364 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1365 bytestream2_put_be32(&pb, x);
1366 bytestream2_skip_p(&pb, pitch - 4);
1371 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1372 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1373 bytestream2_skip_p(&pb, pitch - 4);
1382 static void decode_delta_e(uint8_t *dst,
1383 const uint8_t *buf, const uint8_t *buf_end,
1384 int w, int flag, int bpp, int dst_size)
1386 int planepitch = FFALIGN(w, 16) >> 3;
1387 int pitch = planepitch * bpp;
1388 int planepitch_byte = (w + 7) / 8;
1389 unsigned entries, ofssrc;
1390 GetByteContext gb, ptrs;
1394 if (buf_end - buf <= 4 * bpp)
1397 bytestream2_init_writer(&pb, dst, dst_size);
1398 bytestream2_init(&ptrs, buf, bpp * 4);
1400 for (k = 0; k < bpp; k++) {
1401 ofssrc = bytestream2_get_be32(&ptrs);
1406 if (ofssrc >= buf_end - buf)
1409 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1411 entries = bytestream2_get_be16(&gb);
1412 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1413 int16_t opcode = bytestream2_get_be16(&gb);
1414 unsigned offset = bytestream2_get_be32(&gb);
1416 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1418 uint16_t x = bytestream2_get_be16(&gb);
1419 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1420 bytestream2_put_be16(&pb, x);
1421 bytestream2_skip_p(&pb, pitch - 2);
1426 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1427 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1428 bytestream2_skip_p(&pb, pitch - 2);
1437 static void decode_delta_l(uint8_t *dst,
1438 const uint8_t *buf, const uint8_t *buf_end,
1439 int w, int flag, int bpp, int dst_size)
1441 GetByteContext off0, off1, dgb, ogb;
1443 unsigned poff0, poff1;
1445 int planepitch_byte = (w + 7) / 8;
1446 int planepitch = ((w + 15) / 16) * 2;
1447 int pitch = planepitch * bpp;
1449 if (buf_end - buf <= 64)
1452 bytestream2_init(&off0, buf, buf_end - buf);
1453 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1454 bytestream2_init_writer(&pb, dst, dst_size);
1456 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1458 for (k = 0; k < bpp; k++) {
1459 poff0 = bytestream2_get_be32(&off0);
1460 poff1 = bytestream2_get_be32(&off1);
1465 if (2LL * poff0 >= buf_end - buf)
1468 if (2LL * poff1 >= buf_end - buf)
1471 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1472 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1474 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1475 uint32_t offset = bytestream2_get_be16(&ogb);
1476 int16_t cnt = bytestream2_get_be16(&ogb);
1479 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1481 if (bytestream2_get_bytes_left(&dgb) < 2)
1483 bytestream2_seek_p(&pb, offset, SEEK_SET);
1485 data = bytestream2_get_be16(&dgb);
1486 for (i = 0; i < cnt; i++) {
1487 bytestream2_put_be16(&pb, data);
1488 bytestream2_skip_p(&pb, dstpitch - 2);
1491 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1493 bytestream2_seek_p(&pb, offset, SEEK_SET);
1494 for (i = 0; i < cnt; i++) {
1495 data = bytestream2_get_be16(&dgb);
1496 bytestream2_put_be16(&pb, data);
1497 bytestream2_skip_p(&pb, dstpitch - 2);
1504 static int unsupported(AVCodecContext *avctx)
1506 IffContext *s = avctx->priv_data;
1507 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1508 return AVERROR_INVALIDDATA;
1511 static int decode_frame(AVCodecContext *avctx,
1512 void *data, int *got_frame,
1515 IffContext *s = avctx->priv_data;
1516 AVFrame *frame = data;
1517 const uint8_t *buf = avpkt->data;
1518 int buf_size = avpkt->size;
1519 const uint8_t *buf_end = buf + buf_size;
1521 GetByteContext *gb = &s->gb;
1522 const AVPixFmtDescriptor *desc;
1524 bytestream2_init(gb, avpkt->data, avpkt->size);
1526 if ((res = extract_header(avctx, avpkt)) < 0)
1529 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1533 buf += bytestream2_tell(gb);
1534 buf_size -= bytestream2_tell(gb);
1535 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1537 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1538 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1539 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1541 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1542 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1543 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1548 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1549 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1550 memcpy(s->pal, s->frame->data[1], 256 * 4);
1553 switch (s->compression) {
1555 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1556 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1557 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1558 for (plane = 0; plane < s->bpp; plane++) {
1559 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1560 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1561 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1562 buf += s->planesize;
1565 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1566 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1567 for (y = 0; y < avctx->height; y++) {
1568 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1569 memset(s->ham_buf, 0, s->planesize * 8);
1570 for (plane = 0; plane < s->bpp; plane++) {
1571 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1572 if (start >= buf_end)
1574 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1576 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1579 return unsupported(avctx);
1580 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1581 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1583 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1584 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1585 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1587 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1588 for (x = 0; x < avctx->width; x++)
1589 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1592 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1593 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1594 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1595 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1596 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1597 for (y = 0; y < avctx->height; y++) {
1598 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1599 memset(row, 0, avctx->width);
1600 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1601 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1602 buf += s->planesize;
1605 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1606 for (y = 0; y < avctx->height; y++) {
1607 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1608 memset(s->ham_buf, 0, s->planesize * 8);
1609 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1610 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1611 buf += s->planesize;
1613 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1615 } else { // AV_PIX_FMT_BGR32
1616 for (y = 0; y < avctx->height; y++) {
1617 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1618 memset(row, 0, avctx->width << 2);
1619 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1620 decodeplane32((uint32_t *)row, buf,
1621 FFMIN(s->planesize, buf_end - buf), plane);
1622 buf += s->planesize;
1626 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1627 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1628 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1629 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1630 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1631 buf += avctx->width + (avctx->width % 2); // padding if odd
1633 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1634 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1635 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1636 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1637 buf += avctx->width + (avctx->width & 1); // padding if odd
1638 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1641 return unsupported(avctx);
1643 return unsupported(avctx);
1647 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1648 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1649 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1650 uint8_t *video = s->video[0];
1652 for (y = 0; y < avctx->height; y++) {
1653 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1654 memset(row, 0, avctx->width);
1655 for (plane = 0; plane < s->bpp; plane++) {
1656 buf += decode_byterun(s->planebuf, s->planesize, gb);
1657 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1658 memcpy(video, s->planebuf, s->planesize);
1659 video += s->planesize;
1661 decodeplane8(row, s->planebuf, s->planesize, plane);
1664 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1665 for (y = 0; y < avctx->height; y++) {
1666 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1667 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1668 for (plane = 0; plane < s->bpp; plane++) {
1669 buf += decode_byterun(s->planebuf, s->planesize, gb);
1670 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1672 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1674 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1675 uint8_t *video = s->video[0];
1676 for (y = 0; y < avctx->height; y++) {
1677 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1678 memset(s->ham_buf, 0, s->planesize * 8);
1679 for (plane = 0; plane < s->bpp; plane++) {
1680 buf += decode_byterun(s->planebuf, s->planesize, gb);
1681 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1682 memcpy(video, s->planebuf, s->planesize);
1683 video += s->planesize;
1685 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1687 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1689 } else { // AV_PIX_FMT_BGR32
1690 for (y = 0; y < avctx->height; y++) {
1691 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1692 memset(row, 0, avctx->width << 2);
1693 for (plane = 0; plane < s->bpp; plane++) {
1694 buf += decode_byterun(s->planebuf, s->planesize, gb);
1695 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1699 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1700 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1701 for (y = 0; y < avctx->height; y++) {
1702 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1703 buf += decode_byterun(row, avctx->width, gb);
1705 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1706 for (y = 0; y < avctx->height; y++) {
1707 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1708 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1709 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1712 return unsupported(avctx);
1713 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1714 if (av_get_bits_per_pixel(desc) == 32)
1715 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1717 return unsupported(avctx);
1718 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1719 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1720 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1721 for (plane = 0; plane < s->bpp; plane++) {
1722 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1723 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1724 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1725 buf += s->planesize;
1728 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1729 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1730 for (y = 0; y < avctx->height; y++) {
1731 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1732 memset(s->ham_buf, 0, s->planesize * 8);
1733 for (plane = 0; plane < s->bpp; plane++) {
1734 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1735 if (start >= buf_end)
1737 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1739 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1742 return unsupported(avctx);
1745 return unsupported(avctx);
1749 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1750 for (plane = 0; plane < s->bpp; plane++) {
1751 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1752 for (y = 0; y < avctx->height; y++) {
1753 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1754 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1758 return unsupported(avctx);
1762 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1763 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1764 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1765 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1767 return unsupported(avctx);
1770 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1771 if (av_get_bits_per_pixel(desc) == 32)
1772 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1774 return unsupported(avctx);
1776 return unsupported(avctx);
1780 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1784 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1789 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1791 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1796 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1798 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1802 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1806 if (s->is_interlaced)
1807 return unsupported(avctx);
1808 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1812 if (s->is_interlaced)
1813 return unsupported(avctx);
1814 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1818 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1821 return unsupported(avctx);
1824 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1825 memcpy(s->video[1], s->video[0], s->video_size);
1828 if (s->compression > 0xff) {
1829 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1831 for (y = 0; y < avctx->height; y++) {
1832 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1833 memset(row, 0, avctx->width);
1834 for (plane = 0; plane < s->bpp; plane++) {
1835 decodeplane8(row, buf, s->planesize, plane);
1836 buf += s->planesize;
1839 memcpy(frame->data[1], s->pal, 256 * 4);
1840 } else if (s->ham) {
1841 int i, count = 1 << s->ham;
1844 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1845 for (i = 0; i < count; i++) {
1846 s->ham_palbuf[i*2+1] = s->pal[i];
1848 for (i = 0; i < count; i++) {
1849 uint32_t tmp = i << (8 - s->ham);
1850 tmp |= tmp >> s->ham;
1851 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1852 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1853 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1854 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1855 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1856 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1858 if (s->masking == MASK_HAS_MASK) {
1859 for (i = 0; i < 8 * (1 << s->ham); i++)
1860 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1862 for (y = 0; y < avctx->height; y++) {
1863 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1864 memset(s->ham_buf, 0, s->planesize * 8);
1865 for (plane = 0; plane < s->bpp; plane++) {
1866 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1867 buf += s->planesize;
1869 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1872 return unsupported(avctx);
1876 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1880 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1881 frame->key_frame = 1;
1882 frame->pict_type = AV_PICTURE_TYPE_I;
1884 frame->key_frame = 0;
1885 frame->pict_type = AV_PICTURE_TYPE_P;
1893 #if CONFIG_IFF_ILBM_DECODER
1894 AVCodec ff_iff_ilbm_decoder = {
1896 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1897 .type = AVMEDIA_TYPE_VIDEO,
1898 .id = AV_CODEC_ID_IFF_ILBM,
1899 .priv_data_size = sizeof(IffContext),
1900 .init = decode_init,
1901 .close = decode_end,
1902 .decode = decode_frame,
1903 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1904 .capabilities = AV_CODEC_CAP_DR1,