lavc/iff: rgbn: fix decoding on big endian
[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     avcodec_get_frame_defaults(&s->frame);
365
366     if ((err = extract_header(avctx, NULL)) < 0)
367         return err;
368     s->frame.reference = 3;
369
370     return 0;
371 }
372
373 /**
374  * Decode interleaved plane buffer up to 8bpp
375  * @param dst Destination buffer
376  * @param buf Source buffer
377  * @param buf_size
378  * @param plane plane number to decode as
379  */
380 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
381 {
382     const uint64_t *lut = plane8_lut[plane];
383     if (plane >= 8) {
384         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
385         return;
386     }
387     do {
388         uint64_t v = AV_RN64A(dst) | lut[*buf++];
389         AV_WN64A(dst, v);
390         dst += 8;
391     } while (--buf_size);
392 }
393
394 /**
395  * Decode interleaved plane buffer up to 24bpp
396  * @param dst Destination buffer
397  * @param buf Source buffer
398  * @param buf_size
399  * @param plane plane number to decode as
400  */
401 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
402 {
403     const uint32_t *lut = plane32_lut[plane];
404     do {
405         unsigned mask = (*buf >> 2) & ~3;
406         dst[0] |= lut[mask++];
407         dst[1] |= lut[mask++];
408         dst[2] |= lut[mask++];
409         dst[3] |= lut[mask];
410         mask = (*buf++ << 2) & 0x3F;
411         dst[4] |= lut[mask++];
412         dst[5] |= lut[mask++];
413         dst[6] |= lut[mask++];
414         dst[7] |= lut[mask];
415         dst += 8;
416     } while (--buf_size);
417 }
418
419 #define DECODE_HAM_PLANE32(x)       \
420     first       = buf[x] << 1;      \
421     second      = buf[(x)+1] << 1;  \
422     delta      &= pal[first++];     \
423     delta      |= pal[first];       \
424     dst[x]      = delta;            \
425     delta      &= pal[second++];    \
426     delta      |= pal[second];      \
427     dst[(x)+1]  = delta
428
429 /**
430  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
431  *
432  * @param dst the destination 24bpp buffer
433  * @param buf the source 8bpp chunky buffer
434  * @param pal the HAM decode table
435  * @param buf_size the plane size in bytes
436  */
437 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
438                                const uint32_t *const pal, unsigned buf_size)
439 {
440     uint32_t delta = pal[1]; /* first palette entry */
441     do {
442         uint32_t first, second;
443         DECODE_HAM_PLANE32(0);
444         DECODE_HAM_PLANE32(2);
445         DECODE_HAM_PLANE32(4);
446         DECODE_HAM_PLANE32(6);
447         buf += 8;
448         dst += 8;
449     } while (--buf_size);
450 }
451
452 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
453                          const uint32_t *const pal, unsigned width)
454 {
455     do {
456         *dst++ = pal[*buf++];
457     } while (--width);
458 }
459
460 /**
461  * Decode one complete byterun1 encoded line.
462  *
463  * @param dst the destination buffer where to store decompressed bitstream
464  * @param dst_size the destination plane size in bytes
465  * @param buf the source byterun1 compressed bitstream
466  * @param buf_end the EOF of source byterun1 compressed bitstream
467  * @return number of consumed bytes in byterun1 compressed bitstream
468 */
469 static int decode_byterun(uint8_t *dst, int dst_size,
470                           const uint8_t *buf, const uint8_t *const buf_end) {
471     const uint8_t *const buf_start = buf;
472     unsigned x;
473     for (x = 0; x < dst_size && buf < buf_end;) {
474         unsigned length;
475         const int8_t value = *buf++;
476         if (value >= 0) {
477             length = value + 1;
478             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
479             buf += length;
480         } else if (value > -128) {
481             length = -value + 1;
482             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
483         } else { // noop
484             continue;
485         }
486         x += length;
487     }
488     return buf - buf_start;
489 }
490
491 #define DECODE_RGBX_COMMON(type) \
492     if (!length) { \
493         length = bytestream2_get_byte(gb); \
494         if (!length) { \
495             length = bytestream2_get_be16(gb); \
496             if (!length) \
497                 return; \
498         } \
499     } \
500     for (i = 0; i < length; i++) { \
501         *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
502         x += 1; \
503         if (x >= width) { \
504             y += 1; \
505             if (y >= height) \
506                 return; \
507             x = 0; \
508         } \
509     }
510
511 /**
512  * Decode RGB8 buffer
513  * @param[out] dst Destination buffer
514  * @param width Width of destination buffer (pixels)
515  * @param height Height of destination buffer (pixels)
516  * @param linesize Line size of destination buffer (bytes)
517  */
518 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
519 {
520     int x = 0, y = 0, i, length;
521     while (bytestream2_get_bytes_left(gb) >= 4) {
522         uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
523         length = bytestream2_get_byte(gb) & 0x7F;
524         DECODE_RGBX_COMMON(uint32_t)
525     }
526 }
527
528 /**
529  * Decode RGBN buffer
530  * @param[out] dst Destination buffer
531  * @param width Width of destination buffer (pixels)
532  * @param height Height of destination buffer (pixels)
533  * @param linesize Line size of destination buffer (bytes)
534  */
535 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
536 {
537     int x = 0, y = 0, i, length;
538     while (bytestream2_get_bytes_left(gb) >= 2) {
539         uint32_t pixel = bytestream2_get_be16u(gb);
540         length = pixel & 0x7;
541         pixel >>= 4;
542         DECODE_RGBX_COMMON(uint16_t)
543     }
544 }
545
546 /**
547  * Decode DEEP RLE 32-bit buffer
548  * @param[out] dst Destination buffer
549  * @param[in] src Source buffer
550  * @param src_size Source buffer size (bytes)
551  * @param width Width of destination buffer (pixels)
552  * @param height Height of destination buffer (pixels)
553  * @param linesize Line size of destination buffer (bytes)
554  */
555 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
556 {
557     const uint8_t *src_end = src + src_size;
558     int x = 0, y = 0, i;
559     while (src + 5 <= src_end) {
560         int opcode;
561         opcode = *(int8_t *)src++;
562         if (opcode >= 0) {
563             int size = opcode + 1;
564             for (i = 0; i < size; i++) {
565                 int length = FFMIN(size - i, width);
566                 memcpy(dst + y*linesize + x * 4, src, length * 4);
567                 src += length * 4;
568                 x += length;
569                 i += length;
570                 if (x >= width) {
571                     x = 0;
572                     y += 1;
573                     if (y >= height)
574                         return;
575                 }
576             }
577         } else {
578             int size = -opcode + 1;
579             uint32_t pixel = AV_RL32(src);
580             for (i = 0; i < size; i++) {
581                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
582                 x += 1;
583                 if (x >= width) {
584                     x = 0;
585                     y += 1;
586                     if (y >= height)
587                         return;
588                 }
589             }
590             src += 4;
591         }
592     }
593 }
594
595 /**
596  * Decode DEEP TVDC 32-bit buffer
597  * @param[out] dst Destination buffer
598  * @param[in] src Source buffer
599  * @param src_size Source buffer size (bytes)
600  * @param width Width of destination buffer (pixels)
601  * @param height Height of destination buffer (pixels)
602  * @param linesize Line size of destination buffer (bytes)
603  * @param[int] tvdc TVDC lookup table
604  */
605 static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
606 {
607     int x = 0, y = 0, plane = 0;
608     int8_t pixel = 0;
609     int i, j;
610
611     for (i = 0; i < src_size * 2;) {
612 #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
613         int d = tvdc[GETNIBBLE];
614         i++;
615         if (d) {
616             pixel += d;
617             dst[y * linesize + x*4 + plane] = pixel;
618             x++;
619         } else {
620             if (i >= src_size * 2)
621                 return;
622             d = GETNIBBLE + 1;
623             i++;
624             d = FFMIN(d, width - x);
625             for (j = 0; j < d; j++) {
626                 dst[y * linesize + x*4 + plane] = pixel;
627                 x++;
628             }
629         }
630         if (x >= width) {
631             plane++;
632             if (plane >= 4) {
633                 y++;
634                 if (y >= height)
635                     return;
636                 plane = 0;
637             }
638             x = 0;
639             pixel = 0;
640             i = (i + 1) & ~1;
641         }
642     }
643 }
644
645 static int unsupported(AVCodecContext *avctx)
646 {
647     IffContext *s = avctx->priv_data;
648     av_log_ask_for_sample(avctx, "unsupported bitmap (compression %i, bpp %i, ham %i)\n", s->compression, s->bpp, s->ham);
649     return AVERROR_INVALIDDATA;
650 }
651
652 static int decode_frame(AVCodecContext *avctx,
653                             void *data, int *got_frame,
654                             AVPacket *avpkt)
655 {
656     IffContext *s = avctx->priv_data;
657     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
658     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
659     const uint8_t *buf_end = buf+buf_size;
660     int y, plane, res;
661     GetByteContext gb;
662
663     if ((res = extract_header(avctx, avpkt)) < 0)
664         return res;
665     if (s->init) {
666         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
667             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
668             return res;
669         }
670     } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
671         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
672         return res;
673     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
674         if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
675             return res;
676     } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
677         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
678             return res;
679     }
680     s->init = 1;
681
682     switch (s->compression) {
683     case 0:
684         if (avctx->codec_tag == MKTAG('A','C','B','M')) {
685             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
686                 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
687                 for (plane = 0; plane < s->bpp; plane++) {
688                     for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
689                         uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
690                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
691                         buf += s->planesize;
692                     }
693                 }
694             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
695                 memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
696                 for(y = 0; y < avctx->height; y++) {
697                     uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
698                     memset(s->ham_buf, 0, s->planesize * 8);
699                     for (plane = 0; plane < s->bpp; plane++) {
700                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
701                         if (start >= buf_end)
702                             break;
703                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
704                     }
705                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
706                 }
707             } else
708                 return unsupported(avctx);
709         } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
710             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
711             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
712             int x;
713             for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
714                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
715                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
716                 buf += raw_width;
717                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
718                     for(x = 0; x < avctx->width; x++)
719                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
720                 }
721             }
722         } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
723             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
724                 for(y = 0; y < avctx->height; y++ ) {
725                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
726                     memset(row, 0, avctx->width);
727                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
728                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
729                         buf += s->planesize;
730                     }
731                 }
732             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
733                 for (y = 0; y < avctx->height; y++) {
734                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
735                     memset(s->ham_buf, 0, s->planesize * 8);
736                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
737                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
738                         buf += s->planesize;
739                     }
740                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
741                 }
742             } else { // AV_PIX_FMT_BGR32
743                 for(y = 0; y < avctx->height; y++ ) {
744                     uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
745                     memset(row, 0, avctx->width << 2);
746                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
747                         decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
748                         buf += s->planesize;
749                     }
750                 }
751             }
752         } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
753             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
754                 for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
755                     uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
756                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
757                     buf += avctx->width + (avctx->width % 2); // padding if odd
758                 }
759             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
760                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
761                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
762                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
763                     buf += avctx->width + (avctx->width & 1); // padding if odd
764                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
765                 }
766             } else
767                 return unsupported(avctx);
768         }
769         break;
770     case 1:
771         if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
772             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
773                 for(y = 0; y < avctx->height ; y++ ) {
774                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
775                     memset(row, 0, avctx->width);
776                     for (plane = 0; plane < s->bpp; plane++) {
777                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
778                         decodeplane8(row, s->planebuf, s->planesize, plane);
779                     }
780                 }
781             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
782                 for (y = 0; y < avctx->height ; y++ ) {
783                     uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
784                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
785                     for (plane = 0; plane < s->bpp; plane++) {
786                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
787                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
788                     }
789                     lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
790                 }
791             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
792                 for (y = 0; y < avctx->height ; y++) {
793                     uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
794                     memset(s->ham_buf, 0, s->planesize * 8);
795                     for (plane = 0; plane < s->bpp; plane++) {
796                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
797                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
798                     }
799                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
800                 }
801             } else { //AV_PIX_FMT_BGR32
802                 for(y = 0; y < avctx->height ; y++ ) {
803                     uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
804                     memset(row, 0, avctx->width << 2);
805                     for (plane = 0; plane < s->bpp; plane++) {
806                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
807                         decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
808                     }
809                 }
810             }
811         } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
812             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
813                 for(y = 0; y < avctx->height ; y++ ) {
814                     uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
815                     buf += decode_byterun(row, avctx->width, buf, buf_end);
816                 }
817             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
818                 for (y = 0; y < avctx->height ; y++) {
819                     uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
820                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
821                     decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
822                 }
823             } else
824                 return unsupported(avctx);
825         } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
826             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
827             if (av_get_bits_per_pixel(desc) == 32)
828                 decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
829             else
830                 return unsupported(avctx);
831         }
832         break;
833     case 4:
834         bytestream2_init(&gb, buf, buf_size);
835         if (avctx->codec_tag == MKTAG('R','G','B','8'))
836             decode_rgb8(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
837         else if (avctx->codec_tag == MKTAG('R','G','B','N'))
838             decode_rgbn(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
839         else
840             return unsupported(avctx);
841         break;
842     case 5:
843         if (avctx->codec_tag == MKTAG('D','E','E','P')) {
844             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
845             if (av_get_bits_per_pixel(desc) == 32)
846                 decode_deep_tvdc32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0], s->tvdc);
847             else
848                 return unsupported(avctx);
849         } else
850             return unsupported(avctx);
851         break;
852     default:
853         return unsupported(avctx);
854     }
855
856     *got_frame = 1;
857     *(AVFrame*)data = s->frame;
858     return buf_size;
859 }
860
861 static av_cold int decode_end(AVCodecContext *avctx)
862 {
863     IffContext *s = avctx->priv_data;
864     if (s->frame.data[0])
865         avctx->release_buffer(avctx, &s->frame);
866     av_freep(&s->planebuf);
867     av_freep(&s->ham_buf);
868     av_freep(&s->ham_palbuf);
869     return 0;
870 }
871
872 #if CONFIG_IFF_ILBM_DECODER
873 AVCodec ff_iff_ilbm_decoder = {
874     .name           = "iff",
875     .type           = AVMEDIA_TYPE_VIDEO,
876     .id             = AV_CODEC_ID_IFF_ILBM,
877     .priv_data_size = sizeof(IffContext),
878     .init           = decode_init,
879     .close          = decode_end,
880     .decode         = decode_frame,
881     .capabilities   = CODEC_CAP_DR1,
882     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
883 };
884 #endif
885 #if CONFIG_IFF_BYTERUN1_DECODER
886 AVCodec ff_iff_byterun1_decoder = {
887     .name           = "iff",
888     .type           = AVMEDIA_TYPE_VIDEO,
889     .id             = AV_CODEC_ID_IFF_BYTERUN1,
890     .priv_data_size = sizeof(IffContext),
891     .init           = decode_init,
892     .close          = decode_end,
893     .decode         = decode_frame,
894     .capabilities   = CODEC_CAP_DR1,
895     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
896 };
897 #endif