87a0acbb845250f06cab06a141797742eab0523a
[ffmpeg.git] / 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 /**
42  * Gets the size of CMAP palette data beyond the IFF extra context.
43  * Please note that any value < 2 of IFF extra context or
44  * raw extradata < 0 is considered as illegal extradata.
45  *
46  * @param avctx the AVCodecContext where to extract palette data size from
47  * @return size of raw palette data in bytes
48  */
49 static av_always_inline int get_palette_size(const AVCodecContext *const avctx) {
50     return avctx->extradata_size - AV_RB16(avctx->extradata);
51 }
52
53 /**
54  * Gets the actual raw image data after video properties which
55  * contains the raw image data beyond the IFF extra context.
56  *
57  * @param avpkt the AVPacket where to extract raw image data from
58  * @return pointer to raw image data
59  */
60 static av_always_inline uint8_t *get_image_data(const AVPacket *const avpkt) {
61     return avpkt->data + AV_RB16(avpkt->data);
62 }
63
64 /**
65  * Gets the size of raw image data beyond the IFF extra context.
66  * Please note that any value < 2 of either IFF extra context
67  * or raw image data is considered as an illegal packet.
68  *
69  * @param avpkt the AVPacket where to extract image data size from
70  * @return size of raw image data in bytes
71  */
72 static av_always_inline int get_image_size(const AVPacket *const avpkt) {
73     return avpkt->size - AV_RB16(avpkt->data);
74 }
75
76 typedef struct {
77     AVFrame frame;
78     int planesize;
79     uint8_t * planebuf;
80     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
81     uint32_t *ham_palbuf;   ///< HAM decode table
82     unsigned  compression;  ///< delta compression method used
83     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
84     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
85     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
86     unsigned  transparency; ///< TODO: transparency color index in palette
87     unsigned  masking;      ///< TODO: masking method used
88     int init; // 1 if buffer and palette data already initialized, 0 otherwise
89 } IffContext;
90
91 #define LUT8_PART(plane, v)                             \
92     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
93     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
94     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
95     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
96     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
97     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
98     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
99     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
100     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
101     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
102     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
103     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
104     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
105     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
106     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
107     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
108
109 #define LUT8(plane) {                           \
110     LUT8_PART(plane, 0x0000000),                \
111     LUT8_PART(plane, 0x1000000),                \
112     LUT8_PART(plane, 0x0010000),                \
113     LUT8_PART(plane, 0x1010000),                \
114     LUT8_PART(plane, 0x0000100),                \
115     LUT8_PART(plane, 0x1000100),                \
116     LUT8_PART(plane, 0x0010100),                \
117     LUT8_PART(plane, 0x1010100),                \
118     LUT8_PART(plane, 0x0000001),                \
119     LUT8_PART(plane, 0x1000001),                \
120     LUT8_PART(plane, 0x0010001),                \
121     LUT8_PART(plane, 0x1010001),                \
122     LUT8_PART(plane, 0x0000101),                \
123     LUT8_PART(plane, 0x1000101),                \
124     LUT8_PART(plane, 0x0010101),                \
125     LUT8_PART(plane, 0x1010101),                \
126 }
127
128 // 8 planes * 8-bit mask
129 static const uint64_t plane8_lut[8][256] = {
130     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
131     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
132 };
133
134 #define LUT32(plane) {                                \
135              0,          0,          0,          0,   \
136              0,          0,          0, 1 << plane,   \
137              0,          0, 1 << plane,          0,   \
138              0,          0, 1 << plane, 1 << plane,   \
139              0, 1 << plane,          0,          0,   \
140              0, 1 << plane,          0, 1 << plane,   \
141              0, 1 << plane, 1 << plane,          0,   \
142              0, 1 << plane, 1 << plane, 1 << plane,   \
143     1 << plane,          0,          0,          0,   \
144     1 << plane,          0,          0, 1 << plane,   \
145     1 << plane,          0, 1 << plane,          0,   \
146     1 << plane,          0, 1 << plane, 1 << plane,   \
147     1 << plane, 1 << plane,          0,          0,   \
148     1 << plane, 1 << plane,          0, 1 << plane,   \
149     1 << plane, 1 << plane, 1 << plane,          0,   \
150     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
151 }
152
153 // 32 planes * 4-bit mask * 4 lookup tables each
154 static const uint32_t plane32_lut[32][16*4] = {
155     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
156     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
157     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
158     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
159     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
160     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
161     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
162     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
163 };
164
165 // Gray to RGB, required for palette table of grayscale images with bpp < 8
166 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
167     return x << 16 | x << 8 | x;
168 }
169
170 /**
171  * Convert CMAP buffer (stored in extradata) to lavc palette format
172  */
173 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
174 {
175     int count, i;
176     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
177
178     if (avctx->bits_per_coded_sample > 8) {
179         av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
180         return AVERROR_INVALIDDATA;
181     }
182
183     count = 1 << avctx->bits_per_coded_sample;
184     // If extradata is smaller than actually needed, fill the remaining with black.
185     count = FFMIN(get_palette_size(avctx) / 3, count);
186     if (count) {
187         for (i=0; i < count; i++) {
188             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
189         }
190     } else { // Create gray-scale color palette for bps < 8
191         count = 1 << avctx->bits_per_coded_sample;
192
193         for (i=0; i < count; i++) {
194             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
195         }
196     }
197     return 0;
198 }
199
200 /**
201  * Extracts the IFF extra context and updates internal
202  * decoder structures.
203  *
204  * @param avctx the AVCodecContext where to extract extra context to
205  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
206  * @return 0 in case of success, a negative error code otherwise
207  */
208 static int extract_header(AVCodecContext *const avctx,
209                           const AVPacket *const avpkt) {
210     const uint8_t *buf;
211     unsigned buf_size;
212     IffContext *s = avctx->priv_data;
213     if (avpkt) {
214         if (avpkt->size < 2)
215             return AVERROR_INVALIDDATA;
216         buf = avpkt->data;
217         buf_size = bytestream_get_be16(&buf);
218         if (buf_size <= 1 || get_image_size(avpkt) <= 1) {
219             av_log(avctx, AV_LOG_ERROR,
220                    "Invalid image size received: %u -> image data offset: %d\n",
221                    buf_size, get_image_size(avpkt));
222             return AVERROR_INVALIDDATA;
223         }
224     } else {
225         if (avctx->extradata_size < 2)
226             return AVERROR_INVALIDDATA;
227         buf = avctx->extradata;
228         buf_size = bytestream_get_be16(&buf);
229         if (buf_size <= 1 || get_palette_size(avctx) < 0) {
230             av_log(avctx, AV_LOG_ERROR,
231                    "Invalid palette size received: %u -> palette data offset: %d\n",
232                    buf_size, get_palette_size(avctx));
233             return AVERROR_INVALIDDATA;
234         }
235     }
236
237     if (buf_size > 8) {
238         s->compression  = bytestream_get_byte(&buf);
239         s->bpp          = bytestream_get_byte(&buf);
240         s->ham          = bytestream_get_byte(&buf);
241         s->flags        = bytestream_get_byte(&buf);
242         s->transparency = bytestream_get_be16(&buf);
243         s->masking      = bytestream_get_byte(&buf);
244         if (s->masking == MASK_HAS_TRANSPARENT_COLOR) {
245             av_log(avctx, AV_LOG_ERROR, "Transparency not supported\n");
246             return AVERROR_PATCHWELCOME;
247         } else if (s->masking != MASK_NONE) {
248             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
249             return AVERROR_PATCHWELCOME;
250         }
251         if (!s->bpp || s->bpp > 32) {
252             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
253             return AVERROR_INVALIDDATA;
254         } else if (s->ham >= 8) {
255             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
256             return AVERROR_INVALIDDATA;
257         }
258
259         av_freep(&s->ham_buf);
260         av_freep(&s->ham_palbuf);
261
262         if (s->ham) {
263             int i, count = FFMIN(get_palette_size(avctx) / 3, 1 << s->ham);
264             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
265             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
266             if (!s->ham_buf)
267                 return AVERROR(ENOMEM);
268
269             s->ham_palbuf = av_malloc((8 * (1 << s->ham) * sizeof (uint32_t)) + FF_INPUT_BUFFER_PADDING_SIZE);
270             if (!s->ham_palbuf) {
271                 av_freep(&s->ham_buf);
272                 return AVERROR(ENOMEM);
273             }
274
275             if (count) { // HAM with color palette attached
276                 // prefill with black and palette and set HAM take direct value mask to zero
277                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
278                 for (i=0; i < count; i++) {
279                     s->ham_palbuf[i*2+1] = AV_RL24(palette + i*3);
280                 }
281                 count = 1 << s->ham;
282             } else { // HAM with grayscale color palette
283                 count = 1 << s->ham;
284                 for (i=0; i < count; i++) {
285                     s->ham_palbuf[i*2]   = 0; // take direct color value from palette
286                     s->ham_palbuf[i*2+1] = av_le2ne32(gray2rgb((i * 255) >> s->ham));
287                 }
288             }
289             for (i=0; i < count; i++) {
290                 uint32_t tmp = i << (8 - s->ham);
291                 tmp |= tmp >> s->ham;
292                 s->ham_palbuf[(i+count)*2]     = 0x00FFFF; // just modify blue color component
293                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFF00; // just modify red color component
294                 s->ham_palbuf[(i+count*3)*2]   = 0xFF00FF; // just modify green color component
295                 s->ham_palbuf[(i+count)*2+1]   = tmp << 16;
296                 s->ham_palbuf[(i+count*2)*2+1] = tmp;
297                 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
298             }
299         } else if (s->flags & 1) { // EHB (ExtraHalfBrite) color palette
300             av_log(avctx, AV_LOG_ERROR, "ExtraHalfBrite (EHB) mode not supported\n");
301             return AVERROR_PATCHWELCOME;
302         }
303     }
304
305     return 0;
306 }
307
308 static av_cold int decode_init(AVCodecContext *avctx)
309 {
310     IffContext *s = avctx->priv_data;
311     int err;
312
313     if (avctx->bits_per_coded_sample <= 8) {
314         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
315                          (avctx->extradata_size >= 2 && get_palette_size(avctx)) ? PIX_FMT_PAL8
316                                                                                  : PIX_FMT_GRAY8;
317     } else if (avctx->bits_per_coded_sample <= 32) {
318         avctx->pix_fmt = PIX_FMT_BGR32;
319     } else {
320         return AVERROR_INVALIDDATA;
321     }
322
323     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
324         return err;
325     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
326     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
327     if (!s->planebuf)
328         return AVERROR(ENOMEM);
329
330     s->bpp = avctx->bits_per_coded_sample;
331     avcodec_get_frame_defaults(&s->frame);
332
333     if ((err = extract_header(avctx, NULL)) < 0)
334         return err;
335     s->frame.reference = 1;
336
337     return 0;
338 }
339
340 /**
341  * Decode interleaved plane buffer up to 8bpp
342  * @param dst Destination buffer
343  * @param buf Source buffer
344  * @param buf_size
345  * @param plane plane number to decode as
346  */
347 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
348 {
349     const uint64_t *lut = plane8_lut[plane];
350     do {
351         uint64_t v = AV_RN64A(dst) | lut[*buf++];
352         AV_WN64A(dst, v);
353         dst += 8;
354     } while (--buf_size);
355 }
356
357 /**
358  * Decode interleaved plane buffer up to 24bpp
359  * @param dst Destination buffer
360  * @param buf Source buffer
361  * @param buf_size
362  * @param plane plane number to decode as
363  */
364 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
365 {
366     const uint32_t *lut = plane32_lut[plane];
367     do {
368         unsigned mask = (*buf >> 2) & ~3;
369         dst[0] |= lut[mask++];
370         dst[1] |= lut[mask++];
371         dst[2] |= lut[mask++];
372         dst[3] |= lut[mask];
373         mask = (*buf++ << 2) & 0x3F;
374         dst[4] |= lut[mask++];
375         dst[5] |= lut[mask++];
376         dst[6] |= lut[mask++];
377         dst[7] |= lut[mask];
378         dst += 8;
379     } while (--buf_size);
380 }
381
382 #define DECODE_HAM_PLANE32(x)       \
383     first       = buf[x] << 1;      \
384     second      = buf[(x)+1] << 1;  \
385     delta      &= pal[first++];     \
386     delta      |= pal[first];       \
387     dst[x]      = delta;            \
388     delta      &= pal[second++];    \
389     delta      |= pal[second];      \
390     dst[(x)+1]  = delta
391
392 /**
393  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
394  *
395  * @param dst the destination 24bpp buffer
396  * @param buf the source 8bpp chunky buffer
397  * @param pal the HAM decode table
398  * @param buf_size the plane size in bytes
399  */
400 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
401                                const uint32_t *const pal, unsigned buf_size)
402 {
403     uint32_t delta = 0;
404     do {
405         uint32_t first, second;
406         DECODE_HAM_PLANE32(0);
407         DECODE_HAM_PLANE32(2);
408         DECODE_HAM_PLANE32(4);
409         DECODE_HAM_PLANE32(6);
410         buf += 8;
411         dst += 8;
412     } while (--buf_size);
413 }
414
415 /**
416  * Decode one complete byterun1 encoded line.
417  *
418  * @param dst the destination buffer where to store decompressed bitstream
419  * @param dst_size the destination plane size in bytes
420  * @param buf the source byterun1 compressed bitstream
421  * @param buf_end the EOF of source byterun1 compressed bitstream
422  * @return number of consumed bytes in byterun1 compressed bitstream
423 */
424 static int decode_byterun(uint8_t *dst, int dst_size,
425                           const uint8_t *buf, const uint8_t *const buf_end) {
426     const uint8_t *const buf_start = buf;
427     unsigned x;
428     for (x = 0; x < dst_size && buf < buf_end;) {
429         unsigned length;
430         const int8_t value = *buf++;
431         if (value >= 0) {
432             length = value + 1;
433             memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
434             buf += length;
435         } else if (value > -128) {
436             length = -value + 1;
437             memset(dst + x, *buf++, FFMIN(length, dst_size - x));
438         } else { // noop
439             continue;
440         }
441         x += length;
442     }
443     return buf - buf_start;
444 }
445
446 static int decode_frame_ilbm(AVCodecContext *avctx,
447                             void *data, int *data_size,
448                             AVPacket *avpkt)
449 {
450     IffContext *s = avctx->priv_data;
451     const uint8_t *buf = avpkt->size >= 2 ? get_image_data(avpkt) : NULL;
452     const int buf_size = avpkt->size >= 2 ? get_image_size(avpkt) : 0;
453     const uint8_t *buf_end = buf+buf_size;
454     int y, plane, res;
455
456     if ((res = extract_header(avctx, avpkt)) < 0)
457         return res;
458
459     if (s->init) {
460         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
461             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
462             return res;
463         }
464     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
465         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
466         return res;
467     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
468         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
469             return res;
470     }
471     s->init = 1;
472
473     if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
474         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
475             for(y = 0; y < avctx->height; y++ ) {
476                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
477                 memset(row, 0, avctx->width);
478                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
479                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
480                     buf += s->planesize;
481                 }
482             }
483         } else if (s->ham) { // HAM to PIX_FMT_BGR32
484             for (y = 0; y < avctx->height; y++) {
485                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
486                 memset(s->ham_buf, 0, avctx->width);
487                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
488                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
489                     buf += s->planesize;
490                 }
491                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
492             }
493         } else { // PIX_FMT_BGR32
494             for(y = 0; y < avctx->height; y++ ) {
495                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
496                 memset(row, 0, avctx->width << 2);
497                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
498                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
499                     buf += s->planesize;
500                 }
501             }
502         }
503     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
504         for(y = 0; y < avctx->height; y++ ) {
505             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
506             memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
507             buf += avctx->width + (avctx->width % 2); // padding if odd
508         }
509     } else { // IFF-PBM: HAM to PIX_FMT_BGR32
510         for (y = 0; y < avctx->height; y++) {
511             uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
512             memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
513             buf += avctx->width + (avctx->width & 1); // padding if odd
514             decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
515         }
516     }
517
518     *data_size = sizeof(AVFrame);
519     *(AVFrame*)data = s->frame;
520     return buf_size;
521 }
522
523 static int decode_frame_byterun1(AVCodecContext *avctx,
524                             void *data, int *data_size,
525                             AVPacket *avpkt)
526 {
527     IffContext *s = avctx->priv_data;
528     const uint8_t *buf = avpkt->size >= 2 ? get_image_data(avpkt) : NULL;
529     const int buf_size = avpkt->size >= 2 ? get_image_size(avpkt) : 0;
530     const uint8_t *buf_end = buf+buf_size;
531     int y, plane, res;
532
533     if ((res = extract_header(avctx, avpkt)) < 0)
534         return res;
535     if (s->init) {
536         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
537             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
538             return res;
539         }
540     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
541         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
542         return res;
543     } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
544         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
545             return res;
546     }
547     s->init = 1;
548
549     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
550         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
551             for(y = 0; y < avctx->height ; y++ ) {
552                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
553                 memset(row, 0, avctx->width);
554                 for (plane = 0; plane < s->bpp; plane++) {
555                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
556                     decodeplane8(row, s->planebuf, s->planesize, plane);
557                 }
558             }
559         } else if (s->ham) { // HAM to PIX_FMT_BGR32
560             for (y = 0; y < avctx->height ; y++) {
561                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
562                 memset(s->ham_buf, 0, avctx->width);
563                 for (plane = 0; plane < s->bpp; plane++) {
564                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
565                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
566                 }
567                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
568             }
569         } else { //PIX_FMT_BGR32
570             for(y = 0; y < avctx->height ; y++ ) {
571                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
572                 memset(row, 0, avctx->width << 2);
573                 for (plane = 0; plane < s->bpp; plane++) {
574                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
575                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
576                 }
577             }
578         }
579     } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
580         for(y = 0; y < avctx->height ; y++ ) {
581             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
582             buf += decode_byterun(row, avctx->width, buf, buf_end);
583         }
584     } else { // IFF-PBM: HAM to PIX_FMT_BGR32
585         for (y = 0; y < avctx->height ; y++) {
586             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
587             buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
588             decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, avctx->width);
589         }
590     }
591
592     *data_size = sizeof(AVFrame);
593     *(AVFrame*)data = s->frame;
594     return buf_size;
595 }
596
597 static av_cold int decode_end(AVCodecContext *avctx)
598 {
599     IffContext *s = avctx->priv_data;
600     if (s->frame.data[0])
601         avctx->release_buffer(avctx, &s->frame);
602     av_freep(&s->planebuf);
603     av_freep(&s->ham_buf);
604     av_freep(&s->ham_palbuf);
605     return 0;
606 }
607
608 AVCodec ff_iff_ilbm_decoder = {
609     "iff_ilbm",
610     AVMEDIA_TYPE_VIDEO,
611     CODEC_ID_IFF_ILBM,
612     sizeof(IffContext),
613     decode_init,
614     NULL,
615     decode_end,
616     decode_frame_ilbm,
617     CODEC_CAP_DR1,
618     .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
619 };
620
621 AVCodec ff_iff_byterun1_decoder = {
622     "iff_byterun1",
623     AVMEDIA_TYPE_VIDEO,
624     CODEC_ID_IFF_BYTERUN1,
625     sizeof(IffContext),
626     decode_init,
627     NULL,
628     decode_end,
629     decode_frame_byterun1,
630     CODEC_CAP_DR1,
631     .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
632 };