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