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