2 * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5 * Copyright (c) 2016 Paul B Mahol
7 * This file is part of FFmpeg.
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
31 #include "libavutil/imgutils.h"
33 #include "bytestream.h"
42 MASK_HAS_TRANSPARENT_COLOR,
46 typedef struct IffContext {
50 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
51 uint32_t *ham_palbuf; ///< HAM decode table
52 uint32_t *mask_buf; ///< temporary buffer for palette indices
53 uint32_t *mask_palbuf; ///< masking palette table
54 unsigned compression; ///< delta compression method used
55 unsigned is_short; ///< short compression method used
56 unsigned is_interlaced;///< video is interlaced
57 unsigned is_brush; ///< video is in ANBR format
58 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
59 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
60 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
61 unsigned transparency; ///< TODO: transparency color index in palette
62 unsigned masking; ///< TODO: masking method used
63 int init; // 1 if buffer and palette data already initialized, 0 otherwise
64 int16_t tvdc[16]; ///< TVDC lookup table
71 #define LUT8_PART(plane, v) \
72 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
79 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
80 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
81 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
82 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
83 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
84 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
85 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
86 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
87 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
89 #define LUT8(plane) { \
90 LUT8_PART(plane, 0x0000000), \
91 LUT8_PART(plane, 0x1000000), \
92 LUT8_PART(plane, 0x0010000), \
93 LUT8_PART(plane, 0x1010000), \
94 LUT8_PART(plane, 0x0000100), \
95 LUT8_PART(plane, 0x1000100), \
96 LUT8_PART(plane, 0x0010100), \
97 LUT8_PART(plane, 0x1010100), \
98 LUT8_PART(plane, 0x0000001), \
99 LUT8_PART(plane, 0x1000001), \
100 LUT8_PART(plane, 0x0010001), \
101 LUT8_PART(plane, 0x1010001), \
102 LUT8_PART(plane, 0x0000101), \
103 LUT8_PART(plane, 0x1000101), \
104 LUT8_PART(plane, 0x0010101), \
105 LUT8_PART(plane, 0x1010101), \
108 // 8 planes * 8-bit mask
109 static const uint64_t plane8_lut[8][256] = {
110 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
111 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
114 #define LUT32(plane) { \
116 0, 0, 0, 1 << plane, \
117 0, 0, 1 << plane, 0, \
118 0, 0, 1 << plane, 1 << plane, \
119 0, 1 << plane, 0, 0, \
120 0, 1 << plane, 0, 1 << plane, \
121 0, 1 << plane, 1 << plane, 0, \
122 0, 1 << plane, 1 << plane, 1 << plane, \
123 1 << plane, 0, 0, 0, \
124 1 << plane, 0, 0, 1 << plane, \
125 1 << plane, 0, 1 << plane, 0, \
126 1 << plane, 0, 1 << plane, 1 << plane, \
127 1 << plane, 1 << plane, 0, 0, \
128 1 << plane, 1 << plane, 0, 1 << plane, \
129 1 << plane, 1 << plane, 1 << plane, 0, \
130 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
133 // 32 planes * 4-bit mask * 4 lookup tables each
134 static const uint32_t plane32_lut[32][16*4] = {
135 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
136 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
137 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
138 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
139 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
140 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
141 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
142 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
145 // Gray to RGB, required for palette table of grayscale images with bpp < 8
146 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
147 return x << 16 | x << 8 | x;
151 * Convert CMAP buffer (stored in extradata) to lavc palette format
153 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
155 IffContext *s = avctx->priv_data;
157 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
158 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
160 if (avctx->bits_per_coded_sample > 8) {
161 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
162 return AVERROR_INVALIDDATA;
165 count = 1 << avctx->bits_per_coded_sample;
166 // If extradata is smaller than actually needed, fill the remaining with black.
167 count = FFMIN(palette_size / 3, count);
169 for (i = 0; i < count; i++)
170 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
171 if (s->flags && count >= 32) { // EHB
172 for (i = 0; i < 32; i++)
173 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
174 count = FFMAX(count, 64);
176 } else { // Create gray-scale color palette for bps < 8
177 count = 1 << avctx->bits_per_coded_sample;
179 for (i = 0; i < count; i++)
180 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
182 if (s->masking == MASK_HAS_MASK) {
183 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
184 for (i = 0; i < count; i++)
186 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
187 s->transparency < 1 << avctx->bits_per_coded_sample)
188 pal[s->transparency] &= 0xFFFFFF;
193 * Extracts the IFF extra context and updates internal
194 * decoder structures.
196 * @param avctx the AVCodecContext where to extract extra context to
197 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
198 * @return >= 0 in case of success, a negative error code otherwise
200 static int extract_header(AVCodecContext *const avctx,
201 const AVPacket *const avpkt)
203 IffContext *s = avctx->priv_data;
205 unsigned buf_size = 0;
208 if (avctx->extradata_size < 2) {
209 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
210 return AVERROR_INVALIDDATA;
212 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
214 if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
217 GetByteContext *gb = &s->gb;
219 bytestream2_skip(gb, 4);
220 while (bytestream2_get_bytes_left(gb) >= 1) {
221 chunk_id = bytestream2_get_le32(gb);
222 data_size = bytestream2_get_be32(gb);
224 if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
225 bytestream2_skip(gb, data_size + (data_size & 1));
226 } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
229 return AVERROR_INVALIDDATA;
231 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
232 bytestream2_skip(gb, 19);
233 extra = bytestream2_get_be32(gb);
234 s->is_short = !(extra & 1);
235 s->is_brush = extra == 2;
236 s->is_interlaced = !!(extra & 0x40);
238 bytestream2_skip(gb, data_size + (data_size & 1));
239 } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
240 chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
241 if (chunk_id == MKTAG('B','O','D','Y'))
242 s->compression &= 0xFF;
244 } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
245 int count = data_size / 3;
246 uint32_t *pal = s->pal;
249 return AVERROR_INVALIDDATA;
251 for (i = 0; i < count; i++)
252 pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
254 for (i = 0; i < count; i++)
255 pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
257 bytestream2_skip(gb, data_size & 1);
259 bytestream2_skip(gb, data_size + (data_size&1));
263 buf = avctx->extradata;
264 buf_size = bytestream_get_be16(&buf);
265 if (buf_size <= 1 || palette_size < 0) {
266 av_log(avctx, AV_LOG_ERROR,
267 "Invalid palette size received: %u -> palette data offset: %d\n",
268 buf_size, palette_size);
269 return AVERROR_INVALIDDATA;
273 if (buf_size >= 41) {
274 s->compression = bytestream_get_byte(&buf);
275 s->bpp = bytestream_get_byte(&buf);
276 s->ham = bytestream_get_byte(&buf);
277 s->flags = bytestream_get_byte(&buf);
278 s->transparency = bytestream_get_be16(&buf);
279 s->masking = bytestream_get_byte(&buf);
280 for (i = 0; i < 16; i++)
281 s->tvdc[i] = bytestream_get_be16(&buf);
283 if (s->masking == MASK_HAS_MASK) {
284 if (s->bpp >= 8 && !s->ham) {
285 avctx->pix_fmt = AV_PIX_FMT_RGB32;
286 av_freep(&s->mask_buf);
287 av_freep(&s->mask_palbuf);
288 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
290 return AVERROR(ENOMEM);
292 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
293 av_freep(&s->mask_buf);
294 return AVERROR(ENOMEM);
296 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
297 if (!s->mask_palbuf) {
298 av_freep(&s->mask_buf);
299 return AVERROR(ENOMEM);
303 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
304 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
305 return AVERROR_PATCHWELCOME;
307 if (!s->bpp || s->bpp > 32) {
308 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
309 return AVERROR_INVALIDDATA;
310 } else if (s->ham >= 8) {
311 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
312 return AVERROR_INVALIDDATA;
315 av_freep(&s->ham_buf);
316 av_freep(&s->ham_palbuf);
319 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
321 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
323 s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
325 return AVERROR(ENOMEM);
327 ham_count = 8 * (1 << s->ham);
328 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
329 if (!s->ham_palbuf) {
330 av_freep(&s->ham_buf);
331 return AVERROR(ENOMEM);
334 if (count) { // HAM with color palette attached
335 // prefill with black and palette and set HAM take direct value mask to zero
336 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
337 for (i=0; i < count; i++) {
338 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
341 } else { // HAM with grayscale color palette
343 for (i=0; i < count; i++) {
344 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
345 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
348 for (i=0; i < count; i++) {
349 uint32_t tmp = i << (8 - s->ham);
350 tmp |= tmp >> s->ham;
351 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
352 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
353 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
354 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
355 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
356 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
358 if (s->masking == MASK_HAS_MASK) {
359 for (i = 0; i < ham_count; i++)
360 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
368 static av_cold int decode_end(AVCodecContext *avctx)
370 IffContext *s = avctx->priv_data;
371 av_freep(&s->planebuf);
372 av_freep(&s->ham_buf);
373 av_freep(&s->ham_palbuf);
374 av_freep(&s->video[0]);
375 av_freep(&s->video[1]);
380 static av_cold int decode_init(AVCodecContext *avctx)
382 IffContext *s = avctx->priv_data;
385 if (avctx->bits_per_coded_sample <= 8) {
388 if (avctx->extradata_size >= 2)
389 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
392 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
393 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
394 } else if (avctx->bits_per_coded_sample <= 32) {
395 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
396 avctx->pix_fmt = AV_PIX_FMT_RGB32;
397 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
398 avctx->pix_fmt = AV_PIX_FMT_RGB444;
399 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
400 if (avctx->bits_per_coded_sample == 24) {
401 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
402 } else if (avctx->bits_per_coded_sample == 32) {
403 avctx->pix_fmt = AV_PIX_FMT_BGR32;
405 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
406 return AVERROR_PATCHWELCOME;
410 return AVERROR_INVALIDDATA;
413 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
415 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
416 s->planebuf = av_malloc(s->planesize + AV_INPUT_BUFFER_PADDING_SIZE);
418 return AVERROR(ENOMEM);
420 s->bpp = avctx->bits_per_coded_sample;
422 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
423 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
424 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
425 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
426 s->pal = av_calloc(256, sizeof(*s->pal));
427 if (!s->video[0] || !s->video[1] || !s->pal)
428 return AVERROR(ENOMEM);
431 if ((err = extract_header(avctx, NULL)) < 0)
438 * Decode interleaved plane buffer up to 8bpp
439 * @param dst Destination buffer
440 * @param buf Source buffer
442 * @param plane plane number to decode as
444 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
446 const uint64_t *lut = plane8_lut[plane];
448 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
452 uint64_t v = AV_RN64A(dst) | lut[*buf++];
455 } while (--buf_size);
459 * Decode interleaved plane buffer up to 24bpp
460 * @param dst Destination buffer
461 * @param buf Source buffer
463 * @param plane plane number to decode as
465 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
467 const uint32_t *lut = plane32_lut[plane];
469 unsigned mask = (*buf >> 2) & ~3;
470 dst[0] |= lut[mask++];
471 dst[1] |= lut[mask++];
472 dst[2] |= lut[mask++];
474 mask = (*buf++ << 2) & 0x3F;
475 dst[4] |= lut[mask++];
476 dst[5] |= lut[mask++];
477 dst[6] |= lut[mask++];
480 } while (--buf_size);
483 #define DECODE_HAM_PLANE32(x) \
484 first = buf[x] << 1; \
485 second = buf[(x)+1] << 1; \
486 delta &= pal[first++]; \
487 delta |= pal[first]; \
489 delta &= pal[second++]; \
490 delta |= pal[second]; \
494 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
496 * @param dst the destination 24bpp buffer
497 * @param buf the source 8bpp chunky buffer
498 * @param pal the HAM decode table
499 * @param buf_size the plane size in bytes
501 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
502 const uint32_t *const pal, unsigned buf_size)
504 uint32_t delta = pal[1]; /* first palette entry */
506 uint32_t first, second;
507 DECODE_HAM_PLANE32(0);
508 DECODE_HAM_PLANE32(2);
509 DECODE_HAM_PLANE32(4);
510 DECODE_HAM_PLANE32(6);
513 } while (--buf_size);
516 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
517 const uint32_t *const pal, unsigned width)
520 *dst++ = pal[*buf++];
525 * Decode one complete byterun1 encoded line.
527 * @param dst the destination buffer where to store decompressed bitstream
528 * @param dst_size the destination plane size in bytes
529 * @param buf the source byterun1 compressed bitstream
530 * @param buf_end the EOF of source byterun1 compressed bitstream
531 * @return number of consumed bytes in byterun1 compressed bitstream
533 static int decode_byterun(uint8_t *dst, int dst_size,
537 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
539 const int8_t value = bytestream2_get_byte(gb);
541 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
542 bytestream2_get_buffer(gb, dst + x, length);
543 if (length < value + 1)
544 bytestream2_skip(gb, value + 1 - length);
545 } else if (value > -128) {
546 length = FFMIN(-value + 1, dst_size - x);
547 memset(dst + x, bytestream2_get_byte(gb), length);
554 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
555 memset(dst+x, 0, dst_size - x);
557 return bytestream2_tell(gb);
560 #define DECODE_RGBX_COMMON(type) \
562 length = bytestream2_get_byte(gb); \
564 length = bytestream2_get_be16(gb); \
569 for (i = 0; i < length; i++) { \
570 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
582 * @param[out] dst Destination buffer
583 * @param width Width of destination buffer (pixels)
584 * @param height Height of destination buffer (pixels)
585 * @param linesize Line size of destination buffer (bytes)
587 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
589 int x = 0, y = 0, i, length;
590 while (bytestream2_get_bytes_left(gb) >= 4) {
591 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
592 length = bytestream2_get_byte(gb) & 0x7F;
593 DECODE_RGBX_COMMON(uint32_t)
599 * @param[out] dst Destination buffer
600 * @param width Width of destination buffer (pixels)
601 * @param height Height of destination buffer (pixels)
602 * @param linesize Line size of destination buffer (bytes)
604 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
606 int x = 0, y = 0, i, length;
607 while (bytestream2_get_bytes_left(gb) >= 2) {
608 uint32_t pixel = bytestream2_get_be16u(gb);
609 length = pixel & 0x7;
611 DECODE_RGBX_COMMON(uint16_t)
616 * Decode DEEP RLE 32-bit buffer
617 * @param[out] dst Destination buffer
618 * @param[in] src Source buffer
619 * @param src_size Source buffer size (bytes)
620 * @param width Width of destination buffer (pixels)
621 * @param height Height of destination buffer (pixels)
622 * @param linesize Line size of destination buffer (bytes)
624 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
626 const uint8_t *src_end = src + src_size;
628 while (src + 5 <= src_end) {
630 opcode = *(int8_t *)src++;
632 int size = opcode + 1;
633 for (i = 0; i < size; i++) {
634 int length = FFMIN(size - i, width);
635 memcpy(dst + y*linesize + x * 4, src, length * 4);
647 int size = -opcode + 1;
648 uint32_t pixel = AV_RN32(src);
649 for (i = 0; i < size; i++) {
650 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
665 * Decode DEEP TVDC 32-bit buffer
666 * @param[out] dst Destination buffer
667 * @param[in] src Source buffer
668 * @param src_size Source buffer size (bytes)
669 * @param width Width of destination buffer (pixels)
670 * @param height Height of destination buffer (pixels)
671 * @param linesize Line size of destination buffer (bytes)
672 * @param[int] tvdc TVDC lookup table
674 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)
676 int x = 0, y = 0, plane = 0;
680 for (i = 0; i < src_size * 2;) {
681 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
682 int d = tvdc[GETNIBBLE];
686 dst[y * linesize + x*4 + plane] = pixel;
689 if (i >= src_size * 2)
693 d = FFMIN(d, width - x);
694 for (j = 0; j < d; j++) {
695 dst[y * linesize + x*4 + plane] = pixel;
714 static void decode_short_horizontal_delta(uint8_t *dst,
715 const uint8_t *buf, const uint8_t *buf_end,
716 int w, int bpp, int dst_size)
718 int planepitch = FFALIGN(w, 16) >> 3;
719 int pitch = planepitch * bpp;
720 GetByteContext ptrs, gb;
722 unsigned ofssrc, pos;
725 bytestream2_init(&ptrs, buf, buf_end - buf);
726 bytestream2_init_writer(&pb, dst, dst_size);
728 for (k = 0; k < bpp; k++) {
729 ofssrc = bytestream2_get_be32(&ptrs);
735 if (ofssrc >= buf_end - buf)
738 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
739 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
740 int16_t offset = bytestream2_get_be16(&gb);
744 unsigned data = bytestream2_get_be16(&gb);
747 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
748 bytestream2_seek_p(&pb, noffset, SEEK_SET);
749 bytestream2_put_be16(&pb, data);
751 uint16_t count = bytestream2_get_be16(&gb);
753 pos += 2 * -(offset + 2);
754 for (i = 0; i < count; i++) {
755 uint16_t data = bytestream2_get_be16(&gb);
758 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
759 bytestream2_seek_p(&pb, noffset, SEEK_SET);
760 bytestream2_put_be16(&pb, data);
767 static void decode_byte_vertical_delta(uint8_t *dst,
768 const uint8_t *buf, const uint8_t *buf_end,
769 int w, int xor, int bpp, int dst_size)
771 int ncolumns = ((w + 15) / 16) * 2;
772 int dstpitch = ncolumns * bpp;
773 unsigned ofsdst, ofssrc, opcode, x;
774 GetByteContext ptrs, gb;
778 bytestream2_init(&ptrs, buf, buf_end - buf);
779 bytestream2_init_writer(&pb, dst, dst_size);
781 for (k = 0; k < bpp; k++) {
782 ofssrc = bytestream2_get_be32(&ptrs);
787 if (ofssrc >= buf_end - buf)
790 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
791 for (j = 0; j < ncolumns; j++) {
792 ofsdst = j + k * ncolumns;
794 i = bytestream2_get_byte(&gb);
796 opcode = bytestream2_get_byte(&gb);
799 opcode = bytestream2_get_byte(&gb);
800 x = bytestream2_get_byte(&gb);
803 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
804 if (xor && ofsdst < dst_size) {
805 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
807 bytestream2_put_byte(&pb, x);
812 } else if (opcode < 0x80) {
813 ofsdst += opcode * dstpitch;
818 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
819 if (xor && ofsdst < dst_size) {
820 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
822 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
834 static void decode_delta_j(uint8_t *dst,
835 const uint8_t *buf, const uint8_t *buf_end,
836 int w, int h, int bpp, int dst_size)
840 uint32_t type, flag, cols, groups, rows, bytes;
842 int planepitch_byte = (w + 7) / 8;
843 int planepitch = ((w + 15) / 16) * 2;
844 int kludge_j, b, g, r, d;
847 pitch = planepitch * bpp;
848 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
850 bytestream2_init(&gb, buf, buf_end - buf);
852 while (bytestream2_get_bytes_left(&gb) >= 2) {
853 type = bytestream2_get_be16(&gb);
859 flag = bytestream2_get_be16(&gb);
860 cols = bytestream2_get_be16(&gb);
861 groups = bytestream2_get_be16(&gb);
863 for (g = 0; g < groups; g++) {
864 offset = bytestream2_get_be16(&gb);
866 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
867 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%d*%d)", cols, bpp);
872 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
874 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
876 for (b = 0; b < cols; b++) {
877 for (d = 0; d < bpp; d++) {
878 uint8_t value = bytestream2_get_byte(&gb);
880 if (offset >= dst_size)
889 offset += planepitch;
892 if ((cols * bpp) & 1)
893 bytestream2_skip(&gb, 1);
897 flag = bytestream2_get_be16(&gb);
898 rows = bytestream2_get_be16(&gb);
899 bytes = bytestream2_get_be16(&gb);
900 groups = bytestream2_get_be16(&gb);
902 for (g = 0; g < groups; g++) {
903 offset = bytestream2_get_be16(&gb);
906 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
908 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
910 for (r = 0; r < rows; r++) {
911 for (d = 0; d < bpp; d++) {
912 unsigned noffset = offset + (r * pitch) + d * planepitch;
914 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
915 av_log(NULL, AV_LOG_ERROR, "bytes %d is invalid", bytes);
919 for (b = 0; b < bytes; b++) {
920 uint8_t value = bytestream2_get_byte(&gb);
922 if (noffset >= dst_size)
935 if ((rows * bytes * bpp) & 1)
936 bytestream2_skip(&gb, 1);
945 static void decode_short_vertical_delta(uint8_t *dst,
946 const uint8_t *buf, const uint8_t *buf_end,
947 int w, int bpp, int dst_size)
949 int ncolumns = (w + 15) >> 4;
950 int dstpitch = ncolumns * bpp * 2;
951 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
952 GetByteContext ptrs, gb, dptrs, dgb;
956 if (buf_end - buf <= 64)
959 bytestream2_init(&ptrs, buf, buf_end - buf);
960 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
961 bytestream2_init_writer(&pb, dst, dst_size);
963 for (k = 0; k < bpp; k++) {
964 ofssrc = bytestream2_get_be32(&ptrs);
965 ofsdata = bytestream2_get_be32(&dptrs);
970 if (ofssrc >= buf_end - buf)
973 if (ofsdata >= buf_end - buf)
976 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
977 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
978 for (j = 0; j < ncolumns; j++) {
979 ofsdst = (j + k * ncolumns) * 2;
981 i = bytestream2_get_byte(&gb);
983 opcode = bytestream2_get_byte(&gb);
986 opcode = bytestream2_get_byte(&gb);
987 x = bytestream2_get_be16(&dgb);
990 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
991 bytestream2_put_be16(&pb, x);
995 } else if (opcode < 0x80) {
996 ofsdst += opcode * dstpitch;
1001 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1002 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1013 static void decode_long_vertical_delta(uint8_t *dst,
1014 const uint8_t *buf, const uint8_t *buf_end,
1015 int w, int bpp, int dst_size)
1017 int ncolumns = (w + 31) >> 5;
1018 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1019 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1020 GetByteContext ptrs, gb, dptrs, dgb;
1024 if (buf_end - buf <= 64)
1027 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1028 bytestream2_init(&ptrs, buf, buf_end - buf);
1029 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1030 bytestream2_init_writer(&pb, dst, dst_size);
1032 for (k = 0; k < bpp; k++) {
1033 ofssrc = bytestream2_get_be32(&ptrs);
1034 ofsdata = bytestream2_get_be32(&dptrs);
1039 if (ofssrc >= buf_end - buf)
1042 if (ofsdata >= buf_end - buf)
1045 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1046 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1047 for (j = 0; j < ncolumns; j++) {
1048 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1050 i = bytestream2_get_byte(&gb);
1052 opcode = bytestream2_get_byte(&gb);
1055 opcode = bytestream2_get_byte(&gb);
1056 if (h && (j == (ncolumns - 1))) {
1057 x = bytestream2_get_be16(&dgb);
1058 bytestream2_skip(&dgb, 2);
1060 x = bytestream2_get_be32(&dgb);
1064 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1065 if (h && (j == (ncolumns - 1))) {
1066 bytestream2_put_be16(&pb, x);
1068 bytestream2_put_be32(&pb, x);
1073 } else if (opcode < 0x80) {
1074 ofsdst += opcode * dstpitch;
1079 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1080 if (h && (j == (ncolumns - 1))) {
1081 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1082 bytestream2_skip(&dgb, 2);
1084 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1096 static void decode_short_vertical_delta2(uint8_t *dst,
1097 const uint8_t *buf, const uint8_t *buf_end,
1098 int w, int bpp, int dst_size)
1100 int ncolumns = (w + 15) >> 4;
1101 int dstpitch = ncolumns * bpp * 2;
1102 unsigned ofsdst, ofssrc, opcode, x;
1103 GetByteContext ptrs, gb;
1107 bytestream2_init(&ptrs, buf, buf_end - buf);
1108 bytestream2_init_writer(&pb, dst, dst_size);
1110 for (k = 0; k < bpp; k++) {
1111 ofssrc = bytestream2_get_be32(&ptrs);
1116 if (ofssrc >= buf_end - buf)
1119 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1120 for (j = 0; j < ncolumns; j++) {
1121 ofsdst = (j + k * ncolumns) * 2;
1123 i = bytestream2_get_be16(&gb);
1124 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1125 opcode = bytestream2_get_be16(&gb);
1128 opcode = bytestream2_get_be16(&gb);
1129 x = bytestream2_get_be16(&gb);
1131 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1132 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1133 bytestream2_put_be16(&pb, x);
1137 } else if (opcode < 0x8000) {
1138 ofsdst += opcode * dstpitch;
1142 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1143 bytestream2_get_bytes_left_p(&pb) > 1) {
1144 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1145 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1156 static void decode_long_vertical_delta2(uint8_t *dst,
1157 const uint8_t *buf, const uint8_t *buf_end,
1158 int w, int bpp, int dst_size)
1160 int ncolumns = (w + 31) >> 5;
1161 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1162 unsigned ofsdst, ofssrc, opcode, x;
1163 unsigned skip = 0x80000000, mask = skip - 1;
1164 GetByteContext ptrs, gb;
1168 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1169 bytestream2_init(&ptrs, buf, buf_end - buf);
1170 bytestream2_init_writer(&pb, dst, dst_size);
1172 for (k = 0; k < bpp; k++) {
1173 ofssrc = bytestream2_get_be32(&ptrs);
1178 if (ofssrc >= buf_end - buf)
1181 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1182 for (j = 0; j < ncolumns; j++) {
1183 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1185 if (h && (j == (ncolumns - 1))) {
1190 i = bytestream2_get_be32(&gb);
1191 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1192 opcode = bytestream2_get_be32(&gb);
1195 if (h && (j == ncolumns - 1)) {
1196 opcode = bytestream2_get_be16(&gb);
1197 x = bytestream2_get_be16(&gb);
1199 opcode = bytestream2_get_be32(&gb);
1200 x = bytestream2_get_be32(&gb);
1203 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1204 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1205 if (h && (j == ncolumns - 1))
1206 bytestream2_put_be16(&pb, x);
1208 bytestream2_put_be32(&pb, x);
1212 } else if (opcode < skip) {
1213 ofsdst += opcode * dstpitch;
1217 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1218 bytestream2_get_bytes_left_p(&pb) > 1) {
1219 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1220 if (h && (j == ncolumns - 1)) {
1221 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1223 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1235 static void decode_delta_d(uint8_t *dst,
1236 const uint8_t *buf, const uint8_t *buf_end,
1237 int w, int flag, int bpp, int dst_size)
1239 int planepitch = FFALIGN(w, 16) >> 3;
1240 int pitch = planepitch * bpp;
1241 int planepitch_byte = (w + 7) / 8;
1242 unsigned entries, ofssrc;
1243 GetByteContext gb, ptrs;
1247 if (buf_end - buf <= 4 * bpp)
1250 bytestream2_init_writer(&pb, dst, dst_size);
1251 bytestream2_init(&ptrs, buf, bpp * 4);
1253 for (k = 0; k < bpp; k++) {
1254 ofssrc = bytestream2_get_be32(&ptrs);
1259 if (ofssrc >= buf_end - buf)
1262 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1264 entries = bytestream2_get_be32(&gb);
1265 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1266 int32_t opcode = bytestream2_get_be32(&gb);
1267 unsigned offset = bytestream2_get_be32(&gb);
1269 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1271 uint32_t x = bytestream2_get_be32(&gb);
1272 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1273 bytestream2_put_be32(&pb, x);
1274 bytestream2_skip_p(&pb, pitch - 4);
1279 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1280 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1281 bytestream2_skip_p(&pb, pitch - 4);
1290 static void decode_delta_e(uint8_t *dst,
1291 const uint8_t *buf, const uint8_t *buf_end,
1292 int w, int flag, int bpp, int dst_size)
1294 int planepitch = FFALIGN(w, 16) >> 3;
1295 int pitch = planepitch * bpp;
1296 int planepitch_byte = (w + 7) / 8;
1297 unsigned entries, ofssrc;
1298 GetByteContext gb, ptrs;
1302 if (buf_end - buf <= 4 * bpp)
1305 bytestream2_init_writer(&pb, dst, dst_size);
1306 bytestream2_init(&ptrs, buf, bpp * 4);
1308 for (k = 0; k < bpp; k++) {
1309 ofssrc = bytestream2_get_be32(&ptrs);
1314 if (ofssrc >= buf_end - buf)
1317 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1319 entries = bytestream2_get_be16(&gb);
1320 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1321 int16_t opcode = bytestream2_get_be16(&gb);
1322 unsigned offset = bytestream2_get_be32(&gb);
1324 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1326 uint16_t x = bytestream2_get_be16(&gb);
1327 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1328 bytestream2_put_be16(&pb, x);
1329 bytestream2_skip_p(&pb, pitch - 2);
1334 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1335 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1336 bytestream2_skip_p(&pb, pitch - 2);
1345 static void decode_delta_l(uint8_t *dst,
1346 const uint8_t *buf, const uint8_t *buf_end,
1347 int w, int flag, int bpp, int dst_size)
1349 GetByteContext off0, off1, dgb, ogb;
1351 unsigned poff0, poff1;
1353 int planepitch_byte = (w + 7) / 8;
1354 int planepitch = ((w + 15) / 16) * 2;
1355 int pitch = planepitch * bpp;
1357 if (buf_end - buf <= 64)
1360 bytestream2_init(&off0, buf, buf_end - buf);
1361 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1362 bytestream2_init_writer(&pb, dst, dst_size);
1364 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1366 for (k = 0; k < bpp; k++) {
1367 poff0 = bytestream2_get_be32(&off0);
1368 poff1 = bytestream2_get_be32(&off1);
1373 if (2LL * poff0 >= buf_end - buf)
1376 if (2LL * poff1 >= buf_end - buf)
1379 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1380 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1382 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1383 uint32_t offset = bytestream2_get_be16(&ogb);
1384 int16_t cnt = bytestream2_get_be16(&ogb);
1387 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1389 if (bytestream2_get_bytes_left(&dgb) < 2)
1391 bytestream2_seek_p(&pb, offset, SEEK_SET);
1393 data = bytestream2_get_be16(&dgb);
1394 for (i = 0; i < cnt; i++) {
1395 bytestream2_put_be16(&pb, data);
1396 bytestream2_skip_p(&pb, dstpitch - 2);
1399 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1401 bytestream2_seek_p(&pb, offset, SEEK_SET);
1402 for (i = 0; i < cnt; i++) {
1403 data = bytestream2_get_be16(&dgb);
1404 bytestream2_put_be16(&pb, data);
1405 bytestream2_skip_p(&pb, dstpitch - 2);
1412 static int unsupported(AVCodecContext *avctx)
1414 IffContext *s = avctx->priv_data;
1415 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1416 return AVERROR_INVALIDDATA;
1419 static int decode_frame(AVCodecContext *avctx,
1420 void *data, int *got_frame,
1423 IffContext *s = avctx->priv_data;
1424 AVFrame *frame = data;
1425 const uint8_t *buf = avpkt->data;
1426 int buf_size = avpkt->size;
1427 const uint8_t *buf_end = buf + buf_size;
1429 GetByteContext *gb = &s->gb;
1430 const AVPixFmtDescriptor *desc;
1432 bytestream2_init(gb, avpkt->data, avpkt->size);
1434 if ((res = extract_header(avctx, avpkt)) < 0)
1437 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1441 buf += bytestream2_tell(gb);
1442 buf_size -= bytestream2_tell(gb);
1443 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1445 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1446 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1447 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1449 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1450 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1451 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1456 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1457 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1458 memcpy(s->pal, s->frame->data[1], 256 * 4);
1461 switch (s->compression) {
1463 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1464 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1465 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1466 for (plane = 0; plane < s->bpp; plane++) {
1467 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1468 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1469 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1470 buf += s->planesize;
1473 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1474 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1475 for (y = 0; y < avctx->height; y++) {
1476 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1477 memset(s->ham_buf, 0, s->planesize * 8);
1478 for (plane = 0; plane < s->bpp; plane++) {
1479 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1480 if (start >= buf_end)
1482 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1484 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1487 return unsupported(avctx);
1488 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1489 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1491 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1492 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1493 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1495 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1496 for (x = 0; x < avctx->width; x++)
1497 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1500 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1501 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1502 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1503 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1504 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1505 for (y = 0; y < avctx->height; y++) {
1506 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1507 memset(row, 0, avctx->width);
1508 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1509 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1510 buf += s->planesize;
1513 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1514 for (y = 0; y < avctx->height; y++) {
1515 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1516 memset(s->ham_buf, 0, s->planesize * 8);
1517 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1518 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1519 buf += s->planesize;
1521 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1523 } else { // AV_PIX_FMT_BGR32
1524 for (y = 0; y < avctx->height; y++) {
1525 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1526 memset(row, 0, avctx->width << 2);
1527 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1528 decodeplane32((uint32_t *)row, buf,
1529 FFMIN(s->planesize, buf_end - buf), plane);
1530 buf += s->planesize;
1534 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1535 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1536 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1537 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1538 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1539 buf += avctx->width + (avctx->width % 2); // padding if odd
1541 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1542 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1543 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1544 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1545 buf += avctx->width + (avctx->width & 1); // padding if odd
1546 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1549 return unsupported(avctx);
1553 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1554 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1555 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1556 uint8_t *video = s->video[0];
1558 for (y = 0; y < avctx->height; y++) {
1559 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1560 memset(row, 0, avctx->width);
1561 for (plane = 0; plane < s->bpp; plane++) {
1562 buf += decode_byterun(s->planebuf, s->planesize, gb);
1563 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1564 memcpy(video, s->planebuf, s->planesize);
1565 video += s->planesize;
1567 decodeplane8(row, s->planebuf, s->planesize, plane);
1570 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1571 for (y = 0; y < avctx->height; y++) {
1572 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1573 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1574 for (plane = 0; plane < s->bpp; plane++) {
1575 buf += decode_byterun(s->planebuf, s->planesize, gb);
1576 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1578 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1580 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1581 uint8_t *video = s->video[0];
1582 for (y = 0; y < avctx->height; y++) {
1583 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1584 memset(s->ham_buf, 0, s->planesize * 8);
1585 for (plane = 0; plane < s->bpp; plane++) {
1586 buf += decode_byterun(s->planebuf, s->planesize, gb);
1587 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1588 memcpy(video, s->planebuf, s->planesize);
1589 video += s->planesize;
1591 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1593 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1595 } else { // AV_PIX_FMT_BGR32
1596 for (y = 0; y < avctx->height; y++) {
1597 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1598 memset(row, 0, avctx->width << 2);
1599 for (plane = 0; plane < s->bpp; plane++) {
1600 buf += decode_byterun(s->planebuf, s->planesize, gb);
1601 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1605 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
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 buf += decode_byterun(row, avctx->width, gb);
1611 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1612 for (y = 0; y < avctx->height; y++) {
1613 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1614 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1615 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1618 return unsupported(avctx);
1619 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1620 if (av_get_bits_per_pixel(desc) == 32)
1621 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1623 return unsupported(avctx);
1627 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1628 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1629 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1630 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1632 return unsupported(avctx);
1635 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1636 if (av_get_bits_per_pixel(desc) == 32)
1637 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1639 return unsupported(avctx);
1641 return unsupported(avctx);
1645 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1649 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1654 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1656 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1661 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1663 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1667 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1671 if (s->is_interlaced)
1672 return unsupported(avctx);
1673 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1677 if (s->is_interlaced)
1678 return unsupported(avctx);
1679 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1683 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1686 return unsupported(avctx);
1689 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1690 memcpy(s->video[1], s->video[0], s->video_size);
1693 if (s->compression > 0xff) {
1694 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1696 for (y = 0; y < avctx->height; y++) {
1697 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1698 memset(row, 0, avctx->width);
1699 for (plane = 0; plane < s->bpp; plane++) {
1700 decodeplane8(row, buf, s->planesize, plane);
1701 buf += s->planesize;
1704 memcpy(frame->data[1], s->pal, 256 * 4);
1705 } else if (s->ham) {
1706 int i, count = 1 << s->ham;
1709 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1710 for (i = 0; i < count; i++) {
1711 s->ham_palbuf[i*2+1] = s->pal[i];
1713 for (i = 0; i < count; i++) {
1714 uint32_t tmp = i << (8 - s->ham);
1715 tmp |= tmp >> s->ham;
1716 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1717 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1718 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1719 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1720 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1721 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1723 if (s->masking == MASK_HAS_MASK) {
1724 for (i = 0; i < 8 * (1 << s->ham); i++)
1725 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1727 for (y = 0; y < avctx->height; y++) {
1728 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1729 memset(s->ham_buf, 0, s->planesize * 8);
1730 for (plane = 0; plane < s->bpp; plane++) {
1731 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1732 buf += s->planesize;
1734 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1737 return unsupported(avctx);
1741 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1745 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1746 frame->key_frame = 1;
1747 frame->pict_type = AV_PICTURE_TYPE_I;
1749 frame->key_frame = 0;
1750 frame->pict_type = AV_PICTURE_TYPE_P;
1758 #if CONFIG_IFF_ILBM_DECODER
1759 AVCodec ff_iff_ilbm_decoder = {
1761 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1762 .type = AVMEDIA_TYPE_VIDEO,
1763 .id = AV_CODEC_ID_IFF_ILBM,
1764 .priv_data_size = sizeof(IffContext),
1765 .init = decode_init,
1766 .close = decode_end,
1767 .decode = decode_frame,
1768 .capabilities = AV_CODEC_CAP_DR1,