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[0];
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]);
376 av_freep(&s->pal[0]);
377 av_freep(&s->pal[1]);
381 static av_cold int decode_init(AVCodecContext *avctx)
383 IffContext *s = avctx->priv_data;
386 if (avctx->bits_per_coded_sample <= 8) {
389 if (avctx->extradata_size >= 2)
390 palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
393 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
394 (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
395 } else if (avctx->bits_per_coded_sample <= 32) {
396 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
397 avctx->pix_fmt = AV_PIX_FMT_RGB32;
398 } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
399 avctx->pix_fmt = AV_PIX_FMT_RGB444;
400 } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
401 if (avctx->bits_per_coded_sample == 24) {
402 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
403 } else if (avctx->bits_per_coded_sample == 32) {
404 avctx->pix_fmt = AV_PIX_FMT_BGR32;
406 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
407 return AVERROR_PATCHWELCOME;
411 return AVERROR_INVALIDDATA;
414 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
416 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
417 s->planebuf = av_malloc(s->planesize + AV_INPUT_BUFFER_PADDING_SIZE);
419 return AVERROR(ENOMEM);
421 s->bpp = avctx->bits_per_coded_sample;
423 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
424 s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
425 s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
426 s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
427 s->pal[0] = av_calloc(256, sizeof(*s->pal[0]));
428 s->pal[1] = av_calloc(256, sizeof(*s->pal[1]));
429 if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
430 return AVERROR(ENOMEM);
433 if ((err = extract_header(avctx, NULL)) < 0)
440 * Decode interleaved plane buffer up to 8bpp
441 * @param dst Destination buffer
442 * @param buf Source buffer
444 * @param plane plane number to decode as
446 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
448 const uint64_t *lut = plane8_lut[plane];
450 av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
454 uint64_t v = AV_RN64A(dst) | lut[*buf++];
457 } while (--buf_size);
461 * Decode interleaved plane buffer up to 24bpp
462 * @param dst Destination buffer
463 * @param buf Source buffer
465 * @param plane plane number to decode as
467 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
469 const uint32_t *lut = plane32_lut[plane];
471 unsigned mask = (*buf >> 2) & ~3;
472 dst[0] |= lut[mask++];
473 dst[1] |= lut[mask++];
474 dst[2] |= lut[mask++];
476 mask = (*buf++ << 2) & 0x3F;
477 dst[4] |= lut[mask++];
478 dst[5] |= lut[mask++];
479 dst[6] |= lut[mask++];
482 } while (--buf_size);
485 #define DECODE_HAM_PLANE32(x) \
486 first = buf[x] << 1; \
487 second = buf[(x)+1] << 1; \
488 delta &= pal[first++]; \
489 delta |= pal[first]; \
491 delta &= pal[second++]; \
492 delta |= pal[second]; \
496 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
498 * @param dst the destination 24bpp buffer
499 * @param buf the source 8bpp chunky buffer
500 * @param pal the HAM decode table
501 * @param buf_size the plane size in bytes
503 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
504 const uint32_t *const pal, unsigned buf_size)
506 uint32_t delta = pal[1]; /* first palette entry */
508 uint32_t first, second;
509 DECODE_HAM_PLANE32(0);
510 DECODE_HAM_PLANE32(2);
511 DECODE_HAM_PLANE32(4);
512 DECODE_HAM_PLANE32(6);
515 } while (--buf_size);
518 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
519 const uint32_t *const pal, unsigned width)
522 *dst++ = pal[*buf++];
527 * Decode one complete byterun1 encoded line.
529 * @param dst the destination buffer where to store decompressed bitstream
530 * @param dst_size the destination plane size in bytes
531 * @param buf the source byterun1 compressed bitstream
532 * @param buf_end the EOF of source byterun1 compressed bitstream
533 * @return number of consumed bytes in byterun1 compressed bitstream
535 static int decode_byterun(uint8_t *dst, int dst_size,
539 for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
541 const int8_t value = bytestream2_get_byte(gb);
543 length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
544 bytestream2_get_buffer(gb, dst + x, length);
545 if (length < value + 1)
546 bytestream2_skip(gb, value + 1 - length);
547 } else if (value > -128) {
548 length = FFMIN(-value + 1, dst_size - x);
549 memset(dst + x, bytestream2_get_byte(gb), length);
556 av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
557 memset(dst+x, 0, dst_size - x);
559 return bytestream2_tell(gb);
562 #define DECODE_RGBX_COMMON(type) \
564 length = bytestream2_get_byte(gb); \
566 length = bytestream2_get_be16(gb); \
571 for (i = 0; i < length; i++) { \
572 *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
584 * @param[out] dst Destination buffer
585 * @param width Width of destination buffer (pixels)
586 * @param height Height of destination buffer (pixels)
587 * @param linesize Line size of destination buffer (bytes)
589 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
591 int x = 0, y = 0, i, length;
592 while (bytestream2_get_bytes_left(gb) >= 4) {
593 uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
594 length = bytestream2_get_byte(gb) & 0x7F;
595 DECODE_RGBX_COMMON(uint32_t)
601 * @param[out] dst Destination buffer
602 * @param width Width of destination buffer (pixels)
603 * @param height Height of destination buffer (pixels)
604 * @param linesize Line size of destination buffer (bytes)
606 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
608 int x = 0, y = 0, i, length;
609 while (bytestream2_get_bytes_left(gb) >= 2) {
610 uint32_t pixel = bytestream2_get_be16u(gb);
611 length = pixel & 0x7;
613 DECODE_RGBX_COMMON(uint16_t)
618 * Decode DEEP RLE 32-bit buffer
619 * @param[out] dst Destination buffer
620 * @param[in] src Source buffer
621 * @param src_size Source buffer size (bytes)
622 * @param width Width of destination buffer (pixels)
623 * @param height Height of destination buffer (pixels)
624 * @param linesize Line size of destination buffer (bytes)
626 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
628 const uint8_t *src_end = src + src_size;
630 while (src + 5 <= src_end) {
632 opcode = *(int8_t *)src++;
634 int size = opcode + 1;
635 for (i = 0; i < size; i++) {
636 int length = FFMIN(size - i, width);
637 memcpy(dst + y*linesize + x * 4, src, length * 4);
649 int size = -opcode + 1;
650 uint32_t pixel = AV_RN32(src);
651 for (i = 0; i < size; i++) {
652 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
667 * Decode DEEP TVDC 32-bit buffer
668 * @param[out] dst Destination buffer
669 * @param[in] src Source buffer
670 * @param src_size Source buffer size (bytes)
671 * @param width Width of destination buffer (pixels)
672 * @param height Height of destination buffer (pixels)
673 * @param linesize Line size of destination buffer (bytes)
674 * @param[int] tvdc TVDC lookup table
676 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)
678 int x = 0, y = 0, plane = 0;
682 for (i = 0; i < src_size * 2;) {
683 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
684 int d = tvdc[GETNIBBLE];
688 dst[y * linesize + x*4 + plane] = pixel;
691 if (i >= src_size * 2)
695 d = FFMIN(d, width - x);
696 for (j = 0; j < d; j++) {
697 dst[y * linesize + x*4 + plane] = pixel;
716 static void decode_short_horizontal_delta(uint8_t *dst,
717 const uint8_t *buf, const uint8_t *buf_end,
718 int w, int bpp, int dst_size)
720 int planepitch = FFALIGN(w, 16) >> 3;
721 int pitch = planepitch * bpp;
722 GetByteContext ptrs, gb;
724 unsigned ofssrc, pos;
727 bytestream2_init(&ptrs, buf, buf_end - buf);
728 bytestream2_init_writer(&pb, dst, dst_size);
730 for (k = 0; k < bpp; k++) {
731 ofssrc = bytestream2_get_be32(&ptrs);
737 if (ofssrc >= buf_end - buf)
740 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
741 while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
742 int16_t offset = bytestream2_get_be16(&gb);
746 unsigned data = bytestream2_get_be16(&gb);
749 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
750 bytestream2_seek_p(&pb, noffset, SEEK_SET);
751 bytestream2_put_be16(&pb, data);
753 uint16_t count = bytestream2_get_be16(&gb);
755 pos += 2 * -(offset + 2);
756 for (i = 0; i < count; i++) {
757 uint16_t data = bytestream2_get_be16(&gb);
760 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
761 bytestream2_seek_p(&pb, noffset, SEEK_SET);
762 bytestream2_put_be16(&pb, data);
769 static void decode_byte_vertical_delta(uint8_t *dst,
770 const uint8_t *buf, const uint8_t *buf_end,
771 int w, int xor, int bpp, int dst_size)
773 int ncolumns = ((w + 15) / 16) * 2;
774 int dstpitch = ncolumns * bpp;
775 unsigned ofsdst, ofssrc, opcode, x;
776 GetByteContext ptrs, gb;
780 bytestream2_init(&ptrs, buf, buf_end - buf);
781 bytestream2_init_writer(&pb, dst, dst_size);
783 for (k = 0; k < bpp; k++) {
784 ofssrc = bytestream2_get_be32(&ptrs);
789 if (ofssrc >= buf_end - buf)
792 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
793 for (j = 0; j < ncolumns; j++) {
794 ofsdst = j + k * ncolumns;
796 i = bytestream2_get_byte(&gb);
798 opcode = bytestream2_get_byte(&gb);
801 opcode = bytestream2_get_byte(&gb);
802 x = bytestream2_get_byte(&gb);
805 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
806 if (xor && ofsdst < dst_size) {
807 bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
809 bytestream2_put_byte(&pb, x);
814 } else if (opcode < 0x80) {
815 ofsdst += opcode * dstpitch;
820 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
821 if (xor && ofsdst < dst_size) {
822 bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
824 bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
836 static void decode_delta_j(uint8_t *dst,
837 const uint8_t *buf, const uint8_t *buf_end,
838 int w, int h, int bpp, int dst_size)
842 uint32_t type, flag, cols, groups, rows, bytes;
844 int planepitch_byte = (w + 7) / 8;
845 int planepitch = ((w + 15) / 16) * 2;
846 int kludge_j, b, g, r, d;
849 pitch = planepitch * bpp;
850 kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
852 bytestream2_init(&gb, buf, buf_end - buf);
854 while (bytestream2_get_bytes_left(&gb) >= 2) {
855 type = bytestream2_get_be16(&gb);
861 flag = bytestream2_get_be16(&gb);
862 cols = bytestream2_get_be16(&gb);
863 groups = bytestream2_get_be16(&gb);
865 for (g = 0; g < groups; g++) {
866 offset = bytestream2_get_be16(&gb);
868 if (bytestream2_get_bytes_left(&gb) < 1)
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 (bytestream2_get_bytes_left(&gb) < 1)
917 for (b = 0; b < bytes; b++) {
918 uint8_t value = bytestream2_get_byte(&gb);
920 if (noffset >= dst_size)
933 if ((rows * bytes * bpp) & 1)
934 bytestream2_skip(&gb, 1);
943 static void decode_short_vertical_delta(uint8_t *dst,
944 const uint8_t *buf, const uint8_t *buf_end,
945 int w, int bpp, int dst_size)
947 int ncolumns = (w + 15) >> 4;
948 int dstpitch = ncolumns * bpp * 2;
949 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
950 GetByteContext ptrs, gb, dptrs, dgb;
954 if (buf_end - buf <= 64)
957 bytestream2_init(&ptrs, buf, buf_end - buf);
958 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
959 bytestream2_init_writer(&pb, dst, dst_size);
961 for (k = 0; k < bpp; k++) {
962 ofssrc = bytestream2_get_be32(&ptrs);
963 ofsdata = bytestream2_get_be32(&dptrs);
968 if (ofssrc >= buf_end - buf)
971 if (ofsdata >= buf_end - buf)
974 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
975 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
976 for (j = 0; j < ncolumns; j++) {
977 ofsdst = (j + k * ncolumns) * 2;
979 i = bytestream2_get_byte(&gb);
981 opcode = bytestream2_get_byte(&gb);
984 opcode = bytestream2_get_byte(&gb);
985 x = bytestream2_get_be16(&dgb);
988 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
989 bytestream2_put_be16(&pb, x);
993 } else if (opcode < 0x80) {
994 ofsdst += opcode * dstpitch;
999 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1000 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1011 static void decode_long_vertical_delta(uint8_t *dst,
1012 const uint8_t *buf, const uint8_t *buf_end,
1013 int w, int bpp, int dst_size)
1015 int ncolumns = (w + 31) >> 5;
1016 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1017 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1018 GetByteContext ptrs, gb, dptrs, dgb;
1022 if (buf_end - buf <= 64)
1025 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1026 bytestream2_init(&ptrs, buf, buf_end - buf);
1027 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1028 bytestream2_init_writer(&pb, dst, dst_size);
1030 for (k = 0; k < bpp; k++) {
1031 ofssrc = bytestream2_get_be32(&ptrs);
1032 ofsdata = bytestream2_get_be32(&dptrs);
1037 if (ofssrc >= buf_end - buf)
1040 if (ofsdata >= buf_end - buf)
1043 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1044 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1045 for (j = 0; j < ncolumns; j++) {
1046 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1048 i = bytestream2_get_byte(&gb);
1050 opcode = bytestream2_get_byte(&gb);
1053 opcode = bytestream2_get_byte(&gb);
1054 if (h && (j == (ncolumns - 1))) {
1055 x = bytestream2_get_be16(&dgb);
1056 bytestream2_skip(&dgb, 2);
1058 x = bytestream2_get_be32(&dgb);
1062 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1063 if (h && (j == (ncolumns - 1))) {
1064 bytestream2_put_be16(&pb, x);
1066 bytestream2_put_be32(&pb, x);
1071 } else if (opcode < 0x80) {
1072 ofsdst += opcode * dstpitch;
1077 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1078 if (h && (j == (ncolumns - 1))) {
1079 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1080 bytestream2_skip(&dgb, 2);
1082 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1094 static void decode_short_vertical_delta2(uint8_t *dst,
1095 const uint8_t *buf, const uint8_t *buf_end,
1096 int w, int bpp, int dst_size)
1098 int ncolumns = (w + 15) >> 4;
1099 int dstpitch = ncolumns * bpp * 2;
1100 unsigned ofsdst, ofssrc, opcode, x;
1101 GetByteContext ptrs, gb;
1105 bytestream2_init(&ptrs, buf, buf_end - buf);
1106 bytestream2_init_writer(&pb, dst, dst_size);
1108 for (k = 0; k < bpp; k++) {
1109 ofssrc = bytestream2_get_be32(&ptrs);
1114 if (ofssrc >= buf_end - buf)
1117 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1118 for (j = 0; j < ncolumns; j++) {
1119 ofsdst = (j + k * ncolumns) * 2;
1121 i = bytestream2_get_be16(&gb);
1122 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1123 opcode = bytestream2_get_be16(&gb);
1126 opcode = bytestream2_get_be16(&gb);
1127 x = bytestream2_get_be16(&gb);
1129 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1130 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1131 bytestream2_put_be16(&pb, x);
1135 } else if (opcode < 0x8000) {
1136 ofsdst += opcode * dstpitch;
1140 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1141 bytestream2_get_bytes_left_p(&pb) > 1) {
1142 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1143 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1154 static void decode_long_vertical_delta2(uint8_t *dst,
1155 const uint8_t *buf, const uint8_t *buf_end,
1156 int w, int bpp, int dst_size)
1158 int ncolumns = (w + 31) >> 5;
1159 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1160 unsigned ofsdst, ofssrc, opcode, x;
1161 unsigned skip = 0x80000000, mask = skip - 1;
1162 GetByteContext ptrs, gb;
1166 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1167 bytestream2_init(&ptrs, buf, buf_end - buf);
1168 bytestream2_init_writer(&pb, dst, dst_size);
1170 for (k = 0; k < bpp; k++) {
1171 ofssrc = bytestream2_get_be32(&ptrs);
1176 if (ofssrc >= buf_end - buf)
1179 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1180 for (j = 0; j < ncolumns; j++) {
1181 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1183 if (h && (j == (ncolumns - 1))) {
1188 i = bytestream2_get_be32(&gb);
1189 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1190 opcode = bytestream2_get_be32(&gb);
1193 if (h && (j == ncolumns - 1)) {
1194 opcode = bytestream2_get_be16(&gb);
1195 x = bytestream2_get_be16(&gb);
1197 opcode = bytestream2_get_be32(&gb);
1198 x = bytestream2_get_be32(&gb);
1201 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1202 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1203 if (h && (j == ncolumns - 1))
1204 bytestream2_put_be16(&pb, x);
1206 bytestream2_put_be32(&pb, x);
1210 } else if (opcode < skip) {
1211 ofsdst += opcode * dstpitch;
1215 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1216 bytestream2_get_bytes_left_p(&pb) > 1) {
1217 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1218 if (h && (j == ncolumns - 1)) {
1219 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1221 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1233 static void decode_delta_d(uint8_t *dst,
1234 const uint8_t *buf, const uint8_t *buf_end,
1235 int w, int flag, int bpp, int dst_size)
1237 int planepitch = FFALIGN(w, 16) >> 3;
1238 int pitch = planepitch * bpp;
1239 int planepitch_byte = (w + 7) / 8;
1240 unsigned entries, ofssrc;
1241 GetByteContext gb, ptrs;
1245 if (buf_end - buf <= 4 * bpp)
1248 bytestream2_init_writer(&pb, dst, dst_size);
1249 bytestream2_init(&ptrs, buf, bpp * 4);
1251 for (k = 0; k < bpp; k++) {
1252 ofssrc = bytestream2_get_be32(&ptrs);
1257 if (ofssrc >= buf_end - buf)
1260 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1262 entries = bytestream2_get_be32(&gb);
1263 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1264 int32_t opcode = bytestream2_get_be32(&gb);
1265 unsigned offset = bytestream2_get_be32(&gb);
1267 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1269 uint32_t x = bytestream2_get_be32(&gb);
1270 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1271 bytestream2_put_be32(&pb, x);
1272 bytestream2_skip_p(&pb, pitch - 4);
1277 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1278 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1279 bytestream2_skip_p(&pb, pitch - 4);
1288 static void decode_delta_e(uint8_t *dst,
1289 const uint8_t *buf, const uint8_t *buf_end,
1290 int w, int flag, int bpp, int dst_size)
1292 int planepitch = FFALIGN(w, 16) >> 3;
1293 int pitch = planepitch * bpp;
1294 int planepitch_byte = (w + 7) / 8;
1295 unsigned entries, ofssrc;
1296 GetByteContext gb, ptrs;
1300 if (buf_end - buf <= 4 * bpp)
1303 bytestream2_init_writer(&pb, dst, dst_size);
1304 bytestream2_init(&ptrs, buf, bpp * 4);
1306 for (k = 0; k < bpp; k++) {
1307 ofssrc = bytestream2_get_be32(&ptrs);
1312 if (ofssrc >= buf_end - buf)
1315 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1317 entries = bytestream2_get_be16(&gb);
1318 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1319 int16_t opcode = bytestream2_get_be16(&gb);
1320 unsigned offset = bytestream2_get_be32(&gb);
1322 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1324 uint16_t x = bytestream2_get_be16(&gb);
1325 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1326 bytestream2_put_be16(&pb, x);
1327 bytestream2_skip_p(&pb, pitch - 2);
1332 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1333 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1334 bytestream2_skip_p(&pb, pitch - 2);
1343 static void decode_delta_l(uint8_t *dst,
1344 const uint8_t *buf, const uint8_t *buf_end,
1345 int w, int flag, int bpp, int dst_size)
1347 GetByteContext off0, off1, dgb, ogb;
1349 unsigned poff0, poff1;
1351 int planepitch_byte = (w + 7) / 8;
1352 int planepitch = ((w + 15) / 16) * 2;
1353 int pitch = planepitch * bpp;
1355 if (buf_end - buf <= 64)
1358 bytestream2_init(&off0, buf, buf_end - buf);
1359 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1360 bytestream2_init_writer(&pb, dst, dst_size);
1362 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1364 for (k = 0; k < bpp; k++) {
1365 poff0 = bytestream2_get_be32(&off0);
1366 poff1 = bytestream2_get_be32(&off1);
1371 if (2LL * poff0 >= buf_end - buf)
1374 if (2LL * poff1 >= buf_end - buf)
1377 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1378 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1380 while ((bytestream2_peek_be16(&ogb)) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1381 uint32_t offset = bytestream2_get_be16(&ogb);
1382 int16_t cnt = bytestream2_get_be16(&ogb);
1385 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1387 bytestream2_seek_p(&pb, offset, SEEK_SET);
1389 data = bytestream2_get_be16(&dgb);
1390 for (i = 0; i < cnt; i++) {
1391 bytestream2_put_be16(&pb, data);
1392 bytestream2_skip_p(&pb, dstpitch - 2);
1395 bytestream2_seek_p(&pb, offset, SEEK_SET);
1396 for (i = 0; i < cnt; i++) {
1397 data = bytestream2_get_be16(&dgb);
1398 bytestream2_put_be16(&pb, data);
1399 bytestream2_skip_p(&pb, dstpitch - 2);
1406 static int unsupported(AVCodecContext *avctx)
1408 IffContext *s = avctx->priv_data;
1409 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1410 return AVERROR_INVALIDDATA;
1413 static int decode_frame(AVCodecContext *avctx,
1414 void *data, int *got_frame,
1417 IffContext *s = avctx->priv_data;
1418 AVFrame *frame = data;
1419 const uint8_t *buf = avpkt->data;
1420 int buf_size = avpkt->size;
1421 const uint8_t *buf_end = buf + buf_size;
1423 GetByteContext *gb = &s->gb;
1424 const AVPixFmtDescriptor *desc;
1426 bytestream2_init(gb, avpkt->data, avpkt->size);
1428 if ((res = extract_header(avctx, avpkt)) < 0)
1431 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1435 buf += bytestream2_tell(gb);
1436 buf_size -= bytestream2_tell(gb);
1437 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1439 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1440 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1441 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1443 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1444 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1445 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1450 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1451 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1452 memcpy(s->pal[0], s->frame->data[1], 256 * 4);
1455 switch (s->compression) {
1457 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1458 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1459 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1460 for (plane = 0; plane < s->bpp; plane++) {
1461 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1462 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1463 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1464 buf += s->planesize;
1467 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1468 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1469 for (y = 0; y < avctx->height; y++) {
1470 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1471 memset(s->ham_buf, 0, s->planesize * 8);
1472 for (plane = 0; plane < s->bpp; plane++) {
1473 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1474 if (start >= buf_end)
1476 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1478 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1481 return unsupported(avctx);
1482 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1483 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1485 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1486 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1487 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1489 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1490 for (x = 0; x < avctx->width; x++)
1491 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1494 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1495 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1496 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1497 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1498 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1499 for (y = 0; y < avctx->height; y++) {
1500 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1501 memset(row, 0, avctx->width);
1502 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1503 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1504 buf += s->planesize;
1507 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1508 for (y = 0; y < avctx->height; y++) {
1509 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1510 memset(s->ham_buf, 0, s->planesize * 8);
1511 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1512 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1513 buf += s->planesize;
1515 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1517 } else { // AV_PIX_FMT_BGR32
1518 for (y = 0; y < avctx->height; y++) {
1519 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1520 memset(row, 0, avctx->width << 2);
1521 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1522 decodeplane32((uint32_t *)row, buf,
1523 FFMIN(s->planesize, buf_end - buf), plane);
1524 buf += s->planesize;
1528 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1529 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1530 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1531 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1532 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1533 buf += avctx->width + (avctx->width % 2); // padding if odd
1535 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1536 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1537 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1538 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1539 buf += avctx->width + (avctx->width & 1); // padding if odd
1540 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1543 return unsupported(avctx);
1547 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1548 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1549 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1550 uint8_t *video = s->video[0];
1552 for (y = 0; y < avctx->height; y++) {
1553 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1554 memset(row, 0, avctx->width);
1555 for (plane = 0; plane < s->bpp; plane++) {
1556 buf += decode_byterun(s->planebuf, s->planesize, gb);
1557 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1558 memcpy(video, s->planebuf, s->planesize);
1559 video += s->planesize;
1561 decodeplane8(row, s->planebuf, s->planesize, plane);
1564 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1565 for (y = 0; y < avctx->height; y++) {
1566 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1567 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1568 for (plane = 0; plane < s->bpp; plane++) {
1569 buf += decode_byterun(s->planebuf, s->planesize, gb);
1570 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1572 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1574 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1575 uint8_t *video = s->video[0];
1576 for (y = 0; y < avctx->height; y++) {
1577 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1578 memset(s->ham_buf, 0, s->planesize * 8);
1579 for (plane = 0; plane < s->bpp; plane++) {
1580 buf += decode_byterun(s->planebuf, s->planesize, gb);
1581 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1582 memcpy(video, s->planebuf, s->planesize);
1583 video += s->planesize;
1585 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1587 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1589 } else { // AV_PIX_FMT_BGR32
1590 for (y = 0; y < avctx->height; y++) {
1591 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1592 memset(row, 0, avctx->width << 2);
1593 for (plane = 0; plane < s->bpp; plane++) {
1594 buf += decode_byterun(s->planebuf, s->planesize, gb);
1595 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1599 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1600 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1601 for (y = 0; y < avctx->height; y++) {
1602 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1603 buf += decode_byterun(row, avctx->width, gb);
1605 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1606 for (y = 0; y < avctx->height; y++) {
1607 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1608 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1609 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1612 return unsupported(avctx);
1613 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1614 if (av_get_bits_per_pixel(desc) == 32)
1615 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1617 return unsupported(avctx);
1621 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1622 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1623 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1624 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1626 return unsupported(avctx);
1629 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1630 if (av_get_bits_per_pixel(desc) == 32)
1631 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1633 return unsupported(avctx);
1635 return unsupported(avctx);
1639 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1643 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1648 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1650 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1655 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1657 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1661 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1665 if (s->is_interlaced)
1666 return unsupported(avctx);
1667 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1671 if (s->is_interlaced)
1672 return unsupported(avctx);
1673 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1677 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1680 return unsupported(avctx);
1683 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1684 memcpy(s->pal[1], s->pal[0], 256 * 4);
1685 memcpy(s->video[1], s->video[0], s->video_size);
1688 if (s->compression > 0xff) {
1689 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1691 for (y = 0; y < avctx->height; y++) {
1692 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1693 memset(row, 0, avctx->width);
1694 for (plane = 0; plane < s->bpp; plane++) {
1695 decodeplane8(row, buf, s->planesize, plane);
1696 buf += s->planesize;
1699 memcpy(frame->data[1], s->pal[0], 256 * 4);
1700 } else if (s->ham) {
1701 int i, count = 1 << s->ham;
1704 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1705 for (i = 0; i < count; i++) {
1706 s->ham_palbuf[i*2+1] = s->pal[0][i];
1708 for (i = 0; i < count; i++) {
1709 uint32_t tmp = i << (8 - s->ham);
1710 tmp |= tmp >> s->ham;
1711 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1712 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1713 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1714 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1715 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1716 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1718 if (s->masking == MASK_HAS_MASK) {
1719 for (i = 0; i < 8 * (1 << s->ham); i++)
1720 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1722 for (y = 0; y < avctx->height; y++) {
1723 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1724 memset(s->ham_buf, 0, s->planesize * 8);
1725 for (plane = 0; plane < s->bpp; plane++) {
1726 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1727 buf += s->planesize;
1729 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1732 return unsupported(avctx);
1736 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1737 FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
1741 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1742 frame->key_frame = 1;
1743 frame->pict_type = AV_PICTURE_TYPE_I;
1745 frame->key_frame = 0;
1746 frame->pict_type = AV_PICTURE_TYPE_P;
1754 #if CONFIG_IFF_ILBM_DECODER
1755 AVCodec ff_iff_ilbm_decoder = {
1757 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1758 .type = AVMEDIA_TYPE_VIDEO,
1759 .id = AV_CODEC_ID_IFF_ILBM,
1760 .priv_data_size = sizeof(IffContext),
1761 .init = decode_init,
1762 .close = decode_end,
1763 .decode = decode_frame,
1764 .capabilities = AV_CODEC_CAP_DR1,