]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
Merge commit '8941971a8f2e24b9a84fe29f128d13ceb89c0a65'
[ffmpeg] / 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         if (s->flags && count >= 32) { // EHB
161             for (i = 0; i < 32; i++)
162                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
163             count = FFMAX(count, 64);
164         }
165     } else { // Create gray-scale color palette for bps < 8
166         count = 1 << avctx->bits_per_coded_sample;
167
168         for (i = 0; i < count; i++)
169             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
170     }
171     if (s->masking == MASK_HAS_MASK) {
172         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
173         for (i = 0; i < count; i++)
174             pal[i] &= 0xFFFFFF;
175     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
176         s->transparency < 1 << avctx->bits_per_coded_sample)
177         pal[s->transparency] &= 0xFFFFFF;
178     return 0;
179 }
180
181 /**
182  * Extracts the IFF extra context and updates internal
183  * decoder structures.
184  *
185  * @param avctx the AVCodecContext where to extract extra context to
186  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
187  * @return >= 0 in case of success, a negative error code otherwise
188  */
189 static int extract_header(AVCodecContext *const avctx,
190                           const AVPacket *const avpkt) {
191     const uint8_t *buf;
192     unsigned buf_size;
193     IffContext *s = avctx->priv_data;
194     int i, palette_size;
195
196     if (avctx->extradata_size < 2) {
197         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
198         return AVERROR_INVALIDDATA;
199     }
200     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
201
202     if (avpkt) {
203         int image_size;
204         if (avpkt->size < 2)
205             return AVERROR_INVALIDDATA;
206         image_size = avpkt->size - AV_RB16(avpkt->data);
207         buf = avpkt->data;
208         buf_size = bytestream_get_be16(&buf);
209         if (buf_size <= 1 || image_size <= 1) {
210             av_log(avctx, AV_LOG_ERROR,
211                    "Invalid image size received: %u -> image data offset: %d\n",
212                    buf_size, image_size);
213             return AVERROR_INVALIDDATA;
214         }
215     } else {
216         buf = avctx->extradata;
217         buf_size = bytestream_get_be16(&buf);
218         if (buf_size <= 1 || palette_size < 0) {
219             av_log(avctx, AV_LOG_ERROR,
220                    "Invalid palette size received: %u -> palette data offset: %d\n",
221                    buf_size, palette_size);
222             return AVERROR_INVALIDDATA;
223         }
224     }
225
226     if (buf_size >= 41) {
227         s->compression  = bytestream_get_byte(&buf);
228         s->bpp          = bytestream_get_byte(&buf);
229         s->ham          = bytestream_get_byte(&buf);
230         s->flags        = bytestream_get_byte(&buf);
231         s->transparency = bytestream_get_be16(&buf);
232         s->masking      = bytestream_get_byte(&buf);
233         for (i = 0; i < 16; i++)
234             s->tvdc[i] = bytestream_get_be16(&buf);
235
236         if (s->masking == MASK_HAS_MASK) {
237             if (s->bpp >= 8 && !s->ham) {
238                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
239                 av_freep(&s->mask_buf);
240                 av_freep(&s->mask_palbuf);
241                 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
242                 if (!s->mask_buf)
243                     return AVERROR(ENOMEM);
244                 if (s->bpp > 16) {
245                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
246                     av_freep(&s->mask_buf);
247                     return AVERROR(ENOMEM);
248                 }
249                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
250                 if (!s->mask_palbuf) {
251                     av_freep(&s->mask_buf);
252                     return AVERROR(ENOMEM);
253                 }
254             }
255             s->bpp++;
256         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
257             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
258             return AVERROR_PATCHWELCOME;
259         }
260         if (!s->bpp || s->bpp > 32) {
261             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
262             return AVERROR_INVALIDDATA;
263         } else if (s->ham >= 8) {
264             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
265             return AVERROR_INVALIDDATA;
266         }
267
268         av_freep(&s->ham_buf);
269         av_freep(&s->ham_palbuf);
270
271         if (s->ham) {
272             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
273             int ham_count;
274             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
275
276             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
277             if (!s->ham_buf)
278                 return AVERROR(ENOMEM);
279
280             ham_count = 8 * (1 << s->ham);
281             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
282             if (!s->ham_palbuf) {
283                 av_freep(&s->ham_buf);
284                 return AVERROR(ENOMEM);
285             }
286
287             if (count) { // HAM with color palette attached
288                 // prefill with black and palette and set HAM take direct value mask to zero
289                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
290                 for (i=0; i < count; i++) {
291                     s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
292                 }
293                 count = 1 << s->ham;
294             } else { // HAM with grayscale color palette
295                 count = 1 << s->ham;
296                 for (i=0; i < count; i++) {
297                     s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
298                     s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
299                 }
300             }
301             for (i=0; i < count; i++) {
302                 uint32_t tmp = i << (8 - s->ham);
303                 tmp |= tmp >> s->ham;
304                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
305                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
306                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
307                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
308                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
309                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
310             }
311             if (s->masking == MASK_HAS_MASK) {
312                 for (i = 0; i < ham_count; i++)
313                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
314             }
315         }
316     }
317
318     return 0;
319 }
320
321 static av_cold int decode_init(AVCodecContext *avctx)
322 {
323     IffContext *s = avctx->priv_data;
324     int err;
325
326     if (avctx->bits_per_coded_sample <= 8) {
327         int palette_size;
328
329         if (avctx->extradata_size >= 2)
330             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
331         else
332             palette_size = 0;
333         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
334                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
335     } else if (avctx->bits_per_coded_sample <= 32) {
336         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
337             avctx->pix_fmt = AV_PIX_FMT_RGB32;
338         } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
339             avctx->pix_fmt = AV_PIX_FMT_RGB444;
340         } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
341             if (avctx->bits_per_coded_sample == 24) {
342                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
343             } else if (avctx->bits_per_coded_sample == 32) {
344                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
345             } else {
346                 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
347                 return AVERROR_PATCHWELCOME;
348             }
349         }
350     } else {
351         return AVERROR_INVALIDDATA;
352     }
353
354     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
355         return err;
356     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
357     s->planebuf  = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
358     if (!s->planebuf)
359         return AVERROR(ENOMEM);
360
361     s->bpp = avctx->bits_per_coded_sample;
362     s->frame = av_frame_alloc();
363     if (!s->frame)
364         return AVERROR(ENOMEM);
365
366     if ((err = extract_header(avctx, NULL)) < 0)
367         return err;
368
369     return 0;
370 }
371
372 /**
373  * Decode interleaved plane buffer up to 8bpp
374  * @param dst Destination buffer
375  * @param buf Source buffer
376  * @param buf_size
377  * @param plane plane number to decode as
378  */
379 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
380 {
381     const uint64_t *lut = plane8_lut[plane];
382     if (plane >= 8) {
383         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
384         return;
385     }
386     do {
387         uint64_t v = AV_RN64A(dst) | lut[*buf++];
388         AV_WN64A(dst, v);
389         dst += 8;
390     } while (--buf_size);
391 }
392
393 /**
394  * Decode interleaved plane buffer up to 24bpp
395  * @param dst Destination buffer
396  * @param buf Source buffer
397  * @param buf_size
398  * @param plane plane number to decode as
399  */
400 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
401 {
402     const uint32_t *lut = plane32_lut[plane];
403     do {
404         unsigned mask = (*buf >> 2) & ~3;
405         dst[0] |= lut[mask++];
406         dst[1] |= lut[mask++];
407         dst[2] |= lut[mask++];
408         dst[3] |= lut[mask];
409         mask    = (*buf++ << 2) & 0x3F;
410         dst[4] |= lut[mask++];
411         dst[5] |= lut[mask++];
412         dst[6] |= lut[mask++];
413         dst[7] |= lut[mask];
414         dst    += 8;
415     } while (--buf_size);
416 }
417
418 #define DECODE_HAM_PLANE32(x)       \
419     first       = buf[x] << 1;      \
420     second      = buf[(x)+1] << 1;  \
421     delta      &= pal[first++];     \
422     delta      |= pal[first];       \
423     dst[x]      = delta;            \
424     delta      &= pal[second++];    \
425     delta      |= pal[second];      \
426     dst[(x)+1]  = delta
427
428 /**
429  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
430  *
431  * @param dst the destination 24bpp buffer
432  * @param buf the source 8bpp chunky buffer
433  * @param pal the HAM decode table
434  * @param buf_size the plane size in bytes
435  */
436 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
437                                const uint32_t *const pal, unsigned buf_size)
438 {
439     uint32_t delta = pal[1]; /* first palette entry */
440     do {
441         uint32_t first, second;
442         DECODE_HAM_PLANE32(0);
443         DECODE_HAM_PLANE32(2);
444         DECODE_HAM_PLANE32(4);
445         DECODE_HAM_PLANE32(6);
446         buf += 8;
447         dst += 8;
448     } while (--buf_size);
449 }
450
451 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
452                          const uint32_t *const pal, unsigned width)
453 {
454     do {
455         *dst++ = pal[*buf++];
456     } while (--width);
457 }
458
459 /**
460  * Decode one complete byterun1 encoded line.
461  *
462  * @param dst the destination buffer where to store decompressed bitstream
463  * @param dst_size the destination plane size in bytes
464  * @param buf the source byterun1 compressed bitstream
465  * @param buf_end the EOF of source byterun1 compressed bitstream
466  * @return number of consumed bytes in byterun1 compressed bitstream
467  */
468 static int decode_byterun(uint8_t *dst, int dst_size,
469                           const uint8_t *buf, const uint8_t *const buf_end)
470 {
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_RN32(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     avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", 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 ((res = ff_reget_buffer(avctx, s->frame)) < 0)
666         return res;
667     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
668         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
669         if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
670             return res;
671     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
672                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
673         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
674             return res;
675     }
676     s->init = 1;
677
678     switch (s->compression) {
679     case 0:
680         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
681             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
682                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
683                 for (plane = 0; plane < s->bpp; plane++) {
684                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
685                         uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
686                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
687                         buf += s->planesize;
688                     }
689                 }
690             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
691                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
692                 for (y = 0; y < avctx->height; y++) {
693                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
694                     memset(s->ham_buf, 0, s->planesize * 8);
695                     for (plane = 0; plane < s->bpp; plane++) {
696                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
697                         if (start >= buf_end)
698                             break;
699                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
700                     }
701                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
702                 }
703             } else
704                 return unsupported(avctx);
705         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
706             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
707             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
708             int x;
709             for (y = 0; y < avctx->height && buf < buf_end; y++) {
710                 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
711                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
712                 buf += raw_width;
713                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
714                     for (x = 0; x < avctx->width; x++)
715                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
716                 }
717             }
718         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
719             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
720                 for (y = 0; y < avctx->height; y++) {
721                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
722                     memset(row, 0, avctx->width);
723                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
724                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
725                         buf += s->planesize;
726                     }
727                 }
728             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
729                 for (y = 0; y < avctx->height; y++) {
730                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
731                     memset(s->ham_buf, 0, s->planesize * 8);
732                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
733                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
734                         buf += s->planesize;
735                     }
736                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
737                 }
738             } else { // AV_PIX_FMT_BGR32
739                 for (y = 0; y < avctx->height; y++) {
740                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
741                     memset(row, 0, avctx->width << 2);
742                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
743                         decodeplane32((uint32_t *)row, buf,
744                                       FFMIN(s->planesize, buf_end - buf), plane);
745                         buf += s->planesize;
746                     }
747                 }
748             }
749         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
750             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
751                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
752                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
753                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
754                     buf += avctx->width + (avctx->width % 2); // padding if odd
755                 }
756             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
757                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
758                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
759                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
760                     buf += avctx->width + (avctx->width & 1); // padding if odd
761                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
762                 }
763             } else
764                 return unsupported(avctx);
765         }
766         break;
767     case 1:
768         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
769             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
770                 for (y = 0; y < avctx->height; y++) {
771                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
772                     memset(row, 0, avctx->width);
773                     for (plane = 0; plane < s->bpp; plane++) {
774                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
775                         decodeplane8(row, s->planebuf, s->planesize, plane);
776                     }
777                 }
778             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
779                 for (y = 0; y < avctx->height; y++) {
780                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
781                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
782                     for (plane = 0; plane < s->bpp; plane++) {
783                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
784                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
785                     }
786                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
787                 }
788             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
789                 for (y = 0; y < avctx->height; y++) {
790                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
791                     memset(s->ham_buf, 0, s->planesize * 8);
792                     for (plane = 0; plane < s->bpp; plane++) {
793                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
794                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
795                     }
796                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
797                 }
798             } else { // AV_PIX_FMT_BGR32
799                 for (y = 0; y < avctx->height; y++) {
800                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
801                     memset(row, 0, avctx->width << 2);
802                     for (plane = 0; plane < s->bpp; plane++) {
803                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
804                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
805                     }
806                 }
807             }
808         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
809             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
810                 for (y = 0; y < avctx->height; y++) {
811                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
812                     buf += decode_byterun(row, avctx->width, buf, buf_end);
813                 }
814             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
815                 for (y = 0; y < avctx->height; y++) {
816                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
817                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
818                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
819                 }
820             } else
821                 return unsupported(avctx);
822         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
823             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
824             if (av_get_bits_per_pixel(desc) == 32)
825                 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
826             else
827                 return unsupported(avctx);
828         }
829         break;
830     case 4:
831         bytestream2_init(&gb, buf, buf_size);
832         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
833             decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
834         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
835             decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
836         else
837             return unsupported(avctx);
838         break;
839     case 5:
840         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
841             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
842             if (av_get_bits_per_pixel(desc) == 32)
843                 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
844             else
845                 return unsupported(avctx);
846         } else
847             return unsupported(avctx);
848         break;
849     default:
850         return unsupported(avctx);
851     }
852
853     if ((res = av_frame_ref(data, s->frame)) < 0)
854         return res;
855
856     *got_frame = 1;
857
858     return buf_size;
859 }
860
861 static av_cold int decode_end(AVCodecContext *avctx)
862 {
863     IffContext *s = avctx->priv_data;
864     av_frame_free(&s->frame);
865     av_freep(&s->planebuf);
866     av_freep(&s->ham_buf);
867     av_freep(&s->ham_palbuf);
868     return 0;
869 }
870
871 #if CONFIG_IFF_ILBM_DECODER
872 AVCodec ff_iff_ilbm_decoder = {
873     .name           = "iff",
874     .long_name      = NULL_IF_CONFIG_SMALL("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 };
883 #endif
884 #if CONFIG_IFF_BYTERUN1_DECODER
885 AVCodec ff_iff_byterun1_decoder = {
886     .name           = "iff",
887     .long_name      = NULL_IF_CONFIG_SMALL("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 };
896 #endif