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;
443 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
444 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
445 s->pal = av_calloc(256, sizeof(*s->pal));
446 if (!s->video[0] || !s->video[1] || !s->pal)
447 return AVERROR(ENOMEM);
450 if ((err = extract_header(avctx, NULL)) < 0)
457 * Decode interleaved plane buffer up to 8bpp
458 * @param dst Destination buffer
459 * @param buf Source buffer
461 * @param plane plane number to decode as
463 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
467 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
470 lut = plane8_lut[plane];
472 uint64_t v = AV_RN64A(dst) | lut[*buf++];
475 } while (--buf_size);
479 * Decode interleaved plane buffer up to 24bpp
480 * @param dst Destination buffer
481 * @param buf Source buffer
483 * @param plane plane number to decode as
485 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
487 const uint32_t *lut = plane32_lut[plane];
489 unsigned mask = (*buf >> 2) & ~3;
490 dst[0] |= lut[mask++];
491 dst[1] |= lut[mask++];
492 dst[2] |= lut[mask++];
494 mask = (*buf++ << 2) & 0x3F;
495 dst[4] |= lut[mask++];
496 dst[5] |= lut[mask++];
497 dst[6] |= lut[mask++];
500 } while (--buf_size);
503 #define DECODE_HAM_PLANE32(x) \
504 first = buf[x] << 1; \
505 second = buf[(x)+1] << 1; \
506 delta &= pal[first++]; \
507 delta |= pal[first]; \
509 delta &= pal[second++]; \
510 delta |= pal[second]; \
514 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
516 * @param dst the destination 24bpp buffer
517 * @param buf the source 8bpp chunky buffer
518 * @param pal the HAM decode table
519 * @param buf_size the plane size in bytes
521 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
522 const uint32_t *const pal, unsigned buf_size)
524 uint32_t delta = pal[1]; /* first palette entry */
526 uint32_t first, second;
527 DECODE_HAM_PLANE32(0);
528 DECODE_HAM_PLANE32(2);
529 DECODE_HAM_PLANE32(4);
530 DECODE_HAM_PLANE32(6);
533 } while (--buf_size);
536 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
537 const uint32_t *const pal, unsigned width)
540 *dst++ = pal[*buf++];
545 * Decode one complete byterun1 encoded line.
547 * @param dst the destination buffer where to store decompressed bitstream
548 * @param dst_size the destination plane size in bytes
549 * @param buf the source byterun1 compressed bitstream
550 * @param buf_end the EOF of source byterun1 compressed bitstream
551 * @return number of consumed bytes in byterun1 compressed bitstream
553 static int decode_byterun(uint8_t *dst, int dst_size,
557 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
559 const int8_t value = bytestream2_get_byte(gb);
561 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
562 bytestream2_get_buffer(gb, dst + x, length);
563 if (length < value + 1)
564 bytestream2_skip(gb, value + 1 - length);
565 } else if (value > -128) {
566 length = FFMIN(-value + 1, dst_size - x);
567 memset(dst + x, bytestream2_get_byte(gb), length);
574 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
575 memset(dst+x, 0, dst_size - x);
577 return bytestream2_tell(gb);
580 static int decode_byterun2(uint8_t *dst, int height, int line_size,
585 int i, y_pos = 0, x_pos = 0;
587 if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
590 bytestream2_skip(gb, 4);
591 count = bytestream2_get_be16(gb) - 2;
592 if (bytestream2_get_bytes_left(gb) < count)
595 bytestream2_init(&cmds, gb->buffer, count);
596 bytestream2_skip(gb, count);
598 for (i = 0; i < count && x_pos < line_size; i++) {
599 int8_t cmd = bytestream2_get_byte(&cmds);
603 l = bytestream2_get_be16(gb);
604 while (l-- > 0 && x_pos < line_size) {
605 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
606 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
607 if (y_pos >= height) {
612 } else if (cmd < 0) {
614 while (l-- > 0 && x_pos < line_size) {
615 dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
616 dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
617 if (y_pos >= height) {
622 } else if (cmd == 1) {
623 l = bytestream2_get_be16(gb);
624 r = bytestream2_get_be16(gb);
625 while (l-- > 0 && x_pos < line_size) {
626 dst[x_pos + y_pos * line_size ] = r >> 8;
627 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
628 if (y_pos >= height) {
635 r = bytestream2_get_be16(gb);
636 while (l-- > 0 && x_pos < line_size) {
637 dst[x_pos + y_pos * line_size ] = r >> 8;
638 dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
639 if (y_pos >= height) {
647 return bytestream2_tell(gb);
650 #define DECODE_RGBX_COMMON(type) \
652 length = bytestream2_get_byte(gb); \
654 length = bytestream2_get_be16(gb); \
659 for (i = 0; i < length; i++) { \
660 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
672 * @param[out] dst Destination buffer
673 * @param width Width of destination buffer (pixels)
674 * @param height Height of destination buffer (pixels)
675 * @param linesize Line size of destination buffer (bytes)
677 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
679 int x = 0, y = 0, i, length;
680 while (bytestream2_get_bytes_left(gb) >= 4) {
681 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
682 length = bytestream2_get_byte(gb) & 0x7F;
683 DECODE_RGBX_COMMON(uint32_t)
689 * @param[out] dst Destination buffer
690 * @param width Width of destination buffer (pixels)
691 * @param height Height of destination buffer (pixels)
692 * @param linesize Line size of destination buffer (bytes)
694 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
696 int x = 0, y = 0, i, length;
697 while (bytestream2_get_bytes_left(gb) >= 2) {
698 uint32_t pixel = bytestream2_get_be16u(gb);
699 length = pixel & 0x7;
701 DECODE_RGBX_COMMON(uint16_t)
706 * Decode DEEP RLE 32-bit buffer
707 * @param[out] dst Destination buffer
708 * @param[in] src Source buffer
709 * @param src_size Source buffer size (bytes)
710 * @param width Width of destination buffer (pixels)
711 * @param height Height of destination buffer (pixels)
712 * @param linesize Line size of destination buffer (bytes)
714 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
716 const uint8_t *src_end = src + src_size;
718 while (src_end - src >= 5) {
720 opcode = *(int8_t *)src++;
722 int size = opcode + 1;
723 for (i = 0; i < size; i++) {
724 int length = FFMIN(size - i, width);
725 if (src_end - src < length * 4)
727 memcpy(dst + y*linesize + x * 4, src, length * 4);
739 int size = -opcode + 1;
740 uint32_t pixel = AV_RN32(src);
741 for (i = 0; i < size; i++) {
742 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
757 * Decode DEEP TVDC 32-bit buffer
758 * @param[out] dst Destination buffer
759 * @param[in] src Source buffer
760 * @param src_size Source buffer size (bytes)
761 * @param width Width of destination buffer (pixels)
762 * @param height Height of destination buffer (pixels)
763 * @param linesize Line size of destination buffer (bytes)
764 * @param[int] tvdc TVDC lookup table
766 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)
768 int x = 0, y = 0, plane = 0;
772 for (i = 0; i < src_size * 2;) {
773 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
774 int d = tvdc[GETNIBBLE];
778 dst[y * linesize + x*4 + plane] = pixel;
781 if (i >= src_size * 2)
785 d = FFMIN(d, width - x);
786 for (j = 0; j < d; j++) {
787 dst[y * linesize + x*4 + plane] = pixel;
806 static void decode_short_horizontal_delta(uint8_t *dst,
807 const uint8_t *buf, const uint8_t *buf_end,
808 int w, int bpp, int dst_size)
810 int planepitch = FFALIGN(w, 16) >> 3;
811 int pitch = planepitch * bpp;
812 GetByteContext ptrs, gb;
814 unsigned ofssrc, pos;
817 bytestream2_init(&ptrs, buf, buf_end - buf);
818 bytestream2_init_writer(&pb, dst, dst_size);
820 for (k = 0; k < bpp; k++) {
821 ofssrc = bytestream2_get_be32(&ptrs);
827 if (ofssrc >= buf_end - buf)
830 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
831 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
832 int16_t offset = bytestream2_get_be16(&gb);
836 unsigned data = bytestream2_get_be16(&gb);
839 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
840 bytestream2_seek_p(&pb, noffset, SEEK_SET);
841 bytestream2_put_be16(&pb, data);
843 uint16_t count = bytestream2_get_be16(&gb);
845 pos += 2 * -(offset + 2);
846 for (i = 0; i < count; i++) {
847 uint16_t data = bytestream2_get_be16(&gb);
850 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
851 bytestream2_seek_p(&pb, noffset, SEEK_SET);
852 bytestream2_put_be16(&pb, data);
859 static void decode_byte_vertical_delta(uint8_t *dst,
860 const uint8_t *buf, const uint8_t *buf_end,
861 int w, int xor, int bpp, int dst_size)
863 int ncolumns = ((w + 15) / 16) * 2;
864 int dstpitch = ncolumns * bpp;
865 unsigned ofsdst, ofssrc, opcode, x;
866 GetByteContext ptrs, gb;
870 bytestream2_init(&ptrs, buf, buf_end - buf);
871 bytestream2_init_writer(&pb, dst, dst_size);
873 for (k = 0; k < bpp; k++) {
874 ofssrc = bytestream2_get_be32(&ptrs);
879 if (ofssrc >= buf_end - buf)
882 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
883 for (j = 0; j < ncolumns; j++) {
884 ofsdst = j + k * ncolumns;
886 i = bytestream2_get_byte(&gb);
888 opcode = bytestream2_get_byte(&gb);
891 opcode = bytestream2_get_byte(&gb);
892 x = bytestream2_get_byte(&gb);
895 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
896 if (xor && ofsdst < dst_size) {
897 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
899 bytestream2_put_byte(&pb, x);
904 } else if (opcode < 0x80) {
905 ofsdst += opcode * dstpitch;
910 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
911 if (xor && ofsdst < dst_size) {
912 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
914 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
926 static void decode_delta_j(uint8_t *dst,
927 const uint8_t *buf, const uint8_t *buf_end,
928 int w, int h, int bpp, int dst_size)
932 uint32_t type, flag, cols, groups, rows, bytes;
934 int planepitch_byte = (w + 7) / 8;
935 int planepitch = ((w + 15) / 16) * 2;
936 int kludge_j, b, g, r, d;
939 pitch = planepitch * bpp;
940 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
942 bytestream2_init(&gb, buf, buf_end - buf);
944 while (bytestream2_get_bytes_left(&gb) >= 2) {
945 type = bytestream2_get_be16(&gb);
951 flag = bytestream2_get_be16(&gb);
952 cols = bytestream2_get_be16(&gb);
953 groups = bytestream2_get_be16(&gb);
955 for (g = 0; g < groups; g++) {
956 offset = bytestream2_get_be16(&gb);
958 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
959 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
964 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
966 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
968 for (b = 0; b < cols; b++) {
969 for (d = 0; d < bpp; d++) {
970 uint8_t value = bytestream2_get_byte(&gb);
972 if (offset >= dst_size)
981 offset += planepitch;
984 if ((cols * bpp) & 1)
985 bytestream2_skip(&gb, 1);
989 flag = bytestream2_get_be16(&gb);
990 rows = bytestream2_get_be16(&gb);
991 bytes = bytestream2_get_be16(&gb);
992 groups = bytestream2_get_be16(&gb);
994 for (g = 0; g < groups; g++) {
995 offset = bytestream2_get_be16(&gb);
998 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
1000 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
1002 for (r = 0; r < rows; r++) {
1003 for (d = 0; d < bpp; d++) {
1004 unsigned noffset = offset + (r * pitch) + d * planepitch;
1006 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1007 av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1011 for (b = 0; b < bytes; b++) {
1012 uint8_t value = bytestream2_get_byte(&gb);
1014 if (noffset >= dst_size)
1016 ptr = dst + noffset;
1027 if ((rows * bytes * bpp) & 1)
1028 bytestream2_skip(&gb, 1);
1037 static void decode_short_vertical_delta(uint8_t *dst,
1038 const uint8_t *buf, const uint8_t *buf_end,
1039 int w, int bpp, int dst_size)
1041 int ncolumns = (w + 15) >> 4;
1042 int dstpitch = ncolumns * bpp * 2;
1043 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1044 GetByteContext ptrs, gb, dptrs, dgb;
1048 if (buf_end - buf <= 64)
1051 bytestream2_init(&ptrs, buf, buf_end - buf);
1052 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1053 bytestream2_init_writer(&pb, dst, dst_size);
1055 for (k = 0; k < bpp; k++) {
1056 ofssrc = bytestream2_get_be32(&ptrs);
1057 ofsdata = bytestream2_get_be32(&dptrs);
1062 if (ofssrc >= buf_end - buf)
1065 if (ofsdata >= buf_end - buf)
1068 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1069 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1070 for (j = 0; j < ncolumns; j++) {
1071 ofsdst = (j + k * ncolumns) * 2;
1073 i = bytestream2_get_byte(&gb);
1075 opcode = bytestream2_get_byte(&gb);
1078 opcode = bytestream2_get_byte(&gb);
1079 x = bytestream2_get_be16(&dgb);
1082 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1083 bytestream2_put_be16(&pb, x);
1087 } else if (opcode < 0x80) {
1088 ofsdst += opcode * dstpitch;
1093 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1094 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1105 static void decode_long_vertical_delta(uint8_t *dst,
1106 const uint8_t *buf, const uint8_t *buf_end,
1107 int w, int bpp, int dst_size)
1109 int ncolumns = (w + 31) >> 5;
1110 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1111 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1112 GetByteContext ptrs, gb, dptrs, dgb;
1116 if (buf_end - buf <= 64)
1119 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1120 bytestream2_init(&ptrs, buf, buf_end - buf);
1121 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1122 bytestream2_init_writer(&pb, dst, dst_size);
1124 for (k = 0; k < bpp; k++) {
1125 ofssrc = bytestream2_get_be32(&ptrs);
1126 ofsdata = bytestream2_get_be32(&dptrs);
1131 if (ofssrc >= buf_end - buf)
1134 if (ofsdata >= buf_end - buf)
1137 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1138 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1139 for (j = 0; j < ncolumns; j++) {
1140 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1142 i = bytestream2_get_byte(&gb);
1144 opcode = bytestream2_get_byte(&gb);
1147 opcode = bytestream2_get_byte(&gb);
1148 if (h && (j == (ncolumns - 1))) {
1149 x = bytestream2_get_be16(&dgb);
1150 bytestream2_skip(&dgb, 2);
1152 x = bytestream2_get_be32(&dgb);
1155 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1159 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1160 if (h && (j == (ncolumns - 1))) {
1161 bytestream2_put_be16(&pb, x);
1163 bytestream2_put_be32(&pb, x);
1168 } else if (opcode < 0x80) {
1169 ofsdst += opcode * dstpitch;
1174 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1175 if (h && (j == (ncolumns - 1))) {
1176 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1177 bytestream2_skip(&dgb, 2);
1179 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1191 static void decode_short_vertical_delta2(uint8_t *dst,
1192 const uint8_t *buf, const uint8_t *buf_end,
1193 int w, int bpp, int dst_size)
1195 int ncolumns = (w + 15) >> 4;
1196 int dstpitch = ncolumns * bpp * 2;
1197 unsigned ofsdst, ofssrc, opcode, x;
1198 GetByteContext ptrs, gb;
1202 bytestream2_init(&ptrs, buf, buf_end - buf);
1203 bytestream2_init_writer(&pb, dst, dst_size);
1205 for (k = 0; k < bpp; k++) {
1206 ofssrc = bytestream2_get_be32(&ptrs);
1211 if (ofssrc >= buf_end - buf)
1214 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1215 for (j = 0; j < ncolumns; j++) {
1216 ofsdst = (j + k * ncolumns) * 2;
1218 i = bytestream2_get_be16(&gb);
1219 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1220 opcode = bytestream2_get_be16(&gb);
1223 opcode = bytestream2_get_be16(&gb);
1224 x = bytestream2_get_be16(&gb);
1226 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1227 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1228 bytestream2_put_be16(&pb, x);
1232 } else if (opcode < 0x8000) {
1233 ofsdst += opcode * dstpitch;
1237 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1238 bytestream2_get_bytes_left_p(&pb) > 1) {
1239 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1240 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1251 static void decode_long_vertical_delta2(uint8_t *dst,
1252 const uint8_t *buf, const uint8_t *buf_end,
1253 int w, int bpp, int dst_size)
1255 int ncolumns = (w + 31) >> 5;
1256 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1257 unsigned ofsdst, ofssrc, opcode, x;
1258 unsigned skip = 0x80000000, mask = skip - 1;
1259 GetByteContext ptrs, gb;
1263 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1264 bytestream2_init(&ptrs, buf, buf_end - buf);
1265 bytestream2_init_writer(&pb, dst, dst_size);
1267 for (k = 0; k < bpp; k++) {
1268 ofssrc = bytestream2_get_be32(&ptrs);
1273 if (ofssrc >= buf_end - buf)
1276 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1277 for (j = 0; j < ncolumns; j++) {
1278 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1280 if (h && (j == (ncolumns - 1))) {
1285 i = bytestream2_get_be32(&gb);
1286 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1287 opcode = bytestream2_get_be32(&gb);
1290 if (h && (j == ncolumns - 1)) {
1291 opcode = bytestream2_get_be16(&gb);
1292 x = bytestream2_get_be16(&gb);
1294 opcode = bytestream2_get_be32(&gb);
1295 x = bytestream2_get_be32(&gb);
1298 if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1301 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1302 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1303 if (h && (j == ncolumns - 1))
1304 bytestream2_put_be16(&pb, x);
1306 bytestream2_put_be32(&pb, x);
1310 } else if (opcode < skip) {
1311 ofsdst += opcode * dstpitch;
1315 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1316 bytestream2_get_bytes_left_p(&pb) > 1) {
1317 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1318 if (h && (j == ncolumns - 1)) {
1319 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1321 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1333 static void decode_delta_d(uint8_t *dst,
1334 const uint8_t *buf, const uint8_t *buf_end,
1335 int w, int flag, int bpp, int dst_size)
1337 int planepitch = FFALIGN(w, 16) >> 3;
1338 int pitch = planepitch * bpp;
1339 int planepitch_byte = (w + 7) / 8;
1340 unsigned entries, ofssrc;
1341 GetByteContext gb, ptrs;
1345 if (buf_end - buf <= 4 * bpp)
1348 bytestream2_init_writer(&pb, dst, dst_size);
1349 bytestream2_init(&ptrs, buf, bpp * 4);
1351 for (k = 0; k < bpp; k++) {
1352 ofssrc = bytestream2_get_be32(&ptrs);
1357 if (ofssrc >= buf_end - buf)
1360 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1362 entries = bytestream2_get_be32(&gb);
1363 if (entries * 8LL > bytestream2_get_bytes_left(&gb))
1366 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1367 int32_t opcode = bytestream2_get_be32(&gb);
1368 unsigned offset = bytestream2_get_be32(&gb);
1370 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1372 uint32_t x = bytestream2_get_be32(&gb);
1373 if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1375 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1376 bytestream2_put_be32(&pb, x);
1377 bytestream2_skip_p(&pb, pitch - 4);
1381 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1382 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1383 bytestream2_skip_p(&pb, pitch - 4);
1392 static void decode_delta_e(uint8_t *dst,
1393 const uint8_t *buf, const uint8_t *buf_end,
1394 int w, int flag, int bpp, int dst_size)
1396 int planepitch = FFALIGN(w, 16) >> 3;
1397 int pitch = planepitch * bpp;
1398 int planepitch_byte = (w + 7) / 8;
1399 unsigned entries, ofssrc;
1400 GetByteContext gb, ptrs;
1404 if (buf_end - buf <= 4 * bpp)
1407 bytestream2_init_writer(&pb, dst, dst_size);
1408 bytestream2_init(&ptrs, buf, bpp * 4);
1410 for (k = 0; k < bpp; k++) {
1411 ofssrc = bytestream2_get_be32(&ptrs);
1416 if (ofssrc >= buf_end - buf)
1419 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1421 entries = bytestream2_get_be16(&gb);
1422 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1423 int16_t opcode = bytestream2_get_be16(&gb);
1424 unsigned offset = bytestream2_get_be32(&gb);
1426 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1428 uint16_t x = bytestream2_get_be16(&gb);
1429 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1430 bytestream2_put_be16(&pb, x);
1431 bytestream2_skip_p(&pb, pitch - 2);
1436 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1437 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1438 bytestream2_skip_p(&pb, pitch - 2);
1447 static void decode_delta_l(uint8_t *dst,
1448 const uint8_t *buf, const uint8_t *buf_end,
1449 int w, int flag, int bpp, int dst_size)
1451 GetByteContext off0, off1, dgb, ogb;
1453 unsigned poff0, poff1;
1455 int planepitch_byte = (w + 7) / 8;
1456 int planepitch = ((w + 15) / 16) * 2;
1457 int pitch = planepitch * bpp;
1459 if (buf_end - buf <= 64)
1462 bytestream2_init(&off0, buf, buf_end - buf);
1463 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1464 bytestream2_init_writer(&pb, dst, dst_size);
1466 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1468 for (k = 0; k < bpp; k++) {
1469 poff0 = bytestream2_get_be32(&off0);
1470 poff1 = bytestream2_get_be32(&off1);
1475 if (2LL * poff0 >= buf_end - buf)
1478 if (2LL * poff1 >= buf_end - buf)
1481 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1482 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1484 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1485 uint32_t offset = bytestream2_get_be16(&ogb);
1486 int16_t cnt = bytestream2_get_be16(&ogb);
1489 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1491 if (bytestream2_get_bytes_left(&dgb) < 2)
1493 bytestream2_seek_p(&pb, offset, SEEK_SET);
1495 data = bytestream2_get_be16(&dgb);
1496 for (i = 0; i < cnt; i++) {
1497 bytestream2_put_be16(&pb, data);
1498 bytestream2_skip_p(&pb, dstpitch - 2);
1501 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1503 bytestream2_seek_p(&pb, offset, SEEK_SET);
1504 for (i = 0; i < cnt; i++) {
1505 data = bytestream2_get_be16(&dgb);
1506 bytestream2_put_be16(&pb, data);
1507 bytestream2_skip_p(&pb, dstpitch - 2);
1514 static int unsupported(AVCodecContext *avctx)
1516 IffContext *s = avctx->priv_data;
1517 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1518 return AVERROR_INVALIDDATA;
1521 static int decode_frame(AVCodecContext *avctx,
1522 void *data, int *got_frame,
1525 IffContext *s = avctx->priv_data;
1526 AVFrame *frame = data;
1527 const uint8_t *buf = avpkt->data;
1528 int buf_size = avpkt->size;
1529 const uint8_t *buf_end = buf + buf_size;
1531 GetByteContext *gb = &s->gb;
1532 const AVPixFmtDescriptor *desc;
1534 bytestream2_init(gb, avpkt->data, avpkt->size);
1536 if ((res = extract_header(avctx, avpkt)) < 0)
1539 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1543 buf += bytestream2_tell(gb);
1544 buf_size -= bytestream2_tell(gb);
1545 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1547 if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1548 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1549 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1551 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1552 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1553 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1558 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1559 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1560 memcpy(s->pal, s->frame->data[1], 256 * 4);
1563 switch (s->compression) {
1565 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1566 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1567 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1568 for (plane = 0; plane < s->bpp; plane++) {
1569 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1570 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1571 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1572 buf += s->planesize;
1575 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1576 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1577 for (y = 0; y < avctx->height; y++) {
1578 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1579 memset(s->ham_buf, 0, s->planesize * 8);
1580 for (plane = 0; plane < s->bpp; plane++) {
1581 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1582 if (start >= buf_end)
1584 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1586 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1589 return unsupported(avctx);
1590 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1591 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1593 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1594 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1595 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1597 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1598 for (x = 0; x < avctx->width; x++)
1599 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1602 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1603 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1604 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1605 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1606 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1607 for (y = 0; y < avctx->height; y++) {
1608 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1609 memset(row, 0, avctx->width);
1610 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1611 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1612 buf += s->planesize;
1615 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1616 for (y = 0; y < avctx->height; y++) {
1617 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1618 memset(s->ham_buf, 0, s->planesize * 8);
1619 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1620 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1621 buf += s->planesize;
1623 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1625 } else { // AV_PIX_FMT_BGR32
1626 for (y = 0; y < avctx->height; y++) {
1627 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1628 memset(row, 0, avctx->width << 2);
1629 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1630 decodeplane32((uint32_t *)row, buf,
1631 FFMIN(s->planesize, buf_end - buf), plane);
1632 buf += s->planesize;
1636 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1637 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1638 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1639 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1640 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1641 buf += avctx->width + (avctx->width % 2); // padding if odd
1643 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1644 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1645 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1646 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1647 buf += avctx->width + (avctx->width & 1); // padding if odd
1648 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1651 return unsupported(avctx);
1653 return unsupported(avctx);
1657 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1658 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1659 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1660 uint8_t *video = s->video[0];
1662 for (y = 0; y < avctx->height; y++) {
1663 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1664 memset(row, 0, avctx->width);
1665 for (plane = 0; plane < s->bpp; plane++) {
1666 buf += decode_byterun(s->planebuf, s->planesize, gb);
1667 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1668 memcpy(video, s->planebuf, s->planesize);
1669 video += s->planesize;
1671 decodeplane8(row, s->planebuf, s->planesize, plane);
1674 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1675 for (y = 0; y < avctx->height; y++) {
1676 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1677 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1678 for (plane = 0; plane < s->bpp; plane++) {
1679 buf += decode_byterun(s->planebuf, s->planesize, gb);
1680 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1682 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1684 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1685 uint8_t *video = s->video[0];
1686 for (y = 0; y < avctx->height; y++) {
1687 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1688 memset(s->ham_buf, 0, s->planesize * 8);
1689 for (plane = 0; plane < s->bpp; plane++) {
1690 buf += decode_byterun(s->planebuf, s->planesize, gb);
1691 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1692 memcpy(video, s->planebuf, s->planesize);
1693 video += s->planesize;
1695 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1697 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1699 } else { // AV_PIX_FMT_BGR32
1700 for (y = 0; y < avctx->height; y++) {
1701 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1702 memset(row, 0, avctx->width << 2);
1703 for (plane = 0; plane < s->bpp; plane++) {
1704 buf += decode_byterun(s->planebuf, s->planesize, gb);
1705 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1709 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1710 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1711 for (y = 0; y < avctx->height; y++) {
1712 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1713 buf += decode_byterun(row, avctx->width, gb);
1715 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1716 for (y = 0; y < avctx->height; y++) {
1717 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1718 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1719 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1722 return unsupported(avctx);
1723 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1724 if (av_get_bits_per_pixel(desc) == 32)
1725 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1727 return unsupported(avctx);
1728 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1729 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1730 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1731 for (plane = 0; plane < s->bpp; plane++) {
1732 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1733 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1734 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1735 buf += s->planesize;
1738 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1739 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1740 for (y = 0; y < avctx->height; y++) {
1741 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1742 memset(s->ham_buf, 0, s->planesize * 8);
1743 for (plane = 0; plane < s->bpp; plane++) {
1744 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1745 if (start >= buf_end)
1747 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1749 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1752 return unsupported(avctx);
1755 return unsupported(avctx);
1759 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1760 for (plane = 0; plane < s->bpp; plane++) {
1761 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1762 for (y = 0; y < avctx->height; y++) {
1763 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1764 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1768 return unsupported(avctx);
1772 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1773 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1774 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1775 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1777 return unsupported(avctx);
1780 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1781 if (av_get_bits_per_pixel(desc) == 32)
1782 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1784 return unsupported(avctx);
1786 return unsupported(avctx);
1790 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1794 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1799 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1801 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1806 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1808 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1812 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1816 if (s->is_interlaced)
1817 return unsupported(avctx);
1818 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1822 if (s->is_interlaced)
1823 return unsupported(avctx);
1824 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1828 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1831 return unsupported(avctx);
1834 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1835 memcpy(s->video[1], s->video[0], s->video_size);
1838 if (s->compression > 0xff) {
1839 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1841 for (y = 0; y < avctx->height; y++) {
1842 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1843 memset(row, 0, avctx->width);
1844 for (plane = 0; plane < s->bpp; plane++) {
1845 decodeplane8(row, buf, s->planesize, plane);
1846 buf += s->planesize;
1849 memcpy(frame->data[1], s->pal, 256 * 4);
1850 } else if (s->ham) {
1851 int i, count = 1 << s->ham;
1854 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1855 for (i = 0; i < count; i++) {
1856 s->ham_palbuf[i*2+1] = s->pal[i];
1858 for (i = 0; i < count; i++) {
1859 uint32_t tmp = i << (8 - s->ham);
1860 tmp |= tmp >> s->ham;
1861 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1862 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1863 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1864 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1865 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1866 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1868 if (s->masking == MASK_HAS_MASK) {
1869 for (i = 0; i < 8 * (1 << s->ham); i++)
1870 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1872 for (y = 0; y < avctx->height; y++) {
1873 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1874 memset(s->ham_buf, 0, s->planesize * 8);
1875 for (plane = 0; plane < s->bpp; plane++) {
1876 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1877 buf += s->planesize;
1879 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1882 return unsupported(avctx);
1886 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1890 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1891 frame->key_frame = 1;
1892 frame->pict_type = AV_PICTURE_TYPE_I;
1894 frame->key_frame = 0;
1895 frame->pict_type = AV_PICTURE_TYPE_P;
1903 #if CONFIG_IFF_ILBM_DECODER
1904 AVCodec ff_iff_ilbm_decoder = {
1906 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1907 .type = AVMEDIA_TYPE_VIDEO,
1908 .id = AV_CODEC_ID_IFF_ILBM,
1909 .priv_data_size = sizeof(IffContext),
1910 .init = decode_init,
1911 .close = decode_end,
1912 .decode = decode_frame,
1913 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1914 .capabilities = AV_CODEC_CAP_DR1,