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;
325 if (s->video_size && s->planesize * s->bpp * avctx->height > s->video_size)
326 return AVERROR_INVALIDDATA;
328 av_freep(&s->ham_buf);
329 av_freep(&s->ham_palbuf);
332 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
334 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
336 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
338 return AVERROR(ENOMEM);
340 ham_count = 8 * (1 << s->ham);
341 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
342 if (!s->ham_palbuf) {
343 av_freep(&s->ham_buf);
344 return AVERROR(ENOMEM);
347 if (count) { // HAM with color palette attached
348 // prefill with black and palette and set HAM take direct value mask to zero
349 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
350 for (i=0; i < count; i++) {
351 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
354 } else { // HAM with grayscale color palette
356 for (i=0; i < count; i++) {
357 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
358 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
361 for (i=0; i < count; i++) {
362 uint32_t tmp = i << (8 - s->ham);
363 tmp |= tmp >> s->ham;
364 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
365 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
366 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
367 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
368 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
369 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
371 if (s->masking == MASK_HAS_MASK) {
372 for (i = 0; i < ham_count; i++)
373 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
381 static av_cold int decode_end(AVCodecContext *avctx)
383 IffContext *s = avctx->priv_data;
384 av_freep(&s->planebuf);
385 av_freep(&s->ham_buf);
386 av_freep(&s->ham_palbuf);
387 av_freep(&s->mask_buf);
388 av_freep(&s->mask_palbuf);
389 av_freep(&s->video[0]);
390 av_freep(&s->video[1]);
395 static av_cold int decode_init(AVCodecContext *avctx)
397 IffContext *s = avctx->priv_data;
400 if (avctx->bits_per_coded_sample <= 8) {
403 if (avctx->extradata_size >= 2)
404 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
407 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
408 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
409 } else if (avctx->bits_per_coded_sample <= 32) {
410 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
411 avctx->pix_fmt = AV_PIX_FMT_RGB32;
412 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
413 avctx->pix_fmt = AV_PIX_FMT_RGB444;
414 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
415 if (avctx->bits_per_coded_sample == 24) {
416 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
417 } else if (avctx->bits_per_coded_sample == 32) {
418 avctx->pix_fmt = AV_PIX_FMT_BGR32;
420 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
421 return AVERROR_PATCHWELCOME;
425 return AVERROR_INVALIDDATA;
428 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
430 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
431 s->planebuf = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
433 return AVERROR(ENOMEM);
435 s->bpp = avctx->bits_per_coded_sample;
437 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
438 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
439 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
440 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
441 s->pal = av_calloc(256, sizeof(*s->pal));
442 if (!s->video[0] || !s->video[1] || !s->pal)
443 return AVERROR(ENOMEM);
446 if ((err = extract_header(avctx, NULL)) < 0)
453 * Decode interleaved plane buffer up to 8bpp
454 * @param dst Destination buffer
455 * @param buf Source buffer
457 * @param plane plane number to decode as
459 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
463 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
466 lut = plane8_lut[plane];
468 uint64_t v = AV_RN64A(dst) | lut[*buf++];
471 } while (--buf_size);
475 * Decode interleaved plane buffer up to 24bpp
476 * @param dst Destination buffer
477 * @param buf Source buffer
479 * @param plane plane number to decode as
481 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
483 const uint32_t *lut = plane32_lut[plane];
485 unsigned mask = (*buf >> 2) & ~3;
486 dst[0] |= lut[mask++];
487 dst[1] |= lut[mask++];
488 dst[2] |= lut[mask++];
490 mask = (*buf++ << 2) & 0x3F;
491 dst[4] |= lut[mask++];
492 dst[5] |= lut[mask++];
493 dst[6] |= lut[mask++];
496 } while (--buf_size);
499 #define DECODE_HAM_PLANE32(x) \
500 first = buf[x] << 1; \
501 second = buf[(x)+1] << 1; \
502 delta &= pal[first++]; \
503 delta |= pal[first]; \
505 delta &= pal[second++]; \
506 delta |= pal[second]; \
510 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
512 * @param dst the destination 24bpp buffer
513 * @param buf the source 8bpp chunky buffer
514 * @param pal the HAM decode table
515 * @param buf_size the plane size in bytes
517 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
518 const uint32_t *const pal, unsigned buf_size)
520 uint32_t delta = pal[1]; /* first palette entry */
522 uint32_t first, second;
523 DECODE_HAM_PLANE32(0);
524 DECODE_HAM_PLANE32(2);
525 DECODE_HAM_PLANE32(4);
526 DECODE_HAM_PLANE32(6);
529 } while (--buf_size);
532 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
533 const uint32_t *const pal, unsigned width)
536 *dst++ = pal[*buf++];
541 * Decode one complete byterun1 encoded line.
543 * @param dst the destination buffer where to store decompressed bitstream
544 * @param dst_size the destination plane size in bytes
545 * @param buf the source byterun1 compressed bitstream
546 * @param buf_end the EOF of source byterun1 compressed bitstream
547 * @return number of consumed bytes in byterun1 compressed bitstream
549 static int decode_byterun(uint8_t *dst, int dst_size,
553 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
555 const int8_t value = bytestream2_get_byte(gb);
557 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
558 bytestream2_get_buffer(gb, dst + x, length);
559 if (length < value + 1)
560 bytestream2_skip(gb, value + 1 - length);
561 } else if (value > -128) {
562 length = FFMIN(-value + 1, dst_size - x);
563 memset(dst + x, bytestream2_get_byte(gb), length);
570 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
571 memset(dst+x, 0, dst_size - x);
573 return bytestream2_tell(gb);
576 static int decode_byterun2(uint8_t *dst, int height, int line_size,
581 int i, y_pos = 0, x_pos = 0;
583 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
586 bytestream2_skip(gb, 4);
587 count = bytestream2_get_be16(gb) - 2;
588 if (bytestream2_get_bytes_left(gb) < count)
591 bytestream2_init(&cmds, gb->buffer, count);
592 bytestream2_skip(gb, count);
594 for (i = 0; i < count && x_pos < line_size; i++) {
595 int8_t cmd = bytestream2_get_byte(&cmds);
599 l = bytestream2_get_be16(gb);
600 while (l-- > 0 && x_pos < line_size) {
601 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
602 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
603 if (y_pos >= height) {
608 } else if (cmd < 0) {
610 while (l-- > 0 && x_pos < line_size) {
611 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
612 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
613 if (y_pos >= height) {
618 } else if (cmd == 1) {
619 l = bytestream2_get_be16(gb);
620 r = bytestream2_get_be16(gb);
621 while (l-- > 0 && x_pos < line_size) {
622 dst[x_pos + y_pos * line_size ] = r >> 8;
623 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
624 if (y_pos >= height) {
631 r = bytestream2_get_be16(gb);
632 while (l-- > 0 && x_pos < line_size) {
633 dst[x_pos + y_pos * line_size ] = r >> 8;
634 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
635 if (y_pos >= height) {
643 return bytestream2_tell(gb);
646 #define DECODE_RGBX_COMMON(type) \
648 length = bytestream2_get_byte(gb); \
650 length = bytestream2_get_be16(gb); \
655 for (i = 0; i < length; i++) { \
656 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
668 * @param[out] dst Destination buffer
669 * @param width Width of destination buffer (pixels)
670 * @param height Height of destination buffer (pixels)
671 * @param linesize Line size of destination buffer (bytes)
673 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
675 int x = 0, y = 0, i, length;
676 while (bytestream2_get_bytes_left(gb) >= 4) {
677 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
678 length = bytestream2_get_byte(gb) & 0x7F;
679 DECODE_RGBX_COMMON(uint32_t)
685 * @param[out] dst Destination buffer
686 * @param width Width of destination buffer (pixels)
687 * @param height Height of destination buffer (pixels)
688 * @param linesize Line size of destination buffer (bytes)
690 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
692 int x = 0, y = 0, i, length;
693 while (bytestream2_get_bytes_left(gb) >= 2) {
694 uint32_t pixel = bytestream2_get_be16u(gb);
695 length = pixel & 0x7;
697 DECODE_RGBX_COMMON(uint16_t)
702 * Decode DEEP RLE 32-bit buffer
703 * @param[out] dst Destination buffer
704 * @param[in] src Source buffer
705 * @param src_size Source buffer size (bytes)
706 * @param width Width of destination buffer (pixels)
707 * @param height Height of destination buffer (pixels)
708 * @param linesize Line size of destination buffer (bytes)
710 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
712 const uint8_t *src_end = src + src_size;
714 while (src + 5 <= src_end) {
716 opcode = *(int8_t *)src++;
718 int size = opcode + 1;
719 for (i = 0; i < size; i++) {
720 int length = FFMIN(size - i, width);
721 memcpy(dst + y*linesize + x * 4, src, length * 4);
733 int size = -opcode + 1;
734 uint32_t pixel = AV_RN32(src);
735 for (i = 0; i < size; i++) {
736 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
751 * Decode DEEP TVDC 32-bit buffer
752 * @param[out] dst Destination buffer
753 * @param[in] src Source buffer
754 * @param src_size Source buffer size (bytes)
755 * @param width Width of destination buffer (pixels)
756 * @param height Height of destination buffer (pixels)
757 * @param linesize Line size of destination buffer (bytes)
758 * @param[int] tvdc TVDC lookup table
760 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)
762 int x = 0, y = 0, plane = 0;
766 for (i = 0; i < src_size * 2;) {
767 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
768 int d = tvdc[GETNIBBLE];
772 dst[y * linesize + x*4 + plane] = pixel;
775 if (i >= src_size * 2)
779 d = FFMIN(d, width - x);
780 for (j = 0; j < d; j++) {
781 dst[y * linesize + x*4 + plane] = pixel;
800 static void decode_short_horizontal_delta(uint8_t *dst,
801 const uint8_t *buf, const uint8_t *buf_end,
802 int w, int bpp, int dst_size)
804 int planepitch = FFALIGN(w, 16) >> 3;
805 int pitch = planepitch * bpp;
806 GetByteContext ptrs, gb;
808 unsigned ofssrc, pos;
811 bytestream2_init(&ptrs, buf, buf_end - buf);
812 bytestream2_init_writer(&pb, dst, dst_size);
814 for (k = 0; k < bpp; k++) {
815 ofssrc = bytestream2_get_be32(&ptrs);
821 if (ofssrc >= buf_end - buf)
824 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
825 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
826 int16_t offset = bytestream2_get_be16(&gb);
830 unsigned data = bytestream2_get_be16(&gb);
833 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
834 bytestream2_seek_p(&pb, noffset, SEEK_SET);
835 bytestream2_put_be16(&pb, data);
837 uint16_t count = bytestream2_get_be16(&gb);
839 pos += 2 * -(offset + 2);
840 for (i = 0; i < count; i++) {
841 uint16_t data = bytestream2_get_be16(&gb);
844 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
845 bytestream2_seek_p(&pb, noffset, SEEK_SET);
846 bytestream2_put_be16(&pb, data);
853 static void decode_byte_vertical_delta(uint8_t *dst,
854 const uint8_t *buf, const uint8_t *buf_end,
855 int w, int xor, int bpp, int dst_size)
857 int ncolumns = ((w + 15) / 16) * 2;
858 int dstpitch = ncolumns * bpp;
859 unsigned ofsdst, ofssrc, opcode, x;
860 GetByteContext ptrs, gb;
864 bytestream2_init(&ptrs, buf, buf_end - buf);
865 bytestream2_init_writer(&pb, dst, dst_size);
867 for (k = 0; k < bpp; k++) {
868 ofssrc = bytestream2_get_be32(&ptrs);
873 if (ofssrc >= buf_end - buf)
876 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
877 for (j = 0; j < ncolumns; j++) {
878 ofsdst = j + k * ncolumns;
880 i = bytestream2_get_byte(&gb);
882 opcode = bytestream2_get_byte(&gb);
885 opcode = bytestream2_get_byte(&gb);
886 x = bytestream2_get_byte(&gb);
889 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
890 if (xor && ofsdst < dst_size) {
891 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
893 bytestream2_put_byte(&pb, x);
898 } else if (opcode < 0x80) {
899 ofsdst += opcode * dstpitch;
904 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
905 if (xor && ofsdst < dst_size) {
906 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
908 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
920 static void decode_delta_j(uint8_t *dst,
921 const uint8_t *buf, const uint8_t *buf_end,
922 int w, int h, int bpp, int dst_size)
926 uint32_t type, flag, cols, groups, rows, bytes;
928 int planepitch_byte = (w + 7) / 8;
929 int planepitch = ((w + 15) / 16) * 2;
930 int kludge_j, b, g, r, d;
933 pitch = planepitch * bpp;
934 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
936 bytestream2_init(&gb, buf, buf_end - buf);
938 while (bytestream2_get_bytes_left(&gb) >= 2) {
939 type = bytestream2_get_be16(&gb);
945 flag = bytestream2_get_be16(&gb);
946 cols = bytestream2_get_be16(&gb);
947 groups = bytestream2_get_be16(&gb);
949 for (g = 0; g < groups; g++) {
950 offset = bytestream2_get_be16(&gb);
952 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
953 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
958 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
960 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
962 for (b = 0; b < cols; b++) {
963 for (d = 0; d < bpp; d++) {
964 uint8_t value = bytestream2_get_byte(&gb);
966 if (offset >= dst_size)
975 offset += planepitch;
978 if ((cols * bpp) & 1)
979 bytestream2_skip(&gb, 1);
983 flag = bytestream2_get_be16(&gb);
984 rows = bytestream2_get_be16(&gb);
985 bytes = bytestream2_get_be16(&gb);
986 groups = bytestream2_get_be16(&gb);
988 for (g = 0; g < groups; g++) {
989 offset = bytestream2_get_be16(&gb);
992 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
994 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
996 for (r = 0; r < rows; r++) {
997 for (d = 0; d < bpp; d++) {
998 unsigned noffset = offset + (r * pitch) + d * planepitch;
1000 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1001 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1005 for (b = 0; b < bytes; b++) {
1006 uint8_t value = bytestream2_get_byte(&gb);
1008 if (noffset >= dst_size)
1010 ptr = dst + noffset;
1021 if ((rows * bytes * bpp) & 1)
1022 bytestream2_skip(&gb, 1);
1031 static void decode_short_vertical_delta(uint8_t *dst,
1032 const uint8_t *buf, const uint8_t *buf_end,
1033 int w, int bpp, int dst_size)
1035 int ncolumns = (w + 15) >> 4;
1036 int dstpitch = ncolumns * bpp * 2;
1037 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1038 GetByteContext ptrs, gb, dptrs, dgb;
1042 if (buf_end - buf <= 64)
1045 bytestream2_init(&ptrs, buf, buf_end - buf);
1046 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1047 bytestream2_init_writer(&pb, dst, dst_size);
1049 for (k = 0; k < bpp; k++) {
1050 ofssrc = bytestream2_get_be32(&ptrs);
1051 ofsdata = bytestream2_get_be32(&dptrs);
1056 if (ofssrc >= buf_end - buf)
1059 if (ofsdata >= buf_end - buf)
1062 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1063 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1064 for (j = 0; j < ncolumns; j++) {
1065 ofsdst = (j + k * ncolumns) * 2;
1067 i = bytestream2_get_byte(&gb);
1069 opcode = bytestream2_get_byte(&gb);
1072 opcode = bytestream2_get_byte(&gb);
1073 x = bytestream2_get_be16(&dgb);
1076 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1077 bytestream2_put_be16(&pb, x);
1081 } else if (opcode < 0x80) {
1082 ofsdst += opcode * dstpitch;
1087 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1088 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1099 static void decode_long_vertical_delta(uint8_t *dst,
1100 const uint8_t *buf, const uint8_t *buf_end,
1101 int w, int bpp, int dst_size)
1103 int ncolumns = (w + 31) >> 5;
1104 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1105 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1106 GetByteContext ptrs, gb, dptrs, dgb;
1110 if (buf_end - buf <= 64)
1113 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1114 bytestream2_init(&ptrs, buf, buf_end - buf);
1115 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1116 bytestream2_init_writer(&pb, dst, dst_size);
1118 for (k = 0; k < bpp; k++) {
1119 ofssrc = bytestream2_get_be32(&ptrs);
1120 ofsdata = bytestream2_get_be32(&dptrs);
1125 if (ofssrc >= buf_end - buf)
1128 if (ofsdata >= buf_end - buf)
1131 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1132 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1133 for (j = 0; j < ncolumns; j++) {
1134 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1136 i = bytestream2_get_byte(&gb);
1138 opcode = bytestream2_get_byte(&gb);
1141 opcode = bytestream2_get_byte(&gb);
1142 if (h && (j == (ncolumns - 1))) {
1143 x = bytestream2_get_be16(&dgb);
1144 bytestream2_skip(&dgb, 2);
1146 x = bytestream2_get_be32(&dgb);
1149 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1153 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1154 if (h && (j == (ncolumns - 1))) {
1155 bytestream2_put_be16(&pb, x);
1157 bytestream2_put_be32(&pb, x);
1162 } else if (opcode < 0x80) {
1163 ofsdst += opcode * dstpitch;
1168 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1169 if (h && (j == (ncolumns - 1))) {
1170 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1171 bytestream2_skip(&dgb, 2);
1173 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1185 static void decode_short_vertical_delta2(uint8_t *dst,
1186 const uint8_t *buf, const uint8_t *buf_end,
1187 int w, int bpp, int dst_size)
1189 int ncolumns = (w + 15) >> 4;
1190 int dstpitch = ncolumns * bpp * 2;
1191 unsigned ofsdst, ofssrc, opcode, x;
1192 GetByteContext ptrs, gb;
1196 bytestream2_init(&ptrs, buf, buf_end - buf);
1197 bytestream2_init_writer(&pb, dst, dst_size);
1199 for (k = 0; k < bpp; k++) {
1200 ofssrc = bytestream2_get_be32(&ptrs);
1205 if (ofssrc >= buf_end - buf)
1208 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1209 for (j = 0; j < ncolumns; j++) {
1210 ofsdst = (j + k * ncolumns) * 2;
1212 i = bytestream2_get_be16(&gb);
1213 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1214 opcode = bytestream2_get_be16(&gb);
1217 opcode = bytestream2_get_be16(&gb);
1218 x = bytestream2_get_be16(&gb);
1220 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1221 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1222 bytestream2_put_be16(&pb, x);
1226 } else if (opcode < 0x8000) {
1227 ofsdst += opcode * dstpitch;
1231 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1232 bytestream2_get_bytes_left_p(&pb) > 1) {
1233 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1234 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1245 static void decode_long_vertical_delta2(uint8_t *dst,
1246 const uint8_t *buf, const uint8_t *buf_end,
1247 int w, int bpp, int dst_size)
1249 int ncolumns = (w + 31) >> 5;
1250 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1251 unsigned ofsdst, ofssrc, opcode, x;
1252 unsigned skip = 0x80000000, mask = skip - 1;
1253 GetByteContext ptrs, gb;
1257 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1258 bytestream2_init(&ptrs, buf, buf_end - buf);
1259 bytestream2_init_writer(&pb, dst, dst_size);
1261 for (k = 0; k < bpp; k++) {
1262 ofssrc = bytestream2_get_be32(&ptrs);
1267 if (ofssrc >= buf_end - buf)
1270 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1271 for (j = 0; j < ncolumns; j++) {
1272 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1274 if (h && (j == (ncolumns - 1))) {
1279 i = bytestream2_get_be32(&gb);
1280 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1281 opcode = bytestream2_get_be32(&gb);
1284 if (h && (j == ncolumns - 1)) {
1285 opcode = bytestream2_get_be16(&gb);
1286 x = bytestream2_get_be16(&gb);
1288 opcode = bytestream2_get_be32(&gb);
1289 x = bytestream2_get_be32(&gb);
1292 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1295 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1296 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1297 if (h && (j == ncolumns - 1))
1298 bytestream2_put_be16(&pb, x);
1300 bytestream2_put_be32(&pb, x);
1304 } else if (opcode < skip) {
1305 ofsdst += opcode * dstpitch;
1309 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1310 bytestream2_get_bytes_left_p(&pb) > 1) {
1311 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1312 if (h && (j == ncolumns - 1)) {
1313 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1315 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1327 static void decode_delta_d(uint8_t *dst,
1328 const uint8_t *buf, const uint8_t *buf_end,
1329 int w, int flag, int bpp, int dst_size)
1331 int planepitch = FFALIGN(w, 16) >> 3;
1332 int pitch = planepitch * bpp;
1333 int planepitch_byte = (w + 7) / 8;
1334 unsigned entries, ofssrc;
1335 GetByteContext gb, ptrs;
1339 if (buf_end - buf <= 4 * bpp)
1342 bytestream2_init_writer(&pb, dst, dst_size);
1343 bytestream2_init(&ptrs, buf, bpp * 4);
1345 for (k = 0; k < bpp; k++) {
1346 ofssrc = bytestream2_get_be32(&ptrs);
1351 if (ofssrc >= buf_end - buf)
1354 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1356 entries = bytestream2_get_be32(&gb);
1357 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1358 int32_t opcode = bytestream2_get_be32(&gb);
1359 unsigned offset = bytestream2_get_be32(&gb);
1361 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1363 uint32_t x = bytestream2_get_be32(&gb);
1364 if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1366 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1367 bytestream2_put_be32(&pb, x);
1368 bytestream2_skip_p(&pb, pitch - 4);
1373 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1374 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1375 bytestream2_skip_p(&pb, pitch - 4);
1384 static void decode_delta_e(uint8_t *dst,
1385 const uint8_t *buf, const uint8_t *buf_end,
1386 int w, int flag, int bpp, int dst_size)
1388 int planepitch = FFALIGN(w, 16) >> 3;
1389 int pitch = planepitch * bpp;
1390 int planepitch_byte = (w + 7) / 8;
1391 unsigned entries, ofssrc;
1392 GetByteContext gb, ptrs;
1396 if (buf_end - buf <= 4 * bpp)
1399 bytestream2_init_writer(&pb, dst, dst_size);
1400 bytestream2_init(&ptrs, buf, bpp * 4);
1402 for (k = 0; k < bpp; k++) {
1403 ofssrc = bytestream2_get_be32(&ptrs);
1408 if (ofssrc >= buf_end - buf)
1411 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1413 entries = bytestream2_get_be16(&gb);
1414 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1415 int16_t opcode = bytestream2_get_be16(&gb);
1416 unsigned offset = bytestream2_get_be32(&gb);
1418 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1420 uint16_t x = bytestream2_get_be16(&gb);
1421 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1422 bytestream2_put_be16(&pb, x);
1423 bytestream2_skip_p(&pb, pitch - 2);
1428 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1429 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1430 bytestream2_skip_p(&pb, pitch - 2);
1439 static void decode_delta_l(uint8_t *dst,
1440 const uint8_t *buf, const uint8_t *buf_end,
1441 int w, int flag, int bpp, int dst_size)
1443 GetByteContext off0, off1, dgb, ogb;
1445 unsigned poff0, poff1;
1447 int planepitch_byte = (w + 7) / 8;
1448 int planepitch = ((w + 15) / 16) * 2;
1449 int pitch = planepitch * bpp;
1451 if (buf_end - buf <= 64)
1454 bytestream2_init(&off0, buf, buf_end - buf);
1455 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1456 bytestream2_init_writer(&pb, dst, dst_size);
1458 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1460 for (k = 0; k < bpp; k++) {
1461 poff0 = bytestream2_get_be32(&off0);
1462 poff1 = bytestream2_get_be32(&off1);
1467 if (2LL * poff0 >= buf_end - buf)
1470 if (2LL * poff1 >= buf_end - buf)
1473 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1474 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1476 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1477 uint32_t offset = bytestream2_get_be16(&ogb);
1478 int16_t cnt = bytestream2_get_be16(&ogb);
1481 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1483 if (bytestream2_get_bytes_left(&dgb) < 2)
1485 bytestream2_seek_p(&pb, offset, SEEK_SET);
1487 data = bytestream2_get_be16(&dgb);
1488 for (i = 0; i < cnt; i++) {
1489 bytestream2_put_be16(&pb, data);
1490 bytestream2_skip_p(&pb, dstpitch - 2);
1493 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1495 bytestream2_seek_p(&pb, offset, SEEK_SET);
1496 for (i = 0; i < cnt; i++) {
1497 data = bytestream2_get_be16(&dgb);
1498 bytestream2_put_be16(&pb, data);
1499 bytestream2_skip_p(&pb, dstpitch - 2);
1506 static int unsupported(AVCodecContext *avctx)
1508 IffContext *s = avctx->priv_data;
1509 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1510 return AVERROR_INVALIDDATA;
1513 static int decode_frame(AVCodecContext *avctx,
1514 void *data, int *got_frame,
1517 IffContext *s = avctx->priv_data;
1518 AVFrame *frame = data;
1519 const uint8_t *buf = avpkt->data;
1520 int buf_size = avpkt->size;
1521 const uint8_t *buf_end = buf + buf_size;
1523 GetByteContext *gb = &s->gb;
1524 const AVPixFmtDescriptor *desc;
1526 bytestream2_init(gb, avpkt->data, avpkt->size);
1528 if ((res = extract_header(avctx, avpkt)) < 0)
1531 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1535 buf += bytestream2_tell(gb);
1536 buf_size -= bytestream2_tell(gb);
1537 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1539 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1540 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1541 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1543 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1544 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1545 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1550 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1551 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1552 memcpy(s->pal, s->frame->data[1], 256 * 4);
1555 switch (s->compression) {
1557 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1558 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1559 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1560 for (plane = 0; plane < s->bpp; plane++) {
1561 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1562 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1563 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1564 buf += s->planesize;
1567 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1568 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1569 for (y = 0; y < avctx->height; y++) {
1570 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1571 memset(s->ham_buf, 0, s->planesize * 8);
1572 for (plane = 0; plane < s->bpp; plane++) {
1573 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1574 if (start >= buf_end)
1576 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1578 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1581 return unsupported(avctx);
1582 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1583 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1585 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1586 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1587 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1589 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1590 for (x = 0; x < avctx->width; x++)
1591 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1594 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1595 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1596 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1597 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1598 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1599 for (y = 0; y < avctx->height; y++) {
1600 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1601 memset(row, 0, avctx->width);
1602 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1603 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1604 buf += s->planesize;
1607 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1608 for (y = 0; y < avctx->height; y++) {
1609 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1610 memset(s->ham_buf, 0, s->planesize * 8);
1611 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1612 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1613 buf += s->planesize;
1615 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1617 } else { // AV_PIX_FMT_BGR32
1618 for (y = 0; y < avctx->height; y++) {
1619 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1620 memset(row, 0, avctx->width << 2);
1621 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1622 decodeplane32((uint32_t *)row, buf,
1623 FFMIN(s->planesize, buf_end - buf), plane);
1624 buf += s->planesize;
1628 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1629 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1630 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1631 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1632 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1633 buf += avctx->width + (avctx->width % 2); // padding if odd
1635 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1636 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1637 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1638 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1639 buf += avctx->width + (avctx->width & 1); // padding if odd
1640 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1643 return unsupported(avctx);
1645 return unsupported(avctx);
1649 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1650 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1651 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1652 uint8_t *video = s->video[0];
1654 for (y = 0; y < avctx->height; y++) {
1655 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1656 memset(row, 0, avctx->width);
1657 for (plane = 0; plane < s->bpp; plane++) {
1658 buf += decode_byterun(s->planebuf, s->planesize, gb);
1659 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1660 memcpy(video, s->planebuf, s->planesize);
1661 video += s->planesize;
1663 decodeplane8(row, s->planebuf, s->planesize, plane);
1666 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1667 for (y = 0; y < avctx->height; y++) {
1668 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1669 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1670 for (plane = 0; plane < s->bpp; plane++) {
1671 buf += decode_byterun(s->planebuf, s->planesize, gb);
1672 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1674 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1676 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1677 uint8_t *video = s->video[0];
1678 for (y = 0; y < avctx->height; y++) {
1679 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1680 memset(s->ham_buf, 0, s->planesize * 8);
1681 for (plane = 0; plane < s->bpp; plane++) {
1682 buf += decode_byterun(s->planebuf, s->planesize, gb);
1683 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1684 memcpy(video, s->planebuf, s->planesize);
1685 video += s->planesize;
1687 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1689 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1691 } else { // AV_PIX_FMT_BGR32
1692 for (y = 0; y < avctx->height; y++) {
1693 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1694 memset(row, 0, avctx->width << 2);
1695 for (plane = 0; plane < s->bpp; plane++) {
1696 buf += decode_byterun(s->planebuf, s->planesize, gb);
1697 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1701 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1702 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1703 for (y = 0; y < avctx->height; y++) {
1704 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1705 buf += decode_byterun(row, avctx->width, gb);
1707 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1708 for (y = 0; y < avctx->height; y++) {
1709 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1710 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1711 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1714 return unsupported(avctx);
1715 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1716 if (av_get_bits_per_pixel(desc) == 32)
1717 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1719 return unsupported(avctx);
1720 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1721 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1722 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1723 for (plane = 0; plane < s->bpp; plane++) {
1724 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1725 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1726 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1727 buf += s->planesize;
1730 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1731 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1732 for (y = 0; y < avctx->height; y++) {
1733 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1734 memset(s->ham_buf, 0, s->planesize * 8);
1735 for (plane = 0; plane < s->bpp; plane++) {
1736 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1737 if (start >= buf_end)
1739 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1741 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1744 return unsupported(avctx);
1747 return unsupported(avctx);
1751 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1752 for (plane = 0; plane < s->bpp; plane++) {
1753 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1754 for (y = 0; y < avctx->height; y++) {
1755 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1756 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1760 return unsupported(avctx);
1764 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1765 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1766 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1767 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1769 return unsupported(avctx);
1772 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1773 if (av_get_bits_per_pixel(desc) == 32)
1774 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1776 return unsupported(avctx);
1778 return unsupported(avctx);
1782 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1786 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1791 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1793 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1798 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1800 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1804 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1808 if (s->is_interlaced)
1809 return unsupported(avctx);
1810 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1814 if (s->is_interlaced)
1815 return unsupported(avctx);
1816 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1820 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1823 return unsupported(avctx);
1826 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1827 memcpy(s->video[1], s->video[0], s->video_size);
1830 if (s->compression > 0xff) {
1831 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1833 for (y = 0; y < avctx->height; y++) {
1834 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1835 memset(row, 0, avctx->width);
1836 for (plane = 0; plane < s->bpp; plane++) {
1837 decodeplane8(row, buf, s->planesize, plane);
1838 buf += s->planesize;
1841 memcpy(frame->data[1], s->pal, 256 * 4);
1842 } else if (s->ham) {
1843 int i, count = 1 << s->ham;
1846 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1847 for (i = 0; i < count; i++) {
1848 s->ham_palbuf[i*2+1] = s->pal[i];
1850 for (i = 0; i < count; i++) {
1851 uint32_t tmp = i << (8 - s->ham);
1852 tmp |= tmp >> s->ham;
1853 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1854 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1855 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1856 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1857 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1858 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1860 if (s->masking == MASK_HAS_MASK) {
1861 for (i = 0; i < 8 * (1 << s->ham); i++)
1862 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1864 for (y = 0; y < avctx->height; y++) {
1865 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1866 memset(s->ham_buf, 0, s->planesize * 8);
1867 for (plane = 0; plane < s->bpp; plane++) {
1868 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1869 buf += s->planesize;
1871 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1874 return unsupported(avctx);
1878 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1882 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1883 frame->key_frame = 1;
1884 frame->pict_type = AV_PICTURE_TYPE_I;
1886 frame->key_frame = 0;
1887 frame->pict_type = AV_PICTURE_TYPE_P;
1895 #if CONFIG_IFF_ILBM_DECODER
1896 AVCodec ff_iff_ilbm_decoder = {
1898 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1899 .type = AVMEDIA_TYPE_VIDEO,
1900 .id = AV_CODEC_ID_IFF_ILBM,
1901 .priv_data_size = sizeof(IffContext),
1902 .init = decode_init,
1903 .close = decode_end,
1904 .decode = decode_frame,
1905 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1906 .capabilities = AV_CODEC_CAP_DR1,