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
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
38 MASK_HAS_TRANSPARENT_COLOR,
46 uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
47 uint32_t *ham_palbuf; ///< HAM decode table
48 uint32_t *mask_buf; ///< temporary buffer for palette indices
49 uint32_t *mask_palbuf; ///< masking palette table
50 unsigned compression; ///< delta compression method used
51 unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
52 unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
53 unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
54 unsigned transparency; ///< TODO: transparency color index in palette
55 unsigned masking; ///< TODO: masking method used
56 int init; // 1 if buffer and palette data already initialized, 0 otherwise
57 int16_t tvdc[16]; ///< TVDC lookup table
60 #define LUT8_PART(plane, v) \
61 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
62 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
63 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
64 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
65 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
66 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
67 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
68 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
69 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
70 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
71 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
72 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
73 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
74 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
75 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
76 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
78 #define LUT8(plane) { \
79 LUT8_PART(plane, 0x0000000), \
80 LUT8_PART(plane, 0x1000000), \
81 LUT8_PART(plane, 0x0010000), \
82 LUT8_PART(plane, 0x1010000), \
83 LUT8_PART(plane, 0x0000100), \
84 LUT8_PART(plane, 0x1000100), \
85 LUT8_PART(plane, 0x0010100), \
86 LUT8_PART(plane, 0x1010100), \
87 LUT8_PART(plane, 0x0000001), \
88 LUT8_PART(plane, 0x1000001), \
89 LUT8_PART(plane, 0x0010001), \
90 LUT8_PART(plane, 0x1010001), \
91 LUT8_PART(plane, 0x0000101), \
92 LUT8_PART(plane, 0x1000101), \
93 LUT8_PART(plane, 0x0010101), \
94 LUT8_PART(plane, 0x1010101), \
97 // 8 planes * 8-bit mask
98 static const uint64_t plane8_lut[8][256] = {
99 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
100 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
103 #define LUT32(plane) { \
105 0, 0, 0, 1 << plane, \
106 0, 0, 1 << plane, 0, \
107 0, 0, 1 << plane, 1 << plane, \
108 0, 1 << plane, 0, 0, \
109 0, 1 << plane, 0, 1 << plane, \
110 0, 1 << plane, 1 << plane, 0, \
111 0, 1 << plane, 1 << plane, 1 << plane, \
112 1 << plane, 0, 0, 0, \
113 1 << plane, 0, 0, 1 << plane, \
114 1 << plane, 0, 1 << plane, 0, \
115 1 << plane, 0, 1 << plane, 1 << plane, \
116 1 << plane, 1 << plane, 0, 0, \
117 1 << plane, 1 << plane, 0, 1 << plane, \
118 1 << plane, 1 << plane, 1 << plane, 0, \
119 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
122 // 32 planes * 4-bit mask * 4 lookup tables each
123 static const uint32_t plane32_lut[32][16*4] = {
124 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
125 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
126 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
127 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
128 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
129 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
130 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
131 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
134 // Gray to RGB, required for palette table of grayscale images with bpp < 8
135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
136 return x << 16 | x << 8 | x;
140 * Convert CMAP buffer (stored in extradata) to lavc palette format
142 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
144 IffContext *s = avctx->priv_data;
146 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
147 int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
149 if (avctx->bits_per_coded_sample > 8) {
150 av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
151 return AVERROR_INVALIDDATA;
154 count = 1 << avctx->bits_per_coded_sample;
155 // If extradata is smaller than actually needed, fill the remaining with black.
156 count = FFMIN(palette_size / 3, count);
158 for (i = 0; i < count; i++)
159 pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
160 if (s->flags && count >= 32) { // EHB
161 for (i = 0; i < 32; i++)
162 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
163 count = FFMAX(count, 64);
165 } else { // Create gray-scale color palette for bps < 8
166 count = 1 << avctx->bits_per_coded_sample;
168 for (i = 0; i < count; i++)
169 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
171 if (s->masking == MASK_HAS_MASK) {
172 memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
173 for (i = 0; i < count; i++)
175 } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
176 s->transparency < 1 << avctx->bits_per_coded_sample)
177 pal[s->transparency] &= 0xFFFFFF;
182 * Extracts the IFF extra context and updates internal
183 * decoder structures.
185 * @param avctx the AVCodecContext where to extract extra context to
186 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
187 * @return >= 0 in case of success, a negative error code otherwise
189 static int extract_header(AVCodecContext *const avctx,
190 const AVPacket *const avpkt) {
193 IffContext *s = avctx->priv_data;
196 if (avctx->extradata_size < 2) {
197 av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
198 return AVERROR_INVALIDDATA;
200 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
205 return AVERROR_INVALIDDATA;
206 image_size = avpkt->size - AV_RB16(avpkt->data);
208 buf_size = bytestream_get_be16(&buf);
209 if (buf_size <= 1 || image_size <= 1) {
210 av_log(avctx, AV_LOG_ERROR,
211 "Invalid image size received: %u -> image data offset: %d\n",
212 buf_size, image_size);
213 return AVERROR_INVALIDDATA;
216 buf = avctx->extradata;
217 buf_size = bytestream_get_be16(&buf);
218 if (buf_size <= 1 || palette_size < 0) {
219 av_log(avctx, AV_LOG_ERROR,
220 "Invalid palette size received: %u -> palette data offset: %d\n",
221 buf_size, palette_size);
222 return AVERROR_INVALIDDATA;
226 if (buf_size >= 41) {
227 s->compression = bytestream_get_byte(&buf);
228 s->bpp = bytestream_get_byte(&buf);
229 s->ham = bytestream_get_byte(&buf);
230 s->flags = bytestream_get_byte(&buf);
231 s->transparency = bytestream_get_be16(&buf);
232 s->masking = bytestream_get_byte(&buf);
233 for (i = 0; i < 16; i++)
234 s->tvdc[i] = bytestream_get_be16(&buf);
236 if (s->masking == MASK_HAS_MASK) {
237 if (s->bpp >= 8 && !s->ham) {
238 avctx->pix_fmt = AV_PIX_FMT_RGB32;
239 av_freep(&s->mask_buf);
240 av_freep(&s->mask_palbuf);
241 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
243 return AVERROR(ENOMEM);
245 av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
246 av_freep(&s->mask_buf);
247 return AVERROR(ENOMEM);
249 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
250 if (!s->mask_palbuf) {
251 av_freep(&s->mask_buf);
252 return AVERROR(ENOMEM);
256 } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
257 av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
258 return AVERROR_PATCHWELCOME;
260 if (!s->bpp || s->bpp > 32) {
261 av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
262 return AVERROR_INVALIDDATA;
263 } else if (s->ham >= 8) {
264 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
265 return AVERROR_INVALIDDATA;
268 av_freep(&s->ham_buf);
269 av_freep(&s->ham_palbuf);
272 int i, count = FFMIN(palette_size / 3, 1 << s->ham);
274 const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
276 s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
278 return AVERROR(ENOMEM);
280 ham_count = 8 * (1 << s->ham);
281 s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
282 if (!s->ham_palbuf) {
283 av_freep(&s->ham_buf);
284 return AVERROR(ENOMEM);
287 if (count) { // HAM with color palette attached
288 // prefill with black and palette and set HAM take direct value mask to zero
289 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
290 for (i=0; i < count; i++) {
291 s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
294 } else { // HAM with grayscale color palette
296 for (i=0; i < count; i++) {
297 s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
298 s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
301 for (i=0; i < count; i++) {
302 uint32_t tmp = i << (8 - s->ham);
303 tmp |= tmp >> s->ham;
304 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
305 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
306 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
307 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
308 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
309 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
311 if (s->masking == MASK_HAS_MASK) {
312 for (i = 0; i < ham_count; i++)
313 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
321 static av_cold int decode_end(AVCodecContext *avctx)
323 IffContext *s = avctx->priv_data;
324 av_frame_free(&s->frame);
325 av_freep(&s->planebuf);
326 av_freep(&s->ham_buf);
327 av_freep(&s->ham_palbuf);
331 static av_cold int decode_init(AVCodecContext *avctx)
333 IffContext *s = avctx->priv_data;
336 if (avctx->bits_per_coded_sample <= 8) {
339 if (avctx->extradata_size >= 2)
340 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
343 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
344 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
345 } else if (avctx->bits_per_coded_sample <= 32) {
346 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
347 avctx->pix_fmt = AV_PIX_FMT_RGB32;
348 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
349 avctx->pix_fmt = AV_PIX_FMT_RGB444;
350 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
351 if (avctx->bits_per_coded_sample == 24) {
352 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
353 } else if (avctx->bits_per_coded_sample == 32) {
354 avctx->pix_fmt = AV_PIX_FMT_BGR32;
356 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
357 return AVERROR_PATCHWELCOME;
361 return AVERROR_INVALIDDATA;
364 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
366 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
367 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
369 return AVERROR(ENOMEM);
371 s->bpp = avctx->bits_per_coded_sample;
372 s->frame = av_frame_alloc();
375 return AVERROR(ENOMEM);
378 if ((err = extract_header(avctx, NULL)) < 0)
385 * Decode interleaved plane buffer up to 8bpp
386 * @param dst Destination buffer
387 * @param buf Source buffer
389 * @param plane plane number to decode as
391 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
393 const uint64_t *lut = plane8_lut[plane];
395 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
399 uint64_t v = AV_RN64A(dst) | lut[*buf++];
402 } while (--buf_size);
406 * Decode interleaved plane buffer up to 24bpp
407 * @param dst Destination buffer
408 * @param buf Source buffer
410 * @param plane plane number to decode as
412 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
414 const uint32_t *lut = plane32_lut[plane];
416 unsigned mask = (*buf >> 2) & ~3;
417 dst[0] |= lut[mask++];
418 dst[1] |= lut[mask++];
419 dst[2] |= lut[mask++];
421 mask = (*buf++ << 2) & 0x3F;
422 dst[4] |= lut[mask++];
423 dst[5] |= lut[mask++];
424 dst[6] |= lut[mask++];
427 } while (--buf_size);
430 #define DECODE_HAM_PLANE32(x) \
431 first = buf[x] << 1; \
432 second = buf[(x)+1] << 1; \
433 delta &= pal[first++]; \
434 delta |= pal[first]; \
436 delta &= pal[second++]; \
437 delta |= pal[second]; \
441 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
443 * @param dst the destination 24bpp buffer
444 * @param buf the source 8bpp chunky buffer
445 * @param pal the HAM decode table
446 * @param buf_size the plane size in bytes
448 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
449 const uint32_t *const pal, unsigned buf_size)
451 uint32_t delta = pal[1]; /* first palette entry */
453 uint32_t first, second;
454 DECODE_HAM_PLANE32(0);
455 DECODE_HAM_PLANE32(2);
456 DECODE_HAM_PLANE32(4);
457 DECODE_HAM_PLANE32(6);
460 } while (--buf_size);
463 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
464 const uint32_t *const pal, unsigned width)
467 *dst++ = pal[*buf++];
472 * Decode one complete byterun1 encoded line.
474 * @param dst the destination buffer where to store decompressed bitstream
475 * @param dst_size the destination plane size in bytes
476 * @param buf the source byterun1 compressed bitstream
477 * @param buf_end the EOF of source byterun1 compressed bitstream
478 * @return number of consumed bytes in byterun1 compressed bitstream
480 static int decode_byterun(uint8_t *dst, int dst_size,
481 const uint8_t *buf, const uint8_t *const buf_end)
483 const uint8_t *const buf_start = buf;
485 for (x = 0; x < dst_size && buf < buf_end;) {
487 const int8_t value = *buf++;
490 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
492 } else if (value > -128) {
494 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
500 return buf - buf_start;
503 #define DECODE_RGBX_COMMON(type) \
505 length = bytestream2_get_byte(gb); \
507 length = bytestream2_get_be16(gb); \
512 for (i = 0; i < length; i++) { \
513 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
525 * @param[out] dst Destination buffer
526 * @param width Width of destination buffer (pixels)
527 * @param height Height of destination buffer (pixels)
528 * @param linesize Line size of destination buffer (bytes)
530 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
532 int x = 0, y = 0, i, length;
533 while (bytestream2_get_bytes_left(gb) >= 4) {
534 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
535 length = bytestream2_get_byte(gb) & 0x7F;
536 DECODE_RGBX_COMMON(uint32_t)
542 * @param[out] dst Destination buffer
543 * @param width Width of destination buffer (pixels)
544 * @param height Height of destination buffer (pixels)
545 * @param linesize Line size of destination buffer (bytes)
547 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
549 int x = 0, y = 0, i, length;
550 while (bytestream2_get_bytes_left(gb) >= 2) {
551 uint32_t pixel = bytestream2_get_be16u(gb);
552 length = pixel & 0x7;
554 DECODE_RGBX_COMMON(uint16_t)
559 * Decode DEEP RLE 32-bit buffer
560 * @param[out] dst Destination buffer
561 * @param[in] src Source buffer
562 * @param src_size Source buffer size (bytes)
563 * @param width Width of destination buffer (pixels)
564 * @param height Height of destination buffer (pixels)
565 * @param linesize Line size of destination buffer (bytes)
567 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
569 const uint8_t *src_end = src + src_size;
571 while (src + 5 <= src_end) {
573 opcode = *(int8_t *)src++;
575 int size = opcode + 1;
576 for (i = 0; i < size; i++) {
577 int length = FFMIN(size - i, width);
578 memcpy(dst + y*linesize + x * 4, src, length * 4);
590 int size = -opcode + 1;
591 uint32_t pixel = AV_RN32(src);
592 for (i = 0; i < size; i++) {
593 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
608 * Decode DEEP TVDC 32-bit buffer
609 * @param[out] dst Destination buffer
610 * @param[in] src Source buffer
611 * @param src_size Source buffer size (bytes)
612 * @param width Width of destination buffer (pixels)
613 * @param height Height of destination buffer (pixels)
614 * @param linesize Line size of destination buffer (bytes)
615 * @param[int] tvdc TVDC lookup table
617 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)
619 int x = 0, y = 0, plane = 0;
623 for (i = 0; i < src_size * 2;) {
624 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
625 int d = tvdc[GETNIBBLE];
629 dst[y * linesize + x*4 + plane] = pixel;
632 if (i >= src_size * 2)
636 d = FFMIN(d, width - x);
637 for (j = 0; j < d; j++) {
638 dst[y * linesize + x*4 + plane] = pixel;
657 static int unsupported(AVCodecContext *avctx)
659 IffContext *s = avctx->priv_data;
660 avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
661 return AVERROR_INVALIDDATA;
664 static int decode_frame(AVCodecContext *avctx,
665 void *data, int *got_frame,
668 IffContext *s = avctx->priv_data;
669 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
670 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
671 const uint8_t *buf_end = buf + buf_size;
675 if ((res = extract_header(avctx, avpkt)) < 0)
677 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
679 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
680 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
681 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
683 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
684 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
685 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
690 switch (s->compression) {
692 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
693 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
694 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
695 for (plane = 0; plane < s->bpp; plane++) {
696 for (y = 0; y < avctx->height && buf < buf_end; y++) {
697 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
698 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
702 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
703 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
704 for (y = 0; y < avctx->height; y++) {
705 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
706 memset(s->ham_buf, 0, s->planesize * 8);
707 for (plane = 0; plane < s->bpp; plane++) {
708 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
709 if (start >= buf_end)
711 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
713 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
716 return unsupported(avctx);
717 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
718 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
719 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
721 for (y = 0; y < avctx->height && buf < buf_end; y++) {
722 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
723 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
725 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
726 for (x = 0; x < avctx->width; x++)
727 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
730 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
731 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
732 for (y = 0; y < avctx->height; y++) {
733 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
734 memset(row, 0, avctx->width);
735 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
736 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
740 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
741 for (y = 0; y < avctx->height; y++) {
742 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
743 memset(s->ham_buf, 0, s->planesize * 8);
744 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
745 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
748 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
750 } else { // AV_PIX_FMT_BGR32
751 for (y = 0; y < avctx->height; y++) {
752 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
753 memset(row, 0, avctx->width << 2);
754 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
755 decodeplane32((uint32_t *)row, buf,
756 FFMIN(s->planesize, buf_end - buf), plane);
761 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
762 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
763 for (y = 0; y < avctx->height && buf_end > buf; y++) {
764 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
765 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
766 buf += avctx->width + (avctx->width % 2); // padding if odd
768 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
769 for (y = 0; y < avctx->height && buf_end > buf; y++) {
770 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
771 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
772 buf += avctx->width + (avctx->width & 1); // padding if odd
773 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
776 return unsupported(avctx);
780 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
781 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
782 for (y = 0; y < avctx->height; y++) {
783 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
784 memset(row, 0, avctx->width);
785 for (plane = 0; plane < s->bpp; plane++) {
786 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
787 decodeplane8(row, s->planebuf, s->planesize, plane);
790 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
791 for (y = 0; y < avctx->height; y++) {
792 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
793 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
794 for (plane = 0; plane < s->bpp; plane++) {
795 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
796 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
798 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
800 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
801 for (y = 0; y < avctx->height; y++) {
802 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
803 memset(s->ham_buf, 0, s->planesize * 8);
804 for (plane = 0; plane < s->bpp; plane++) {
805 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
806 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
808 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
810 } else { // AV_PIX_FMT_BGR32
811 for (y = 0; y < avctx->height; y++) {
812 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
813 memset(row, 0, avctx->width << 2);
814 for (plane = 0; plane < s->bpp; plane++) {
815 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
816 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
820 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
821 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
822 for (y = 0; y < avctx->height; y++) {
823 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
824 buf += decode_byterun(row, avctx->width, buf, buf_end);
826 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
827 for (y = 0; y < avctx->height; y++) {
828 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
829 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
830 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
833 return unsupported(avctx);
834 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
835 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
836 if (av_get_bits_per_pixel(desc) == 32)
837 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
839 return unsupported(avctx);
843 bytestream2_init(&gb, buf, buf_size);
844 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
845 decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
846 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
847 decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
849 return unsupported(avctx);
852 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
853 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
854 if (av_get_bits_per_pixel(desc) == 32)
855 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
857 return unsupported(avctx);
859 return unsupported(avctx);
862 return unsupported(avctx);
865 if ((res = av_frame_ref(data, s->frame)) < 0)
873 #if CONFIG_IFF_ILBM_DECODER
874 AVCodec ff_iff_ilbm_decoder = {
876 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
877 .type = AVMEDIA_TYPE_VIDEO,
878 .id = AV_CODEC_ID_IFF_ILBM,
879 .priv_data_size = sizeof(IffContext),
882 .decode = decode_frame,
883 .capabilities = CODEC_CAP_DR1,
886 #if CONFIG_IFF_BYTERUN1_DECODER
887 AVCodec ff_iff_byterun1_decoder = {
889 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
890 .type = AVMEDIA_TYPE_VIDEO,
891 .id = AV_CODEC_ID_IFF_BYTERUN1,
892 .priv_data_size = sizeof(IffContext),
895 .decode = decode_frame,
896 .capabilities = CODEC_CAP_DR1,