]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
Merge commit '4012fe1ee819edc7689e182189e66c5401fb4b41'
[ffmpeg] / libavcodec / iff.c
1 /*
2  * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
3  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5  * Copyright (c) 2016 Paul B Mahol
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 /**
25  * @file
26  * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
27  */
28
29 #include <stdint.h>
30
31 #include "libavutil/imgutils.h"
32 #include "bytestream.h"
33 #include "avcodec.h"
34 #include "internal.h"
35 #include "mathops.h"
36
37 // TODO: masking bits
38 typedef enum {
39     MASK_NONE,
40     MASK_HAS_MASK,
41     MASK_HAS_TRANSPARENT_COLOR,
42     MASK_LASSO
43 } mask_type;
44
45 typedef struct IffContext {
46     AVFrame *frame;
47     int planesize;
48     uint8_t * planebuf;
49     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
50     uint32_t *ham_palbuf;   ///< HAM decode table
51     uint32_t *mask_buf;     ///< temporary buffer for palette indices
52     uint32_t *mask_palbuf;  ///< masking palette table
53     unsigned  compression;  ///< delta compression method used
54     unsigned  is_short;     ///< short compression method used
55     unsigned  is_interlaced;///< video is interlaced
56     unsigned  is_brush;     ///< video is in ANBR format
57     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
58     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
59     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
60     unsigned  transparency; ///< TODO: transparency color index in palette
61     unsigned  masking;      ///< TODO: masking method used
62     int init; // 1 if buffer and palette data already initialized, 0 otherwise
63     int16_t   tvdc[16];     ///< TVDC lookup table
64     GetByteContext gb;
65     uint8_t *video[2];
66     unsigned video_size;
67     uint32_t *pal[2];
68 } IffContext;
69
70 #define LUT8_PART(plane, v)                             \
71     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
72     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
73     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
74     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
75     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
76     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
77     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
78     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
79     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
80     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
81     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
82     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
83     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
84     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
85     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
86     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
87
88 #define LUT8(plane) {                           \
89     LUT8_PART(plane, 0x0000000),                \
90     LUT8_PART(plane, 0x1000000),                \
91     LUT8_PART(plane, 0x0010000),                \
92     LUT8_PART(plane, 0x1010000),                \
93     LUT8_PART(plane, 0x0000100),                \
94     LUT8_PART(plane, 0x1000100),                \
95     LUT8_PART(plane, 0x0010100),                \
96     LUT8_PART(plane, 0x1010100),                \
97     LUT8_PART(plane, 0x0000001),                \
98     LUT8_PART(plane, 0x1000001),                \
99     LUT8_PART(plane, 0x0010001),                \
100     LUT8_PART(plane, 0x1010001),                \
101     LUT8_PART(plane, 0x0000101),                \
102     LUT8_PART(plane, 0x1000101),                \
103     LUT8_PART(plane, 0x0010101),                \
104     LUT8_PART(plane, 0x1010101),                \
105 }
106
107 // 8 planes * 8-bit mask
108 static const uint64_t plane8_lut[8][256] = {
109     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
110     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
111 };
112
113 #define LUT32(plane) {                                \
114              0,          0,          0,          0,   \
115              0,          0,          0, 1 << plane,   \
116              0,          0, 1 << plane,          0,   \
117              0,          0, 1 << plane, 1 << plane,   \
118              0, 1 << plane,          0,          0,   \
119              0, 1 << plane,          0, 1 << plane,   \
120              0, 1 << plane, 1 << plane,          0,   \
121              0, 1 << plane, 1 << plane, 1 << plane,   \
122     1 << plane,          0,          0,          0,   \
123     1 << plane,          0,          0, 1 << plane,   \
124     1 << plane,          0, 1 << plane,          0,   \
125     1 << plane,          0, 1 << plane, 1 << plane,   \
126     1 << plane, 1 << plane,          0,          0,   \
127     1 << plane, 1 << plane,          0, 1 << plane,   \
128     1 << plane, 1 << plane, 1 << plane,          0,   \
129     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
130 }
131
132 // 32 planes * 4-bit mask * 4 lookup tables each
133 static const uint32_t plane32_lut[32][16*4] = {
134     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
135     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
136     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
137     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
138     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
139     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
140     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
141     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
142 };
143
144 // Gray to RGB, required for palette table of grayscale images with bpp < 8
145 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
146     return x << 16 | x << 8 | x;
147 }
148
149 /**
150  * Convert CMAP buffer (stored in extradata) to lavc palette format
151  */
152 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
153 {
154     IffContext *s = avctx->priv_data;
155     int count, i;
156     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
157     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
158
159     if (avctx->bits_per_coded_sample > 8) {
160         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
161         return AVERROR_INVALIDDATA;
162     }
163
164     count = 1 << avctx->bits_per_coded_sample;
165     // If extradata is smaller than actually needed, fill the remaining with black.
166     count = FFMIN(palette_size / 3, count);
167     if (count) {
168         for (i = 0; i < count; i++)
169             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
170         if (s->flags && count >= 32) { // EHB
171             for (i = 0; i < 32; i++)
172                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
173             count = FFMAX(count, 64);
174         }
175     } else { // Create gray-scale color palette for bps < 8
176         count = 1 << avctx->bits_per_coded_sample;
177
178         for (i = 0; i < count; i++)
179             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
180     }
181     if (s->masking == MASK_HAS_MASK) {
182         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
183         for (i = 0; i < count; i++)
184             pal[i] &= 0xFFFFFF;
185     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
186         s->transparency < 1 << avctx->bits_per_coded_sample)
187         pal[s->transparency] &= 0xFFFFFF;
188     return 0;
189 }
190
191 /**
192  * Extracts the IFF extra context and updates internal
193  * decoder structures.
194  *
195  * @param avctx the AVCodecContext where to extract extra context to
196  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
197  * @return >= 0 in case of success, a negative error code otherwise
198  */
199 static int extract_header(AVCodecContext *const avctx,
200                           const AVPacket *const avpkt)
201 {
202     IffContext *s = avctx->priv_data;
203     const uint8_t *buf;
204     unsigned buf_size = 0;
205     int i, palette_size;
206
207     if (avctx->extradata_size < 2) {
208         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
209         return AVERROR_INVALIDDATA;
210     }
211     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
212
213     if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
214         uint32_t chunk_id;
215         uint64_t data_size;
216         GetByteContext *gb = &s->gb;
217
218         bytestream2_skip(gb, 4);
219         while (bytestream2_get_bytes_left(gb) >= 1) {
220             chunk_id  = bytestream2_get_le32(gb);
221             data_size = bytestream2_get_be32(gb);
222
223             if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
224                 bytestream2_skip(gb, data_size + (data_size & 1));
225             } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
226                 unsigned extra;
227                 if (data_size < 40)
228                     return AVERROR_INVALIDDATA;
229
230                 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
231                 bytestream2_skip(gb, 19);
232                 extra = bytestream2_get_be32(gb);
233                 s->is_short = !(extra & 1);
234                 s->is_brush = extra == 2;
235                 s->is_interlaced = !!(extra & 0x40);
236                 data_size -= 24;
237                 bytestream2_skip(gb, data_size + (data_size & 1));
238             } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
239                        chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
240                 if (chunk_id == MKTAG('B','O','D','Y'))
241                     s->compression &= 0xFF;
242                 break;
243             } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
244                 int count = data_size / 3;
245                 uint32_t *pal = s->pal[0];
246
247                 if (count > 256)
248                     return AVERROR_INVALIDDATA;
249                 if (s->ham) {
250                     for (i = 0; i < count; i++)
251                         pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
252                 } else {
253                     for (i = 0; i < count; i++)
254                         pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
255                 }
256                 bytestream2_skip(gb, data_size & 1);
257             } else {
258                 bytestream2_skip(gb, data_size + (data_size&1));
259             }
260         }
261     } else if (!avpkt) {
262         buf = avctx->extradata;
263         buf_size = bytestream_get_be16(&buf);
264         if (buf_size <= 1 || palette_size < 0) {
265             av_log(avctx, AV_LOG_ERROR,
266                    "Invalid palette size received: %u -> palette data offset: %d\n",
267                    buf_size, palette_size);
268             return AVERROR_INVALIDDATA;
269         }
270     }
271
272     if (buf_size >= 41) {
273         s->compression  = bytestream_get_byte(&buf);
274         s->bpp          = bytestream_get_byte(&buf);
275         s->ham          = bytestream_get_byte(&buf);
276         s->flags        = bytestream_get_byte(&buf);
277         s->transparency = bytestream_get_be16(&buf);
278         s->masking      = bytestream_get_byte(&buf);
279         for (i = 0; i < 16; i++)
280             s->tvdc[i] = bytestream_get_be16(&buf);
281
282         if (s->masking == MASK_HAS_MASK) {
283             if (s->bpp >= 8 && !s->ham) {
284                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
285                 av_freep(&s->mask_buf);
286                 av_freep(&s->mask_palbuf);
287                 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
288                 if (!s->mask_buf)
289                     return AVERROR(ENOMEM);
290                 if (s->bpp > 16) {
291                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
292                     av_freep(&s->mask_buf);
293                     return AVERROR(ENOMEM);
294                 }
295                 s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
296                 if (!s->mask_palbuf) {
297                     av_freep(&s->mask_buf);
298                     return AVERROR(ENOMEM);
299                 }
300             }
301             s->bpp++;
302         } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
303             av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
304             return AVERROR_PATCHWELCOME;
305         }
306         if (!s->bpp || s->bpp > 32) {
307             av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
308             return AVERROR_INVALIDDATA;
309         } else if (s->ham >= 8) {
310             av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
311             return AVERROR_INVALIDDATA;
312         }
313
314         av_freep(&s->ham_buf);
315         av_freep(&s->ham_palbuf);
316
317         if (s->ham) {
318             int i, count = FFMIN(palette_size / 3, 1 << s->ham);
319             int ham_count;
320             const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
321
322             s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
323             if (!s->ham_buf)
324                 return AVERROR(ENOMEM);
325
326             ham_count = 8 * (1 << s->ham);
327             s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
328             if (!s->ham_palbuf) {
329                 av_freep(&s->ham_buf);
330                 return AVERROR(ENOMEM);
331             }
332
333             if (count) { // HAM with color palette attached
334                 // prefill with black and palette and set HAM take direct value mask to zero
335                 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
336                 for (i=0; i < count; i++) {
337                     s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
338                 }
339                 count = 1 << s->ham;
340             } else { // HAM with grayscale color palette
341                 count = 1 << s->ham;
342                 for (i=0; i < count; i++) {
343                     s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
344                     s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
345                 }
346             }
347             for (i=0; i < count; i++) {
348                 uint32_t tmp = i << (8 - s->ham);
349                 tmp |= tmp >> s->ham;
350                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
351                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
352                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
353                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
354                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
355                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
356             }
357             if (s->masking == MASK_HAS_MASK) {
358                 for (i = 0; i < ham_count; i++)
359                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
360             }
361         }
362     }
363
364     return 0;
365 }
366
367 static av_cold int decode_end(AVCodecContext *avctx)
368 {
369     IffContext *s = avctx->priv_data;
370     av_freep(&s->planebuf);
371     av_freep(&s->ham_buf);
372     av_freep(&s->ham_palbuf);
373     av_freep(&s->video[0]);
374     av_freep(&s->video[1]);
375     av_freep(&s->pal[0]);
376     av_freep(&s->pal[1]);
377     return 0;
378 }
379
380 static av_cold int decode_init(AVCodecContext *avctx)
381 {
382     IffContext *s = avctx->priv_data;
383     int err;
384
385     if (avctx->bits_per_coded_sample <= 8) {
386         int palette_size;
387
388         if (avctx->extradata_size >= 2)
389             palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
390         else
391             palette_size = 0;
392         avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
393                          (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
394     } else if (avctx->bits_per_coded_sample <= 32) {
395         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
396             avctx->pix_fmt = AV_PIX_FMT_RGB32;
397         } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
398             avctx->pix_fmt = AV_PIX_FMT_RGB444;
399         } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
400             if (avctx->bits_per_coded_sample == 24) {
401                 avctx->pix_fmt = AV_PIX_FMT_0BGR32;
402             } else if (avctx->bits_per_coded_sample == 32) {
403                 avctx->pix_fmt = AV_PIX_FMT_BGR32;
404             } else {
405                 avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
406                 return AVERROR_PATCHWELCOME;
407             }
408         }
409     } else {
410         return AVERROR_INVALIDDATA;
411     }
412
413     if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
414         return err;
415     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
416     s->planebuf  = av_malloc(s->planesize + AV_INPUT_BUFFER_PADDING_SIZE);
417     if (!s->planebuf)
418         return AVERROR(ENOMEM);
419
420     s->bpp = avctx->bits_per_coded_sample;
421
422     if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
423         s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
424         s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
425         s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
426         s->pal[0] = av_calloc(256, sizeof(*s->pal[0]));
427         s->pal[1] = av_calloc(256, sizeof(*s->pal[1]));
428         if (!s->video[0] || !s->video[1] || !s->pal[0] || !s->pal[1])
429             return AVERROR(ENOMEM);
430     }
431
432     if ((err = extract_header(avctx, NULL)) < 0)
433         return err;
434
435     return 0;
436 }
437
438 /**
439  * Decode interleaved plane buffer up to 8bpp
440  * @param dst Destination buffer
441  * @param buf Source buffer
442  * @param buf_size
443  * @param plane plane number to decode as
444  */
445 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
446 {
447     const uint64_t *lut = plane8_lut[plane];
448     if (plane >= 8) {
449         av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
450         return;
451     }
452     do {
453         uint64_t v = AV_RN64A(dst) | lut[*buf++];
454         AV_WN64A(dst, v);
455         dst += 8;
456     } while (--buf_size);
457 }
458
459 /**
460  * Decode interleaved plane buffer up to 24bpp
461  * @param dst Destination buffer
462  * @param buf Source buffer
463  * @param buf_size
464  * @param plane plane number to decode as
465  */
466 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
467 {
468     const uint32_t *lut = plane32_lut[plane];
469     do {
470         unsigned mask = (*buf >> 2) & ~3;
471         dst[0] |= lut[mask++];
472         dst[1] |= lut[mask++];
473         dst[2] |= lut[mask++];
474         dst[3] |= lut[mask];
475         mask    = (*buf++ << 2) & 0x3F;
476         dst[4] |= lut[mask++];
477         dst[5] |= lut[mask++];
478         dst[6] |= lut[mask++];
479         dst[7] |= lut[mask];
480         dst    += 8;
481     } while (--buf_size);
482 }
483
484 #define DECODE_HAM_PLANE32(x)       \
485     first       = buf[x] << 1;      \
486     second      = buf[(x)+1] << 1;  \
487     delta      &= pal[first++];     \
488     delta      |= pal[first];       \
489     dst[x]      = delta;            \
490     delta      &= pal[second++];    \
491     delta      |= pal[second];      \
492     dst[(x)+1]  = delta
493
494 /**
495  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
496  *
497  * @param dst the destination 24bpp buffer
498  * @param buf the source 8bpp chunky buffer
499  * @param pal the HAM decode table
500  * @param buf_size the plane size in bytes
501  */
502 static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
503                                const uint32_t *const pal, unsigned buf_size)
504 {
505     uint32_t delta = pal[1]; /* first palette entry */
506     do {
507         uint32_t first, second;
508         DECODE_HAM_PLANE32(0);
509         DECODE_HAM_PLANE32(2);
510         DECODE_HAM_PLANE32(4);
511         DECODE_HAM_PLANE32(6);
512         buf += 8;
513         dst += 8;
514     } while (--buf_size);
515 }
516
517 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
518                          const uint32_t *const pal, unsigned width)
519 {
520     do {
521         *dst++ = pal[*buf++];
522     } while (--width);
523 }
524
525 /**
526  * Decode one complete byterun1 encoded line.
527  *
528  * @param dst the destination buffer where to store decompressed bitstream
529  * @param dst_size the destination plane size in bytes
530  * @param buf the source byterun1 compressed bitstream
531  * @param buf_end the EOF of source byterun1 compressed bitstream
532  * @return number of consumed bytes in byterun1 compressed bitstream
533  */
534 static int decode_byterun(uint8_t *dst, int dst_size,
535                           GetByteContext *gb)
536 {
537     unsigned x;
538     for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
539         unsigned length;
540         const int8_t value = bytestream2_get_byte(gb);
541         if (value >= 0) {
542             length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
543             bytestream2_get_buffer(gb, dst + x, length);
544             if (length < value + 1)
545                 bytestream2_skip(gb, value + 1 - length);
546         } else if (value > -128) {
547             length = FFMIN(-value + 1, dst_size - x);
548             memset(dst + x, bytestream2_get_byte(gb), length);
549         } else { // noop
550             continue;
551         }
552         x += length;
553     }
554     if (x < dst_size) {
555         av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
556         memset(dst+x, 0, dst_size - x);
557     }
558     return bytestream2_tell(gb);
559 }
560
561 #define DECODE_RGBX_COMMON(type) \
562     if (!length) { \
563         length = bytestream2_get_byte(gb); \
564         if (!length) { \
565             length = bytestream2_get_be16(gb); \
566             if (!length) \
567                 return; \
568         } \
569     } \
570     for (i = 0; i < length; i++) { \
571         *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
572         x += 1; \
573         if (x >= width) { \
574             y += 1; \
575             if (y >= height) \
576                 return; \
577             x = 0; \
578         } \
579     }
580
581 /**
582  * Decode RGB8 buffer
583  * @param[out] dst Destination buffer
584  * @param width Width of destination buffer (pixels)
585  * @param height Height of destination buffer (pixels)
586  * @param linesize Line size of destination buffer (bytes)
587  */
588 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
589 {
590     int x = 0, y = 0, i, length;
591     while (bytestream2_get_bytes_left(gb) >= 4) {
592         uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
593         length = bytestream2_get_byte(gb) & 0x7F;
594         DECODE_RGBX_COMMON(uint32_t)
595     }
596 }
597
598 /**
599  * Decode RGBN buffer
600  * @param[out] dst Destination buffer
601  * @param width Width of destination buffer (pixels)
602  * @param height Height of destination buffer (pixels)
603  * @param linesize Line size of destination buffer (bytes)
604  */
605 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
606 {
607     int x = 0, y = 0, i, length;
608     while (bytestream2_get_bytes_left(gb) >= 2) {
609         uint32_t pixel = bytestream2_get_be16u(gb);
610         length = pixel & 0x7;
611         pixel >>= 4;
612         DECODE_RGBX_COMMON(uint16_t)
613     }
614 }
615
616 /**
617  * Decode DEEP RLE 32-bit buffer
618  * @param[out] dst Destination buffer
619  * @param[in] src Source buffer
620  * @param src_size Source buffer size (bytes)
621  * @param width Width of destination buffer (pixels)
622  * @param height Height of destination buffer (pixels)
623  * @param linesize Line size of destination buffer (bytes)
624  */
625 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
626 {
627     const uint8_t *src_end = src + src_size;
628     int x = 0, y = 0, i;
629     while (src + 5 <= src_end) {
630         int opcode;
631         opcode = *(int8_t *)src++;
632         if (opcode >= 0) {
633             int size = opcode + 1;
634             for (i = 0; i < size; i++) {
635                 int length = FFMIN(size - i, width);
636                 memcpy(dst + y*linesize + x * 4, src, length * 4);
637                 src += length * 4;
638                 x += length;
639                 i += length;
640                 if (x >= width) {
641                     x = 0;
642                     y += 1;
643                     if (y >= height)
644                         return;
645                 }
646             }
647         } else {
648             int size = -opcode + 1;
649             uint32_t pixel = AV_RN32(src);
650             for (i = 0; i < size; i++) {
651                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
652                 x += 1;
653                 if (x >= width) {
654                     x = 0;
655                     y += 1;
656                     if (y >= height)
657                         return;
658                 }
659             }
660             src += 4;
661         }
662     }
663 }
664
665 /**
666  * Decode DEEP TVDC 32-bit buffer
667  * @param[out] dst Destination buffer
668  * @param[in] src Source buffer
669  * @param src_size Source buffer size (bytes)
670  * @param width Width of destination buffer (pixels)
671  * @param height Height of destination buffer (pixels)
672  * @param linesize Line size of destination buffer (bytes)
673  * @param[int] tvdc TVDC lookup table
674  */
675 static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
676 {
677     int x = 0, y = 0, plane = 0;
678     int8_t pixel = 0;
679     int i, j;
680
681     for (i = 0; i < src_size * 2;) {
682 #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
683         int d = tvdc[GETNIBBLE];
684         i++;
685         if (d) {
686             pixel += d;
687             dst[y * linesize + x*4 + plane] = pixel;
688             x++;
689         } else {
690             if (i >= src_size * 2)
691                 return;
692             d = GETNIBBLE + 1;
693             i++;
694             d = FFMIN(d, width - x);
695             for (j = 0; j < d; j++) {
696                 dst[y * linesize + x*4 + plane] = pixel;
697                 x++;
698             }
699         }
700         if (x >= width) {
701             plane++;
702             if (plane >= 4) {
703                 y++;
704                 if (y >= height)
705                     return;
706                 plane = 0;
707             }
708             x = 0;
709             pixel = 0;
710             i = (i + 1) & ~1;
711         }
712     }
713 }
714
715 static void decode_short_horizontal_delta(uint8_t *dst,
716                                           const uint8_t *buf, const uint8_t *buf_end,
717                                           int w, int bpp, int dst_size)
718 {
719     int planepitch = FFALIGN(w, 16) >> 3;
720     int pitch = planepitch * bpp;
721     GetByteContext ptrs, gb;
722     PutByteContext pb;
723     unsigned ofssrc, pos;
724     int i, k;
725
726     bytestream2_init(&ptrs, buf, buf_end - buf);
727     bytestream2_init_writer(&pb, dst, dst_size);
728
729     for (k = 0; k < bpp; k++) {
730         ofssrc = bytestream2_get_be32(&ptrs);
731         pos = 0;
732
733         if (!ofssrc)
734             continue;
735
736         if (ofssrc >= buf_end - buf)
737             continue;
738
739         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
740         while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
741             int16_t offset = bytestream2_get_be16(&gb);
742             unsigned noffset;
743
744             if (offset >= 0) {
745                 unsigned data = bytestream2_get_be16(&gb);
746
747                 pos += offset * 2;
748                 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
749                 bytestream2_seek_p(&pb, noffset, SEEK_SET);
750                 bytestream2_put_be16(&pb, data);
751             } else {
752                 uint16_t count = bytestream2_get_be16(&gb);
753
754                 pos += 2 * -(offset + 2);
755                 for (i = 0; i < count; i++) {
756                     uint16_t data = bytestream2_get_be16(&gb);
757
758                     pos += 2;
759                     noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
760                     bytestream2_seek_p(&pb, noffset, SEEK_SET);
761                     bytestream2_put_be16(&pb, data);
762                 }
763             }
764         }
765     }
766 }
767
768 static void decode_byte_vertical_delta(uint8_t *dst,
769                                        const uint8_t *buf, const uint8_t *buf_end,
770                                        int w, int xor, int bpp, int dst_size)
771 {
772     int ncolumns = ((w + 15) / 16) * 2;
773     int dstpitch = ncolumns * bpp;
774     unsigned ofsdst, ofssrc, opcode, x;
775     GetByteContext ptrs, gb;
776     PutByteContext pb;
777     int i, j, k;
778
779     bytestream2_init(&ptrs, buf, buf_end - buf);
780     bytestream2_init_writer(&pb, dst, dst_size);
781
782     for (k = 0; k < bpp; k++) {
783         ofssrc = bytestream2_get_be32(&ptrs);
784
785         if (!ofssrc)
786             continue;
787
788         if (ofssrc >= buf_end - buf)
789             continue;
790
791         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
792         for (j = 0; j < ncolumns; j++) {
793             ofsdst = j + k * ncolumns;
794
795             i = bytestream2_get_byte(&gb);
796             while (i > 0) {
797                 opcode = bytestream2_get_byte(&gb);
798
799                 if (opcode == 0) {
800                     opcode  = bytestream2_get_byte(&gb);
801                     x = bytestream2_get_byte(&gb);
802
803                     while (opcode) {
804                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
805                         if (xor && ofsdst < dst_size) {
806                             bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
807                         } else {
808                             bytestream2_put_byte(&pb, x);
809                         }
810                         ofsdst += dstpitch;
811                         opcode--;
812                     }
813                 } else if (opcode < 0x80) {
814                     ofsdst += opcode * dstpitch;
815                 } else {
816                     opcode &= 0x7f;
817
818                     while (opcode) {
819                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
820                         if (xor && ofsdst < dst_size) {
821                             bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
822                         } else {
823                             bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
824                         }
825                         ofsdst += dstpitch;
826                         opcode--;
827                     }
828                 }
829                 i--;
830             }
831         }
832     }
833 }
834
835 static void decode_delta_j(uint8_t *dst,
836                            const uint8_t *buf, const uint8_t *buf_end,
837                            int w, int h, int bpp, int dst_size)
838 {
839     int32_t pitch;
840     uint8_t *ptr;
841     uint32_t type, flag, cols, groups, rows, bytes;
842     uint32_t offset;
843     int planepitch_byte = (w + 7) / 8;
844     int planepitch = ((w + 15) / 16) * 2;
845     int kludge_j, b, g, r, d;
846     GetByteContext gb;
847
848     pitch = planepitch * bpp;
849     kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
850
851     bytestream2_init(&gb, buf, buf_end - buf);
852
853     while (bytestream2_get_bytes_left(&gb) >= 2) {
854         type = bytestream2_get_be16(&gb);
855
856         switch (type) {
857         case 0:
858             return;
859         case 1:
860             flag   = bytestream2_get_be16(&gb);
861             cols   = bytestream2_get_be16(&gb);
862             groups = bytestream2_get_be16(&gb);
863
864             for (g = 0; g < groups; g++) {
865                 offset = bytestream2_get_be16(&gb);
866
867                 if (bytestream2_get_bytes_left(&gb) < 1)
868                     return;
869
870                 if (kludge_j)
871                     offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
872                 else
873                     offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
874
875                 for (b = 0; b < cols; b++) {
876                     for (d = 0; d < bpp; d++) {
877                         uint8_t value = bytestream2_get_byte(&gb);
878
879                         if (offset >= dst_size)
880                             return;
881                         ptr = dst + offset;
882
883                         if (flag)
884                             ptr[0] ^= value;
885                         else
886                             ptr[0]  = value;
887
888                         offset += planepitch;
889                     }
890                 }
891                 if ((cols * bpp) & 1)
892                     bytestream2_skip(&gb, 1);
893             }
894             break;
895         case 2:
896             flag   = bytestream2_get_be16(&gb);
897             rows   = bytestream2_get_be16(&gb);
898             bytes  = bytestream2_get_be16(&gb);
899             groups = bytestream2_get_be16(&gb);
900
901             for (g = 0; g < groups; g++) {
902                 offset = bytestream2_get_be16(&gb);
903
904                 if (kludge_j)
905                     offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
906                 else
907                     offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
908
909                 for (r = 0; r < rows; r++) {
910                     for (d = 0; d < bpp; d++) {
911                         unsigned noffset = offset + (r * pitch) + d * planepitch;
912
913                         if (bytestream2_get_bytes_left(&gb) < 1)
914                             return;
915
916                         for (b = 0; b < bytes; b++) {
917                             uint8_t value = bytestream2_get_byte(&gb);
918
919                             if (noffset >= dst_size)
920                                 return;
921                             ptr = dst + noffset;
922
923                             if (flag)
924                                 ptr[0] ^= value;
925                             else
926                                 ptr[0]  = value;
927
928                             noffset++;
929                         }
930                     }
931                 }
932                 if ((rows * bytes * bpp) & 1)
933                     bytestream2_skip(&gb, 1);
934             }
935             break;
936         default:
937             return;
938         }
939     }
940 }
941
942 static void decode_short_vertical_delta(uint8_t *dst,
943                                         const uint8_t *buf, const uint8_t *buf_end,
944                                         int w, int bpp, int dst_size)
945 {
946     int ncolumns = (w + 15) >> 4;
947     int dstpitch = ncolumns * bpp * 2;
948     unsigned ofsdst, ofssrc, ofsdata, opcode, x;
949     GetByteContext ptrs, gb, dptrs, dgb;
950     PutByteContext pb;
951     int i, j, k;
952
953     if (buf_end - buf <= 64)
954         return;
955
956     bytestream2_init(&ptrs, buf, buf_end - buf);
957     bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
958     bytestream2_init_writer(&pb, dst, dst_size);
959
960     for (k = 0; k < bpp; k++) {
961         ofssrc = bytestream2_get_be32(&ptrs);
962         ofsdata = bytestream2_get_be32(&dptrs);
963
964         if (!ofssrc)
965             continue;
966
967         if (ofssrc >= buf_end - buf)
968             return;
969
970         if (ofsdata >= buf_end - buf)
971             return;
972
973         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
974         bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
975         for (j = 0; j < ncolumns; j++) {
976             ofsdst = (j + k * ncolumns) * 2;
977
978             i = bytestream2_get_byte(&gb);
979             while (i > 0) {
980                 opcode = bytestream2_get_byte(&gb);
981
982                 if (opcode == 0) {
983                     opcode = bytestream2_get_byte(&gb);
984                     x = bytestream2_get_be16(&dgb);
985
986                     while (opcode) {
987                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
988                         bytestream2_put_be16(&pb, x);
989                         ofsdst += dstpitch;
990                         opcode--;
991                     }
992                 } else if (opcode < 0x80) {
993                     ofsdst += opcode * dstpitch;
994                 } else {
995                     opcode &= 0x7f;
996
997                     while (opcode) {
998                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
999                         bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1000                         ofsdst += dstpitch;
1001                         opcode--;
1002                     }
1003                 }
1004                 i--;
1005             }
1006         }
1007     }
1008 }
1009
1010 static void decode_long_vertical_delta(uint8_t *dst,
1011                                        const uint8_t *buf, const uint8_t *buf_end,
1012                                        int w, int bpp, int dst_size)
1013 {
1014     int ncolumns = (w + 31) >> 5;
1015     int dstpitch = ((w + 15) / 16 * 2) * bpp;
1016     unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1017     GetByteContext ptrs, gb, dptrs, dgb;
1018     PutByteContext pb;
1019     int i, j, k, h;
1020
1021     if (buf_end - buf <= 64)
1022         return;
1023
1024     h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1025     bytestream2_init(&ptrs, buf, buf_end - buf);
1026     bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1027     bytestream2_init_writer(&pb, dst, dst_size);
1028
1029     for (k = 0; k < bpp; k++) {
1030         ofssrc = bytestream2_get_be32(&ptrs);
1031         ofsdata = bytestream2_get_be32(&dptrs);
1032
1033         if (!ofssrc)
1034             continue;
1035
1036         if (ofssrc >= buf_end - buf)
1037             return;
1038
1039         if (ofsdata >= buf_end - buf)
1040             return;
1041
1042         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1043         bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1044         for (j = 0; j < ncolumns; j++) {
1045             ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1046
1047             i = bytestream2_get_byte(&gb);
1048             while (i > 0) {
1049                 opcode = bytestream2_get_byte(&gb);
1050
1051                 if (opcode == 0) {
1052                     opcode = bytestream2_get_byte(&gb);
1053                     if (h && (j == (ncolumns - 1))) {
1054                         x = bytestream2_get_be16(&dgb);
1055                         bytestream2_skip(&dgb, 2);
1056                     } else {
1057                         x = bytestream2_get_be32(&dgb);
1058                     }
1059
1060                     while (opcode) {
1061                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1062                         if (h && (j == (ncolumns - 1))) {
1063                             bytestream2_put_be16(&pb, x);
1064                         } else {
1065                             bytestream2_put_be32(&pb, x);
1066                         }
1067                         ofsdst += dstpitch;
1068                         opcode--;
1069                     }
1070                 } else if (opcode < 0x80) {
1071                     ofsdst += opcode * dstpitch;
1072                 } else {
1073                     opcode &= 0x7f;
1074
1075                     while (opcode) {
1076                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1077                         if (h && (j == (ncolumns - 1))) {
1078                             bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1079                             bytestream2_skip(&dgb, 2);
1080                         } else {
1081                             bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1082                         }
1083                         ofsdst += dstpitch;
1084                         opcode--;
1085                     }
1086                 }
1087                 i--;
1088             }
1089         }
1090     }
1091 }
1092
1093 static void decode_short_vertical_delta2(uint8_t *dst,
1094                                          const uint8_t *buf, const uint8_t *buf_end,
1095                                          int w, int bpp, int dst_size)
1096 {
1097     int ncolumns = (w + 15) >> 4;
1098     int dstpitch = ncolumns * bpp * 2;
1099     unsigned ofsdst, ofssrc, opcode, x;
1100     GetByteContext ptrs, gb;
1101     PutByteContext pb;
1102     int i, j, k;
1103
1104     bytestream2_init(&ptrs, buf, buf_end - buf);
1105     bytestream2_init_writer(&pb, dst, dst_size);
1106
1107     for (k = 0; k < bpp; k++) {
1108         ofssrc = bytestream2_get_be32(&ptrs);
1109
1110         if (!ofssrc)
1111             continue;
1112
1113         if (ofssrc >= buf_end - buf)
1114             continue;
1115
1116         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1117         for (j = 0; j < ncolumns; j++) {
1118             ofsdst = (j + k * ncolumns) * 2;
1119
1120             i = bytestream2_get_be16(&gb);
1121             while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1122                 opcode = bytestream2_get_be16(&gb);
1123
1124                 if (opcode == 0) {
1125                     opcode = bytestream2_get_be16(&gb);
1126                     x = bytestream2_get_be16(&gb);
1127
1128                     while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1129                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1130                         bytestream2_put_be16(&pb, x);
1131                         ofsdst += dstpitch;
1132                         opcode--;
1133                     }
1134                 } else if (opcode < 0x8000) {
1135                     ofsdst += opcode * dstpitch;
1136                 } else {
1137                     opcode &= 0x7fff;
1138
1139                     while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1140                            bytestream2_get_bytes_left_p(&pb) > 1) {
1141                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1142                         bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1143                         ofsdst += dstpitch;
1144                         opcode--;
1145                     }
1146                 }
1147                 i--;
1148             }
1149         }
1150     }
1151 }
1152
1153 static void decode_long_vertical_delta2(uint8_t *dst,
1154                                         const uint8_t *buf, const uint8_t *buf_end,
1155                                         int w, int bpp, int dst_size)
1156 {
1157     int ncolumns = (w + 31) >> 5;
1158     int dstpitch = ((w + 15) / 16 * 2) * bpp;
1159     unsigned ofsdst, ofssrc, opcode, x;
1160     unsigned skip = 0x80000000, mask = skip - 1;
1161     GetByteContext ptrs, gb;
1162     PutByteContext pb;
1163     int i, j, k, h;
1164
1165     h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1166     bytestream2_init(&ptrs, buf, buf_end - buf);
1167     bytestream2_init_writer(&pb, dst, dst_size);
1168
1169     for (k = 0; k < bpp; k++) {
1170         ofssrc = bytestream2_get_be32(&ptrs);
1171
1172         if (!ofssrc)
1173             continue;
1174
1175         if (ofssrc >= buf_end - buf)
1176             continue;
1177
1178         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1179         for (j = 0; j < ncolumns; j++) {
1180             ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1181
1182             if (h && (j == (ncolumns - 1))) {
1183                 skip = 0x8000;
1184                 mask = skip - 1;
1185             }
1186
1187             i = bytestream2_get_be32(&gb);
1188             while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1189                 opcode = bytestream2_get_be32(&gb);
1190
1191                 if (opcode == 0) {
1192                     if (h && (j == ncolumns - 1)) {
1193                         opcode = bytestream2_get_be16(&gb);
1194                         x = bytestream2_get_be16(&gb);
1195                     } else {
1196                         opcode = bytestream2_get_be32(&gb);
1197                         x = bytestream2_get_be32(&gb);
1198                     }
1199
1200                     while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1201                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1202                         if (h && (j == ncolumns - 1))
1203                             bytestream2_put_be16(&pb, x);
1204                         else
1205                             bytestream2_put_be32(&pb, x);
1206                         ofsdst += dstpitch;
1207                         opcode--;
1208                     }
1209                 } else if (opcode < skip) {
1210                     ofsdst += opcode * dstpitch;
1211                 } else {
1212                     opcode &= mask;
1213
1214                     while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1215                            bytestream2_get_bytes_left_p(&pb) > 1) {
1216                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1217                         if (h && (j == ncolumns - 1)) {
1218                             bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1219                         } else {
1220                             bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1221                         }
1222                         ofsdst += dstpitch;
1223                         opcode--;
1224                     }
1225                 }
1226                 i--;
1227             }
1228         }
1229     }
1230 }
1231
1232 static void decode_delta_d(uint8_t *dst,
1233                            const uint8_t *buf, const uint8_t *buf_end,
1234                            int w, int flag, int bpp, int dst_size)
1235 {
1236     int planepitch = FFALIGN(w, 16) >> 3;
1237     int pitch = planepitch * bpp;
1238     int planepitch_byte = (w + 7) / 8;
1239     unsigned entries, ofssrc;
1240     GetByteContext gb, ptrs;
1241     PutByteContext pb;
1242     int k;
1243
1244     if (buf_end - buf <= 4 * bpp)
1245         return;
1246
1247     bytestream2_init_writer(&pb, dst, dst_size);
1248     bytestream2_init(&ptrs, buf, bpp * 4);
1249
1250     for (k = 0; k < bpp; k++) {
1251         ofssrc = bytestream2_get_be32(&ptrs);
1252
1253         if (!ofssrc)
1254             continue;
1255
1256         if (ofssrc >= buf_end - buf)
1257             continue;
1258
1259         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1260
1261         entries = bytestream2_get_be32(&gb);
1262         while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1263             int32_t opcode  = bytestream2_get_be32(&gb);
1264             unsigned offset = bytestream2_get_be32(&gb);
1265
1266             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1267             if (opcode >= 0) {
1268                 uint32_t x = bytestream2_get_be32(&gb);
1269                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1270                     bytestream2_put_be32(&pb, x);
1271                     bytestream2_skip_p(&pb, pitch - 4);
1272                     opcode--;
1273                 }
1274             } else {
1275                 opcode = -opcode;
1276                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1277                     bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1278                     bytestream2_skip_p(&pb, pitch - 4);
1279                     opcode--;
1280                 }
1281             }
1282             entries--;
1283         }
1284     }
1285 }
1286
1287 static void decode_delta_e(uint8_t *dst,
1288                            const uint8_t *buf, const uint8_t *buf_end,
1289                            int w, int flag, int bpp, int dst_size)
1290 {
1291     int planepitch = FFALIGN(w, 16) >> 3;
1292     int pitch = planepitch * bpp;
1293     int planepitch_byte = (w + 7) / 8;
1294     unsigned entries, ofssrc;
1295     GetByteContext gb, ptrs;
1296     PutByteContext pb;
1297     int k;
1298
1299     if (buf_end - buf <= 4 * bpp)
1300         return;
1301
1302     bytestream2_init_writer(&pb, dst, dst_size);
1303     bytestream2_init(&ptrs, buf, bpp * 4);
1304
1305     for (k = 0; k < bpp; k++) {
1306         ofssrc = bytestream2_get_be32(&ptrs);
1307
1308         if (!ofssrc)
1309             continue;
1310
1311         if (ofssrc >= buf_end - buf)
1312             continue;
1313
1314         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1315
1316         entries = bytestream2_get_be16(&gb);
1317         while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1318             int16_t opcode  = bytestream2_get_be16(&gb);
1319             unsigned offset = bytestream2_get_be32(&gb);
1320
1321             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1322             if (opcode >= 0) {
1323                 uint16_t x = bytestream2_get_be16(&gb);
1324                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1325                     bytestream2_put_be16(&pb, x);
1326                     bytestream2_skip_p(&pb, pitch - 2);
1327                     opcode--;
1328                 }
1329             } else {
1330                 opcode = -opcode;
1331                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1332                     bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1333                     bytestream2_skip_p(&pb, pitch - 2);
1334                     opcode--;
1335                 }
1336             }
1337             entries--;
1338         }
1339     }
1340 }
1341
1342 static void decode_delta_l(uint8_t *dst,
1343                            const uint8_t *buf, const uint8_t *buf_end,
1344                            int w, int flag, int bpp, int dst_size)
1345 {
1346     GetByteContext off0, off1, dgb, ogb;
1347     PutByteContext pb;
1348     unsigned poff0, poff1;
1349     int i, k, dstpitch;
1350     int planepitch_byte = (w + 7) / 8;
1351     int planepitch = ((w + 15) / 16) * 2;
1352     int pitch = planepitch * bpp;
1353
1354     if (buf_end - buf <= 64)
1355         return;
1356
1357     bytestream2_init(&off0, buf, buf_end - buf);
1358     bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1359     bytestream2_init_writer(&pb, dst, dst_size);
1360
1361     dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1362
1363     for (k = 0; k < bpp; k++) {
1364         poff0 = bytestream2_get_be32(&off0);
1365         poff1 = bytestream2_get_be32(&off1);
1366
1367         if (!poff0)
1368             continue;
1369
1370         if (2LL * poff0 >= buf_end - buf)
1371             return;
1372
1373         if (2LL * poff1 >= buf_end - buf)
1374             return;
1375
1376         bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1377         bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1378
1379         while ((bytestream2_peek_be16(&ogb)) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1380             uint32_t offset = bytestream2_get_be16(&ogb);
1381             int16_t cnt = bytestream2_get_be16(&ogb);
1382             uint16_t data;
1383
1384             offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1385             if (cnt < 0) {
1386                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1387                 cnt = -cnt;
1388                 data = bytestream2_get_be16(&dgb);
1389                 for (i = 0; i < cnt; i++) {
1390                     bytestream2_put_be16(&pb, data);
1391                     bytestream2_skip_p(&pb, dstpitch - 2);
1392                 }
1393             } else {
1394                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1395                 for (i = 0; i < cnt; i++) {
1396                     data = bytestream2_get_be16(&dgb);
1397                     bytestream2_put_be16(&pb, data);
1398                     bytestream2_skip_p(&pb, dstpitch - 2);
1399                 }
1400             }
1401         }
1402     }
1403 }
1404
1405 static int unsupported(AVCodecContext *avctx)
1406 {
1407     IffContext *s = avctx->priv_data;
1408     avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1409     return AVERROR_INVALIDDATA;
1410 }
1411
1412 static int decode_frame(AVCodecContext *avctx,
1413                         void *data, int *got_frame,
1414                         AVPacket *avpkt)
1415 {
1416     IffContext *s          = avctx->priv_data;
1417     AVFrame *frame         = data;
1418     const uint8_t *buf     = avpkt->data;
1419     int buf_size           = avpkt->size;
1420     const uint8_t *buf_end = buf + buf_size;
1421     int y, plane, res;
1422     GetByteContext *gb = &s->gb;
1423     const AVPixFmtDescriptor *desc;
1424
1425     bytestream2_init(gb, avpkt->data, avpkt->size);
1426
1427     if ((res = extract_header(avctx, avpkt)) < 0)
1428         return res;
1429
1430     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1431         return res;
1432     s->frame = frame;
1433
1434     buf      += bytestream2_tell(gb);
1435     buf_size -= bytestream2_tell(gb);
1436     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1437
1438     if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1439         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1440         if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1441             return res;
1442     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1443                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1444         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1445             return res;
1446     }
1447     s->init = 1;
1448
1449     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1450         if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1451             memcpy(s->pal[0], s->frame->data[1], 256 * 4);
1452     }
1453
1454     switch (s->compression) {
1455     case 0x0:
1456         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1457             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1458                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1459                 for (plane = 0; plane < s->bpp; plane++) {
1460                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1461                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1462                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1463                         buf += s->planesize;
1464                     }
1465                 }
1466             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1467                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1468                 for (y = 0; y < avctx->height; y++) {
1469                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1470                     memset(s->ham_buf, 0, s->planesize * 8);
1471                     for (plane = 0; plane < s->bpp; plane++) {
1472                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1473                         if (start >= buf_end)
1474                             break;
1475                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1476                     }
1477                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1478                 }
1479             } else
1480                 return unsupported(avctx);
1481         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1482             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1483             int x;
1484             for (y = 0; y < avctx->height && buf < buf_end; y++) {
1485                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1486                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1487                 buf += raw_width;
1488                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1489                     for (x = 0; x < avctx->width; x++)
1490                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1491                 }
1492             }
1493         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1494                    avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1495             if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1496                 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1497             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1498                 for (y = 0; y < avctx->height; y++) {
1499                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1500                     memset(row, 0, avctx->width);
1501                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1502                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1503                         buf += s->planesize;
1504                     }
1505                 }
1506             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1507                 for (y = 0; y < avctx->height; y++) {
1508                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1509                     memset(s->ham_buf, 0, s->planesize * 8);
1510                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1511                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1512                         buf += s->planesize;
1513                     }
1514                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1515                 }
1516             } else { // AV_PIX_FMT_BGR32
1517                 for (y = 0; y < avctx->height; y++) {
1518                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1519                     memset(row, 0, avctx->width << 2);
1520                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1521                         decodeplane32((uint32_t *)row, buf,
1522                                       FFMIN(s->planesize, buf_end - buf), plane);
1523                         buf += s->planesize;
1524                     }
1525                 }
1526             }
1527         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1528             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1529                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1530                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1531                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1532                     buf += avctx->width + (avctx->width % 2); // padding if odd
1533                 }
1534             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1535                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1536                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1537                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1538                     buf += avctx->width + (avctx->width & 1); // padding if odd
1539                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1540                 }
1541             } else
1542                 return unsupported(avctx);
1543         }
1544         break;
1545     case 0x1:
1546         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1547             avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1548             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1549                 uint8_t *video = s->video[0];
1550
1551                 for (y = 0; y < avctx->height; y++) {
1552                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1553                     memset(row, 0, avctx->width);
1554                     for (plane = 0; plane < s->bpp; plane++) {
1555                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1556                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1557                             memcpy(video, s->planebuf, s->planesize);
1558                             video += s->planesize;
1559                         }
1560                         decodeplane8(row, s->planebuf, s->planesize, plane);
1561                     }
1562                 }
1563             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1564                 for (y = 0; y < avctx->height; y++) {
1565                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1566                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1567                     for (plane = 0; plane < s->bpp; plane++) {
1568                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1569                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1570                     }
1571                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1572                 }
1573             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1574                 uint8_t *video = s->video[0];
1575                 for (y = 0; y < avctx->height; y++) {
1576                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1577                     memset(s->ham_buf, 0, s->planesize * 8);
1578                     for (plane = 0; plane < s->bpp; plane++) {
1579                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1580                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1581                             memcpy(video, s->planebuf, s->planesize);
1582                             video += s->planesize;
1583                         }
1584                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1585                     }
1586                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1587                 }
1588             } else { // AV_PIX_FMT_BGR32
1589                 for (y = 0; y < avctx->height; y++) {
1590                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1591                     memset(row, 0, avctx->width << 2);
1592                     for (plane = 0; plane < s->bpp; plane++) {
1593                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1594                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1595                     }
1596                 }
1597             }
1598         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1599             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1600                 for (y = 0; y < avctx->height; y++) {
1601                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1602                     buf += decode_byterun(row, avctx->width, gb);
1603                 }
1604             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1605                 for (y = 0; y < avctx->height; y++) {
1606                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1607                     buf += decode_byterun(s->ham_buf, avctx->width, gb);
1608                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1609                 }
1610             } else
1611                 return unsupported(avctx);
1612         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1613             if (av_get_bits_per_pixel(desc) == 32)
1614                 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1615             else
1616                 return unsupported(avctx);
1617         }
1618         break;
1619     case 0x4:
1620         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1621             decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1622         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1623             decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1624         else
1625             return unsupported(avctx);
1626         break;
1627     case 0x5:
1628         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1629             if (av_get_bits_per_pixel(desc) == 32)
1630                 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1631             else
1632                 return unsupported(avctx);
1633         } else
1634             return unsupported(avctx);
1635         break;
1636     case 0x300:
1637     case 0x301:
1638         decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1639         break;
1640     case 0x500:
1641     case 0x501:
1642         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1643         break;
1644     case 0x700:
1645     case 0x701:
1646         if (s->is_short)
1647             decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1648         else
1649             decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1650         break;
1651     case 0x800:
1652     case 0x801:
1653         if (s->is_short)
1654             decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1655         else
1656             decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1657         break;
1658     case 0x4a00:
1659     case 0x4a01:
1660         decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1661         break;
1662     case 0x6400:
1663     case 0x6401:
1664         if (s->is_interlaced)
1665             return unsupported(avctx);
1666         decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1667         break;
1668     case 0x6500:
1669     case 0x6501:
1670         if (s->is_interlaced)
1671             return unsupported(avctx);
1672         decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1673         break;
1674     case 0x6c00:
1675     case 0x6c01:
1676         decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1677         break;
1678     default:
1679         return unsupported(avctx);
1680     }
1681
1682     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1683         memcpy(s->pal[1], s->pal[0], 256 * 4);
1684         memcpy(s->video[1], s->video[0], s->video_size);
1685     }
1686
1687     if (s->compression > 0xff) {
1688         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1689             buf = s->video[0];
1690             for (y = 0; y < avctx->height; y++) {
1691                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1692                 memset(row, 0, avctx->width);
1693                 for (plane = 0; plane < s->bpp; plane++) {
1694                     decodeplane8(row, buf, s->planesize, plane);
1695                     buf += s->planesize;
1696                 }
1697             }
1698             memcpy(frame->data[1], s->pal[0], 256 * 4);
1699         } else if (s->ham) {
1700             int i, count = 1 << s->ham;
1701
1702             buf = s->video[0];
1703             memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1704             for (i = 0; i < count; i++) {
1705                 s->ham_palbuf[i*2+1] = s->pal[0][i];
1706             }
1707             for (i = 0; i < count; i++) {
1708                 uint32_t tmp = i << (8 - s->ham);
1709                 tmp |= tmp >> s->ham;
1710                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
1711                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
1712                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
1713                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
1714                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1715                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1716             }
1717             if (s->masking == MASK_HAS_MASK) {
1718                 for (i = 0; i < 8 * (1 << s->ham); i++)
1719                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1720             }
1721             for (y = 0; y < avctx->height; y++) {
1722                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1723                 memset(s->ham_buf, 0, s->planesize * 8);
1724                 for (plane = 0; plane < s->bpp; plane++) {
1725                     decodeplane8(s->ham_buf, buf, s->planesize, plane);
1726                     buf += s->planesize;
1727                 }
1728                 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1729             }
1730         } else {
1731             return unsupported(avctx);
1732         }
1733
1734         if (!s->is_brush) {
1735             FFSWAP(uint8_t *, s->video[0], s->video[1]);
1736             FFSWAP(uint32_t *, s->pal[0], s->pal[1]);
1737         }
1738     }
1739
1740     if (avpkt->flags & AV_PKT_FLAG_KEY) {
1741         frame->key_frame = 1;
1742         frame->pict_type = AV_PICTURE_TYPE_I;
1743     } else {
1744         frame->key_frame = 0;
1745         frame->pict_type = AV_PICTURE_TYPE_P;
1746     }
1747
1748     *got_frame = 1;
1749
1750     return buf_size;
1751 }
1752
1753 #if CONFIG_IFF_ILBM_DECODER
1754 AVCodec ff_iff_ilbm_decoder = {
1755     .name           = "iff",
1756     .long_name      = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1757     .type           = AVMEDIA_TYPE_VIDEO,
1758     .id             = AV_CODEC_ID_IFF_ILBM,
1759     .priv_data_size = sizeof(IffContext),
1760     .init           = decode_init,
1761     .close          = decode_end,
1762     .decode         = decode_frame,
1763     .capabilities   = AV_CODEC_CAP_DR1,
1764 };
1765 #endif