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);
337 if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ') && s->ham == 4)
340 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
342 return AVERROR(ENOMEM);
344 ham_count = 8 * (1 << s->ham);
345 s->ham_palbuf = av_malloc(extra_space * (ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
346 if (!s->ham_palbuf) {
347 av_freep(&s->ham_buf);
348 return AVERROR(ENOMEM);
351 if (count) { // HAM with color palette attached
352 // prefill with black and palette and set HAM take direct value mask to zero
353 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
354 for (i=0; i < count; i++) {
355 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
358 } else { // HAM with grayscale color palette
360 for (i=0; i < count; i++) {
361 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
362 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
365 for (i=0; i < count; i++) {
366 uint32_t tmp = i << (8 - s->ham);
367 tmp |= tmp >> s->ham;
368 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
369 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
370 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
371 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
372 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
373 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
375 if (s->masking == MASK_HAS_MASK) {
376 for (i = 0; i < ham_count; i++)
377 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
385 static av_cold int decode_end(AVCodecContext *avctx)
387 IffContext *s = avctx->priv_data;
388 av_freep(&s->planebuf);
389 av_freep(&s->ham_buf);
390 av_freep(&s->ham_palbuf);
391 av_freep(&s->mask_buf);
392 av_freep(&s->mask_palbuf);
393 av_freep(&s->video[0]);
394 av_freep(&s->video[1]);
399 static av_cold int decode_init(AVCodecContext *avctx)
401 IffContext *s = avctx->priv_data;
404 if (avctx->bits_per_coded_sample <= 8) {
407 if (avctx->extradata_size >= 2)
408 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
411 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
412 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
413 } else if (avctx->bits_per_coded_sample <= 32) {
414 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
415 avctx->pix_fmt = AV_PIX_FMT_RGB32;
416 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
417 avctx->pix_fmt = AV_PIX_FMT_RGB444;
418 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
419 if (avctx->bits_per_coded_sample == 24) {
420 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
421 } else if (avctx->bits_per_coded_sample == 32) {
422 avctx->pix_fmt = AV_PIX_FMT_BGR32;
424 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
425 return AVERROR_PATCHWELCOME;
429 return AVERROR_INVALIDDATA;
432 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
434 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
435 s->planebuf = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
437 return AVERROR(ENOMEM);
439 s->bpp = avctx->bits_per_coded_sample;
441 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
442 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
444 return AVERROR_INVALIDDATA;
445 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
446 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
447 s->pal = av_calloc(256, sizeof(*s->pal));
448 if (!s->video[0] || !s->video[1] || !s->pal)
449 return AVERROR(ENOMEM);
452 if ((err = extract_header(avctx, NULL)) < 0)
459 * Decode interleaved plane buffer up to 8bpp
460 * @param dst Destination buffer
461 * @param buf Source buffer
463 * @param plane plane number to decode as
465 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
469 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
472 lut = plane8_lut[plane];
474 uint64_t v = AV_RN64A(dst) | lut[*buf++];
477 } while (--buf_size);
481 * Decode interleaved plane buffer up to 24bpp
482 * @param dst Destination buffer
483 * @param buf Source buffer
485 * @param plane plane number to decode as
487 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
489 const uint32_t *lut = plane32_lut[plane];
491 unsigned mask = (*buf >> 2) & ~3;
492 dst[0] |= lut[mask++];
493 dst[1] |= lut[mask++];
494 dst[2] |= lut[mask++];
496 mask = (*buf++ << 2) & 0x3F;
497 dst[4] |= lut[mask++];
498 dst[5] |= lut[mask++];
499 dst[6] |= lut[mask++];
502 } while (--buf_size);
505 #define DECODE_HAM_PLANE32(x) \
506 first = buf[x] << 1; \
507 second = buf[(x)+1] << 1; \
508 delta &= pal[first++]; \
509 delta |= pal[first]; \
511 delta &= pal[second++]; \
512 delta |= pal[second]; \
516 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
518 * @param dst the destination 24bpp buffer
519 * @param buf the source 8bpp chunky buffer
520 * @param pal the HAM decode table
521 * @param buf_size the plane size in bytes
523 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
524 const uint32_t *const pal, unsigned buf_size)
526 uint32_t delta = pal[1]; /* first palette entry */
528 uint32_t first, second;
529 DECODE_HAM_PLANE32(0);
530 DECODE_HAM_PLANE32(2);
531 DECODE_HAM_PLANE32(4);
532 DECODE_HAM_PLANE32(6);
535 } while (--buf_size);
538 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
539 const uint32_t *const pal, unsigned width)
542 *dst++ = pal[*buf++];
547 * Decode one complete byterun1 encoded line.
549 * @param dst the destination buffer where to store decompressed bitstream
550 * @param dst_size the destination plane size in bytes
551 * @param buf the source byterun1 compressed bitstream
552 * @param buf_end the EOF of source byterun1 compressed bitstream
553 * @return number of consumed bytes in byterun1 compressed bitstream
555 static int decode_byterun(uint8_t *dst, int dst_size,
559 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
561 const int8_t value = bytestream2_get_byte(gb);
563 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
564 bytestream2_get_buffer(gb, dst + x, length);
565 if (length < value + 1)
566 bytestream2_skip(gb, value + 1 - length);
567 } else if (value > -128) {
568 length = FFMIN(-value + 1, dst_size - x);
569 memset(dst + x, bytestream2_get_byte(gb), length);
576 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
577 memset(dst+x, 0, dst_size - x);
579 return bytestream2_tell(gb);
582 static int decode_byterun2(uint8_t *dst, int height, int line_size,
587 int i, y_pos = 0, x_pos = 0;
589 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
592 bytestream2_skip(gb, 4);
593 count = bytestream2_get_be16(gb) - 2;
594 if (bytestream2_get_bytes_left(gb) < count)
597 bytestream2_init(&cmds, gb->buffer, count);
598 bytestream2_skip(gb, count);
600 for (i = 0; i < count && x_pos < line_size; i++) {
601 int8_t cmd = bytestream2_get_byte(&cmds);
605 l = bytestream2_get_be16(gb);
606 while (l-- > 0 && x_pos < line_size) {
607 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
608 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
609 if (y_pos >= height) {
614 } else if (cmd < 0) {
616 while (l-- > 0 && x_pos < line_size) {
617 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
618 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
619 if (y_pos >= height) {
624 } else if (cmd == 1) {
625 l = bytestream2_get_be16(gb);
626 r = bytestream2_get_be16(gb);
627 while (l-- > 0 && x_pos < line_size) {
628 dst[x_pos + y_pos * line_size ] = r >> 8;
629 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
630 if (y_pos >= height) {
637 r = bytestream2_get_be16(gb);
638 while (l-- > 0 && x_pos < line_size) {
639 dst[x_pos + y_pos * line_size ] = r >> 8;
640 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
641 if (y_pos >= height) {
649 return bytestream2_tell(gb);
652 #define DECODE_RGBX_COMMON(type) \
654 length = bytestream2_get_byte(gb); \
656 length = bytestream2_get_be16(gb); \
661 for (i = 0; i < length; i++) { \
662 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
674 * @param[out] dst Destination buffer
675 * @param width Width of destination buffer (pixels)
676 * @param height Height of destination buffer (pixels)
677 * @param linesize Line size of destination buffer (bytes)
679 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
681 int x = 0, y = 0, i, length;
682 while (bytestream2_get_bytes_left(gb) >= 4) {
683 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
684 length = bytestream2_get_byte(gb) & 0x7F;
685 DECODE_RGBX_COMMON(uint32_t)
691 * @param[out] dst Destination buffer
692 * @param width Width of destination buffer (pixels)
693 * @param height Height of destination buffer (pixels)
694 * @param linesize Line size of destination buffer (bytes)
696 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
698 int x = 0, y = 0, i, length;
699 while (bytestream2_get_bytes_left(gb) >= 2) {
700 uint32_t pixel = bytestream2_get_be16u(gb);
701 length = pixel & 0x7;
703 DECODE_RGBX_COMMON(uint16_t)
708 * Decode DEEP RLE 32-bit buffer
709 * @param[out] dst Destination buffer
710 * @param[in] src Source buffer
711 * @param src_size Source buffer size (bytes)
712 * @param width Width of destination buffer (pixels)
713 * @param height Height of destination buffer (pixels)
714 * @param linesize Line size of destination buffer (bytes)
716 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
718 const uint8_t *src_end = src + src_size;
720 while (src_end - src >= 5) {
722 opcode = *(int8_t *)src++;
724 int size = opcode + 1;
725 for (i = 0; i < size; i++) {
726 int length = FFMIN(size - i, width - x);
727 if (src_end - src < length * 4)
729 memcpy(dst + y*linesize + x * 4, src, length * 4);
741 int size = -opcode + 1;
742 uint32_t pixel = AV_RN32(src);
743 for (i = 0; i < size; i++) {
744 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
759 * Decode DEEP TVDC 32-bit buffer
760 * @param[out] dst Destination buffer
761 * @param[in] src Source buffer
762 * @param src_size Source buffer size (bytes)
763 * @param width Width of destination buffer (pixels)
764 * @param height Height of destination buffer (pixels)
765 * @param linesize Line size of destination buffer (bytes)
766 * @param[int] tvdc TVDC lookup table
768 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)
770 int x = 0, y = 0, plane = 0;
774 for (i = 0; i < src_size * 2;) {
775 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
776 int d = tvdc[GETNIBBLE];
780 dst[y * linesize + x*4 + plane] = pixel;
783 if (i >= src_size * 2)
787 d = FFMIN(d, width - x);
788 for (j = 0; j < d; j++) {
789 dst[y * linesize + x*4 + plane] = pixel;
808 static void decode_short_horizontal_delta(uint8_t *dst,
809 const uint8_t *buf, const uint8_t *buf_end,
810 int w, int bpp, int dst_size)
812 int planepitch = FFALIGN(w, 16) >> 3;
813 int pitch = planepitch * bpp;
814 GetByteContext ptrs, gb;
816 unsigned ofssrc, pos;
819 bytestream2_init(&ptrs, buf, buf_end - buf);
820 bytestream2_init_writer(&pb, dst, dst_size);
822 for (k = 0; k < bpp; k++) {
823 ofssrc = bytestream2_get_be32(&ptrs);
829 if (ofssrc >= buf_end - buf)
832 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
833 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
834 int16_t offset = bytestream2_get_be16(&gb);
838 unsigned data = bytestream2_get_be16(&gb);
841 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
842 bytestream2_seek_p(&pb, noffset, SEEK_SET);
843 bytestream2_put_be16(&pb, data);
845 uint16_t count = bytestream2_get_be16(&gb);
847 pos += 2 * -(offset + 2);
848 for (i = 0; i < count; i++) {
849 uint16_t data = bytestream2_get_be16(&gb);
852 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
853 bytestream2_seek_p(&pb, noffset, SEEK_SET);
854 bytestream2_put_be16(&pb, data);
861 static void decode_byte_vertical_delta(uint8_t *dst,
862 const uint8_t *buf, const uint8_t *buf_end,
863 int w, int xor, int bpp, int dst_size)
865 int ncolumns = ((w + 15) / 16) * 2;
866 int dstpitch = ncolumns * bpp;
867 unsigned ofsdst, ofssrc, opcode, x;
868 GetByteContext ptrs, gb;
872 bytestream2_init(&ptrs, buf, buf_end - buf);
873 bytestream2_init_writer(&pb, dst, dst_size);
875 for (k = 0; k < bpp; k++) {
876 ofssrc = bytestream2_get_be32(&ptrs);
881 if (ofssrc >= buf_end - buf)
884 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
885 for (j = 0; j < ncolumns; j++) {
886 ofsdst = j + k * ncolumns;
888 i = bytestream2_get_byte(&gb);
890 opcode = bytestream2_get_byte(&gb);
893 opcode = bytestream2_get_byte(&gb);
894 x = bytestream2_get_byte(&gb);
897 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
898 if (xor && ofsdst < dst_size) {
899 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
901 bytestream2_put_byte(&pb, x);
906 } else if (opcode < 0x80) {
907 ofsdst += opcode * dstpitch;
912 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
913 if (xor && ofsdst < dst_size) {
914 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
916 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
928 static void decode_delta_j(uint8_t *dst,
929 const uint8_t *buf, const uint8_t *buf_end,
930 int w, int h, int bpp, int dst_size)
934 uint32_t type, flag, cols, groups, rows, bytes;
936 int planepitch_byte = (w + 7) / 8;
937 int planepitch = ((w + 15) / 16) * 2;
938 int kludge_j, b, g, r, d;
941 pitch = planepitch * bpp;
942 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
944 bytestream2_init(&gb, buf, buf_end - buf);
946 while (bytestream2_get_bytes_left(&gb) >= 2) {
947 type = bytestream2_get_be16(&gb);
953 flag = bytestream2_get_be16(&gb);
954 cols = bytestream2_get_be16(&gb);
955 groups = bytestream2_get_be16(&gb);
957 for (g = 0; g < groups; g++) {
958 offset = bytestream2_get_be16(&gb);
960 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
961 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
966 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
968 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
970 for (b = 0; b < cols; b++) {
971 for (d = 0; d < bpp; d++) {
972 uint8_t value = bytestream2_get_byte(&gb);
974 if (offset >= dst_size)
983 offset += planepitch;
986 if ((cols * bpp) & 1)
987 bytestream2_skip(&gb, 1);
991 flag = bytestream2_get_be16(&gb);
992 rows = bytestream2_get_be16(&gb);
993 bytes = bytestream2_get_be16(&gb);
994 groups = bytestream2_get_be16(&gb);
996 for (g = 0; g < groups; g++) {
997 offset = bytestream2_get_be16(&gb);
1000 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
1002 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
1004 for (r = 0; r < rows; r++) {
1005 for (d = 0; d < bpp; d++) {
1006 unsigned noffset = offset + (r * pitch) + d * planepitch;
1008 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1009 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1013 for (b = 0; b < bytes; b++) {
1014 uint8_t value = bytestream2_get_byte(&gb);
1016 if (noffset >= dst_size)
1018 ptr = dst + noffset;
1029 if ((rows * bytes * bpp) & 1)
1030 bytestream2_skip(&gb, 1);
1039 static void decode_short_vertical_delta(uint8_t *dst,
1040 const uint8_t *buf, const uint8_t *buf_end,
1041 int w, int bpp, int dst_size)
1043 int ncolumns = (w + 15) >> 4;
1044 int dstpitch = ncolumns * bpp * 2;
1045 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1046 GetByteContext ptrs, gb, dptrs, dgb;
1050 if (buf_end - buf <= 64)
1053 bytestream2_init(&ptrs, buf, buf_end - buf);
1054 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1055 bytestream2_init_writer(&pb, dst, dst_size);
1057 for (k = 0; k < bpp; k++) {
1058 ofssrc = bytestream2_get_be32(&ptrs);
1059 ofsdata = bytestream2_get_be32(&dptrs);
1064 if (ofssrc >= buf_end - buf)
1067 if (ofsdata >= buf_end - buf)
1070 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1071 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1072 for (j = 0; j < ncolumns; j++) {
1073 ofsdst = (j + k * ncolumns) * 2;
1075 i = bytestream2_get_byte(&gb);
1077 opcode = bytestream2_get_byte(&gb);
1080 opcode = bytestream2_get_byte(&gb);
1081 x = bytestream2_get_be16(&dgb);
1084 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1085 bytestream2_put_be16(&pb, x);
1089 } else if (opcode < 0x80) {
1090 ofsdst += opcode * dstpitch;
1095 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1096 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1107 static void decode_long_vertical_delta(uint8_t *dst,
1108 const uint8_t *buf, const uint8_t *buf_end,
1109 int w, int bpp, int dst_size)
1111 int ncolumns = (w + 31) >> 5;
1112 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1113 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1114 GetByteContext ptrs, gb, dptrs, dgb;
1118 if (buf_end - buf <= 64)
1121 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1122 bytestream2_init(&ptrs, buf, buf_end - buf);
1123 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1124 bytestream2_init_writer(&pb, dst, dst_size);
1126 for (k = 0; k < bpp; k++) {
1127 ofssrc = bytestream2_get_be32(&ptrs);
1128 ofsdata = bytestream2_get_be32(&dptrs);
1133 if (ofssrc >= buf_end - buf)
1136 if (ofsdata >= buf_end - buf)
1139 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1140 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1141 for (j = 0; j < ncolumns; j++) {
1142 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1144 i = bytestream2_get_byte(&gb);
1146 opcode = bytestream2_get_byte(&gb);
1149 opcode = bytestream2_get_byte(&gb);
1150 if (h && (j == (ncolumns - 1))) {
1151 x = bytestream2_get_be16(&dgb);
1152 bytestream2_skip(&dgb, 2);
1154 x = bytestream2_get_be32(&dgb);
1157 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1161 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1162 if (h && (j == (ncolumns - 1))) {
1163 bytestream2_put_be16(&pb, x);
1165 bytestream2_put_be32(&pb, x);
1170 } else if (opcode < 0x80) {
1171 ofsdst += opcode * dstpitch;
1176 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1177 if (h && (j == (ncolumns - 1))) {
1178 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1179 bytestream2_skip(&dgb, 2);
1181 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1193 static void decode_short_vertical_delta2(uint8_t *dst,
1194 const uint8_t *buf, const uint8_t *buf_end,
1195 int w, int bpp, int dst_size)
1197 int ncolumns = (w + 15) >> 4;
1198 int dstpitch = ncolumns * bpp * 2;
1199 unsigned ofsdst, ofssrc, opcode, x;
1200 GetByteContext ptrs, gb;
1204 bytestream2_init(&ptrs, buf, buf_end - buf);
1205 bytestream2_init_writer(&pb, dst, dst_size);
1207 for (k = 0; k < bpp; k++) {
1208 ofssrc = bytestream2_get_be32(&ptrs);
1213 if (ofssrc >= buf_end - buf)
1216 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1217 for (j = 0; j < ncolumns; j++) {
1218 ofsdst = (j + k * ncolumns) * 2;
1220 i = bytestream2_get_be16(&gb);
1221 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1222 opcode = bytestream2_get_be16(&gb);
1225 opcode = bytestream2_get_be16(&gb);
1226 x = bytestream2_get_be16(&gb);
1228 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1229 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1230 bytestream2_put_be16(&pb, x);
1234 } else if (opcode < 0x8000) {
1235 ofsdst += opcode * dstpitch;
1239 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1240 bytestream2_get_bytes_left_p(&pb) > 1) {
1241 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1242 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1253 static void decode_long_vertical_delta2(uint8_t *dst,
1254 const uint8_t *buf, const uint8_t *buf_end,
1255 int w, int bpp, int dst_size)
1257 int ncolumns = (w + 31) >> 5;
1258 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1259 unsigned ofsdst, ofssrc, opcode, x;
1260 unsigned skip = 0x80000000, mask = skip - 1;
1261 GetByteContext ptrs, gb;
1265 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1266 bytestream2_init(&ptrs, buf, buf_end - buf);
1267 bytestream2_init_writer(&pb, dst, dst_size);
1269 for (k = 0; k < bpp; k++) {
1270 ofssrc = bytestream2_get_be32(&ptrs);
1275 if (ofssrc >= buf_end - buf)
1278 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1279 for (j = 0; j < ncolumns; j++) {
1280 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1282 if (h && (j == (ncolumns - 1))) {
1287 i = bytestream2_get_be32(&gb);
1288 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1289 opcode = bytestream2_get_be32(&gb);
1292 if (h && (j == ncolumns - 1)) {
1293 opcode = bytestream2_get_be16(&gb);
1294 x = bytestream2_get_be16(&gb);
1296 opcode = bytestream2_get_be32(&gb);
1297 x = bytestream2_get_be32(&gb);
1300 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1303 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1304 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1305 if (h && (j == ncolumns - 1))
1306 bytestream2_put_be16(&pb, x);
1308 bytestream2_put_be32(&pb, x);
1312 } else if (opcode < skip) {
1313 ofsdst += opcode * dstpitch;
1317 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1318 bytestream2_get_bytes_left_p(&pb) > 1) {
1319 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1320 if (h && (j == ncolumns - 1)) {
1321 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1323 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1335 static void decode_delta_d(uint8_t *dst,
1336 const uint8_t *buf, const uint8_t *buf_end,
1337 int w, int flag, int bpp, int dst_size)
1339 int planepitch = FFALIGN(w, 16) >> 3;
1340 int pitch = planepitch * bpp;
1341 int planepitch_byte = (w + 7) / 8;
1342 unsigned entries, ofssrc;
1343 GetByteContext gb, ptrs;
1347 if (buf_end - buf <= 4 * bpp)
1350 bytestream2_init_writer(&pb, dst, dst_size);
1351 bytestream2_init(&ptrs, buf, bpp * 4);
1353 for (k = 0; k < bpp; k++) {
1354 ofssrc = bytestream2_get_be32(&ptrs);
1359 if (ofssrc >= buf_end - buf)
1362 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1364 entries = bytestream2_get_be32(&gb);
1365 if (entries * 8LL > bytestream2_get_bytes_left(&gb))
1368 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1369 int32_t opcode = bytestream2_get_be32(&gb);
1370 unsigned offset = bytestream2_get_be32(&gb);
1372 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1374 uint32_t x = bytestream2_get_be32(&gb);
1375 if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1377 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1378 bytestream2_put_be32(&pb, x);
1379 bytestream2_skip_p(&pb, pitch - 4);
1383 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1384 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1385 bytestream2_skip_p(&pb, pitch - 4);
1394 static void decode_delta_e(uint8_t *dst,
1395 const uint8_t *buf, const uint8_t *buf_end,
1396 int w, int flag, int bpp, int dst_size)
1398 int planepitch = FFALIGN(w, 16) >> 3;
1399 int pitch = planepitch * bpp;
1400 int planepitch_byte = (w + 7) / 8;
1401 unsigned entries, ofssrc;
1402 GetByteContext gb, ptrs;
1406 if (buf_end - buf <= 4 * bpp)
1409 bytestream2_init_writer(&pb, dst, dst_size);
1410 bytestream2_init(&ptrs, buf, bpp * 4);
1412 for (k = 0; k < bpp; k++) {
1413 ofssrc = bytestream2_get_be32(&ptrs);
1418 if (ofssrc >= buf_end - buf)
1421 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1423 entries = bytestream2_get_be16(&gb);
1424 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1425 int16_t opcode = bytestream2_get_be16(&gb);
1426 unsigned offset = bytestream2_get_be32(&gb);
1428 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1430 uint16_t x = bytestream2_get_be16(&gb);
1431 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1432 bytestream2_put_be16(&pb, x);
1433 bytestream2_skip_p(&pb, pitch - 2);
1438 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1439 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1440 bytestream2_skip_p(&pb, pitch - 2);
1449 static void decode_delta_l(uint8_t *dst,
1450 const uint8_t *buf, const uint8_t *buf_end,
1451 int w, int flag, int bpp, int dst_size)
1453 GetByteContext off0, off1, dgb, ogb;
1455 unsigned poff0, poff1;
1457 int planepitch_byte = (w + 7) / 8;
1458 int planepitch = ((w + 15) / 16) * 2;
1459 int pitch = planepitch * bpp;
1461 if (buf_end - buf <= 64)
1464 bytestream2_init(&off0, buf, buf_end - buf);
1465 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1466 bytestream2_init_writer(&pb, dst, dst_size);
1468 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1470 for (k = 0; k < bpp; k++) {
1471 poff0 = bytestream2_get_be32(&off0);
1472 poff1 = bytestream2_get_be32(&off1);
1477 if (2LL * poff0 >= buf_end - buf)
1480 if (2LL * poff1 >= buf_end - buf)
1483 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1484 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1486 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1487 uint32_t offset = bytestream2_get_be16(&ogb);
1488 int16_t cnt = bytestream2_get_be16(&ogb);
1491 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1493 if (bytestream2_get_bytes_left(&dgb) < 2)
1495 bytestream2_seek_p(&pb, offset, SEEK_SET);
1497 data = bytestream2_get_be16(&dgb);
1498 for (i = 0; i < cnt; i++) {
1499 bytestream2_put_be16(&pb, data);
1500 bytestream2_skip_p(&pb, dstpitch - 2);
1503 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1505 bytestream2_seek_p(&pb, offset, SEEK_SET);
1506 for (i = 0; i < cnt; i++) {
1507 data = bytestream2_get_be16(&dgb);
1508 bytestream2_put_be16(&pb, data);
1509 bytestream2_skip_p(&pb, dstpitch - 2);
1516 static int unsupported(AVCodecContext *avctx)
1518 IffContext *s = avctx->priv_data;
1519 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1520 return AVERROR_INVALIDDATA;
1523 static int decode_frame(AVCodecContext *avctx,
1524 void *data, int *got_frame,
1527 IffContext *s = avctx->priv_data;
1528 AVFrame *frame = data;
1529 const uint8_t *buf = avpkt->data;
1530 int buf_size = avpkt->size;
1531 const uint8_t *buf_end = buf + buf_size;
1533 GetByteContext *gb = &s->gb;
1534 const AVPixFmtDescriptor *desc;
1536 bytestream2_init(gb, avpkt->data, avpkt->size);
1538 if ((res = extract_header(avctx, avpkt)) < 0)
1541 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1545 buf += bytestream2_tell(gb);
1546 buf_size -= bytestream2_tell(gb);
1547 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1549 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1550 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1551 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1553 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1554 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1555 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1560 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1561 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1562 memcpy(s->pal, s->frame->data[1], 256 * 4);
1565 switch (s->compression) {
1567 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1568 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1569 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1570 for (plane = 0; plane < s->bpp; plane++) {
1571 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1572 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1573 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1574 buf += s->planesize;
1577 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1578 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1579 for (y = 0; y < avctx->height; y++) {
1580 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1581 memset(s->ham_buf, 0, s->planesize * 8);
1582 for (plane = 0; plane < s->bpp; plane++) {
1583 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1584 if (start >= buf_end)
1586 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1588 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1591 return unsupported(avctx);
1592 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1593 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1595 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1596 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1597 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1599 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1600 for (x = 0; x < avctx->width; x++)
1601 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1604 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1605 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1606 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1607 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1608 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1609 for (y = 0; y < avctx->height; y++) {
1610 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1611 memset(row, 0, avctx->width);
1612 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1613 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1614 buf += s->planesize;
1617 } else if (s->ham) { // HAM to 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(s->ham_buf, 0, s->planesize * 8);
1621 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1622 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1623 buf += s->planesize;
1625 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1627 } else { // AV_PIX_FMT_BGR32
1628 for (y = 0; y < avctx->height; y++) {
1629 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1630 memset(row, 0, avctx->width << 2);
1631 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1632 decodeplane32((uint32_t *)row, buf,
1633 FFMIN(s->planesize, buf_end - buf), plane);
1634 buf += s->planesize;
1638 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1639 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1640 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1641 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1642 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1643 buf += avctx->width + (avctx->width % 2); // padding if odd
1645 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1646 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1647 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1648 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1649 buf += avctx->width + (avctx->width & 1); // padding if odd
1650 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1653 return unsupported(avctx);
1655 return unsupported(avctx);
1659 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1660 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1661 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1662 uint8_t *video = s->video[0];
1664 for (y = 0; y < avctx->height; y++) {
1665 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1666 memset(row, 0, avctx->width);
1667 for (plane = 0; plane < s->bpp; plane++) {
1668 buf += decode_byterun(s->planebuf, s->planesize, gb);
1669 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1670 memcpy(video, s->planebuf, s->planesize);
1671 video += s->planesize;
1673 decodeplane8(row, s->planebuf, s->planesize, plane);
1676 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1677 for (y = 0; y < avctx->height; y++) {
1678 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1679 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1680 for (plane = 0; plane < s->bpp; plane++) {
1681 buf += decode_byterun(s->planebuf, s->planesize, gb);
1682 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1684 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1686 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1687 uint8_t *video = s->video[0];
1688 for (y = 0; y < avctx->height; y++) {
1689 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1690 memset(s->ham_buf, 0, s->planesize * 8);
1691 for (plane = 0; plane < s->bpp; plane++) {
1692 buf += decode_byterun(s->planebuf, s->planesize, gb);
1693 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1694 memcpy(video, s->planebuf, s->planesize);
1695 video += s->planesize;
1697 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1699 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1701 } else { // AV_PIX_FMT_BGR32
1702 for (y = 0; y < avctx->height; y++) {
1703 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1704 memset(row, 0, avctx->width << 2);
1705 for (plane = 0; plane < s->bpp; plane++) {
1706 buf += decode_byterun(s->planebuf, s->planesize, gb);
1707 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1711 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1712 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1713 for (y = 0; y < avctx->height; y++) {
1714 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1715 buf += decode_byterun(row, avctx->width, gb);
1717 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1718 for (y = 0; y < avctx->height; y++) {
1719 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1720 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1721 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1724 return unsupported(avctx);
1725 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1726 if (av_get_bits_per_pixel(desc) == 32)
1727 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1729 return unsupported(avctx);
1730 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1731 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1732 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1733 for (plane = 0; plane < s->bpp; plane++) {
1734 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1735 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1736 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1737 buf += s->planesize;
1740 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1741 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1742 for (y = 0; y < avctx->height; y++) {
1743 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1744 memset(s->ham_buf, 0, s->planesize * 8);
1745 for (plane = 0; plane < s->bpp; plane++) {
1746 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1747 if (start >= buf_end)
1749 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1751 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1754 return unsupported(avctx);
1757 return unsupported(avctx);
1761 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1762 for (plane = 0; plane < s->bpp; plane++) {
1763 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1764 for (y = 0; y < avctx->height; y++) {
1765 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1766 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1770 return unsupported(avctx);
1774 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1775 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1776 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1777 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1779 return unsupported(avctx);
1782 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1783 if (av_get_bits_per_pixel(desc) == 32)
1784 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1786 return unsupported(avctx);
1788 return unsupported(avctx);
1792 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1796 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1801 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1803 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1808 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1810 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1814 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1818 if (s->is_interlaced)
1819 return unsupported(avctx);
1820 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1824 if (s->is_interlaced)
1825 return unsupported(avctx);
1826 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1830 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1833 return unsupported(avctx);
1836 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1837 memcpy(s->video[1], s->video[0], s->video_size);
1840 if (s->compression > 0xff) {
1841 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1843 for (y = 0; y < avctx->height; y++) {
1844 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1845 memset(row, 0, avctx->width);
1846 for (plane = 0; plane < s->bpp; plane++) {
1847 decodeplane8(row, buf, s->planesize, plane);
1848 buf += s->planesize;
1851 memcpy(frame->data[1], s->pal, 256 * 4);
1852 } else if (s->ham) {
1853 int i, count = 1 << s->ham;
1856 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1857 for (i = 0; i < count; i++) {
1858 s->ham_palbuf[i*2+1] = s->pal[i];
1860 for (i = 0; i < count; i++) {
1861 uint32_t tmp = i << (8 - s->ham);
1862 tmp |= tmp >> s->ham;
1863 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1864 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1865 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1866 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1867 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1868 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1870 if (s->masking == MASK_HAS_MASK) {
1871 for (i = 0; i < 8 * (1 << s->ham); i++)
1872 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1874 for (y = 0; y < avctx->height; y++) {
1875 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1876 memset(s->ham_buf, 0, s->planesize * 8);
1877 for (plane = 0; plane < s->bpp; plane++) {
1878 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1879 buf += s->planesize;
1881 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1884 return unsupported(avctx);
1888 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1892 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1893 frame->key_frame = 1;
1894 frame->pict_type = AV_PICTURE_TYPE_I;
1896 frame->key_frame = 0;
1897 frame->pict_type = AV_PICTURE_TYPE_P;
1905 #if CONFIG_IFF_ILBM_DECODER
1906 AVCodec ff_iff_ilbm_decoder = {
1908 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1909 .type = AVMEDIA_TYPE_VIDEO,
1910 .id = AV_CODEC_ID_IFF_ILBM,
1911 .priv_data_size = sizeof(IffContext),
1912 .init = decode_init,
1913 .close = decode_end,
1914 .decode = decode_frame,
1915 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1916 .capabilities = AV_CODEC_CAP_DR1,