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 (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
869 av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%d*%d)", cols, bpp);
874 offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
876 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
878 for (b = 0; b < cols; b++) {
879 for (d = 0; d < bpp; d++) {
880 uint8_t value = bytestream2_get_byte(&gb);
882 if (offset >= dst_size)
891 offset += planepitch;
894 if ((cols * bpp) & 1)
895 bytestream2_skip(&gb, 1);
899 flag = bytestream2_get_be16(&gb);
900 rows = bytestream2_get_be16(&gb);
901 bytes = bytestream2_get_be16(&gb);
902 groups = bytestream2_get_be16(&gb);
904 for (g = 0; g < groups; g++) {
905 offset = bytestream2_get_be16(&gb);
908 offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
910 offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
912 for (r = 0; r < rows; r++) {
913 for (d = 0; d < bpp; d++) {
914 unsigned noffset = offset + (r * pitch) + d * planepitch;
916 if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
917 av_log(NULL, AV_LOG_ERROR, "bytes %d is invalid", bytes);
921 for (b = 0; b < bytes; b++) {
922 uint8_t value = bytestream2_get_byte(&gb);
924 if (noffset >= dst_size)
937 if ((rows * bytes * bpp) & 1)
938 bytestream2_skip(&gb, 1);
947 static void decode_short_vertical_delta(uint8_t *dst,
948 const uint8_t *buf, const uint8_t *buf_end,
949 int w, int bpp, int dst_size)
951 int ncolumns = (w + 15) >> 4;
952 int dstpitch = ncolumns * bpp * 2;
953 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
954 GetByteContext ptrs, gb, dptrs, dgb;
958 if (buf_end - buf <= 64)
961 bytestream2_init(&ptrs, buf, buf_end - buf);
962 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
963 bytestream2_init_writer(&pb, dst, dst_size);
965 for (k = 0; k < bpp; k++) {
966 ofssrc = bytestream2_get_be32(&ptrs);
967 ofsdata = bytestream2_get_be32(&dptrs);
972 if (ofssrc >= buf_end - buf)
975 if (ofsdata >= buf_end - buf)
978 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
979 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
980 for (j = 0; j < ncolumns; j++) {
981 ofsdst = (j + k * ncolumns) * 2;
983 i = bytestream2_get_byte(&gb);
985 opcode = bytestream2_get_byte(&gb);
988 opcode = bytestream2_get_byte(&gb);
989 x = bytestream2_get_be16(&dgb);
992 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
993 bytestream2_put_be16(&pb, x);
997 } else if (opcode < 0x80) {
998 ofsdst += opcode * dstpitch;
1003 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1004 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1015 static void decode_long_vertical_delta(uint8_t *dst,
1016 const uint8_t *buf, const uint8_t *buf_end,
1017 int w, int bpp, int dst_size)
1019 int ncolumns = (w + 31) >> 5;
1020 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1021 unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1022 GetByteContext ptrs, gb, dptrs, dgb;
1026 if (buf_end - buf <= 64)
1029 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1030 bytestream2_init(&ptrs, buf, buf_end - buf);
1031 bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1032 bytestream2_init_writer(&pb, dst, dst_size);
1034 for (k = 0; k < bpp; k++) {
1035 ofssrc = bytestream2_get_be32(&ptrs);
1036 ofsdata = bytestream2_get_be32(&dptrs);
1041 if (ofssrc >= buf_end - buf)
1044 if (ofsdata >= buf_end - buf)
1047 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1048 bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1049 for (j = 0; j < ncolumns; j++) {
1050 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1052 i = bytestream2_get_byte(&gb);
1054 opcode = bytestream2_get_byte(&gb);
1057 opcode = bytestream2_get_byte(&gb);
1058 if (h && (j == (ncolumns - 1))) {
1059 x = bytestream2_get_be16(&dgb);
1060 bytestream2_skip(&dgb, 2);
1062 x = bytestream2_get_be32(&dgb);
1066 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1067 if (h && (j == (ncolumns - 1))) {
1068 bytestream2_put_be16(&pb, x);
1070 bytestream2_put_be32(&pb, x);
1075 } else if (opcode < 0x80) {
1076 ofsdst += opcode * dstpitch;
1081 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1082 if (h && (j == (ncolumns - 1))) {
1083 bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1084 bytestream2_skip(&dgb, 2);
1086 bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1098 static void decode_short_vertical_delta2(uint8_t *dst,
1099 const uint8_t *buf, const uint8_t *buf_end,
1100 int w, int bpp, int dst_size)
1102 int ncolumns = (w + 15) >> 4;
1103 int dstpitch = ncolumns * bpp * 2;
1104 unsigned ofsdst, ofssrc, opcode, x;
1105 GetByteContext ptrs, gb;
1109 bytestream2_init(&ptrs, buf, buf_end - buf);
1110 bytestream2_init_writer(&pb, dst, dst_size);
1112 for (k = 0; k < bpp; k++) {
1113 ofssrc = bytestream2_get_be32(&ptrs);
1118 if (ofssrc >= buf_end - buf)
1121 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1122 for (j = 0; j < ncolumns; j++) {
1123 ofsdst = (j + k * ncolumns) * 2;
1125 i = bytestream2_get_be16(&gb);
1126 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1127 opcode = bytestream2_get_be16(&gb);
1130 opcode = bytestream2_get_be16(&gb);
1131 x = bytestream2_get_be16(&gb);
1133 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1134 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1135 bytestream2_put_be16(&pb, x);
1139 } else if (opcode < 0x8000) {
1140 ofsdst += opcode * dstpitch;
1144 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1145 bytestream2_get_bytes_left_p(&pb) > 1) {
1146 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1147 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1158 static void decode_long_vertical_delta2(uint8_t *dst,
1159 const uint8_t *buf, const uint8_t *buf_end,
1160 int w, int bpp, int dst_size)
1162 int ncolumns = (w + 31) >> 5;
1163 int dstpitch = ((w + 15) / 16 * 2) * bpp;
1164 unsigned ofsdst, ofssrc, opcode, x;
1165 unsigned skip = 0x80000000, mask = skip - 1;
1166 GetByteContext ptrs, gb;
1170 h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1171 bytestream2_init(&ptrs, buf, buf_end - buf);
1172 bytestream2_init_writer(&pb, dst, dst_size);
1174 for (k = 0; k < bpp; k++) {
1175 ofssrc = bytestream2_get_be32(&ptrs);
1180 if (ofssrc >= buf_end - buf)
1183 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1184 for (j = 0; j < ncolumns; j++) {
1185 ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1187 if (h && (j == (ncolumns - 1))) {
1192 i = bytestream2_get_be32(&gb);
1193 while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1194 opcode = bytestream2_get_be32(&gb);
1197 if (h && (j == ncolumns - 1)) {
1198 opcode = bytestream2_get_be16(&gb);
1199 x = bytestream2_get_be16(&gb);
1201 opcode = bytestream2_get_be32(&gb);
1202 x = bytestream2_get_be32(&gb);
1205 while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1206 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1207 if (h && (j == ncolumns - 1))
1208 bytestream2_put_be16(&pb, x);
1210 bytestream2_put_be32(&pb, x);
1214 } else if (opcode < skip) {
1215 ofsdst += opcode * dstpitch;
1219 while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1220 bytestream2_get_bytes_left_p(&pb) > 1) {
1221 bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1222 if (h && (j == ncolumns - 1)) {
1223 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1225 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1237 static void decode_delta_d(uint8_t *dst,
1238 const uint8_t *buf, const uint8_t *buf_end,
1239 int w, int flag, int bpp, int dst_size)
1241 int planepitch = FFALIGN(w, 16) >> 3;
1242 int pitch = planepitch * bpp;
1243 int planepitch_byte = (w + 7) / 8;
1244 unsigned entries, ofssrc;
1245 GetByteContext gb, ptrs;
1249 if (buf_end - buf <= 4 * bpp)
1252 bytestream2_init_writer(&pb, dst, dst_size);
1253 bytestream2_init(&ptrs, buf, bpp * 4);
1255 for (k = 0; k < bpp; k++) {
1256 ofssrc = bytestream2_get_be32(&ptrs);
1261 if (ofssrc >= buf_end - buf)
1264 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1266 entries = bytestream2_get_be32(&gb);
1267 while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1268 int32_t opcode = bytestream2_get_be32(&gb);
1269 unsigned offset = bytestream2_get_be32(&gb);
1271 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1273 uint32_t x = bytestream2_get_be32(&gb);
1274 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1275 bytestream2_put_be32(&pb, x);
1276 bytestream2_skip_p(&pb, pitch - 4);
1281 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1282 bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1283 bytestream2_skip_p(&pb, pitch - 4);
1292 static void decode_delta_e(uint8_t *dst,
1293 const uint8_t *buf, const uint8_t *buf_end,
1294 int w, int flag, int bpp, int dst_size)
1296 int planepitch = FFALIGN(w, 16) >> 3;
1297 int pitch = planepitch * bpp;
1298 int planepitch_byte = (w + 7) / 8;
1299 unsigned entries, ofssrc;
1300 GetByteContext gb, ptrs;
1304 if (buf_end - buf <= 4 * bpp)
1307 bytestream2_init_writer(&pb, dst, dst_size);
1308 bytestream2_init(&ptrs, buf, bpp * 4);
1310 for (k = 0; k < bpp; k++) {
1311 ofssrc = bytestream2_get_be32(&ptrs);
1316 if (ofssrc >= buf_end - buf)
1319 bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1321 entries = bytestream2_get_be16(&gb);
1322 while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1323 int16_t opcode = bytestream2_get_be16(&gb);
1324 unsigned offset = bytestream2_get_be32(&gb);
1326 bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1328 uint16_t x = bytestream2_get_be16(&gb);
1329 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1330 bytestream2_put_be16(&pb, x);
1331 bytestream2_skip_p(&pb, pitch - 2);
1336 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1337 bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1338 bytestream2_skip_p(&pb, pitch - 2);
1347 static void decode_delta_l(uint8_t *dst,
1348 const uint8_t *buf, const uint8_t *buf_end,
1349 int w, int flag, int bpp, int dst_size)
1351 GetByteContext off0, off1, dgb, ogb;
1353 unsigned poff0, poff1;
1355 int planepitch_byte = (w + 7) / 8;
1356 int planepitch = ((w + 15) / 16) * 2;
1357 int pitch = planepitch * bpp;
1359 if (buf_end - buf <= 64)
1362 bytestream2_init(&off0, buf, buf_end - buf);
1363 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1364 bytestream2_init_writer(&pb, dst, dst_size);
1366 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1368 for (k = 0; k < bpp; k++) {
1369 poff0 = bytestream2_get_be32(&off0);
1370 poff1 = bytestream2_get_be32(&off1);
1375 if (2LL * poff0 >= buf_end - buf)
1378 if (2LL * poff1 >= buf_end - buf)
1381 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1382 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1384 while ((bytestream2_peek_be16(&ogb)) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1385 uint32_t offset = bytestream2_get_be16(&ogb);
1386 int16_t cnt = bytestream2_get_be16(&ogb);
1389 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1391 bytestream2_seek_p(&pb, offset, SEEK_SET);
1393 data = bytestream2_get_be16(&dgb);
1394 for (i = 0; i < cnt; i++) {
1395 bytestream2_put_be16(&pb, data);
1396 bytestream2_skip_p(&pb, dstpitch - 2);
1399 bytestream2_seek_p(&pb, offset, SEEK_SET);
1400 for (i = 0; i < cnt; i++) {
1401 data = bytestream2_get_be16(&dgb);
1402 bytestream2_put_be16(&pb, data);
1403 bytestream2_skip_p(&pb, dstpitch - 2);
1410 static int unsupported(AVCodecContext *avctx)
1412 IffContext *s = avctx->priv_data;
1413 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1414 return AVERROR_INVALIDDATA;
1417 static int decode_frame(AVCodecContext *avctx,
1418 void *data, int *got_frame,
1421 IffContext *s = avctx->priv_data;
1422 AVFrame *frame = data;
1423 const uint8_t *buf = avpkt->data;
1424 int buf_size = avpkt->size;
1425 const uint8_t *buf_end = buf + buf_size;
1427 GetByteContext *gb = &s->gb;
1428 const AVPixFmtDescriptor *desc;
1430 bytestream2_init(gb, avpkt->data, avpkt->size);
1432 if ((res = extract_header(avctx, avpkt)) < 0)
1435 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1439 buf += bytestream2_tell(gb);
1440 buf_size -= bytestream2_tell(gb);
1441 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1443 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1444 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1445 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1447 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1448 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1449 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1454 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1455 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1456 memcpy(s->pal[0], s->frame->data[1], 256 * 4);
1459 switch (s->compression) {
1461 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1462 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1463 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1464 for (plane = 0; plane < s->bpp; plane++) {
1465 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1466 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1467 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1468 buf += s->planesize;
1471 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1472 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1473 for (y = 0; y < avctx->height; y++) {
1474 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1475 memset(s->ham_buf, 0, s->planesize * 8);
1476 for (plane = 0; plane < s->bpp; plane++) {
1477 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1478 if (start >= buf_end)
1480 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1482 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1485 return unsupported(avctx);
1486 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1487 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1489 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1490 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1491 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1493 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1494 for (x = 0; x < avctx->width; x++)
1495 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1498 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1499 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1500 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1501 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1502 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1503 for (y = 0; y < avctx->height; y++) {
1504 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1505 memset(row, 0, avctx->width);
1506 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1507 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1508 buf += s->planesize;
1511 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1512 for (y = 0; y < avctx->height; y++) {
1513 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1514 memset(s->ham_buf, 0, s->planesize * 8);
1515 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1516 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1517 buf += s->planesize;
1519 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1521 } else { // AV_PIX_FMT_BGR32
1522 for (y = 0; y < avctx->height; y++) {
1523 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1524 memset(row, 0, avctx->width << 2);
1525 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1526 decodeplane32((uint32_t *)row, buf,
1527 FFMIN(s->planesize, buf_end - buf), plane);
1528 buf += s->planesize;
1532 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1533 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1534 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1535 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1536 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1537 buf += avctx->width + (avctx->width % 2); // padding if odd
1539 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1540 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1541 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1542 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1543 buf += avctx->width + (avctx->width & 1); // padding if odd
1544 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1547 return unsupported(avctx);
1551 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1552 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1553 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1554 uint8_t *video = s->video[0];
1556 for (y = 0; y < avctx->height; y++) {
1557 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1558 memset(row, 0, avctx->width);
1559 for (plane = 0; plane < s->bpp; plane++) {
1560 buf += decode_byterun(s->planebuf, s->planesize, gb);
1561 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1562 memcpy(video, s->planebuf, s->planesize);
1563 video += s->planesize;
1565 decodeplane8(row, s->planebuf, s->planesize, plane);
1568 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1569 for (y = 0; y < avctx->height; y++) {
1570 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1571 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1572 for (plane = 0; plane < s->bpp; plane++) {
1573 buf += decode_byterun(s->planebuf, s->planesize, gb);
1574 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1576 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1578 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1579 uint8_t *video = s->video[0];
1580 for (y = 0; y < avctx->height; y++) {
1581 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1582 memset(s->ham_buf, 0, s->planesize * 8);
1583 for (plane = 0; plane < s->bpp; plane++) {
1584 buf += decode_byterun(s->planebuf, s->planesize, gb);
1585 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1586 memcpy(video, s->planebuf, s->planesize);
1587 video += s->planesize;
1589 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1591 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1593 } else { // AV_PIX_FMT_BGR32
1594 for (y = 0; y < avctx->height; y++) {
1595 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1596 memset(row, 0, avctx->width << 2);
1597 for (plane = 0; plane < s->bpp; plane++) {
1598 buf += decode_byterun(s->planebuf, s->planesize, gb);
1599 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1603 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1604 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1605 for (y = 0; y < avctx->height; y++) {
1606 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1607 buf += decode_byterun(row, avctx->width, gb);
1609 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1610 for (y = 0; y < avctx->height; y++) {
1611 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1612 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1613 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1616 return unsupported(avctx);
1617 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1618 if (av_get_bits_per_pixel(desc) == 32)
1619 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1621 return unsupported(avctx);
1625 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1626 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1627 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1628 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1630 return unsupported(avctx);
1633 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1634 if (av_get_bits_per_pixel(desc) == 32)
1635 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1637 return unsupported(avctx);
1639 return unsupported(avctx);
1643 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1647 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1652 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1654 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1659 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1661 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1665 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1669 if (s->is_interlaced)
1670 return unsupported(avctx);
1671 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1675 if (s->is_interlaced)
1676 return unsupported(avctx);
1677 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1681 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1684 return unsupported(avctx);
1687 if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1688 memcpy(s->pal[1], s->pal[0], 256 * 4);
1689 memcpy(s->video[1], s->video[0], s->video_size);
1692 if (s->compression > 0xff) {
1693 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1695 for (y = 0; y < avctx->height; y++) {
1696 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1697 memset(row, 0, avctx->width);
1698 for (plane = 0; plane < s->bpp; plane++) {
1699 decodeplane8(row, buf, s->planesize, plane);
1700 buf += s->planesize;
1703 memcpy(frame->data[1], s->pal[0], 256 * 4);
1704 } else if (s->ham) {
1705 int i, count = 1 << s->ham;
1708 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1709 for (i = 0; i < count; i++) {
1710 s->ham_palbuf[i*2+1] = s->pal[0][i];
1712 for (i = 0; i < count; i++) {
1713 uint32_t tmp = i << (8 - s->ham);
1714 tmp |= tmp >> s->ham;
1715 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1716 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1717 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1718 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1719 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1720 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1722 if (s->masking == MASK_HAS_MASK) {
1723 for (i = 0; i < 8 * (1 << s->ham); i++)
1724 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1726 for (y = 0; y < avctx->height; y++) {
1727 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1728 memset(s->ham_buf, 0, s->planesize * 8);
1729 for (plane = 0; plane < s->bpp; plane++) {
1730 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1731 buf += s->planesize;
1733 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1736 return unsupported(avctx);
1740 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1741 FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
1745 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1746 frame->key_frame = 1;
1747 frame->pict_type = AV_PICTURE_TYPE_I;
1749 frame->key_frame = 0;
1750 frame->pict_type = AV_PICTURE_TYPE_P;
1758 #if CONFIG_IFF_ILBM_DECODER
1759 AVCodec ff_iff_ilbm_decoder = {
1761 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1762 .type = AVMEDIA_TYPE_VIDEO,
1763 .id = AV_CODEC_ID_IFF_ILBM,
1764 .priv_data_size = sizeof(IffContext),
1765 .init = decode_init,
1766 .close = decode_end,
1767 .decode = decode_frame,
1768 .capabilities = AV_CODEC_CAP_DR1,