]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
Fix compilation error around struct visibility when VDPAU disabled.
[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 <stdint.h>
29
30 #include "libavutil/imgutils.h"
31 #include "bytestream.h"
32 #include "avcodec.h"
33 #include "get_bits.h"
34 #include "internal.h"
35
36 // TODO: masking bits
37 typedef enum {
38     MASK_NONE,
39     MASK_HAS_MASK,
40     MASK_HAS_TRANSPARENT_COLOR,
41     MASK_LASSO
42 } mask_type;
43
44 typedef struct {
45     AVFrame *frame;
46     int planesize;
47     uint8_t * planebuf;
48     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
49     uint32_t *ham_palbuf;   ///< HAM decode table
50     uint32_t *mask_buf;     ///< temporary buffer for palette indices
51     uint32_t *mask_palbuf;  ///< masking palette table
52     unsigned  compression;  ///< delta compression method used
53     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
54     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
55     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
56     unsigned  transparency; ///< TODO: transparency color index in palette
57     unsigned  masking;      ///< TODO: masking method used
58     int init; // 1 if buffer and palette data already initialized, 0 otherwise
59     int16_t   tvdc[16];     ///< TVDC lookup table
60 } IffContext;
61
62 #define LUT8_PART(plane, v)                             \
63     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
64     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
65     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
66     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
67     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
68     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
69     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
70     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
71     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
72     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
73     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
74     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
75     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
76     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
77     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
78     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
79
80 #define LUT8(plane) {                           \
81     LUT8_PART(plane, 0x0000000),                \
82     LUT8_PART(plane, 0x1000000),                \
83     LUT8_PART(plane, 0x0010000),                \
84     LUT8_PART(plane, 0x1010000),                \
85     LUT8_PART(plane, 0x0000100),                \
86     LUT8_PART(plane, 0x1000100),                \
87     LUT8_PART(plane, 0x0010100),                \
88     LUT8_PART(plane, 0x1010100),                \
89     LUT8_PART(plane, 0x0000001),                \
90     LUT8_PART(plane, 0x1000001),                \
91     LUT8_PART(plane, 0x0010001),                \
92     LUT8_PART(plane, 0x1010001),                \
93     LUT8_PART(plane, 0x0000101),                \
94     LUT8_PART(plane, 0x1000101),                \
95     LUT8_PART(plane, 0x0010101),                \
96     LUT8_PART(plane, 0x1010101),                \
97 }
98
99 // 8 planes * 8-bit mask
100 static const uint64_t plane8_lut[8][256] = {
101     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
102     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
103 };
104
105 #define LUT32(plane) {                                \
106              0,          0,          0,          0,   \
107              0,          0,          0, 1 << plane,   \
108              0,          0, 1 << plane,          0,   \
109              0,          0, 1 << plane, 1 << plane,   \
110              0, 1 << plane,          0,          0,   \
111              0, 1 << plane,          0, 1 << plane,   \
112              0, 1 << plane, 1 << plane,          0,   \
113              0, 1 << plane, 1 << plane, 1 << plane,   \
114     1 << plane,          0,          0,          0,   \
115     1 << plane,          0,          0, 1 << plane,   \
116     1 << plane,          0, 1 << plane,          0,   \
117     1 << plane,          0, 1 << plane, 1 << plane,   \
118     1 << plane, 1 << plane,          0,          0,   \
119     1 << plane, 1 << plane,          0, 1 << plane,   \
120     1 << plane, 1 << plane, 1 << plane,          0,   \
121     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
122 }
123
124 // 32 planes * 4-bit mask * 4 lookup tables each
125 static const uint32_t plane32_lut[32][16*4] = {
126     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
127     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
128     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
129     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
130     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
131     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
132     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
133     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
134 };
135
136 // Gray to RGB, required for palette table of grayscale images with bpp < 8
137 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
138     return x << 16 | x << 8 | x;
139 }
140
141 /**
142  * Convert CMAP buffer (stored in extradata) to lavc palette format
143  */
144 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
145 {
146     IffContext *s = avctx->priv_data;
147     int count, i;
148     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
149     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
150
151     if (avctx->bits_per_coded_sample > 8) {
152         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
153         return AVERROR_INVALIDDATA;
154     }
155
156     count = 1 << avctx->bits_per_coded_sample;
157     // If extradata is smaller than actually needed, fill the remaining with black.
158     count = FFMIN(palette_size / 3, count);
159     if (count) {
160         for (i = 0; i < count; i++)
161             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
162         if (s->flags && count >= 32) { // EHB
163             for (i = 0; i < 32; i++)
164                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
165             count = FFMAX(count, 64);
166         }
167     } else { // Create gray-scale color palette for bps < 8
168         count = 1 << avctx->bits_per_coded_sample;
169
170         for (i = 0; i < count; i++)
171             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
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_end(AVCodecContext *avctx)
324 {
325     IffContext *s = avctx->priv_data;
326     av_frame_free(&s->frame);
327     av_freep(&s->planebuf);
328     av_freep(&s->ham_buf);
329     av_freep(&s->ham_palbuf);
330     return 0;
331 }
332
333 static av_cold int decode_init(AVCodecContext *avctx)
334 {
335     IffContext *s = avctx->priv_data;
336     int err;
337
338     if (avctx->bits_per_coded_sample <= 8) {
339         int palette_size;
340
341         if (avctx->extradata_size >= 2)
342             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
343         else
344             palette_size = 0;
345         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
346                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
347     } else if (avctx->bits_per_coded_sample <= 32) {
348         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
349             avctx->pix_fmt = AV_PIX_FMT_RGB32;
350         } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
351             avctx->pix_fmt = AV_PIX_FMT_RGB444;
352         } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
353             if (avctx->bits_per_coded_sample == 24) {
354                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
355             } else if (avctx->bits_per_coded_sample == 32) {
356                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
357             } else {
358                 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
359                 return AVERROR_PATCHWELCOME;
360             }
361         }
362     } else {
363         return AVERROR_INVALIDDATA;
364     }
365
366     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
367         return err;
368     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
369     s->planebuf  = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
370     if (!s->planebuf)
371         return AVERROR(ENOMEM);
372
373     s->bpp = avctx->bits_per_coded_sample;
374     s->frame = av_frame_alloc();
375     if (!s->frame) {
376         decode_end(avctx);
377         return AVERROR(ENOMEM);
378     }
379
380     if ((err = extract_header(avctx, NULL)) < 0)
381         return err;
382
383     return 0;
384 }
385
386 /**
387  * Decode interleaved plane buffer up to 8bpp
388  * @param dst Destination buffer
389  * @param buf Source buffer
390  * @param buf_size
391  * @param plane plane number to decode as
392  */
393 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
394 {
395     const uint64_t *lut = plane8_lut[plane];
396     if (plane >= 8) {
397         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
398         return;
399     }
400     do {
401         uint64_t v = AV_RN64A(dst) | lut[*buf++];
402         AV_WN64A(dst, v);
403         dst += 8;
404     } while (--buf_size);
405 }
406
407 /**
408  * Decode interleaved plane buffer up to 24bpp
409  * @param dst Destination buffer
410  * @param buf Source buffer
411  * @param buf_size
412  * @param plane plane number to decode as
413  */
414 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
415 {
416     const uint32_t *lut = plane32_lut[plane];
417     do {
418         unsigned mask = (*buf >> 2) & ~3;
419         dst[0] |= lut[mask++];
420         dst[1] |= lut[mask++];
421         dst[2] |= lut[mask++];
422         dst[3] |= lut[mask];
423         mask    = (*buf++ << 2) & 0x3F;
424         dst[4] |= lut[mask++];
425         dst[5] |= lut[mask++];
426         dst[6] |= lut[mask++];
427         dst[7] |= lut[mask];
428         dst    += 8;
429     } while (--buf_size);
430 }
431
432 #define DECODE_HAM_PLANE32(x)       \
433     first       = buf[x] << 1;      \
434     second      = buf[(x)+1] << 1;  \
435     delta      &= pal[first++];     \
436     delta      |= pal[first];       \
437     dst[x]      = delta;            \
438     delta      &= pal[second++];    \
439     delta      |= pal[second];      \
440     dst[(x)+1]  = delta
441
442 /**
443  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
444  *
445  * @param dst the destination 24bpp buffer
446  * @param buf the source 8bpp chunky buffer
447  * @param pal the HAM decode table
448  * @param buf_size the plane size in bytes
449  */
450 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
451                                const uint32_t *const pal, unsigned buf_size)
452 {
453     uint32_t delta = pal[1]; /* first palette entry */
454     do {
455         uint32_t first, second;
456         DECODE_HAM_PLANE32(0);
457         DECODE_HAM_PLANE32(2);
458         DECODE_HAM_PLANE32(4);
459         DECODE_HAM_PLANE32(6);
460         buf += 8;
461         dst += 8;
462     } while (--buf_size);
463 }
464
465 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
466                          const uint32_t *const pal, unsigned width)
467 {
468     do {
469         *dst++ = pal[*buf++];
470     } while (--width);
471 }
472
473 /**
474  * Decode one complete byterun1 encoded line.
475  *
476  * @param dst the destination buffer where to store decompressed bitstream
477  * @param dst_size the destination plane size in bytes
478  * @param buf the source byterun1 compressed bitstream
479  * @param buf_end the EOF of source byterun1 compressed bitstream
480  * @return number of consumed bytes in byterun1 compressed bitstream
481  */
482 static int decode_byterun(uint8_t *dst, int dst_size,
483                           const uint8_t *buf, const uint8_t *const buf_end)
484 {
485     const uint8_t *const buf_start = buf;
486     unsigned x;
487     for (x = 0; x < dst_size && buf < buf_end;) {
488         unsigned length;
489         const int8_t value = *buf++;
490         if (value >= 0) {
491             length = FFMIN3(value + 1, dst_size - x, buf_end - buf);
492             memcpy(dst + x, buf, length);
493             buf += length;
494         } else if (value > -128) {
495             length = FFMIN(-value + 1, dst_size - x);
496             memset(dst + x, *buf++, length);
497         } else { // noop
498             continue;
499         }
500         x += length;
501     }
502     if (x < dst_size) {
503         av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
504         memset(dst+x, 0, dst_size - x);
505     }
506     return buf - buf_start;
507 }
508
509 #define DECODE_RGBX_COMMON(type) \
510     if (!length) { \
511         length = bytestream2_get_byte(gb); \
512         if (!length) { \
513             length = bytestream2_get_be16(gb); \
514             if (!length) \
515                 return; \
516         } \
517     } \
518     for (i = 0; i < length; i++) { \
519         *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
520         x += 1; \
521         if (x >= width) { \
522             y += 1; \
523             if (y >= height) \
524                 return; \
525             x = 0; \
526         } \
527     }
528
529 /**
530  * Decode RGB8 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_rgb8(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) >= 4) {
540         uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
541         length = bytestream2_get_byte(gb) & 0x7F;
542         DECODE_RGBX_COMMON(uint32_t)
543     }
544 }
545
546 /**
547  * Decode RGBN buffer
548  * @param[out] dst Destination buffer
549  * @param width Width of destination buffer (pixels)
550  * @param height Height of destination buffer (pixels)
551  * @param linesize Line size of destination buffer (bytes)
552  */
553 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
554 {
555     int x = 0, y = 0, i, length;
556     while (bytestream2_get_bytes_left(gb) >= 2) {
557         uint32_t pixel = bytestream2_get_be16u(gb);
558         length = pixel & 0x7;
559         pixel >>= 4;
560         DECODE_RGBX_COMMON(uint16_t)
561     }
562 }
563
564 /**
565  * Decode DEEP RLE 32-bit buffer
566  * @param[out] dst Destination buffer
567  * @param[in] src Source buffer
568  * @param src_size Source buffer size (bytes)
569  * @param width Width of destination buffer (pixels)
570  * @param height Height of destination buffer (pixels)
571  * @param linesize Line size of destination buffer (bytes)
572  */
573 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
574 {
575     const uint8_t *src_end = src + src_size;
576     int x = 0, y = 0, i;
577     while (src + 5 <= src_end) {
578         int opcode;
579         opcode = *(int8_t *)src++;
580         if (opcode >= 0) {
581             int size = opcode + 1;
582             for (i = 0; i < size; i++) {
583                 int length = FFMIN(size - i, width);
584                 memcpy(dst + y*linesize + x * 4, src, length * 4);
585                 src += length * 4;
586                 x += length;
587                 i += length;
588                 if (x >= width) {
589                     x = 0;
590                     y += 1;
591                     if (y >= height)
592                         return;
593                 }
594             }
595         } else {
596             int size = -opcode + 1;
597             uint32_t pixel = AV_RN32(src);
598             for (i = 0; i < size; i++) {
599                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
600                 x += 1;
601                 if (x >= width) {
602                     x = 0;
603                     y += 1;
604                     if (y >= height)
605                         return;
606                 }
607             }
608             src += 4;
609         }
610     }
611 }
612
613 /**
614  * Decode DEEP TVDC 32-bit buffer
615  * @param[out] dst Destination buffer
616  * @param[in] src Source buffer
617  * @param src_size Source buffer size (bytes)
618  * @param width Width of destination buffer (pixels)
619  * @param height Height of destination buffer (pixels)
620  * @param linesize Line size of destination buffer (bytes)
621  * @param[int] tvdc TVDC lookup table
622  */
623 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)
624 {
625     int x = 0, y = 0, plane = 0;
626     int8_t pixel = 0;
627     int i, j;
628
629     for (i = 0; i < src_size * 2;) {
630 #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
631         int d = tvdc[GETNIBBLE];
632         i++;
633         if (d) {
634             pixel += d;
635             dst[y * linesize + x*4 + plane] = pixel;
636             x++;
637         } else {
638             if (i >= src_size * 2)
639                 return;
640             d = GETNIBBLE + 1;
641             i++;
642             d = FFMIN(d, width - x);
643             for (j = 0; j < d; j++) {
644                 dst[y * linesize + x*4 + plane] = pixel;
645                 x++;
646             }
647         }
648         if (x >= width) {
649             plane++;
650             if (plane >= 4) {
651                 y++;
652                 if (y >= height)
653                     return;
654                 plane = 0;
655             }
656             x = 0;
657             pixel = 0;
658             i = (i + 1) & ~1;
659         }
660     }
661 }
662
663 static int unsupported(AVCodecContext *avctx)
664 {
665     IffContext *s = avctx->priv_data;
666     avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
667     return AVERROR_INVALIDDATA;
668 }
669
670 static int decode_frame(AVCodecContext *avctx,
671                         void *data, int *got_frame,
672                         AVPacket *avpkt)
673 {
674     IffContext *s          = avctx->priv_data;
675     const uint8_t *buf     = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
676     const int buf_size     = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
677     const uint8_t *buf_end = buf + buf_size;
678     int y, plane, res;
679     GetByteContext gb;
680
681     if ((res = extract_header(avctx, avpkt)) < 0)
682         return res;
683     if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
684         return res;
685     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
686         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
687         if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
688             return res;
689     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
690                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
691         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
692             return res;
693     }
694     s->init = 1;
695
696     switch (s->compression) {
697     case 0:
698         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
699             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
700                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
701                 for (plane = 0; plane < s->bpp; plane++) {
702                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
703                         uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
704                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
705                         buf += s->planesize;
706                     }
707                 }
708             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
709                 memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
710                 for (y = 0; y < avctx->height; y++) {
711                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
712                     memset(s->ham_buf, 0, s->planesize * 8);
713                     for (plane = 0; plane < s->bpp; plane++) {
714                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
715                         if (start >= buf_end)
716                             break;
717                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
718                     }
719                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
720                 }
721             } else
722                 return unsupported(avctx);
723         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
724             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
725             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
726             int x;
727             for (y = 0; y < avctx->height && buf < buf_end; y++) {
728                 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
729                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
730                 buf += raw_width;
731                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
732                     for (x = 0; x < avctx->width; x++)
733                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
734                 }
735             }
736         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
737             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
738                 for (y = 0; y < avctx->height; y++) {
739                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
740                     memset(row, 0, avctx->width);
741                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
742                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
743                         buf += s->planesize;
744                     }
745                 }
746             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
747                 for (y = 0; y < avctx->height; y++) {
748                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
749                     memset(s->ham_buf, 0, s->planesize * 8);
750                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
751                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
752                         buf += s->planesize;
753                     }
754                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
755                 }
756             } else { // AV_PIX_FMT_BGR32
757                 for (y = 0; y < avctx->height; y++) {
758                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
759                     memset(row, 0, avctx->width << 2);
760                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
761                         decodeplane32((uint32_t *)row, buf,
762                                       FFMIN(s->planesize, buf_end - buf), plane);
763                         buf += s->planesize;
764                     }
765                 }
766             }
767         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
768             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
769                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
770                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
771                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
772                     buf += avctx->width + (avctx->width % 2); // padding if odd
773                 }
774             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
775                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
776                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
777                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
778                     buf += avctx->width + (avctx->width & 1); // padding if odd
779                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
780                 }
781             } else
782                 return unsupported(avctx);
783         }
784         break;
785     case 1:
786         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
787             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
788                 for (y = 0; y < avctx->height; y++) {
789                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
790                     memset(row, 0, avctx->width);
791                     for (plane = 0; plane < s->bpp; plane++) {
792                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
793                         decodeplane8(row, s->planebuf, s->planesize, plane);
794                     }
795                 }
796             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
797                 for (y = 0; y < avctx->height; y++) {
798                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
799                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
800                     for (plane = 0; plane < s->bpp; plane++) {
801                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
802                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
803                     }
804                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
805                 }
806             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
807                 for (y = 0; y < avctx->height; y++) {
808                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
809                     memset(s->ham_buf, 0, s->planesize * 8);
810                     for (plane = 0; plane < s->bpp; plane++) {
811                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
812                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
813                     }
814                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
815                 }
816             } else { // 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                     memset(row, 0, avctx->width << 2);
820                     for (plane = 0; plane < s->bpp; plane++) {
821                         buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
822                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
823                     }
824                 }
825             }
826         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
827             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
828                 for (y = 0; y < avctx->height; y++) {
829                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
830                     buf += decode_byterun(row, avctx->width, buf, buf_end);
831                 }
832             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
833                 for (y = 0; y < avctx->height; y++) {
834                     uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
835                     buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
836                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
837                 }
838             } else
839                 return unsupported(avctx);
840         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
841             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
842             if (av_get_bits_per_pixel(desc) == 32)
843                 decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
844             else
845                 return unsupported(avctx);
846         }
847         break;
848     case 4:
849         bytestream2_init(&gb, buf, buf_size);
850         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
851             decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
852         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
853             decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
854         else
855             return unsupported(avctx);
856         break;
857     case 5:
858         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
859             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
860             if (av_get_bits_per_pixel(desc) == 32)
861                 decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
862             else
863                 return unsupported(avctx);
864         } else
865             return unsupported(avctx);
866         break;
867     default:
868         return unsupported(avctx);
869     }
870
871     if ((res = av_frame_ref(data, s->frame)) < 0)
872         return res;
873
874     *got_frame = 1;
875
876     return buf_size;
877 }
878
879 #if CONFIG_IFF_ILBM_DECODER
880 AVCodec ff_iff_ilbm_decoder = {
881     .name           = "iff",
882     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
883     .type           = AVMEDIA_TYPE_VIDEO,
884     .id             = AV_CODEC_ID_IFF_ILBM,
885     .priv_data_size = sizeof(IffContext),
886     .init           = decode_init,
887     .close          = decode_end,
888     .decode         = decode_frame,
889     .capabilities   = CODEC_CAP_DR1,
890 };
891 #endif
892 #if CONFIG_IFF_BYTERUN1_DECODER
893 AVCodec ff_iff_byterun1_decoder = {
894     .name           = "iff",
895     .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
896     .type           = AVMEDIA_TYPE_VIDEO,
897     .id             = AV_CODEC_ID_IFF_BYTERUN1,
898     .priv_data_size = sizeof(IffContext),
899     .init           = decode_init,
900     .close          = decode_end,
901     .decode         = decode_frame,
902     .capabilities   = CODEC_CAP_DR1,
903 };
904 #endif