2 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
30 #include "libavutil/imgutils.h"
31 #include "bytestream.h"
40 MASK_HAS_TRANSPARENT_COLOR,
48 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
49 uint32_t *ham_palbuf; ///< HAM decode table
50 uint32_t *mask_buf; ///< temporary buffer for palette indices
51 uint32_t *mask_palbuf; ///< masking palette table
52 unsigned compression; ///< delta compression method used
53 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
54 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
55 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
56 unsigned transparency; ///< TODO: transparency color index in palette
57 unsigned masking; ///< TODO: masking method used
58 int init; // 1 if buffer and palette data already initialized, 0 otherwise
59 int16_t tvdc[16]; ///< TVDC lookup table
62 #define LUT8_PART(plane, v) \
63 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
64 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
65 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
66 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
67 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
68 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
69 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
70 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
71 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
72 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
77 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
78 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
80 #define LUT8(plane) { \
81 LUT8_PART(plane, 0x0000000), \
82 LUT8_PART(plane, 0x1000000), \
83 LUT8_PART(plane, 0x0010000), \
84 LUT8_PART(plane, 0x1010000), \
85 LUT8_PART(plane, 0x0000100), \
86 LUT8_PART(plane, 0x1000100), \
87 LUT8_PART(plane, 0x0010100), \
88 LUT8_PART(plane, 0x1010100), \
89 LUT8_PART(plane, 0x0000001), \
90 LUT8_PART(plane, 0x1000001), \
91 LUT8_PART(plane, 0x0010001), \
92 LUT8_PART(plane, 0x1010001), \
93 LUT8_PART(plane, 0x0000101), \
94 LUT8_PART(plane, 0x1000101), \
95 LUT8_PART(plane, 0x0010101), \
96 LUT8_PART(plane, 0x1010101), \
99 // 8 planes * 8-bit mask
100 static const uint64_t plane8_lut[8][256] = {
101 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
102 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
105 #define LUT32(plane) { \
107 0, 0, 0, 1 << plane, \
108 0, 0, 1 << plane, 0, \
109 0, 0, 1 << plane, 1 << plane, \
110 0, 1 << plane, 0, 0, \
111 0, 1 << plane, 0, 1 << plane, \
112 0, 1 << plane, 1 << plane, 0, \
113 0, 1 << plane, 1 << plane, 1 << plane, \
114 1 << plane, 0, 0, 0, \
115 1 << plane, 0, 0, 1 << plane, \
116 1 << plane, 0, 1 << plane, 0, \
117 1 << plane, 0, 1 << plane, 1 << plane, \
118 1 << plane, 1 << plane, 0, 0, \
119 1 << plane, 1 << plane, 0, 1 << plane, \
120 1 << plane, 1 << plane, 1 << plane, 0, \
121 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
124 // 32 planes * 4-bit mask * 4 lookup tables each
125 static const uint32_t plane32_lut[32][16*4] = {
126 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
127 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
128 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
129 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
130 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
131 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
132 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
133 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
136 // Gray to RGB, required for palette table of grayscale images with bpp < 8
137 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
138 return x << 16 | x << 8 | x;
142 * Convert CMAP buffer (stored in extradata) to lavc palette format
144 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
146 IffContext *s = avctx->priv_data;
148 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
149 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
151 if (avctx->bits_per_coded_sample > 8) {
152 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
153 return AVERROR_INVALIDDATA;
156 count = 1 << avctx->bits_per_coded_sample;
157 // If extradata is smaller than actually needed, fill the remaining with black.
158 count = FFMIN(palette_size / 3, count);
160 for (i = 0; i < count; i++)
161 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
162 if (s->flags && count >= 32) { // EHB
163 for (i = 0; i < 32; i++)
164 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
165 count = FFMAX(count, 64);
167 } else { // Create gray-scale color palette for bps < 8
168 count = 1 << avctx->bits_per_coded_sample;
170 for (i = 0; i < count; i++)
171 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
173 if (s->masking == MASK_HAS_MASK) {
174 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
175 for (i = 0; i < count; i++)
177 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
178 s->transparency < 1 << avctx->bits_per_coded_sample)
179 pal[s->transparency] &= 0xFFFFFF;
184 * Extracts the IFF extra context and updates internal
185 * decoder structures.
187 * @param avctx the AVCodecContext where to extract extra context to
188 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
189 * @return >= 0 in case of success, a negative error code otherwise
191 static int extract_header(AVCodecContext *const avctx,
192 const AVPacket *const avpkt) {
195 IffContext *s = avctx->priv_data;
198 if (avctx->extradata_size < 2) {
199 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
200 return AVERROR_INVALIDDATA;
202 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
207 return AVERROR_INVALIDDATA;
208 image_size = avpkt->size - AV_RB16(avpkt->data);
210 buf_size = bytestream_get_be16(&buf);
211 if (buf_size <= 1 || image_size <= 1) {
212 av_log(avctx, AV_LOG_ERROR,
213 "Invalid image size received: %u -> image data offset: %d\n",
214 buf_size, image_size);
215 return AVERROR_INVALIDDATA;
218 buf = avctx->extradata;
219 buf_size = bytestream_get_be16(&buf);
220 if (buf_size <= 1 || palette_size < 0) {
221 av_log(avctx, AV_LOG_ERROR,
222 "Invalid palette size received: %u -> palette data offset: %d\n",
223 buf_size, palette_size);
224 return AVERROR_INVALIDDATA;
228 if (buf_size >= 41) {
229 s->compression = bytestream_get_byte(&buf);
230 s->bpp = bytestream_get_byte(&buf);
231 s->ham = bytestream_get_byte(&buf);
232 s->flags = bytestream_get_byte(&buf);
233 s->transparency = bytestream_get_be16(&buf);
234 s->masking = bytestream_get_byte(&buf);
235 for (i = 0; i < 16; i++)
236 s->tvdc[i] = bytestream_get_be16(&buf);
238 if (s->masking == MASK_HAS_MASK) {
239 if (s->bpp >= 8 && !s->ham) {
240 avctx->pix_fmt = AV_PIX_FMT_RGB32;
241 av_freep(&s->mask_buf);
242 av_freep(&s->mask_palbuf);
243 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
245 return AVERROR(ENOMEM);
247 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
248 av_freep(&s->mask_buf);
249 return AVERROR(ENOMEM);
251 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
252 if (!s->mask_palbuf) {
253 av_freep(&s->mask_buf);
254 return AVERROR(ENOMEM);
258 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
259 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
260 return AVERROR_PATCHWELCOME;
262 if (!s->bpp || s->bpp > 32) {
263 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
264 return AVERROR_INVALIDDATA;
265 } else if (s->ham >= 8) {
266 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
267 return AVERROR_INVALIDDATA;
270 av_freep(&s->ham_buf);
271 av_freep(&s->ham_palbuf);
274 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
276 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
278 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
280 return AVERROR(ENOMEM);
282 ham_count = 8 * (1 << s->ham);
283 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
284 if (!s->ham_palbuf) {
285 av_freep(&s->ham_buf);
286 return AVERROR(ENOMEM);
289 if (count) { // HAM with color palette attached
290 // prefill with black and palette and set HAM take direct value mask to zero
291 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
292 for (i=0; i < count; i++) {
293 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
296 } else { // HAM with grayscale color palette
298 for (i=0; i < count; i++) {
299 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
300 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
303 for (i=0; i < count; i++) {
304 uint32_t tmp = i << (8 - s->ham);
305 tmp |= tmp >> s->ham;
306 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
307 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
308 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
309 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
310 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
311 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
313 if (s->masking == MASK_HAS_MASK) {
314 for (i = 0; i < ham_count; i++)
315 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
323 static av_cold int decode_end(AVCodecContext *avctx)
325 IffContext *s = avctx->priv_data;
326 av_frame_free(&s->frame);
327 av_freep(&s->planebuf);
328 av_freep(&s->ham_buf);
329 av_freep(&s->ham_palbuf);
333 static av_cold int decode_init(AVCodecContext *avctx)
335 IffContext *s = avctx->priv_data;
338 if (avctx->bits_per_coded_sample <= 8) {
341 if (avctx->extradata_size >= 2)
342 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
345 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
346 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
347 } else if (avctx->bits_per_coded_sample <= 32) {
348 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
349 avctx->pix_fmt = AV_PIX_FMT_RGB32;
350 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
351 avctx->pix_fmt = AV_PIX_FMT_RGB444;
352 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
353 if (avctx->bits_per_coded_sample == 24) {
354 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
355 } else if (avctx->bits_per_coded_sample == 32) {
356 avctx->pix_fmt = AV_PIX_FMT_BGR32;
358 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
359 return AVERROR_PATCHWELCOME;
363 return AVERROR_INVALIDDATA;
366 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
368 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
369 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
371 return AVERROR(ENOMEM);
373 s->bpp = avctx->bits_per_coded_sample;
374 s->frame = av_frame_alloc();
377 return AVERROR(ENOMEM);
380 if ((err = extract_header(avctx, NULL)) < 0)
387 * Decode interleaved plane buffer up to 8bpp
388 * @param dst Destination buffer
389 * @param buf Source buffer
391 * @param plane plane number to decode as
393 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
395 const uint64_t *lut = plane8_lut[plane];
397 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
401 uint64_t v = AV_RN64A(dst) | lut[*buf++];
404 } while (--buf_size);
408 * Decode interleaved plane buffer up to 24bpp
409 * @param dst Destination buffer
410 * @param buf Source buffer
412 * @param plane plane number to decode as
414 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
416 const uint32_t *lut = plane32_lut[plane];
418 unsigned mask = (*buf >> 2) & ~3;
419 dst[0] |= lut[mask++];
420 dst[1] |= lut[mask++];
421 dst[2] |= lut[mask++];
423 mask = (*buf++ << 2) & 0x3F;
424 dst[4] |= lut[mask++];
425 dst[5] |= lut[mask++];
426 dst[6] |= lut[mask++];
429 } while (--buf_size);
432 #define DECODE_HAM_PLANE32(x) \
433 first = buf[x] << 1; \
434 second = buf[(x)+1] << 1; \
435 delta &= pal[first++]; \
436 delta |= pal[first]; \
438 delta &= pal[second++]; \
439 delta |= pal[second]; \
443 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
445 * @param dst the destination 24bpp buffer
446 * @param buf the source 8bpp chunky buffer
447 * @param pal the HAM decode table
448 * @param buf_size the plane size in bytes
450 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
451 const uint32_t *const pal, unsigned buf_size)
453 uint32_t delta = pal[1]; /* first palette entry */
455 uint32_t first, second;
456 DECODE_HAM_PLANE32(0);
457 DECODE_HAM_PLANE32(2);
458 DECODE_HAM_PLANE32(4);
459 DECODE_HAM_PLANE32(6);
462 } while (--buf_size);
465 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
466 const uint32_t *const pal, unsigned width)
469 *dst++ = pal[*buf++];
474 * Decode one complete byterun1 encoded line.
476 * @param dst the destination buffer where to store decompressed bitstream
477 * @param dst_size the destination plane size in bytes
478 * @param buf the source byterun1 compressed bitstream
479 * @param buf_end the EOF of source byterun1 compressed bitstream
480 * @return number of consumed bytes in byterun1 compressed bitstream
482 static int decode_byterun(uint8_t *dst, int dst_size,
483 const uint8_t *buf, const uint8_t *const buf_end)
485 const uint8_t *const buf_start = buf;
487 for (x = 0; x < dst_size && buf < buf_end;) {
489 const int8_t value = *buf++;
492 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
494 } else if (value > -128) {
496 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
502 return buf - buf_start;
505 #define DECODE_RGBX_COMMON(type) \
507 length = bytestream2_get_byte(gb); \
509 length = bytestream2_get_be16(gb); \
514 for (i = 0; i < length; i++) { \
515 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
527 * @param[out] dst Destination buffer
528 * @param width Width of destination buffer (pixels)
529 * @param height Height of destination buffer (pixels)
530 * @param linesize Line size of destination buffer (bytes)
532 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
534 int x = 0, y = 0, i, length;
535 while (bytestream2_get_bytes_left(gb) >= 4) {
536 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
537 length = bytestream2_get_byte(gb) & 0x7F;
538 DECODE_RGBX_COMMON(uint32_t)
544 * @param[out] dst Destination buffer
545 * @param width Width of destination buffer (pixels)
546 * @param height Height of destination buffer (pixels)
547 * @param linesize Line size of destination buffer (bytes)
549 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
551 int x = 0, y = 0, i, length;
552 while (bytestream2_get_bytes_left(gb) >= 2) {
553 uint32_t pixel = bytestream2_get_be16u(gb);
554 length = pixel & 0x7;
556 DECODE_RGBX_COMMON(uint16_t)
561 * Decode DEEP RLE 32-bit buffer
562 * @param[out] dst Destination buffer
563 * @param[in] src Source buffer
564 * @param src_size Source buffer size (bytes)
565 * @param width Width of destination buffer (pixels)
566 * @param height Height of destination buffer (pixels)
567 * @param linesize Line size of destination buffer (bytes)
569 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
571 const uint8_t *src_end = src + src_size;
573 while (src + 5 <= src_end) {
575 opcode = *(int8_t *)src++;
577 int size = opcode + 1;
578 for (i = 0; i < size; i++) {
579 int length = FFMIN(size - i, width);
580 memcpy(dst + y*linesize + x * 4, src, length * 4);
592 int size = -opcode + 1;
593 uint32_t pixel = AV_RN32(src);
594 for (i = 0; i < size; i++) {
595 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
610 * Decode DEEP TVDC 32-bit buffer
611 * @param[out] dst Destination buffer
612 * @param[in] src Source buffer
613 * @param src_size Source buffer size (bytes)
614 * @param width Width of destination buffer (pixels)
615 * @param height Height of destination buffer (pixels)
616 * @param linesize Line size of destination buffer (bytes)
617 * @param[int] tvdc TVDC lookup table
619 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)
621 int x = 0, y = 0, plane = 0;
625 for (i = 0; i < src_size * 2;) {
626 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
627 int d = tvdc[GETNIBBLE];
631 dst[y * linesize + x*4 + plane] = pixel;
634 if (i >= src_size * 2)
638 d = FFMIN(d, width - x);
639 for (j = 0; j < d; j++) {
640 dst[y * linesize + x*4 + plane] = pixel;
659 static int unsupported(AVCodecContext *avctx)
661 IffContext *s = avctx->priv_data;
662 avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
663 return AVERROR_INVALIDDATA;
666 static int decode_frame(AVCodecContext *avctx,
667 void *data, int *got_frame,
670 IffContext *s = avctx->priv_data;
671 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
672 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
673 const uint8_t *buf_end = buf + buf_size;
677 if ((res = extract_header(avctx, avpkt)) < 0)
679 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
681 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
682 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
683 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
685 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
686 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
687 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
692 switch (s->compression) {
694 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
695 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
696 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
697 for (plane = 0; plane < s->bpp; plane++) {
698 for (y = 0; y < avctx->height && buf < buf_end; y++) {
699 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
700 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
704 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
705 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
706 for (y = 0; y < avctx->height; y++) {
707 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
708 memset(s->ham_buf, 0, s->planesize * 8);
709 for (plane = 0; plane < s->bpp; plane++) {
710 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
711 if (start >= buf_end)
713 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
715 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
718 return unsupported(avctx);
719 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
720 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
721 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
723 for (y = 0; y < avctx->height && buf < buf_end; y++) {
724 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
725 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
727 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
728 for (x = 0; x < avctx->width; x++)
729 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
732 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
733 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
734 for (y = 0; y < avctx->height; y++) {
735 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
736 memset(row, 0, avctx->width);
737 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
738 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
742 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
743 for (y = 0; y < avctx->height; y++) {
744 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
745 memset(s->ham_buf, 0, s->planesize * 8);
746 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
747 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
750 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
752 } else { // AV_PIX_FMT_BGR32
753 for (y = 0; y < avctx->height; y++) {
754 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
755 memset(row, 0, avctx->width << 2);
756 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
757 decodeplane32((uint32_t *)row, buf,
758 FFMIN(s->planesize, buf_end - buf), plane);
763 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
764 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
765 for (y = 0; y < avctx->height && buf_end > buf; y++) {
766 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
767 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
768 buf += avctx->width + (avctx->width % 2); // padding if odd
770 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
771 for (y = 0; y < avctx->height && buf_end > buf; y++) {
772 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
773 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
774 buf += avctx->width + (avctx->width & 1); // padding if odd
775 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
778 return unsupported(avctx);
782 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
783 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
784 for (y = 0; y < avctx->height; y++) {
785 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
786 memset(row, 0, avctx->width);
787 for (plane = 0; plane < s->bpp; plane++) {
788 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
789 decodeplane8(row, s->planebuf, s->planesize, plane);
792 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
793 for (y = 0; y < avctx->height; y++) {
794 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
795 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
796 for (plane = 0; plane < s->bpp; plane++) {
797 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
798 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
800 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
802 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
803 for (y = 0; y < avctx->height; y++) {
804 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
805 memset(s->ham_buf, 0, s->planesize * 8);
806 for (plane = 0; plane < s->bpp; plane++) {
807 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
808 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
810 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
812 } else { // AV_PIX_FMT_BGR32
813 for (y = 0; y < avctx->height; y++) {
814 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
815 memset(row, 0, avctx->width << 2);
816 for (plane = 0; plane < s->bpp; plane++) {
817 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
818 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
822 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
823 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
824 for (y = 0; y < avctx->height; y++) {
825 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
826 buf += decode_byterun(row, avctx->width, buf, buf_end);
828 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
829 for (y = 0; y < avctx->height; y++) {
830 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
831 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
832 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
835 return unsupported(avctx);
836 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
837 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
838 if (av_get_bits_per_pixel(desc) == 32)
839 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
841 return unsupported(avctx);
845 bytestream2_init(&gb, buf, buf_size);
846 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
847 decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
848 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
849 decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
851 return unsupported(avctx);
854 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
855 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
856 if (av_get_bits_per_pixel(desc) == 32)
857 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
859 return unsupported(avctx);
861 return unsupported(avctx);
864 return unsupported(avctx);
867 if ((res = av_frame_ref(data, s->frame)) < 0)
875 #if CONFIG_IFF_ILBM_DECODER
876 AVCodec ff_iff_ilbm_decoder = {
878 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
879 .type = AVMEDIA_TYPE_VIDEO,
880 .id = AV_CODEC_ID_IFF_ILBM,
881 .priv_data_size = sizeof(IffContext),
884 .decode = decode_frame,
885 .capabilities = CODEC_CAP_DR1,
888 #if CONFIG_IFF_BYTERUN1_DECODER
889 AVCodec ff_iff_byterun1_decoder = {
891 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
892 .type = AVMEDIA_TYPE_VIDEO,
893 .id = AV_CODEC_ID_IFF_BYTERUN1,
894 .priv_data_size = sizeof(IffContext),
897 .decode = decode_frame,
898 .capabilities = CODEC_CAP_DR1,