]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
iff: DEEP RLE 32-bit decoder
[ffmpeg] / libavcodec / iff.c
1 /*
2  * IFF PBM/ILBM 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 PBM/ILBM bitmap decoder
26  */
27
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
30 #include "avcodec.h"
31 #include "get_bits.h"
32
33 // TODO: masking bits
34 typedef enum {
35     MASK_NONE,
36     MASK_HAS_MASK,
37     MASK_HAS_TRANSPARENT_COLOR,
38     MASK_LASSO
39 } mask_type;
40
41 typedef struct {
42     AVFrame frame;
43     int planesize;
44     uint8_t * planebuf;
45     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
46     uint32_t *ham_palbuf;   ///< HAM decode table
47     uint32_t *mask_buf;     ///< temporary buffer for palette indices
48     uint32_t *mask_palbuf;  ///< masking palette table
49     unsigned  compression;  ///< delta compression method used
50     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
51     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
52     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
53     unsigned  transparency; ///< TODO: transparency color index in palette
54     unsigned  masking;      ///< TODO: masking method used
55     int init; // 1 if buffer and palette data already initialized, 0 otherwise
56 } IffContext;
57
58 #define LUT8_PART(plane, v)                             \
59     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
60     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
61     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
62     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
63     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
64     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
65     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
66     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
67     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
68     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
69     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
70     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
71     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
72     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
73     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
74     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
75
76 #define LUT8(plane) {                           \
77     LUT8_PART(plane, 0x0000000),                \
78     LUT8_PART(plane, 0x1000000),                \
79     LUT8_PART(plane, 0x0010000),                \
80     LUT8_PART(plane, 0x1010000),                \
81     LUT8_PART(plane, 0x0000100),                \
82     LUT8_PART(plane, 0x1000100),                \
83     LUT8_PART(plane, 0x0010100),                \
84     LUT8_PART(plane, 0x1010100),                \
85     LUT8_PART(plane, 0x0000001),                \
86     LUT8_PART(plane, 0x1000001),                \
87     LUT8_PART(plane, 0x0010001),                \
88     LUT8_PART(plane, 0x1010001),                \
89     LUT8_PART(plane, 0x0000101),                \
90     LUT8_PART(plane, 0x1000101),                \
91     LUT8_PART(plane, 0x0010101),                \
92     LUT8_PART(plane, 0x1010101),                \
93 }
94
95 // 8 planes * 8-bit mask
96 static const uint64_t plane8_lut[8][256] = {
97     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
98     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
99 };
100
101 #define LUT32(plane) {                                \
102              0,          0,          0,          0,   \
103              0,          0,          0, 1 << plane,   \
104              0,          0, 1 << plane,          0,   \
105              0,          0, 1 << plane, 1 << plane,   \
106              0, 1 << plane,          0,          0,   \
107              0, 1 << plane,          0, 1 << plane,   \
108              0, 1 << plane, 1 << plane,          0,   \
109              0, 1 << plane, 1 << plane, 1 << plane,   \
110     1 << plane,          0,          0,          0,   \
111     1 << plane,          0,          0, 1 << plane,   \
112     1 << plane,          0, 1 << plane,          0,   \
113     1 << plane,          0, 1 << plane, 1 << plane,   \
114     1 << plane, 1 << plane,          0,          0,   \
115     1 << plane, 1 << plane,          0, 1 << plane,   \
116     1 << plane, 1 << plane, 1 << plane,          0,   \
117     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
118 }
119
120 // 32 planes * 4-bit mask * 4 lookup tables each
121 static const uint32_t plane32_lut[32][16*4] = {
122     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
123     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
124     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
125     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
126     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
127     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
128     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
129     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
130 };
131
132 // Gray to RGB, required for palette table of grayscale images with bpp < 8
133 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
134     return x << 16 | x << 8 | x;
135 }
136
137 /**
138  * Convert CMAP buffer (stored in extradata) to lavc palette format
139  */
140 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
141 {
142     IffContext *s = avctx->priv_data;
143     int count, i;
144     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
145     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
146
147     if (avctx->bits_per_coded_sample > 8) {
148         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
149         return AVERROR_INVALIDDATA;
150     }
151
152     count = 1 << avctx->bits_per_coded_sample;
153     // If extradata is smaller than actually needed, fill the remaining with black.
154     count = FFMIN(palette_size / 3, count);
155     if (count) {
156         for (i=0; i < count; i++) {
157             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
158         }
159         if (s->flags && count >= 32) { // EHB
160             for (i = 0; i < 32; i++)
161                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
162             count = FFMAX(count, 64);
163         }
164     } else { // Create gray-scale color palette for bps < 8
165         count = 1 << avctx->bits_per_coded_sample;
166
167         for (i=0; i < count; i++) {
168             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
169         }
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 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 > 8) {
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         if (s->masking == MASK_HAS_MASK) {
234             if (s->bpp >= 8 && !s->ham) {
235                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
236                 av_freep(&s->mask_buf);
237                 av_freep(&s->mask_palbuf);
238                 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
239                 if (!s->mask_buf)
240                     return AVERROR(ENOMEM);
241                 if (s->bpp > 16) {
242                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
243                     av_freep(&s->mask_buf);
244                     return AVERROR(ENOMEM);
245                 }
246                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
247                 if (!s->mask_palbuf) {
248                     av_freep(&s->mask_buf);
249                     return AVERROR(ENOMEM);
250                 }
251             }
252             s->bpp++;
253         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
254             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
255             return AVERROR_PATCHWELCOME;
256         }
257         if (!s->bpp || s->bpp > 32) {
258             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
259             return AVERROR_INVALIDDATA;
260         } else if (s->ham >= 8) {
261             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
262             return AVERROR_INVALIDDATA;
263         }
264
265         av_freep(&s->ham_buf);
266         av_freep(&s->ham_palbuf);
267
268         if (s->ham) {
269             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
270             int ham_count;
271             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
272
273             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
274             if (!s->ham_buf)
275                 return AVERROR(ENOMEM);
276
277             ham_count = 8 * (1 << s->ham);
278             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
279             if (!s->ham_palbuf) {
280                 av_freep(&s->ham_buf);
281                 return AVERROR(ENOMEM);
282             }
283
284             if (count) { // HAM with color palette attached
285                 // prefill with black and palette and set HAM take direct value mask to zero
286                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
287                 for (i=0; i < count; i++) {
288                     s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
289                 }
290                 count = 1 << s->ham;
291             } else { // HAM with grayscale color palette
292                 count = 1 << s->ham;
293                 for (i=0; i < count; i++) {
294                     s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
295                     s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
296                 }
297             }
298             for (i=0; i < count; i++) {
299                 uint32_t tmp = i << (8 - s->ham);
300                 tmp |= tmp >> s->ham;
301                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
302                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
303                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
304                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
305                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
306                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
307             }
308             if (s->masking == MASK_HAS_MASK) {
309                 for (i = 0; i < ham_count; i++)
310                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
311             }
312         }
313     }
314
315     return 0;
316 }
317
318 static av_cold int decode_init(AVCodecContext *avctx)
319 {
320     IffContext *s = avctx->priv_data;
321     int err;
322
323     if (avctx->bits_per_coded_sample <= 8) {
324         int palette_size;
325
326         if (avctx->extradata_size >= 2)
327             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
328         else
329             palette_size = 0;
330         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
331                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
332     } else if (avctx->bits_per_coded_sample <= 32) {
333         if (avctx->codec_tag != MKTAG('D','E','E','P')) {
334             if (avctx->bits_per_coded_sample == 24) {
335                 avctx->pix_fmt = AV_PIX_FMT_RGB0;
336             } else if (avctx->bits_per_coded_sample == 32) {
337                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
338             } else {
339                 av_log_ask_for_sample(avctx, "unknown bits_per_coded_sample\n");
340                 return AVERROR_PATCHWELCOME;
341             }
342         }
343     } else {
344         return AVERROR_INVALIDDATA;
345     }
346
347     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
348         return err;
349     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
350     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
351     if (!s->planebuf)
352         return AVERROR(ENOMEM);
353
354     s->bpp = avctx->bits_per_coded_sample;
355     avcodec_get_frame_defaults(&s->frame);
356
357     if ((err = extract_header(avctx, NULL)) < 0)
358         return err;
359     s->frame.reference = 3;
360
361     return 0;
362 }
363
364 /**
365  * Decode interleaved plane buffer up to 8bpp
366  * @param dst Destination buffer
367  * @param buf Source buffer
368  * @param buf_size
369  * @param plane plane number to decode as
370  */
371 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
372 {
373     const uint64_t *lut = plane8_lut[plane];
374     if (plane >= 8) {
375         av_log(0, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
376         return;
377     }
378     do {
379         uint64_t v = AV_RN64A(dst) | lut[*buf++];
380         AV_WN64A(dst, v);
381         dst += 8;
382     } while (--buf_size);
383 }
384
385 /**
386  * Decode interleaved plane buffer up to 24bpp
387  * @param dst Destination buffer
388  * @param buf Source buffer
389  * @param buf_size
390  * @param plane plane number to decode as
391  */
392 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
393 {
394     const uint32_t *lut = plane32_lut[plane];
395     do {
396         unsigned mask = (*buf >> 2) & ~3;
397         dst[0] |= lut[mask++];
398         dst[1] |= lut[mask++];
399         dst[2] |= lut[mask++];
400         dst[3] |= lut[mask];
401         mask = (*buf++ << 2) & 0x3F;
402         dst[4] |= lut[mask++];
403         dst[5] |= lut[mask++];
404         dst[6] |= lut[mask++];
405         dst[7] |= lut[mask];
406         dst += 8;
407     } while (--buf_size);
408 }
409
410 #define DECODE_HAM_PLANE32(x)       \
411     first       = buf[x] << 1;      \
412     second      = buf[(x)+1] << 1;  \
413     delta      &= pal[first++];     \
414     delta      |= pal[first];       \
415     dst[x]      = delta;            \
416     delta      &= pal[second++];    \
417     delta      |= pal[second];      \
418     dst[(x)+1]  = delta
419
420 /**
421  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
422  *
423  * @param dst the destination 24bpp buffer
424  * @param buf the source 8bpp chunky buffer
425  * @param pal the HAM decode table
426  * @param buf_size the plane size in bytes
427  */
428 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
429                                const uint32_t *const pal, unsigned buf_size)
430 {
431     uint32_t delta = 0;
432     do {
433         uint32_t first, second;
434         DECODE_HAM_PLANE32(0);
435         DECODE_HAM_PLANE32(2);
436         DECODE_HAM_PLANE32(4);
437         DECODE_HAM_PLANE32(6);
438         buf += 8;
439         dst += 8;
440     } while (--buf_size);
441 }
442
443 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
444                          const uint32_t *const pal, unsigned width)
445 {
446     do {
447         *dst++ = pal[*buf++];
448     } while (--width);
449 }
450
451 /**
452  * Decode one complete byterun1 encoded line.
453  *
454  * @param dst the destination buffer where to store decompressed bitstream
455  * @param dst_size the destination plane size in bytes
456  * @param buf the source byterun1 compressed bitstream
457  * @param buf_end the EOF of source byterun1 compressed bitstream
458  * @return number of consumed bytes in byterun1 compressed bitstream
459 */
460 static int decode_byterun(uint8_t *dst, int dst_size,
461                           const uint8_t *buf, const uint8_t *const buf_end) {
462     const uint8_t *const buf_start = buf;
463     unsigned x;
464     for (x = 0; x < dst_size && buf < buf_end;) {
465         unsigned length;
466         const int8_t value = *buf++;
467         if (value >= 0) {
468             length = value + 1;
469             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
470             buf += length;
471         } else if (value > -128) {
472             length = -value + 1;
473             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
474         } else { // noop
475             continue;
476         }
477         x += length;
478     }
479     return buf - buf_start;
480 }
481
482 static int decode_frame_ilbm(AVCodecContext *avctx,
483                             void *data, int *data_size,
484                             AVPacket *avpkt)
485 {
486     IffContext *s = avctx->priv_data;
487     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
488     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
489     const uint8_t *buf_end = buf+buf_size;
490     int y, plane, res;
491
492     if ((res = extract_header(avctx, avpkt)) < 0)
493         return res;
494
495     if (s->init) {
496         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
497             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
498             return res;
499         }
500     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
501         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
502         return res;
503     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
504         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
505             return res;
506     }
507     s->init = 1;
508
509     if (avctx->codec_tag == MKTAG('A','C','B','M')) {
510         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
511             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
512             for (plane = 0; plane < s->bpp; plane++) {
513                 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
514                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
515                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
516                     buf += s->planesize;
517                 }
518             }
519         } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
520             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
521             for(y = 0; y < avctx->height; y++) {
522                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
523                 memset(s->ham_buf, 0, s->planesize * 8);
524                 for (plane = 0; plane < s->bpp; plane++) {
525                     const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
526                     if (start >= buf_end)
527                         break;
528                     decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
529                 }
530                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
531             }
532         }
533     } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
534         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
535         int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
536         int x;
537         for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
538             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
539             memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
540             buf += raw_width;
541             if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
542                 for(x = 0; x < avctx->width; x++)
543                     row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
544             }
545         }
546     } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
547         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
548             for(y = 0; y < avctx->height; y++ ) {
549                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
550                 memset(row, 0, avctx->width);
551                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
552                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
553                     buf += s->planesize;
554                 }
555             }
556         } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
557             for (y = 0; y < avctx->height; y++) {
558                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
559                 memset(s->ham_buf, 0, s->planesize * 8);
560                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
561                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
562                     buf += s->planesize;
563                 }
564                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
565             }
566         } else { // AV_PIX_FMT_BGR32
567             for(y = 0; y < avctx->height; y++ ) {
568                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
569                 memset(row, 0, avctx->width << 2);
570                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
571                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
572                     buf += s->planesize;
573                 }
574             }
575         }
576     } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
577         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
578             for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
579                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
580                 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
581                 buf += avctx->width + (avctx->width % 2); // padding if odd
582             }
583         } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
584             for (y = 0; y < avctx->height && buf_end > buf; y++) {
585                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
586                 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
587                 buf += avctx->width + (avctx->width & 1); // padding if odd
588                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
589             }
590         } else {
591             av_log_ask_for_sample(avctx, "unsupported bpp\n");
592             return AVERROR_INVALIDDATA;
593         }
594     }
595
596     *data_size = sizeof(AVFrame);
597     *(AVFrame*)data = s->frame;
598     return buf_size;
599 }
600
601 /**
602  * Decode DEEP RLE 32-bit buffer
603  * @param[out] dst Destination buffer
604  * @param[in] src Source buffer
605  * @param src_size Source buffer size (bytes)
606  * @param width Width of destination buffer (pixels)
607  * @param height Height of destination buffer (pixels)
608  * @param linesize Line size of destination buffer (bytes)
609  */
610 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
611 {
612     const uint8_t *src_end = src + src_size;
613     int x = 0, y = 0, i;
614     while (src + 5 <= src_end) {
615         int opcode;
616         opcode = *(int8_t *)src++;
617         if (opcode >= 0) {
618             int size = opcode + 1;
619             for (i = 0; i < size; i++) {
620                 int length = FFMIN(size - i, width);
621                 memcpy(dst + y*linesize + x * 4, src, length * 4);
622                 src += length * 4;
623                 x += length;
624                 i += length;
625                 if (x >= width) {
626                     x = 0;
627                     y += 1;
628                     if (y >= height)
629                         return;
630                 }
631             }
632         } else {
633             int size = -opcode + 1;
634             uint32_t pixel = AV_RL32(src);
635             for (i = 0; i < size; i++) {
636                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
637                 x += 1;
638                 if (x >= width) {
639                     x = 0;
640                     y += 1;
641                     if (y >= height)
642                         return;
643                 }
644             }
645             src += 4;
646         }
647     }
648 }
649
650 static int decode_frame_byterun1(AVCodecContext *avctx,
651                             void *data, int *data_size,
652                             AVPacket *avpkt)
653 {
654     IffContext *s = avctx->priv_data;
655     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
656     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
657     const uint8_t *buf_end = buf+buf_size;
658     int y, plane, res;
659
660     if ((res = extract_header(avctx, avpkt)) < 0)
661         return res;
662     if (s->init) {
663         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
664             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
665             return res;
666         }
667     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
668         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
669         return res;
670     } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
671         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
672             return res;
673     } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
674         if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
675             return res;
676     }
677     s->init = 1;
678
679     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
680         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
681             for(y = 0; y < avctx->height ; y++ ) {
682                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
683                 memset(row, 0, avctx->width);
684                 for (plane = 0; plane < s->bpp; plane++) {
685                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
686                     decodeplane8(row, s->planebuf, s->planesize, plane);
687                 }
688             }
689         } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
690             for (y = 0; y < avctx->height ; y++ ) {
691                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
692                 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
693                 for (plane = 0; plane < s->bpp; plane++) {
694                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
695                     decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
696                 }
697                 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
698             }
699         } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
700             for (y = 0; y < avctx->height ; y++) {
701                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
702                 memset(s->ham_buf, 0, s->planesize * 8);
703                 for (plane = 0; plane < s->bpp; plane++) {
704                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
705                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
706                 }
707                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
708             }
709         } else { //AV_PIX_FMT_BGR32
710             for(y = 0; y < avctx->height ; y++ ) {
711                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
712                 memset(row, 0, avctx->width << 2);
713                 for (plane = 0; plane < s->bpp; plane++) {
714                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
715                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
716                 }
717             }
718         }
719     } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
720         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
721             for(y = 0; y < avctx->height ; y++ ) {
722                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
723                 buf += decode_byterun(row, avctx->width, buf, buf_end);
724             }
725         } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
726             for (y = 0; y < avctx->height ; y++) {
727                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
728                 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
729                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
730             }
731         } else {
732             av_log_ask_for_sample(avctx, "unsupported bpp\n");
733             return AVERROR_INVALIDDATA;
734         }
735     } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
736         const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
737         if (av_get_bits_per_pixel(desc) == 32)
738             decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
739         else {
740             av_log_ask_for_sample(avctx, "unsupported bpp\n");
741             return AVERROR_INVALIDDATA;
742         }
743     }
744
745     *data_size = sizeof(AVFrame);
746     *(AVFrame*)data = s->frame;
747     return buf_size;
748 }
749
750 static av_cold int decode_end(AVCodecContext *avctx)
751 {
752     IffContext *s = avctx->priv_data;
753     if (s->frame.data[0])
754         avctx->release_buffer(avctx, &s->frame);
755     av_freep(&s->planebuf);
756     av_freep(&s->ham_buf);
757     av_freep(&s->ham_palbuf);
758     return 0;
759 }
760
761 #if CONFIG_IFF_ILBM_DECODER
762 AVCodec ff_iff_ilbm_decoder = {
763     .name           = "iff_ilbm",
764     .type           = AVMEDIA_TYPE_VIDEO,
765     .id             = AV_CODEC_ID_IFF_ILBM,
766     .priv_data_size = sizeof(IffContext),
767     .init           = decode_init,
768     .close          = decode_end,
769     .decode         = decode_frame_ilbm,
770     .capabilities   = CODEC_CAP_DR1,
771     .long_name      = NULL_IF_CONFIG_SMALL("IFF ILBM"),
772 };
773 #endif
774 #if CONFIG_IFF_BYTERUN1_DECODER
775 AVCodec ff_iff_byterun1_decoder = {
776     .name           = "iff_byterun1",
777     .type           = AVMEDIA_TYPE_VIDEO,
778     .id             = AV_CODEC_ID_IFF_BYTERUN1,
779     .priv_data_size = sizeof(IffContext),
780     .init           = decode_init,
781     .close          = decode_end,
782     .decode         = decode_frame_byterun1,
783     .capabilities   = CODEC_CAP_DR1,
784     .long_name      = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
785 };
786 #endif