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