]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
h264: (trivial) remove unneeded macro argument in x86/cabac.h
[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 = avctx->extradata_size - AV_RB16(avctx->extradata);
195
196     if (avpkt) {
197         int image_size;
198         if (avpkt->size < 2)
199             return AVERROR_INVALIDDATA;
200         image_size = avpkt->size - AV_RB16(avpkt->data);
201         buf = avpkt->data;
202         buf_size = bytestream_get_be16(&buf);
203         if (buf_size <= 1 || image_size <= 1) {
204             av_log(avctx, AV_LOG_ERROR,
205                    "Invalid image size received: %u -> image data offset: %d\n",
206                    buf_size, image_size);
207             return AVERROR_INVALIDDATA;
208         }
209     } else {
210         if (avctx->extradata_size < 2)
211             return AVERROR_INVALIDDATA;
212         buf = avctx->extradata;
213         buf_size = bytestream_get_be16(&buf);
214         if (buf_size <= 1 || palette_size < 0) {
215             av_log(avctx, AV_LOG_ERROR,
216                    "Invalid palette size received: %u -> palette data offset: %d\n",
217                    buf_size, palette_size);
218             return AVERROR_INVALIDDATA;
219         }
220     }
221
222     if (buf_size > 8) {
223         s->compression  = bytestream_get_byte(&buf);
224         s->bpp          = bytestream_get_byte(&buf);
225         s->ham          = bytestream_get_byte(&buf);
226         s->flags        = bytestream_get_byte(&buf);
227         s->transparency = bytestream_get_be16(&buf);
228         s->masking      = bytestream_get_byte(&buf);
229         if (s->masking == MASK_HAS_MASK) {
230             if (s->bpp >= 8) {
231                 avctx->pix_fmt = PIX_FMT_RGB32;
232                 av_freep(&s->mask_buf);
233                 av_freep(&s->mask_palbuf);
234                 s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
235                 if (!s->mask_buf)
236                     return AVERROR(ENOMEM);
237                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
238                 if (!s->mask_palbuf) {
239                     av_freep(&s->mask_buf);
240                     return AVERROR(ENOMEM);
241                 }
242             }
243             s->bpp++;
244         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
245             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
246             return AVERROR_PATCHWELCOME;
247         }
248         if (!s->bpp || s->bpp > 32) {
249             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
250             return AVERROR_INVALIDDATA;
251         } else if (s->ham >= 8) {
252             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
253             return AVERROR_INVALIDDATA;
254         }
255
256         av_freep(&s->ham_buf);
257         av_freep(&s->ham_palbuf);
258
259         if (s->ham) {
260             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
261             int ham_count;
262             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
263
264             s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
265             if (!s->ham_buf)
266                 return AVERROR(ENOMEM);
267
268             ham_count = 8 * (1 << s->ham);
269             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * 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             if (s->masking == MASK_HAS_MASK) {
300                 for (i = 0; i < ham_count; i++)
301                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
302             }
303         }
304     }
305
306     return 0;
307 }
308
309 static av_cold int decode_init(AVCodecContext *avctx)
310 {
311     IffContext *s = avctx->priv_data;
312     int err;
313
314     if (avctx->bits_per_coded_sample <= 8) {
315         int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
316         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
317                          (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8;
318     } else if (avctx->bits_per_coded_sample <= 32) {
319         if (avctx->codec_tag != MKTAG('D','E','E','P'))
320             avctx->pix_fmt = PIX_FMT_BGR32;
321     } else {
322         return AVERROR_INVALIDDATA;
323     }
324
325     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
326         return err;
327     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
328     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
329     if (!s->planebuf)
330         return AVERROR(ENOMEM);
331
332     s->bpp = avctx->bits_per_coded_sample;
333     avcodec_get_frame_defaults(&s->frame);
334
335     if ((err = extract_header(avctx, NULL)) < 0)
336         return err;
337     s->frame.reference = 3;
338
339     return 0;
340 }
341
342 /**
343  * Decode interleaved plane buffer up to 8bpp
344  * @param dst Destination buffer
345  * @param buf Source buffer
346  * @param buf_size
347  * @param plane plane number to decode as
348  */
349 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
350 {
351     const uint64_t *lut = plane8_lut[plane];
352     do {
353         uint64_t v = AV_RN64A(dst) | lut[*buf++];
354         AV_WN64A(dst, v);
355         dst += 8;
356     } while (--buf_size);
357 }
358
359 /**
360  * Decode interleaved plane buffer up to 24bpp
361  * @param dst Destination buffer
362  * @param buf Source buffer
363  * @param buf_size
364  * @param plane plane number to decode as
365  */
366 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
367 {
368     const uint32_t *lut = plane32_lut[plane];
369     do {
370         unsigned mask = (*buf >> 2) & ~3;
371         dst[0] |= lut[mask++];
372         dst[1] |= lut[mask++];
373         dst[2] |= lut[mask++];
374         dst[3] |= lut[mask];
375         mask = (*buf++ << 2) & 0x3F;
376         dst[4] |= lut[mask++];
377         dst[5] |= lut[mask++];
378         dst[6] |= lut[mask++];
379         dst[7] |= lut[mask];
380         dst += 8;
381     } while (--buf_size);
382 }
383
384 #define DECODE_HAM_PLANE32(x)       \
385     first       = buf[x] << 1;      \
386     second      = buf[(x)+1] << 1;  \
387     delta      &= pal[first++];     \
388     delta      |= pal[first];       \
389     dst[x]      = delta;            \
390     delta      &= pal[second++];    \
391     delta      |= pal[second];      \
392     dst[(x)+1]  = delta
393
394 /**
395  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
396  *
397  * @param dst the destination 24bpp buffer
398  * @param buf the source 8bpp chunky buffer
399  * @param pal the HAM decode table
400  * @param buf_size the plane size in bytes
401  */
402 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
403                                const uint32_t *const pal, unsigned buf_size)
404 {
405     uint32_t delta = 0;
406     do {
407         uint32_t first, second;
408         DECODE_HAM_PLANE32(0);
409         DECODE_HAM_PLANE32(2);
410         DECODE_HAM_PLANE32(4);
411         DECODE_HAM_PLANE32(6);
412         buf += 8;
413         dst += 8;
414     } while (--buf_size);
415 }
416
417 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
418                          const uint32_t *const pal, unsigned width)
419 {
420     do {
421         *dst++ = pal[*buf++];
422     } while (--width);
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 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
462     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 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_PAL8) {
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('A','C','B','M')) {
484         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
485             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
486             for (plane = 0; plane < s->bpp; plane++) {
487                 for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
488                     uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
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             memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
495             for(y = 0; y < avctx->height; y++) {
496                 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
497                 memset(s->ham_buf, 0, s->planesize * 8);
498                 for (plane = 0; plane < s->bpp; plane++) {
499                     const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
500                     if (start >= buf_end)
501                         break;
502                     decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
503                 }
504                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
505             }
506         }
507     } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
508         int raw_width = avctx->width * (av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]) >> 3);
509         int x;
510         for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
511             uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
512             memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
513             buf += raw_width;
514             if (avctx->pix_fmt == PIX_FMT_BGR32) {
515                 for(x = 0; x < avctx->width; x++)
516                     row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
517             }
518         }
519     } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
520         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
521             for(y = 0; y < avctx->height; y++ ) {
522                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
523                 memset(row, 0, avctx->width);
524                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
525                     decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
526                     buf += s->planesize;
527                 }
528             }
529         } else if (s->ham) { // HAM to PIX_FMT_BGR32
530             for (y = 0; y < avctx->height; y++) {
531                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
532                 memset(s->ham_buf, 0, s->planesize * 8);
533                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
534                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
535                     buf += s->planesize;
536                 }
537                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
538             }
539         } else { // PIX_FMT_BGR32
540             for(y = 0; y < avctx->height; y++ ) {
541                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
542                 memset(row, 0, avctx->width << 2);
543                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
544                     decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
545                     buf += s->planesize;
546                 }
547             }
548         }
549     } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
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                 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
554                 buf += avctx->width + (avctx->width % 2); // padding if odd
555             }
556         } else if (s->ham) { // IFF-PBM: HAM to PIX_FMT_BGR32
557             for (y = 0; y < avctx->height; y++) {
558                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
559                 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
560                 buf += avctx->width + (avctx->width & 1); // padding if odd
561                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
562             }
563         } else {
564             av_log_ask_for_sample(avctx, "unsupported bpp\n");
565             return AVERROR_INVALIDDATA;
566         }
567     }
568
569     *data_size = sizeof(AVFrame);
570     *(AVFrame*)data = s->frame;
571     return buf_size;
572 }
573
574 static int decode_frame_byterun1(AVCodecContext *avctx,
575                             void *data, int *data_size,
576                             AVPacket *avpkt)
577 {
578     IffContext *s = avctx->priv_data;
579     const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
580     const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
581     const uint8_t *buf_end = buf+buf_size;
582     int y, plane, res;
583
584     if ((res = extract_header(avctx, avpkt)) < 0)
585         return res;
586     if (s->init) {
587         if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
588             av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
589             return res;
590         }
591     } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
592         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
593         return res;
594     } else if (avctx->pix_fmt == PIX_FMT_PAL8) {
595         if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
596             return res;
597     } else if (avctx->pix_fmt == PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
598         if ((res = ff_cmap_read_palette(avctx, s->mask_palbuf)) < 0)
599             return res;
600     }
601     s->init = 1;
602
603     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
604         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
605             for(y = 0; y < avctx->height ; y++ ) {
606                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
607                 memset(row, 0, avctx->width);
608                 for (plane = 0; plane < s->bpp; plane++) {
609                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
610                     decodeplane8(row, s->planebuf, s->planesize, plane);
611                 }
612             }
613         } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to PIX_FMT_BGR32
614             for (y = 0; y < avctx->height ; y++ ) {
615                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
616                 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
617                 for (plane = 0; plane < s->bpp; plane++) {
618                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
619                     decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
620                 }
621                 lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
622             }
623         } else if (s->ham) { // HAM to PIX_FMT_BGR32
624             for (y = 0; y < avctx->height ; y++) {
625                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
626                 memset(s->ham_buf, 0, s->planesize * 8);
627                 for (plane = 0; plane < s->bpp; plane++) {
628                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
629                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
630                 }
631                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
632             }
633         } else { //PIX_FMT_BGR32
634             for(y = 0; y < avctx->height ; y++ ) {
635                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
636                 memset(row, 0, avctx->width << 2);
637                 for (plane = 0; plane < s->bpp; plane++) {
638                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
639                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
640                 }
641             }
642         }
643     } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
644         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
645             for(y = 0; y < avctx->height ; y++ ) {
646                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
647                 buf += decode_byterun(row, avctx->width, buf, buf_end);
648             }
649         } else if (s->ham) { // IFF-PBM: HAM to PIX_FMT_BGR32
650             for (y = 0; y < avctx->height ; y++) {
651                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
652                 buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
653                 decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
654             }
655         } else {
656             av_log_ask_for_sample(avctx, "unsupported bpp\n");
657             return AVERROR_INVALIDDATA;
658         }
659     }
660
661     *data_size = sizeof(AVFrame);
662     *(AVFrame*)data = s->frame;
663     return buf_size;
664 }
665
666 static av_cold int decode_end(AVCodecContext *avctx)
667 {
668     IffContext *s = avctx->priv_data;
669     if (s->frame.data[0])
670         avctx->release_buffer(avctx, &s->frame);
671     av_freep(&s->planebuf);
672     av_freep(&s->ham_buf);
673     av_freep(&s->ham_palbuf);
674     return 0;
675 }
676
677 AVCodec ff_iff_ilbm_decoder = {
678     .name           = "iff_ilbm",
679     .type           = AVMEDIA_TYPE_VIDEO,
680     .id             = CODEC_ID_IFF_ILBM,
681     .priv_data_size = sizeof(IffContext),
682     .init           = decode_init,
683     .close          = decode_end,
684     .decode         = decode_frame_ilbm,
685     .capabilities   = CODEC_CAP_DR1,
686     .long_name      = NULL_IF_CONFIG_SMALL("IFF ILBM"),
687 };
688
689 AVCodec ff_iff_byterun1_decoder = {
690     .name           = "iff_byterun1",
691     .type           = AVMEDIA_TYPE_VIDEO,
692     .id             = CODEC_ID_IFF_BYTERUN1,
693     .priv_data_size = sizeof(IffContext),
694     .init           = decode_init,
695     .close          = decode_end,
696     .decode         = decode_frame_byterun1,
697     .capabilities   = CODEC_CAP_DR1,
698     .long_name      = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
699 };