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