dc70b9fea4472e006c07a4a62306f65bf8fef0e0
[ffmpeg.git] / libavcodec / iff.c
1 /*
2  * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
3  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 /**
24  * @file
25  * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
26  */
27
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
30 #include "avcodec.h"
31 #include "get_bits.h"
32 #include "internal.h"
33
34 // TODO: masking bits
35 typedef enum {
36     MASK_NONE,
37     MASK_HAS_MASK,
38     MASK_HAS_TRANSPARENT_COLOR,
39     MASK_LASSO
40 } mask_type;
41
42 typedef struct {
43     AVFrame *frame;
44     int planesize;
45     uint8_t * planebuf;
46     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
47     uint32_t *ham_palbuf;   ///< HAM decode table
48     uint32_t *mask_buf;     ///< temporary buffer for palette indices
49     uint32_t *mask_palbuf;  ///< masking palette table
50     unsigned  compression;  ///< delta compression method used
51     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
52     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
53     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
54     unsigned  transparency; ///< TODO: transparency color index in palette
55     unsigned  masking;      ///< TODO: masking method used
56     int init; // 1 if buffer and palette data already initialized, 0 otherwise
57     int16_t   tvdc[16];     ///< TVDC lookup table
58 } IffContext;
59
60 #define LUT8_PART(plane, v)                             \
61     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
62     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
63     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
64     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
65     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
66     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
67     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
68     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
69     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
70     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
71     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
72     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
73     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
74     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
75     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
76     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
77
78 #define LUT8(plane) {                           \
79     LUT8_PART(plane, 0x0000000),                \
80     LUT8_PART(plane, 0x1000000),                \
81     LUT8_PART(plane, 0x0010000),                \
82     LUT8_PART(plane, 0x1010000),                \
83     LUT8_PART(plane, 0x0000100),                \
84     LUT8_PART(plane, 0x1000100),                \
85     LUT8_PART(plane, 0x0010100),                \
86     LUT8_PART(plane, 0x1010100),                \
87     LUT8_PART(plane, 0x0000001),                \
88     LUT8_PART(plane, 0x1000001),                \
89     LUT8_PART(plane, 0x0010001),                \
90     LUT8_PART(plane, 0x1010001),                \
91     LUT8_PART(plane, 0x0000101),                \
92     LUT8_PART(plane, 0x1000101),                \
93     LUT8_PART(plane, 0x0010101),                \
94     LUT8_PART(plane, 0x1010101),                \
95 }
96
97 // 8 planes * 8-bit mask
98 static const uint64_t plane8_lut[8][256] = {
99     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
100     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
101 };
102
103 #define LUT32(plane) {                                \
104              0,          0,          0,          0,   \
105              0,          0,          0, 1 << plane,   \
106              0,          0, 1 << plane,          0,   \
107              0,          0, 1 << plane, 1 << plane,   \
108              0, 1 << plane,          0,          0,   \
109              0, 1 << plane,          0, 1 << plane,   \
110              0, 1 << plane, 1 << plane,          0,   \
111              0, 1 << plane, 1 << plane, 1 << plane,   \
112     1 << plane,          0,          0,          0,   \
113     1 << plane,          0,          0, 1 << plane,   \
114     1 << plane,          0, 1 << plane,          0,   \
115     1 << plane,          0, 1 << plane, 1 << plane,   \
116     1 << plane, 1 << plane,          0,          0,   \
117     1 << plane, 1 << plane,          0, 1 << plane,   \
118     1 << plane, 1 << plane, 1 << plane,          0,   \
119     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
120 }
121
122 // 32 planes * 4-bit mask * 4 lookup tables each
123 static const uint32_t plane32_lut[32][16*4] = {
124     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
125     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
126     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
127     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
128     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
129     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
130     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
131     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
132 };
133
134 // Gray to RGB, required for palette table of grayscale images with bpp < 8
135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
136     return x << 16 | x << 8 | x;
137 }
138
139 /**
140  * Convert CMAP buffer (stored in extradata) to lavc palette format
141  */
142 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
143 {
144     IffContext *s = avctx->priv_data;
145     int count, i;
146     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
147     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
148
149     if (avctx->bits_per_coded_sample > 8) {
150         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
151         return AVERROR_INVALIDDATA;
152     }
153
154     count = 1 << avctx->bits_per_coded_sample;
155     // If extradata is smaller than actually needed, fill the remaining with black.
156     count = FFMIN(palette_size / 3, count);
157     if (count) {
158         for (i=0; i < count; i++) {
159             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
160         }
161         if (s->flags && count >= 32) { // EHB
162             for (i = 0; i < 32; i++)
163                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
164             count = FFMAX(count, 64);
165         }
166     } else { // Create gray-scale color palette for bps < 8
167         count = 1 << avctx->bits_per_coded_sample;
168
169         for (i=0; i < count; i++) {
170             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
171         }
172     }
173     if (s->masking == MASK_HAS_MASK) {
174         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
175         for (i = 0; i < count; i++)
176             pal[i] &= 0xFFFFFF;
177     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
178         s->transparency < 1 << avctx->bits_per_coded_sample)
179         pal[s->transparency] &= 0xFFFFFF;
180     return 0;
181 }
182
183 /**
184  * Extracts the IFF extra context and updates internal
185  * decoder structures.
186  *
187  * @param avctx the AVCodecContext where to extract extra context to
188  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
189  * @return 0 in case of success, a negative error code otherwise
190  */
191 static int extract_header(AVCodecContext *const avctx,
192                           const AVPacket *const avpkt) {
193     const uint8_t *buf;
194     unsigned buf_size;
195     IffContext *s = avctx->priv_data;
196     int i, palette_size;
197
198     if (avctx->extradata_size < 2) {
199         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
200         return AVERROR_INVALIDDATA;
201     }
202     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
203
204     if (avpkt) {
205         int image_size;
206         if (avpkt->size < 2)
207             return AVERROR_INVALIDDATA;
208         image_size = avpkt->size - AV_RB16(avpkt->data);
209         buf = avpkt->data;
210         buf_size = bytestream_get_be16(&buf);
211         if (buf_size <= 1 || image_size <= 1) {
212             av_log(avctx, AV_LOG_ERROR,
213                    "Invalid image size received: %u -> image data offset: %d\n",
214                    buf_size, image_size);
215             return AVERROR_INVALIDDATA;
216         }
217     } else {
218         buf = avctx->extradata;
219         buf_size = bytestream_get_be16(&buf);
220         if (buf_size <= 1 || palette_size < 0) {
221             av_log(avctx, AV_LOG_ERROR,
222                    "Invalid palette size received: %u -> palette data offset: %d\n",
223                    buf_size, palette_size);
224             return AVERROR_INVALIDDATA;
225         }
226     }
227
228     if (buf_size >= 41) {
229         s->compression  = bytestream_get_byte(&buf);
230         s->bpp          = bytestream_get_byte(&buf);
231         s->ham          = bytestream_get_byte(&buf);
232         s->flags        = bytestream_get_byte(&buf);
233         s->transparency = bytestream_get_be16(&buf);
234         s->masking      = bytestream_get_byte(&buf);
235         for (i = 0; i < 16; i++)
236             s->tvdc[i] = bytestream_get_be16(&buf);
237
238         if (s->masking == MASK_HAS_MASK) {
239             if (s->bpp >= 8 && !s->ham) {
240                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
241                 av_freep(&s->mask_buf);
242                 av_freep(&s->mask_palbuf);
243                 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
244                 if (!s->mask_buf)
245                     return AVERROR(ENOMEM);
246                 if (s->bpp > 16) {
247                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
248                     av_freep(&s->mask_buf);
249                     return AVERROR(ENOMEM);
250                 }
251                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
252                 if (!s->mask_palbuf) {
253                     av_freep(&s->mask_buf);
254                     return AVERROR(ENOMEM);
255                 }
256             }
257             s->bpp++;
258         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
259             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
260             return AVERROR_PATCHWELCOME;
261         }
262         if (!s->bpp || s->bpp > 32) {
263             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
264             return AVERROR_INVALIDDATA;
265         } else if (s->ham >= 8) {
266             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
267             return AVERROR_INVALIDDATA;
268         }
269
270         av_freep(&s->ham_buf);
271         av_freep(&s->ham_palbuf);
272
273         if (s->ham) {
274             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
275             int ham_count;
276             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
277
278             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
279             if (!s->ham_buf)
280                 return AVERROR(ENOMEM);
281
282             ham_count = 8 * (1 << s->ham);
283             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
284             if (!s->ham_palbuf) {
285                 av_freep(&s->ham_buf);
286                 return AVERROR(ENOMEM);
287             }
288
289             if (count) { // HAM with color palette attached
290                 // prefill with black and palette and set HAM take direct value mask to zero
291                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
292                 for (i=0; i < count; i++) {
293                     s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
294                 }
295                 count = 1 << s->ham;
296             } else { // HAM with grayscale color palette
297                 count = 1 << s->ham;
298                 for (i=0; i < count; i++) {
299                     s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
300                     s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
301                 }
302             }
303             for (i=0; i < count; i++) {
304                 uint32_t tmp = i << (8 - s->ham);
305                 tmp |= tmp >> s->ham;
306                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
307                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
308                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
309                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
310                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
311                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
312             }
313             if (s->masking == MASK_HAS_MASK) {
314                 for (i = 0; i < ham_count; i++)
315                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
316             }
317         }
318     }
319
320     return 0;
321 }
322
323 static av_cold int decode_init(AVCodecContext *avctx)
324 {
325     IffContext *s = avctx->priv_data;
326     int err;
327
328     if (avctx->bits_per_coded_sample <= 8) {
329         int palette_size;
330
331         if (avctx->extradata_size >= 2)
332             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
333         else
334             palette_size = 0;
335         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
336                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
337     } else if (avctx->bits_per_coded_sample <= 32) {
338         if (avctx->codec_tag == MKTAG('R','G','B','8')) {
339             avctx->pix_fmt = AV_PIX_FMT_RGB32;
340         } else if (avctx->codec_tag == MKTAG('R','G','B','N')) {
341             avctx->pix_fmt = AV_PIX_FMT_RGB444;
342         } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
343             if (avctx->bits_per_coded_sample == 24) {
344                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
345             } else if (avctx->bits_per_coded_sample == 32) {
346                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
347             } else {
348                 av_log_ask_for_sample(avctx, "unknown bits_per_coded_sample\n");
349                 return AVERROR_PATCHWELCOME;
350             }
351         }
352     } else {
353         return AVERROR_INVALIDDATA;
354     }
355
356     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
357         return err;
358     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
359     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
360     if (!s->planebuf)
361         return AVERROR(ENOMEM);
362
363     s->bpp = avctx->bits_per_coded_sample;
364     s->frame = av_frame_alloc();
365     if (!s->frame)
366         return AVERROR(ENOMEM);
367
368     if ((err = extract_header(avctx, NULL)) < 0)
369         return err;
370
371     return 0;
372 }
373
374 /**
375  * Decode interleaved plane buffer up to 8bpp
376  * @param dst Destination buffer
377  * @param buf Source buffer
378  * @param buf_size
379  * @param plane plane number to decode as
380  */
381 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
382 {
383     const uint64_t *lut = plane8_lut[plane];
384     if (plane >= 8) {
385         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
386         return;
387     }
388     do {
389         uint64_t v = AV_RN64A(dst) | lut[*buf++];
390         AV_WN64A(dst, v);
391         dst += 8;
392     } while (--buf_size);
393 }
394
395 /**
396  * Decode interleaved plane buffer up to 24bpp
397  * @param dst Destination buffer
398  * @param buf Source buffer
399  * @param buf_size
400  * @param plane plane number to decode as
401  */
402 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
403 {
404     const uint32_t *lut = plane32_lut[plane];
405     do {
406         unsigned mask = (*buf >> 2) & ~3;
407         dst[0] |= lut[mask++];
408         dst[1] |= lut[mask++];
409         dst[2] |= lut[mask++];
410         dst[3] |= lut[mask];
411         mask = (*buf++ << 2) & 0x3F;
412         dst[4] |= lut[mask++];
413         dst[5] |= lut[mask++];
414         dst[6] |= lut[mask++];
415         dst[7] |= lut[mask];
416         dst += 8;
417     } while (--buf_size);
418 }
419
420 #define DECODE_HAM_PLANE32(x)       \
421     first       = buf[x] << 1;      \
422     second      = buf[(x)+1] << 1;  \
423     delta      &= pal[first++];     \
424     delta      |= pal[first];       \
425     dst[x]      = delta;            \
426     delta      &= pal[second++];    \
427     delta      |= pal[second];      \
428     dst[(x)+1]  = delta
429
430 /**
431  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
432  *
433  * @param dst the destination 24bpp buffer
434  * @param buf the source 8bpp chunky buffer
435  * @param pal the HAM decode table
436  * @param buf_size the plane size in bytes
437  */
438 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
439                                const uint32_t *const pal, unsigned buf_size)
440 {
441     uint32_t delta = pal[1]; /* first palette entry */
442     do {
443         uint32_t first, second;
444         DECODE_HAM_PLANE32(0);
445         DECODE_HAM_PLANE32(2);
446         DECODE_HAM_PLANE32(4);
447         DECODE_HAM_PLANE32(6);
448         buf += 8;
449         dst += 8;
450     } while (--buf_size);
451 }
452
453 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
454                          const uint32_t *const pal, unsigned width)
455 {
456     do {
457         *dst++ = pal[*buf++];
458     } while (--width);
459 }
460
461 /**
462  * Decode one complete byterun1 encoded line.
463  *
464  * @param dst the destination buffer where to store decompressed bitstream
465  * @param dst_size the destination plane size in bytes
466  * @param buf the source byterun1 compressed bitstream
467  * @param buf_end the EOF of source byterun1 compressed bitstream
468  * @return number of consumed bytes in byterun1 compressed bitstream
469 */
470 static int decode_byterun(uint8_t *dst, int dst_size,
471                           const uint8_t *buf, const uint8_t *const buf_end) {
472     const uint8_t *const buf_start = buf;
473     unsigned x;
474     for (x = 0; x < dst_size && buf < buf_end;) {
475         unsigned length;
476         const int8_t value = *buf++;
477         if (value >= 0) {
478             length = value + 1;
479             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
480             buf += length;
481         } else if (value > -128) {
482             length = -value + 1;
483             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
484         } else { // noop
485             continue;
486         }
487         x += length;
488     }
489     return buf - buf_start;
490 }
491
492 #define DECODE_RGBX_COMMON(type) \
493     if (!length) { \
494         length = bytestream2_get_byte(gb); \
495         if (!length) { \
496             length = bytestream2_get_be16(gb); \
497             if (!length) \
498                 return; \
499         } \
500     } \
501     for (i = 0; i < length; i++) { \
502         *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
503         x += 1; \
504         if (x >= width) { \
505             y += 1; \
506             if (y >= height) \
507                 return; \
508             x = 0; \
509         } \
510     }
511
512 /**
513  * Decode RGB8 buffer
514  * @param[out] dst Destination buffer
515  * @param width Width of destination buffer (pixels)
516  * @param height Height of destination buffer (pixels)
517  * @param linesize Line size of destination buffer (bytes)
518  */
519 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
520 {
521     int x = 0, y = 0, i, length;
522     while (bytestream2_get_bytes_left(gb) >= 4) {
523         uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
524         length = bytestream2_get_byte(gb) & 0x7F;
525         DECODE_RGBX_COMMON(uint32_t)
526     }
527 }
528
529 /**
530  * Decode RGBN buffer
531  * @param[out] dst Destination buffer
532  * @param width Width of destination buffer (pixels)
533  * @param height Height of destination buffer (pixels)
534  * @param linesize Line size of destination buffer (bytes)
535  */
536 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
537 {
538     int x = 0, y = 0, i, length;
539     while (bytestream2_get_bytes_left(gb) >= 2) {
540         uint32_t pixel = bytestream2_get_be16u(gb);
541         length = pixel & 0x7;
542         pixel >>= 4;
543         DECODE_RGBX_COMMON(uint16_t)
544     }
545 }
546
547 /**
548  * Decode DEEP RLE 32-bit buffer
549  * @param[out] dst Destination buffer
550  * @param[in] src Source buffer
551  * @param src_size Source buffer size (bytes)
552  * @param width Width of destination buffer (pixels)
553  * @param height Height of destination buffer (pixels)
554  * @param linesize Line size of destination buffer (bytes)
555  */
556 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
557 {
558     const uint8_t *src_end = src + src_size;
559     int x = 0, y = 0, i;
560     while (src + 5 <= src_end) {
561         int opcode;
562         opcode = *(int8_t *)src++;
563         if (opcode >= 0) {
564             int size = opcode + 1;
565             for (i = 0; i < size; i++) {
566                 int length = FFMIN(size - i, width);
567                 memcpy(dst + y*linesize + x * 4, src, length * 4);
568                 src += length * 4;
569                 x += length;
570                 i += length;
571                 if (x >= width) {
572                     x = 0;
573                     y += 1;
574                     if (y >= height)
575                         return;
576                 }
577             }
578         } else {
579             int size = -opcode + 1;
580             uint32_t pixel = AV_RN32(src);
581             for (i = 0; i < size; i++) {
582                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
583                 x += 1;
584                 if (x >= width) {
585                     x = 0;
586                     y += 1;
587                     if (y >= height)
588                         return;
589                 }
590             }
591             src += 4;
592         }
593     }
594 }
595
596 /**
597  * Decode DEEP TVDC 32-bit buffer
598  * @param[out] dst Destination buffer
599  * @param[in] src Source buffer
600  * @param src_size Source buffer size (bytes)
601  * @param width Width of destination buffer (pixels)
602  * @param height Height of destination buffer (pixels)
603  * @param linesize Line size of destination buffer (bytes)
604  * @param[int] tvdc TVDC lookup table
605  */
606 static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
607 {
608     int x = 0, y = 0, plane = 0;
609     int8_t pixel = 0;
610     int i, j;
611
612     for (i = 0; i < src_size * 2;) {
613 #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
614         int d = tvdc[GETNIBBLE];
615         i++;
616         if (d) {
617             pixel += d;
618             dst[y * linesize + x*4 + plane] = pixel;
619             x++;
620         } else {
621             if (i >= src_size * 2)
622                 return;
623             d = GETNIBBLE + 1;
624             i++;
625             d = FFMIN(d, width - x);
626             for (j = 0; j < d; j++) {
627                 dst[y * linesize + x*4 + plane] = pixel;
628                 x++;
629             }
630         }
631         if (x >= width) {
632             plane++;
633             if (plane >= 4) {
634                 y++;
635                 if (y >= height)
636                     return;
637                 plane = 0;
638             }
639             x = 0;
640             pixel = 0;
641             i = (i + 1) & ~1;
642         }
643     }
644 }
645
646 static int unsupported(AVCodecContext *avctx)
647 {
648     IffContext *s = avctx->priv_data;
649     av_log_ask_for_sample(avctx, "unsupported bitmap (compression %i, bpp %i, ham %i)\n", s->compression, s->bpp, s->ham);
650     return AVERROR_INVALIDDATA;
651 }
652
653 static int decode_frame(AVCodecContext *avctx,
654                             void *data, int *got_frame,
655                             AVPacket *avpkt)
656 {
657     IffContext *s = avctx->priv_data;
658     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
659     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
660     const uint8_t *buf_end = buf+buf_size;
661     int y, plane, res;
662     GetByteContext gb;
663
664     if ((res = extract_header(avctx, avpkt)) < 0)
665         return res;
666     if ((res = ff_reget_buffer(avctx, s->frame)) < 0) {
667         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
668         return res;
669     }
670     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
671         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
672         if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame->data[1])) < 0)
673             return res;
674     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
675                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
676         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
677             return res;
678     }
679     s->init = 1;
680
681     switch (s->compression) {
682     case 0:
683         if (avctx->codec_tag == MKTAG('A','C','B','M')) {
684             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
685                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
686                 for (plane = 0; plane < s->bpp; plane++) {
687                     for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
688                         uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
689                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
690                         buf += s->planesize;
691                     }
692                 }
693             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
694                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
695                 for(y = 0; y < avctx->height; y++) {
696                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
697                     memset(s->ham_buf, 0, s->planesize * 8);
698                     for (plane = 0; plane < s->bpp; plane++) {
699                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
700                         if (start >= buf_end)
701                             break;
702                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
703                     }
704                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
705                 }
706             } else
707                 return unsupported(avctx);
708         } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
709             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
710             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
711             int x;
712             for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
713                 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
714                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
715                 buf += raw_width;
716                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
717                     for(x = 0; x < avctx->width; x++)
718                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
719                 }
720             }
721         } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
722             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
723                 for(y = 0; y < avctx->height; y++ ) {
724                     uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
725                     memset(row, 0, avctx->width);
726                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
727                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
728                         buf += s->planesize;
729                     }
730                 }
731             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
732                 for (y = 0; y < avctx->height; y++) {
733                     uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
734                     memset(s->ham_buf, 0, s->planesize * 8);
735                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
736                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
737                         buf += s->planesize;
738                     }
739                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
740                 }
741             } else { // AV_PIX_FMT_BGR32
742                 for(y = 0; y < avctx->height; y++ ) {
743                     uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
744                     memset(row, 0, avctx->width << 2);
745                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
746                         decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
747                         buf += s->planesize;
748                     }
749                 }
750             }
751         } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
752             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
753                 for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
754                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
755                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
756                     buf += avctx->width + (avctx->width % 2); // padding if odd
757                 }
758             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
759                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
760                     uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
761                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
762                     buf += avctx->width + (avctx->width & 1); // padding if odd
763                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
764                 }
765             } else
766                 return unsupported(avctx);
767         }
768         break;
769     case 1:
770         if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
771             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
772                 for(y = 0; y < avctx->height ; y++ ) {
773                     uint8_t *row = &s->frame->data[0][ y*s->frame->linesize[0] ];
774                     memset(row, 0, avctx->width);
775                     for (plane = 0; plane < s->bpp; plane++) {
776                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
777                         decodeplane8(row, s->planebuf, s->planesize, plane);
778                     }
779                 }
780             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
781                 for (y = 0; y < avctx->height ; y++ ) {
782                     uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
783                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
784                     for (plane = 0; plane < s->bpp; plane++) {
785                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
786                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
787                     }
788                     lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
789                 }
790             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
791                 for (y = 0; y < avctx->height ; y++) {
792                     uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
793                     memset(s->ham_buf, 0, s->planesize * 8);
794                     for (plane = 0; plane < s->bpp; plane++) {
795                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
796                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
797                     }
798                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
799                 }
800             } else { //AV_PIX_FMT_BGR32
801                 for(y = 0; y < avctx->height ; y++ ) {
802                     uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
803                     memset(row, 0, avctx->width << 2);
804                     for (plane = 0; plane < s->bpp; plane++) {
805                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
806                         decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
807                     }
808                 }
809             }
810         } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
811             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
812                 for(y = 0; y < avctx->height ; y++ ) {
813                     uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
814                     buf += decode_byterun(row, avctx->width, buf, buf_end);
815                 }
816             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
817                 for (y = 0; y < avctx->height ; y++) {
818                     uint8_t *row = &s->frame->data[0][y*s->frame->linesize[0]];
819                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
820                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
821                 }
822             } else
823                 return unsupported(avctx);
824         } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
825             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
826             if (av_get_bits_per_pixel(desc) == 32)
827                 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
828             else
829                 return unsupported(avctx);
830         }
831         break;
832     case 4:
833         bytestream2_init(&gb, buf, buf_size);
834         if (avctx->codec_tag == MKTAG('R','G','B','8'))
835             decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
836         else if (avctx->codec_tag == MKTAG('R','G','B','N'))
837             decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
838         else
839             return unsupported(avctx);
840         break;
841     case 5:
842         if (avctx->codec_tag == MKTAG('D','E','E','P')) {
843             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
844             if (av_get_bits_per_pixel(desc) == 32)
845                 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
846             else
847                 return unsupported(avctx);
848         } else
849             return unsupported(avctx);
850         break;
851     default:
852         return unsupported(avctx);
853     }
854
855     if ((res = av_frame_ref(data, s->frame)) < 0)
856         return res;
857
858     *got_frame = 1;
859
860     return buf_size;
861 }
862
863 static av_cold int decode_end(AVCodecContext *avctx)
864 {
865     IffContext *s = avctx->priv_data;
866     av_frame_free(&s->frame);
867     av_freep(&s->planebuf);
868     av_freep(&s->ham_buf);
869     av_freep(&s->ham_palbuf);
870     return 0;
871 }
872
873 #if CONFIG_IFF_ILBM_DECODER
874 AVCodec ff_iff_ilbm_decoder = {
875     .name           = "iff",
876     .type           = AVMEDIA_TYPE_VIDEO,
877     .id             = AV_CODEC_ID_IFF_ILBM,
878     .priv_data_size = sizeof(IffContext),
879     .init           = decode_init,
880     .close          = decode_end,
881     .decode         = decode_frame,
882     .capabilities   = CODEC_CAP_DR1,
883     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
884 };
885 #endif
886 #if CONFIG_IFF_BYTERUN1_DECODER
887 AVCodec ff_iff_byterun1_decoder = {
888     .name           = "iff",
889     .type           = AVMEDIA_TYPE_VIDEO,
890     .id             = AV_CODEC_ID_IFF_BYTERUN1,
891     .priv_data_size = sizeof(IffContext),
892     .init           = decode_init,
893     .close          = decode_end,
894     .decode         = decode_frame,
895     .capabilities   = CODEC_CAP_DR1,
896     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
897 };
898 #endif