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_init(AVCodecContext *avctx)
323 IffContext *s = avctx->priv_data;
326 if (avctx->bits_per_coded_sample <= 8) {
329 if (avctx->extradata_size >= 2)
330 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
333 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
334 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
335 } else if (avctx->bits_per_coded_sample <= 32) {
336 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
337 avctx->pix_fmt = AV_PIX_FMT_RGB32;
338 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
339 avctx->pix_fmt = AV_PIX_FMT_RGB444;
340 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
341 if (avctx->bits_per_coded_sample == 24) {
342 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
343 } else if (avctx->bits_per_coded_sample == 32) {
344 avctx->pix_fmt = AV_PIX_FMT_BGR32;
346 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
347 return AVERROR_PATCHWELCOME;
351 return AVERROR_INVALIDDATA;
354 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
356 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
357 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
359 return AVERROR(ENOMEM);
361 s->bpp = avctx->bits_per_coded_sample;
362 s->frame = av_frame_alloc();
364 return AVERROR(ENOMEM);
366 if ((err = extract_header(avctx, NULL)) < 0)
373 * Decode interleaved plane buffer up to 8bpp
374 * @param dst Destination buffer
375 * @param buf Source buffer
377 * @param plane plane number to decode as
379 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
381 const uint64_t *lut = plane8_lut[plane];
383 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
387 uint64_t v = AV_RN64A(dst) | lut[*buf++];
390 } while (--buf_size);
394 * Decode interleaved plane buffer up to 24bpp
395 * @param dst Destination buffer
396 * @param buf Source buffer
398 * @param plane plane number to decode as
400 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
402 const uint32_t *lut = plane32_lut[plane];
404 unsigned mask = (*buf >> 2) & ~3;
405 dst[0] |= lut[mask++];
406 dst[1] |= lut[mask++];
407 dst[2] |= lut[mask++];
409 mask = (*buf++ << 2) & 0x3F;
410 dst[4] |= lut[mask++];
411 dst[5] |= lut[mask++];
412 dst[6] |= lut[mask++];
415 } while (--buf_size);
418 #define DECODE_HAM_PLANE32(x) \
419 first = buf[x] << 1; \
420 second = buf[(x)+1] << 1; \
421 delta &= pal[first++]; \
422 delta |= pal[first]; \
424 delta &= pal[second++]; \
425 delta |= pal[second]; \
429 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
431 * @param dst the destination 24bpp buffer
432 * @param buf the source 8bpp chunky buffer
433 * @param pal the HAM decode table
434 * @param buf_size the plane size in bytes
436 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
437 const uint32_t *const pal, unsigned buf_size)
439 uint32_t delta = pal[1]; /* first palette entry */
441 uint32_t first, second;
442 DECODE_HAM_PLANE32(0);
443 DECODE_HAM_PLANE32(2);
444 DECODE_HAM_PLANE32(4);
445 DECODE_HAM_PLANE32(6);
448 } while (--buf_size);
451 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
452 const uint32_t *const pal, unsigned width)
455 *dst++ = pal[*buf++];
460 * Decode one complete byterun1 encoded line.
462 * @param dst the destination buffer where to store decompressed bitstream
463 * @param dst_size the destination plane size in bytes
464 * @param buf the source byterun1 compressed bitstream
465 * @param buf_end the EOF of source byterun1 compressed bitstream
466 * @return number of consumed bytes in byterun1 compressed bitstream
468 static int decode_byterun(uint8_t *dst, int dst_size,
469 const uint8_t *buf, const uint8_t *const buf_end)
471 const uint8_t *const buf_start = buf;
473 for (x = 0; x < dst_size && buf < buf_end;) {
475 const int8_t value = *buf++;
478 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
480 } else if (value > -128) {
482 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
488 return buf - buf_start;
491 #define DECODE_RGBX_COMMON(type) \
493 length = bytestream2_get_byte(gb); \
495 length = bytestream2_get_be16(gb); \
500 for (i = 0; i < length; i++) { \
501 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
513 * @param[out] dst Destination buffer
514 * @param width Width of destination buffer (pixels)
515 * @param height Height of destination buffer (pixels)
516 * @param linesize Line size of destination buffer (bytes)
518 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
520 int x = 0, y = 0, i, length;
521 while (bytestream2_get_bytes_left(gb) >= 4) {
522 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
523 length = bytestream2_get_byte(gb) & 0x7F;
524 DECODE_RGBX_COMMON(uint32_t)
530 * @param[out] dst Destination buffer
531 * @param width Width of destination buffer (pixels)
532 * @param height Height of destination buffer (pixels)
533 * @param linesize Line size of destination buffer (bytes)
535 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
537 int x = 0, y = 0, i, length;
538 while (bytestream2_get_bytes_left(gb) >= 2) {
539 uint32_t pixel = bytestream2_get_be16u(gb);
540 length = pixel & 0x7;
542 DECODE_RGBX_COMMON(uint16_t)
547 * Decode DEEP RLE 32-bit buffer
548 * @param[out] dst Destination buffer
549 * @param[in] src Source buffer
550 * @param src_size Source buffer size (bytes)
551 * @param width Width of destination buffer (pixels)
552 * @param height Height of destination buffer (pixels)
553 * @param linesize Line size of destination buffer (bytes)
555 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
557 const uint8_t *src_end = src + src_size;
559 while (src + 5 <= src_end) {
561 opcode = *(int8_t *)src++;
563 int size = opcode + 1;
564 for (i = 0; i < size; i++) {
565 int length = FFMIN(size - i, width);
566 memcpy(dst + y*linesize + x * 4, src, length * 4);
578 int size = -opcode + 1;
579 uint32_t pixel = AV_RN32(src);
580 for (i = 0; i < size; i++) {
581 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
596 * Decode DEEP TVDC 32-bit buffer
597 * @param[out] dst Destination buffer
598 * @param[in] src Source buffer
599 * @param src_size Source buffer size (bytes)
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)
603 * @param[int] tvdc TVDC lookup table
605 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)
607 int x = 0, y = 0, plane = 0;
611 for (i = 0; i < src_size * 2;) {
612 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
613 int d = tvdc[GETNIBBLE];
617 dst[y * linesize + x*4 + plane] = pixel;
620 if (i >= src_size * 2)
624 d = FFMIN(d, width - x);
625 for (j = 0; j < d; j++) {
626 dst[y * linesize + x*4 + plane] = pixel;
645 static int unsupported(AVCodecContext *avctx)
647 IffContext *s = avctx->priv_data;
648 avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
649 return AVERROR_INVALIDDATA;
652 static int decode_frame(AVCodecContext *avctx,
653 void *data, int *got_frame,
656 IffContext *s = avctx->priv_data;
657 const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
658 const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
659 const uint8_t *buf_end = buf + buf_size;
663 if ((res = extract_header(avctx, avpkt)) < 0)
665 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
667 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
668 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
669 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
671 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
672 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
673 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
678 switch (s->compression) {
680 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
681 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
682 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
683 for (plane = 0; plane < s->bpp; plane++) {
684 for (y = 0; y < avctx->height && buf < buf_end; y++) {
685 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
686 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
690 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
691 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
692 for (y = 0; y < avctx->height; y++) {
693 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
694 memset(s->ham_buf, 0, s->planesize * 8);
695 for (plane = 0; plane < s->bpp; plane++) {
696 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
697 if (start >= buf_end)
699 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
701 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
704 return unsupported(avctx);
705 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
706 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
707 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
709 for (y = 0; y < avctx->height && buf < buf_end; y++) {
710 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
711 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
713 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
714 for (x = 0; x < avctx->width; x++)
715 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
718 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
719 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
720 for (y = 0; y < avctx->height; y++) {
721 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
722 memset(row, 0, avctx->width);
723 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
724 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
728 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
729 for (y = 0; y < avctx->height; y++) {
730 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
731 memset(s->ham_buf, 0, s->planesize * 8);
732 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
733 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
736 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
738 } else { // AV_PIX_FMT_BGR32
739 for (y = 0; y < avctx->height; y++) {
740 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
741 memset(row, 0, avctx->width << 2);
742 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
743 decodeplane32((uint32_t *)row, buf,
744 FFMIN(s->planesize, buf_end - buf), plane);
749 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
750 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
751 for (y = 0; y < avctx->height && buf_end > buf; y++) {
752 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
753 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
754 buf += avctx->width + (avctx->width % 2); // padding if odd
756 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
757 for (y = 0; y < avctx->height && buf_end > buf; y++) {
758 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
759 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
760 buf += avctx->width + (avctx->width & 1); // padding if odd
761 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
764 return unsupported(avctx);
768 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
769 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
770 for (y = 0; y < avctx->height; y++) {
771 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
772 memset(row, 0, avctx->width);
773 for (plane = 0; plane < s->bpp; plane++) {
774 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
775 decodeplane8(row, s->planebuf, s->planesize, plane);
778 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
779 for (y = 0; y < avctx->height; y++) {
780 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
781 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
782 for (plane = 0; plane < s->bpp; plane++) {
783 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
784 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
786 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
788 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
789 for (y = 0; y < avctx->height; y++) {
790 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
791 memset(s->ham_buf, 0, s->planesize * 8);
792 for (plane = 0; plane < s->bpp; plane++) {
793 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
794 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
796 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
798 } else { // AV_PIX_FMT_BGR32
799 for (y = 0; y < avctx->height; y++) {
800 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
801 memset(row, 0, avctx->width << 2);
802 for (plane = 0; plane < s->bpp; plane++) {
803 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
804 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
808 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
809 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
810 for (y = 0; y < avctx->height; y++) {
811 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
812 buf += decode_byterun(row, avctx->width, buf, buf_end);
814 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
815 for (y = 0; y < avctx->height; y++) {
816 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
817 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
818 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
821 return unsupported(avctx);
822 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
823 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
824 if (av_get_bits_per_pixel(desc) == 32)
825 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
827 return unsupported(avctx);
831 bytestream2_init(&gb, buf, buf_size);
832 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
833 decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
834 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
835 decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
837 return unsupported(avctx);
840 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
841 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
842 if (av_get_bits_per_pixel(desc) == 32)
843 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
845 return unsupported(avctx);
847 return unsupported(avctx);
850 return unsupported(avctx);
853 if ((res = av_frame_ref(data, s->frame)) < 0)
861 static av_cold int decode_end(AVCodecContext *avctx)
863 IffContext *s = avctx->priv_data;
864 av_frame_free(&s->frame);
865 av_freep(&s->planebuf);
866 av_freep(&s->ham_buf);
867 av_freep(&s->ham_palbuf);
871 #if CONFIG_IFF_ILBM_DECODER
872 AVCodec ff_iff_ilbm_decoder = {
874 .type = AVMEDIA_TYPE_VIDEO,
875 .id = AV_CODEC_ID_IFF_ILBM,
876 .priv_data_size = sizeof(IffContext),
879 .decode = decode_frame,
880 .capabilities = CODEC_CAP_DR1,
881 .long_name = NULL_IF_CONFIG_SMALL("IFF"),
884 #if CONFIG_IFF_BYTERUN1_DECODER
885 AVCodec ff_iff_byterun1_decoder = {
887 .type = AVMEDIA_TYPE_VIDEO,
888 .id = AV_CODEC_ID_IFF_BYTERUN1,
889 .priv_data_size = sizeof(IffContext),
892 .decode = decode_frame,
893 .capabilities = CODEC_CAP_DR1,
894 .long_name = NULL_IF_CONFIG_SMALL("IFF"),