]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
Merge remote-tracking branch 'qatar/master'
[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, "bit_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) {
235                 avctx->pix_fmt = 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                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
242                 if (!s->mask_palbuf) {
243                     av_freep(&s->mask_buf);
244                     return AVERROR(ENOMEM);
245                 }
246             }
247             s->bpp++;
248         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
249             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
250             return AVERROR_PATCHWELCOME;
251         }
252         if (!s->bpp || s->bpp > 32) {
253             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
254             return AVERROR_INVALIDDATA;
255         } else if (s->ham >= 8) {
256             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
257             return AVERROR_INVALIDDATA;
258         }
259
260         av_freep(&s->ham_buf);
261         av_freep(&s->ham_palbuf);
262
263         if (s->ham) {
264             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
265             int ham_count;
266             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
267
268             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
269             if (!s->ham_buf)
270                 return AVERROR(ENOMEM);
271
272             ham_count = 8 * (1 << s->ham);
273             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
274             if (!s->ham_palbuf) {
275                 av_freep(&s->ham_buf);
276                 return AVERROR(ENOMEM);
277             }
278
279             if (count) { // HAM with color palette attached
280                 // prefill with black and palette and set HAM take direct value mask to zero
281                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
282                 for (i=0; i < count; i++) {
283                     s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3);
284                 }
285                 count = 1 << s->ham;
286             } else { // HAM with grayscale color palette
287                 count = 1 << s->ham;
288                 for (i=0; i < count; i++) {
289                     s->ham_palbuf[i*2]   = 0; // take direct color value from palette
290                     s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham));
291                 }
292             }
293             for (i=0; i < count; i++) {
294                 uint32_t tmp = i << (8 - s->ham);
295                 tmp |= tmp >> s->ham;
296                 s->ham_palbuf[(i+count)*2]     = 0x00FFFF; // just modify blue color component
297                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFF00; // just modify red color component
298                 s->ham_palbuf[(i+count*3)*2]   = 0xFF00FF; // just modify green color component
299                 s->ham_palbuf[(i+count)*2+1]   = tmp << 16;
300                 s->ham_palbuf[(i+count*2)*2+1] = tmp;
301                 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
302             }
303             if (s->masking == MASK_HAS_MASK) {
304                 for (i = 0; i < ham_count; i++)
305                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
306             }
307         }
308     }
309
310     return 0;
311 }
312
313 static av_cold int decode_init(AVCodecContext *avctx)
314 {
315     IffContext *s = avctx->priv_data;
316     int err;
317
318     if (avctx->bits_per_coded_sample <= 8) {
319         int palette_size;
320
321         if (avctx->extradata_size >= 2)
322             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
323         else
324             palette_size = 0;
325         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
326                          (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
327     } else if (avctx->bits_per_coded_sample <= 32) {
328         if (avctx->codec_tag != MKTAG('D','E','E','P'))
329             avctx->pix_fmt = PIX_FMT_BGR32;
330     } else {
331         return AVERROR_INVALIDDATA;
332     }
333
334     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
335         return err;
336     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
337     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
338     if (!s->planebuf)
339         return AVERROR(ENOMEM);
340
341     s->bpp = avctx->bits_per_coded_sample;
342     avcodec_get_frame_defaults(&s->frame);
343
344     if ((err = extract_header(avctx, NULL)) < 0)
345         return err;
346     s->frame.reference = 3;
347
348     return 0;
349 }
350
351 /**
352  * Decode interleaved plane buffer up to 8bpp
353  * @param dst Destination buffer
354  * @param buf Source buffer
355  * @param buf_size
356  * @param plane plane number to decode as
357  */
358 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
359 {
360     const uint64_t *lut = plane8_lut[plane];
361     do {
362         uint64_t v = AV_RN64A(dst) | lut[*buf++];
363         AV_WN64A(dst, v);
364         dst += 8;
365     } while (--buf_size);
366 }
367
368 /**
369  * Decode interleaved plane buffer up to 24bpp
370  * @param dst Destination buffer
371  * @param buf Source buffer
372  * @param buf_size
373  * @param plane plane number to decode as
374  */
375 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
376 {
377     const uint32_t *lut = plane32_lut[plane];
378     do {
379         unsigned mask = (*buf >> 2) & ~3;
380         dst[0] |= lut[mask++];
381         dst[1] |= lut[mask++];
382         dst[2] |= lut[mask++];
383         dst[3] |= lut[mask];
384         mask = (*buf++ << 2) & 0x3F;
385         dst[4] |= lut[mask++];
386         dst[5] |= lut[mask++];
387         dst[6] |= lut[mask++];
388         dst[7] |= lut[mask];
389         dst += 8;
390     } while (--buf_size);
391 }
392
393 #define DECODE_HAM_PLANE32(x)       \
394     first       = buf[x] << 1;      \
395     second      = buf[(x)+1] << 1;  \
396     delta      &= pal[first++];     \
397     delta      |= pal[first];       \
398     dst[x]      = delta;            \
399     delta      &= pal[second++];    \
400     delta      |= pal[second];      \
401     dst[(x)+1]  = delta
402
403 /**
404  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
405  *
406  * @param dst the destination 24bpp buffer
407  * @param buf the source 8bpp chunky buffer
408  * @param pal the HAM decode table
409  * @param buf_size the plane size in bytes
410  */
411 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
412                                const uint32_t *const pal, unsigned buf_size)
413 {
414     uint32_t delta = 0;
415     do {
416         uint32_t first, second;
417         DECODE_HAM_PLANE32(0);
418         DECODE_HAM_PLANE32(2);
419         DECODE_HAM_PLANE32(4);
420         DECODE_HAM_PLANE32(6);
421         buf += 8;
422         dst += 8;
423     } while (--buf_size);
424 }
425
426 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
427                          const uint32_t *const pal, unsigned width)
428 {
429     do {
430         *dst++ = pal[*buf++];
431     } while (--width);
432 }
433
434 /**
435  * Decode one complete byterun1 encoded line.
436  *
437  * @param dst the destination buffer where to store decompressed bitstream
438  * @param dst_size the destination plane size in bytes
439  * @param buf the source byterun1 compressed bitstream
440  * @param buf_end the EOF of source byterun1 compressed bitstream
441  * @return number of consumed bytes in byterun1 compressed bitstream
442 */
443 static int decode_byterun(uint8_t *dst, int dst_size,
444                           const uint8_t *buf, const uint8_t *const buf_end) {
445     const uint8_t *const buf_start = buf;
446     unsigned x;
447     for (x = 0; x < dst_size && buf < buf_end;) {
448         unsigned length;
449         const int8_t value = *buf++;
450         if (value >= 0) {
451             length = value + 1;
452             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
453             buf += length;
454         } else if (value > -128) {
455             length = -value + 1;
456             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
457         } else { // noop
458             continue;
459         }
460         x += length;
461     }
462     return buf - buf_start;
463 }
464
465 static int decode_frame_ilbm(AVCodecContext *avctx,
466                             void *data, int *data_size,
467                             AVPacket *avpkt)
468 {
469     IffContext *s = avctx->priv_data;
470     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
471     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
472     const uint8_t *buf_end = buf+buf_size;
473     int y, plane, res;
474
475     if ((res = extract_header(avctx, avpkt)) < 0)
476         return res;
477
478     if (s->init) {
479         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
480             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
481             return res;
482         }
483     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
484         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
485         return res;
486     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == PIX_FMT_PAL8) {
487         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
488             return res;
489     }
490     s->init = 1;
491
492     if (avctx->codec_tag == MKTAG('A','C','B','M')) {
493         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
494             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
495             for (plane = 0; plane < s->bpp; plane++) {
496                 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
497                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
498                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
499                     buf += s->planesize;
500                 }
501             }
502         } else if (s->ham) { // HAM to PIX_FMT_BGR32
503             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
504             for(y = 0; y < avctx->height; y++) {
505                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
506                 memset(s->ham_buf, 0, s->planesize * 8);
507                 for (plane = 0; plane < s->bpp; plane++) {
508                     const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
509                     if (start >= buf_end)
510                         break;
511                     decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
512                 }
513                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
514             }
515         }
516     } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
517         int raw_width = avctx->width * (av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]) >> 3);
518         int x;
519         for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
520             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
521             memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
522             buf += raw_width;
523             if (avctx->pix_fmt == PIX_FMT_BGR32) {
524                 for(x = 0; x < avctx->width; x++)
525                     row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
526             }
527         }
528     } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
529         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
530             for(y = 0; y < avctx->height; y++ ) {
531                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
532                 memset(row, 0, avctx->width);
533                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
534                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
535                     buf += s->planesize;
536                 }
537             }
538         } else if (s->ham) { // HAM to PIX_FMT_BGR32
539             for (y = 0; y < avctx->height; y++) {
540                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
541                 memset(s->ham_buf, 0, s->planesize * 8);
542                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
543                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
544                     buf += s->planesize;
545                 }
546                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
547             }
548         } else { // PIX_FMT_BGR32
549             for(y = 0; y < avctx->height; y++ ) {
550                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
551                 memset(row, 0, avctx->width << 2);
552                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
553                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
554                     buf += s->planesize;
555                 }
556             }
557         }
558     } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
559         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
560             for(y = 0; y < avctx->height; y++ ) {
561                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
562                 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
563                 buf += avctx->width + (avctx->width % 2); // padding if odd
564             }
565         } else if (s->ham) { // IFF-PBM: HAM to PIX_FMT_BGR32
566             for (y = 0; y < avctx->height; y++) {
567                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
568                 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
569                 buf += avctx->width + (avctx->width & 1); // padding if odd
570                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
571             }
572         } else {
573             av_log_ask_for_sample(avctx, "unsupported bpp\n");
574             return AVERROR_INVALIDDATA;
575         }
576     }
577
578     *data_size = sizeof(AVFrame);
579     *(AVFrame*)data = s->frame;
580     return buf_size;
581 }
582
583 static int decode_frame_byterun1(AVCodecContext *avctx,
584                             void *data, int *data_size,
585                             AVPacket *avpkt)
586 {
587     IffContext *s = avctx->priv_data;
588     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
589     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
590     const uint8_t *buf_end = buf+buf_size;
591     int y, plane, res;
592
593     if ((res = extract_header(avctx, avpkt)) < 0)
594         return res;
595     if (s->init) {
596         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
597             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
598             return res;
599         }
600     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
601         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
602         return res;
603     } else if (avctx->pix_fmt == PIX_FMT_PAL8) {
604         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
605             return res;
606     } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
607         if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
608             return res;
609     }
610     s->init = 1;
611
612     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
613         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
614             for(y = 0; y < avctx->height ; y++ ) {
615                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
616                 memset(row, 0, avctx->width);
617                 for (plane = 0; plane < s->bpp; plane++) {
618                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
619                     decodeplane8(row, s->planebuf, s->planesize, plane);
620                 }
621             }
622         } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to PIX_FMT_BGR32
623             for (y = 0; y < avctx->height ; y++ ) {
624                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
625                 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
626                 for (plane = 0; plane < s->bpp; plane++) {
627                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
628                     decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
629                 }
630                 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
631             }
632         } else if (s->ham) { // HAM to PIX_FMT_BGR32
633             for (y = 0; y < avctx->height ; y++) {
634                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
635                 memset(s->ham_buf, 0, s->planesize * 8);
636                 for (plane = 0; plane < s->bpp; plane++) {
637                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
638                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
639                 }
640                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
641             }
642         } else { //PIX_FMT_BGR32
643             for(y = 0; y < avctx->height ; y++ ) {
644                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
645                 memset(row, 0, avctx->width << 2);
646                 for (plane = 0; plane < s->bpp; plane++) {
647                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
648                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
649                 }
650             }
651         }
652     } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
653         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
654             for(y = 0; y < avctx->height ; y++ ) {
655                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
656                 buf += decode_byterun(row, avctx->width, buf, buf_end);
657             }
658         } else if (s->ham) { // IFF-PBM: HAM to PIX_FMT_BGR32
659             for (y = 0; y < avctx->height ; y++) {
660                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
661                 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
662                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
663             }
664         } else {
665             av_log_ask_for_sample(avctx, "unsupported bpp\n");
666             return AVERROR_INVALIDDATA;
667         }
668     }
669
670     *data_size = sizeof(AVFrame);
671     *(AVFrame*)data = s->frame;
672     return buf_size;
673 }
674
675 static av_cold int decode_end(AVCodecContext *avctx)
676 {
677     IffContext *s = avctx->priv_data;
678     if (s->frame.data[0])
679         avctx->release_buffer(avctx, &s->frame);
680     av_freep(&s->planebuf);
681     av_freep(&s->ham_buf);
682     av_freep(&s->ham_palbuf);
683     return 0;
684 }
685
686 #if CONFIG_IFF_ILBM_DECODER
687 AVCodec ff_iff_ilbm_decoder = {
688     .name           = "iff_ilbm",
689     .type           = AVMEDIA_TYPE_VIDEO,
690     .id             = CODEC_ID_IFF_ILBM,
691     .priv_data_size = sizeof(IffContext),
692     .init           = decode_init,
693     .close          = decode_end,
694     .decode         = decode_frame_ilbm,
695     .capabilities   = CODEC_CAP_DR1,
696     .long_name      = NULL_IF_CONFIG_SMALL("IFF ILBM"),
697 };
698 #endif
699 #if CONFIG_IFF_BYTERUN1_DECODER
700 AVCodec ff_iff_byterun1_decoder = {
701     .name           = "iff_byterun1",
702     .type           = AVMEDIA_TYPE_VIDEO,
703     .id             = CODEC_ID_IFF_BYTERUN1,
704     .priv_data_size = sizeof(IffContext),
705     .init           = decode_init,
706     .close          = decode_end,
707     .decode         = decode_frame_byterun1,
708     .capabilities   = CODEC_CAP_DR1,
709     .long_name      = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
710 };
711 #endif