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