]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
avcodec/iff: Fix invalid pointer intermediates in decode_deep_rle32()
[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                 memcpy(dst + y*linesize + x * 4, src, length * 4);
726                 src += length * 4;
727                 x += length;
728                 i += length;
729                 if (x >= width) {
730                     x = 0;
731                     y += 1;
732                     if (y >= height)
733                         return;
734                 }
735             }
736         } else {
737             int size = -opcode + 1;
738             uint32_t pixel = AV_RN32(src);
739             for (i = 0; i < size; i++) {
740                 *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
741                 x += 1;
742                 if (x >= width) {
743                     x = 0;
744                     y += 1;
745                     if (y >= height)
746                         return;
747                 }
748             }
749             src += 4;
750         }
751     }
752 }
753
754 /**
755  * Decode DEEP TVDC 32-bit buffer
756  * @param[out] dst Destination buffer
757  * @param[in] src Source buffer
758  * @param src_size Source buffer size (bytes)
759  * @param width Width of destination buffer (pixels)
760  * @param height Height of destination buffer (pixels)
761  * @param linesize Line size of destination buffer (bytes)
762  * @param[int] tvdc TVDC lookup table
763  */
764 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)
765 {
766     int x = 0, y = 0, plane = 0;
767     int8_t pixel = 0;
768     int i, j;
769
770     for (i = 0; i < src_size * 2;) {
771 #define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
772         int d = tvdc[GETNIBBLE];
773         i++;
774         if (d) {
775             pixel += d;
776             dst[y * linesize + x*4 + plane] = pixel;
777             x++;
778         } else {
779             if (i >= src_size * 2)
780                 return;
781             d = GETNIBBLE + 1;
782             i++;
783             d = FFMIN(d, width - x);
784             for (j = 0; j < d; j++) {
785                 dst[y * linesize + x*4 + plane] = pixel;
786                 x++;
787             }
788         }
789         if (x >= width) {
790             plane++;
791             if (plane >= 4) {
792                 y++;
793                 if (y >= height)
794                     return;
795                 plane = 0;
796             }
797             x = 0;
798             pixel = 0;
799             i = (i + 1) & ~1;
800         }
801     }
802 }
803
804 static void decode_short_horizontal_delta(uint8_t *dst,
805                                           const uint8_t *buf, const uint8_t *buf_end,
806                                           int w, int bpp, int dst_size)
807 {
808     int planepitch = FFALIGN(w, 16) >> 3;
809     int pitch = planepitch * bpp;
810     GetByteContext ptrs, gb;
811     PutByteContext pb;
812     unsigned ofssrc, pos;
813     int i, k;
814
815     bytestream2_init(&ptrs, buf, buf_end - buf);
816     bytestream2_init_writer(&pb, dst, dst_size);
817
818     for (k = 0; k < bpp; k++) {
819         ofssrc = bytestream2_get_be32(&ptrs);
820         pos = 0;
821
822         if (!ofssrc)
823             continue;
824
825         if (ofssrc >= buf_end - buf)
826             continue;
827
828         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
829         while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
830             int16_t offset = bytestream2_get_be16(&gb);
831             unsigned noffset;
832
833             if (offset >= 0) {
834                 unsigned data = bytestream2_get_be16(&gb);
835
836                 pos += offset * 2;
837                 noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
838                 bytestream2_seek_p(&pb, noffset, SEEK_SET);
839                 bytestream2_put_be16(&pb, data);
840             } else {
841                 uint16_t count = bytestream2_get_be16(&gb);
842
843                 pos += 2 * -(offset + 2);
844                 for (i = 0; i < count; i++) {
845                     uint16_t data = bytestream2_get_be16(&gb);
846
847                     pos += 2;
848                     noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
849                     bytestream2_seek_p(&pb, noffset, SEEK_SET);
850                     bytestream2_put_be16(&pb, data);
851                 }
852             }
853         }
854     }
855 }
856
857 static void decode_byte_vertical_delta(uint8_t *dst,
858                                        const uint8_t *buf, const uint8_t *buf_end,
859                                        int w, int xor, int bpp, int dst_size)
860 {
861     int ncolumns = ((w + 15) / 16) * 2;
862     int dstpitch = ncolumns * bpp;
863     unsigned ofsdst, ofssrc, opcode, x;
864     GetByteContext ptrs, gb;
865     PutByteContext pb;
866     int i, j, k;
867
868     bytestream2_init(&ptrs, buf, buf_end - buf);
869     bytestream2_init_writer(&pb, dst, dst_size);
870
871     for (k = 0; k < bpp; k++) {
872         ofssrc = bytestream2_get_be32(&ptrs);
873
874         if (!ofssrc)
875             continue;
876
877         if (ofssrc >= buf_end - buf)
878             continue;
879
880         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
881         for (j = 0; j < ncolumns; j++) {
882             ofsdst = j + k * ncolumns;
883
884             i = bytestream2_get_byte(&gb);
885             while (i > 0) {
886                 opcode = bytestream2_get_byte(&gb);
887
888                 if (opcode == 0) {
889                     opcode  = bytestream2_get_byte(&gb);
890                     x = bytestream2_get_byte(&gb);
891
892                     while (opcode) {
893                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
894                         if (xor && ofsdst < dst_size) {
895                             bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
896                         } else {
897                             bytestream2_put_byte(&pb, x);
898                         }
899                         ofsdst += dstpitch;
900                         opcode--;
901                     }
902                 } else if (opcode < 0x80) {
903                     ofsdst += opcode * dstpitch;
904                 } else {
905                     opcode &= 0x7f;
906
907                     while (opcode) {
908                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
909                         if (xor && ofsdst < dst_size) {
910                             bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
911                         } else {
912                             bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
913                         }
914                         ofsdst += dstpitch;
915                         opcode--;
916                     }
917                 }
918                 i--;
919             }
920         }
921     }
922 }
923
924 static void decode_delta_j(uint8_t *dst,
925                            const uint8_t *buf, const uint8_t *buf_end,
926                            int w, int h, int bpp, int dst_size)
927 {
928     int32_t pitch;
929     uint8_t *ptr;
930     uint32_t type, flag, cols, groups, rows, bytes;
931     uint32_t offset;
932     int planepitch_byte = (w + 7) / 8;
933     int planepitch = ((w + 15) / 16) * 2;
934     int kludge_j, b, g, r, d;
935     GetByteContext gb;
936
937     pitch = planepitch * bpp;
938     kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
939
940     bytestream2_init(&gb, buf, buf_end - buf);
941
942     while (bytestream2_get_bytes_left(&gb) >= 2) {
943         type = bytestream2_get_be16(&gb);
944
945         switch (type) {
946         case 0:
947             return;
948         case 1:
949             flag   = bytestream2_get_be16(&gb);
950             cols   = bytestream2_get_be16(&gb);
951             groups = bytestream2_get_be16(&gb);
952
953             for (g = 0; g < groups; g++) {
954                 offset = bytestream2_get_be16(&gb);
955
956                 if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
957                     av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
958                     return;
959                 }
960
961                 if (kludge_j)
962                     offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
963                 else
964                     offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
965
966                 for (b = 0; b < cols; b++) {
967                     for (d = 0; d < bpp; d++) {
968                         uint8_t value = bytestream2_get_byte(&gb);
969
970                         if (offset >= dst_size)
971                             return;
972                         ptr = dst + offset;
973
974                         if (flag)
975                             ptr[0] ^= value;
976                         else
977                             ptr[0]  = value;
978
979                         offset += planepitch;
980                     }
981                 }
982                 if ((cols * bpp) & 1)
983                     bytestream2_skip(&gb, 1);
984             }
985             break;
986         case 2:
987             flag   = bytestream2_get_be16(&gb);
988             rows   = bytestream2_get_be16(&gb);
989             bytes  = bytestream2_get_be16(&gb);
990             groups = bytestream2_get_be16(&gb);
991
992             for (g = 0; g < groups; g++) {
993                 offset = bytestream2_get_be16(&gb);
994
995                 if (kludge_j)
996                     offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
997                 else
998                     offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
999
1000                 for (r = 0; r < rows; r++) {
1001                     for (d = 0; d < bpp; d++) {
1002                         unsigned noffset = offset + (r * pitch) + d * planepitch;
1003
1004                         if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1005                             av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1006                             return;
1007                         }
1008
1009                         for (b = 0; b < bytes; b++) {
1010                             uint8_t value = bytestream2_get_byte(&gb);
1011
1012                             if (noffset >= dst_size)
1013                                 return;
1014                             ptr = dst + noffset;
1015
1016                             if (flag)
1017                                 ptr[0] ^= value;
1018                             else
1019                                 ptr[0]  = value;
1020
1021                             noffset++;
1022                         }
1023                     }
1024                 }
1025                 if ((rows * bytes * bpp) & 1)
1026                     bytestream2_skip(&gb, 1);
1027             }
1028             break;
1029         default:
1030             return;
1031         }
1032     }
1033 }
1034
1035 static void decode_short_vertical_delta(uint8_t *dst,
1036                                         const uint8_t *buf, const uint8_t *buf_end,
1037                                         int w, int bpp, int dst_size)
1038 {
1039     int ncolumns = (w + 15) >> 4;
1040     int dstpitch = ncolumns * bpp * 2;
1041     unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1042     GetByteContext ptrs, gb, dptrs, dgb;
1043     PutByteContext pb;
1044     int i, j, k;
1045
1046     if (buf_end - buf <= 64)
1047         return;
1048
1049     bytestream2_init(&ptrs, buf, buf_end - buf);
1050     bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1051     bytestream2_init_writer(&pb, dst, dst_size);
1052
1053     for (k = 0; k < bpp; k++) {
1054         ofssrc = bytestream2_get_be32(&ptrs);
1055         ofsdata = bytestream2_get_be32(&dptrs);
1056
1057         if (!ofssrc)
1058             continue;
1059
1060         if (ofssrc >= buf_end - buf)
1061             return;
1062
1063         if (ofsdata >= buf_end - buf)
1064             return;
1065
1066         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1067         bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1068         for (j = 0; j < ncolumns; j++) {
1069             ofsdst = (j + k * ncolumns) * 2;
1070
1071             i = bytestream2_get_byte(&gb);
1072             while (i > 0) {
1073                 opcode = bytestream2_get_byte(&gb);
1074
1075                 if (opcode == 0) {
1076                     opcode = bytestream2_get_byte(&gb);
1077                     x = bytestream2_get_be16(&dgb);
1078
1079                     while (opcode) {
1080                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1081                         bytestream2_put_be16(&pb, x);
1082                         ofsdst += dstpitch;
1083                         opcode--;
1084                     }
1085                 } else if (opcode < 0x80) {
1086                     ofsdst += opcode * dstpitch;
1087                 } else {
1088                     opcode &= 0x7f;
1089
1090                     while (opcode) {
1091                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1092                         bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1093                         ofsdst += dstpitch;
1094                         opcode--;
1095                     }
1096                 }
1097                 i--;
1098             }
1099         }
1100     }
1101 }
1102
1103 static void decode_long_vertical_delta(uint8_t *dst,
1104                                        const uint8_t *buf, const uint8_t *buf_end,
1105                                        int w, int bpp, int dst_size)
1106 {
1107     int ncolumns = (w + 31) >> 5;
1108     int dstpitch = ((w + 15) / 16 * 2) * bpp;
1109     unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1110     GetByteContext ptrs, gb, dptrs, dgb;
1111     PutByteContext pb;
1112     int i, j, k, h;
1113
1114     if (buf_end - buf <= 64)
1115         return;
1116
1117     h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1118     bytestream2_init(&ptrs, buf, buf_end - buf);
1119     bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1120     bytestream2_init_writer(&pb, dst, dst_size);
1121
1122     for (k = 0; k < bpp; k++) {
1123         ofssrc = bytestream2_get_be32(&ptrs);
1124         ofsdata = bytestream2_get_be32(&dptrs);
1125
1126         if (!ofssrc)
1127             continue;
1128
1129         if (ofssrc >= buf_end - buf)
1130             return;
1131
1132         if (ofsdata >= buf_end - buf)
1133             return;
1134
1135         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1136         bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1137         for (j = 0; j < ncolumns; j++) {
1138             ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1139
1140             i = bytestream2_get_byte(&gb);
1141             while (i > 0) {
1142                 opcode = bytestream2_get_byte(&gb);
1143
1144                 if (opcode == 0) {
1145                     opcode = bytestream2_get_byte(&gb);
1146                     if (h && (j == (ncolumns - 1))) {
1147                         x = bytestream2_get_be16(&dgb);
1148                         bytestream2_skip(&dgb, 2);
1149                     } else {
1150                         x = bytestream2_get_be32(&dgb);
1151                     }
1152
1153                     if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1154                         return;
1155
1156                     while (opcode) {
1157                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1158                         if (h && (j == (ncolumns - 1))) {
1159                             bytestream2_put_be16(&pb, x);
1160                         } else {
1161                             bytestream2_put_be32(&pb, x);
1162                         }
1163                         ofsdst += dstpitch;
1164                         opcode--;
1165                     }
1166                 } else if (opcode < 0x80) {
1167                     ofsdst += opcode * dstpitch;
1168                 } else {
1169                     opcode &= 0x7f;
1170
1171                     while (opcode) {
1172                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1173                         if (h && (j == (ncolumns - 1))) {
1174                             bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1175                             bytestream2_skip(&dgb, 2);
1176                         } else {
1177                             bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1178                         }
1179                         ofsdst += dstpitch;
1180                         opcode--;
1181                     }
1182                 }
1183                 i--;
1184             }
1185         }
1186     }
1187 }
1188
1189 static void decode_short_vertical_delta2(uint8_t *dst,
1190                                          const uint8_t *buf, const uint8_t *buf_end,
1191                                          int w, int bpp, int dst_size)
1192 {
1193     int ncolumns = (w + 15) >> 4;
1194     int dstpitch = ncolumns * bpp * 2;
1195     unsigned ofsdst, ofssrc, opcode, x;
1196     GetByteContext ptrs, gb;
1197     PutByteContext pb;
1198     int i, j, k;
1199
1200     bytestream2_init(&ptrs, buf, buf_end - buf);
1201     bytestream2_init_writer(&pb, dst, dst_size);
1202
1203     for (k = 0; k < bpp; k++) {
1204         ofssrc = bytestream2_get_be32(&ptrs);
1205
1206         if (!ofssrc)
1207             continue;
1208
1209         if (ofssrc >= buf_end - buf)
1210             continue;
1211
1212         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1213         for (j = 0; j < ncolumns; j++) {
1214             ofsdst = (j + k * ncolumns) * 2;
1215
1216             i = bytestream2_get_be16(&gb);
1217             while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1218                 opcode = bytestream2_get_be16(&gb);
1219
1220                 if (opcode == 0) {
1221                     opcode = bytestream2_get_be16(&gb);
1222                     x = bytestream2_get_be16(&gb);
1223
1224                     while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1225                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1226                         bytestream2_put_be16(&pb, x);
1227                         ofsdst += dstpitch;
1228                         opcode--;
1229                     }
1230                 } else if (opcode < 0x8000) {
1231                     ofsdst += opcode * dstpitch;
1232                 } else {
1233                     opcode &= 0x7fff;
1234
1235                     while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1236                            bytestream2_get_bytes_left_p(&pb) > 1) {
1237                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1238                         bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1239                         ofsdst += dstpitch;
1240                         opcode--;
1241                     }
1242                 }
1243                 i--;
1244             }
1245         }
1246     }
1247 }
1248
1249 static void decode_long_vertical_delta2(uint8_t *dst,
1250                                         const uint8_t *buf, const uint8_t *buf_end,
1251                                         int w, int bpp, int dst_size)
1252 {
1253     int ncolumns = (w + 31) >> 5;
1254     int dstpitch = ((w + 15) / 16 * 2) * bpp;
1255     unsigned ofsdst, ofssrc, opcode, x;
1256     unsigned skip = 0x80000000, mask = skip - 1;
1257     GetByteContext ptrs, gb;
1258     PutByteContext pb;
1259     int i, j, k, h;
1260
1261     h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1262     bytestream2_init(&ptrs, buf, buf_end - buf);
1263     bytestream2_init_writer(&pb, dst, dst_size);
1264
1265     for (k = 0; k < bpp; k++) {
1266         ofssrc = bytestream2_get_be32(&ptrs);
1267
1268         if (!ofssrc)
1269             continue;
1270
1271         if (ofssrc >= buf_end - buf)
1272             continue;
1273
1274         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1275         for (j = 0; j < ncolumns; j++) {
1276             ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1277
1278             if (h && (j == (ncolumns - 1))) {
1279                 skip = 0x8000;
1280                 mask = skip - 1;
1281             }
1282
1283             i = bytestream2_get_be32(&gb);
1284             while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1285                 opcode = bytestream2_get_be32(&gb);
1286
1287                 if (opcode == 0) {
1288                     if (h && (j == ncolumns - 1)) {
1289                         opcode = bytestream2_get_be16(&gb);
1290                         x = bytestream2_get_be16(&gb);
1291                     } else {
1292                         opcode = bytestream2_get_be32(&gb);
1293                         x = bytestream2_get_be32(&gb);
1294                     }
1295
1296                     if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1297                         return;
1298
1299                     while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1300                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1301                         if (h && (j == ncolumns - 1))
1302                             bytestream2_put_be16(&pb, x);
1303                         else
1304                             bytestream2_put_be32(&pb, x);
1305                         ofsdst += dstpitch;
1306                         opcode--;
1307                     }
1308                 } else if (opcode < skip) {
1309                     ofsdst += opcode * dstpitch;
1310                 } else {
1311                     opcode &= mask;
1312
1313                     while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1314                            bytestream2_get_bytes_left_p(&pb) > 1) {
1315                         bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1316                         if (h && (j == ncolumns - 1)) {
1317                             bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1318                         } else {
1319                             bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1320                         }
1321                         ofsdst += dstpitch;
1322                         opcode--;
1323                     }
1324                 }
1325                 i--;
1326             }
1327         }
1328     }
1329 }
1330
1331 static void decode_delta_d(uint8_t *dst,
1332                            const uint8_t *buf, const uint8_t *buf_end,
1333                            int w, int flag, int bpp, int dst_size)
1334 {
1335     int planepitch = FFALIGN(w, 16) >> 3;
1336     int pitch = planepitch * bpp;
1337     int planepitch_byte = (w + 7) / 8;
1338     unsigned entries, ofssrc;
1339     GetByteContext gb, ptrs;
1340     PutByteContext pb;
1341     int k;
1342
1343     if (buf_end - buf <= 4 * bpp)
1344         return;
1345
1346     bytestream2_init_writer(&pb, dst, dst_size);
1347     bytestream2_init(&ptrs, buf, bpp * 4);
1348
1349     for (k = 0; k < bpp; k++) {
1350         ofssrc = bytestream2_get_be32(&ptrs);
1351
1352         if (!ofssrc)
1353             continue;
1354
1355         if (ofssrc >= buf_end - buf)
1356             continue;
1357
1358         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1359
1360         entries = bytestream2_get_be32(&gb);
1361         if (entries * 8LL > bytestream2_get_bytes_left(&gb))
1362             return;
1363
1364         while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1365             int32_t opcode  = bytestream2_get_be32(&gb);
1366             unsigned offset = bytestream2_get_be32(&gb);
1367
1368             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1369             if (opcode >= 0) {
1370                 uint32_t x = bytestream2_get_be32(&gb);
1371                 if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1372                     continue;
1373                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1374                     bytestream2_put_be32(&pb, x);
1375                     bytestream2_skip_p(&pb, pitch - 4);
1376                     opcode--;
1377                 }
1378             } else {
1379                 opcode = -opcode;
1380                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1381                     bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1382                     bytestream2_skip_p(&pb, pitch - 4);
1383                     opcode--;
1384                 }
1385             }
1386             entries--;
1387         }
1388     }
1389 }
1390
1391 static void decode_delta_e(uint8_t *dst,
1392                            const uint8_t *buf, const uint8_t *buf_end,
1393                            int w, int flag, int bpp, int dst_size)
1394 {
1395     int planepitch = FFALIGN(w, 16) >> 3;
1396     int pitch = planepitch * bpp;
1397     int planepitch_byte = (w + 7) / 8;
1398     unsigned entries, ofssrc;
1399     GetByteContext gb, ptrs;
1400     PutByteContext pb;
1401     int k;
1402
1403     if (buf_end - buf <= 4 * bpp)
1404         return;
1405
1406     bytestream2_init_writer(&pb, dst, dst_size);
1407     bytestream2_init(&ptrs, buf, bpp * 4);
1408
1409     for (k = 0; k < bpp; k++) {
1410         ofssrc = bytestream2_get_be32(&ptrs);
1411
1412         if (!ofssrc)
1413             continue;
1414
1415         if (ofssrc >= buf_end - buf)
1416             continue;
1417
1418         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1419
1420         entries = bytestream2_get_be16(&gb);
1421         while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1422             int16_t opcode  = bytestream2_get_be16(&gb);
1423             unsigned offset = bytestream2_get_be32(&gb);
1424
1425             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1426             if (opcode >= 0) {
1427                 uint16_t x = bytestream2_get_be16(&gb);
1428                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1429                     bytestream2_put_be16(&pb, x);
1430                     bytestream2_skip_p(&pb, pitch - 2);
1431                     opcode--;
1432                 }
1433             } else {
1434                 opcode = -opcode;
1435                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1436                     bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1437                     bytestream2_skip_p(&pb, pitch - 2);
1438                     opcode--;
1439                 }
1440             }
1441             entries--;
1442         }
1443     }
1444 }
1445
1446 static void decode_delta_l(uint8_t *dst,
1447                            const uint8_t *buf, const uint8_t *buf_end,
1448                            int w, int flag, int bpp, int dst_size)
1449 {
1450     GetByteContext off0, off1, dgb, ogb;
1451     PutByteContext pb;
1452     unsigned poff0, poff1;
1453     int i, k, dstpitch;
1454     int planepitch_byte = (w + 7) / 8;
1455     int planepitch = ((w + 15) / 16) * 2;
1456     int pitch = planepitch * bpp;
1457
1458     if (buf_end - buf <= 64)
1459         return;
1460
1461     bytestream2_init(&off0, buf, buf_end - buf);
1462     bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1463     bytestream2_init_writer(&pb, dst, dst_size);
1464
1465     dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1466
1467     for (k = 0; k < bpp; k++) {
1468         poff0 = bytestream2_get_be32(&off0);
1469         poff1 = bytestream2_get_be32(&off1);
1470
1471         if (!poff0)
1472             continue;
1473
1474         if (2LL * poff0 >= buf_end - buf)
1475             return;
1476
1477         if (2LL * poff1 >= buf_end - buf)
1478             return;
1479
1480         bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1481         bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1482
1483         while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1484             uint32_t offset = bytestream2_get_be16(&ogb);
1485             int16_t cnt = bytestream2_get_be16(&ogb);
1486             uint16_t data;
1487
1488             offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1489             if (cnt < 0) {
1490                 if (bytestream2_get_bytes_left(&dgb) < 2)
1491                     break;
1492                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1493                 cnt = -cnt;
1494                 data = bytestream2_get_be16(&dgb);
1495                 for (i = 0; i < cnt; i++) {
1496                     bytestream2_put_be16(&pb, data);
1497                     bytestream2_skip_p(&pb, dstpitch - 2);
1498                 }
1499             } else {
1500                 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1501                     break;
1502                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1503                 for (i = 0; i < cnt; i++) {
1504                     data = bytestream2_get_be16(&dgb);
1505                     bytestream2_put_be16(&pb, data);
1506                     bytestream2_skip_p(&pb, dstpitch - 2);
1507                 }
1508             }
1509         }
1510     }
1511 }
1512
1513 static int unsupported(AVCodecContext *avctx)
1514 {
1515     IffContext *s = avctx->priv_data;
1516     avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1517     return AVERROR_INVALIDDATA;
1518 }
1519
1520 static int decode_frame(AVCodecContext *avctx,
1521                         void *data, int *got_frame,
1522                         AVPacket *avpkt)
1523 {
1524     IffContext *s          = avctx->priv_data;
1525     AVFrame *frame         = data;
1526     const uint8_t *buf     = avpkt->data;
1527     int buf_size           = avpkt->size;
1528     const uint8_t *buf_end = buf + buf_size;
1529     int y, plane, res;
1530     GetByteContext *gb = &s->gb;
1531     const AVPixFmtDescriptor *desc;
1532
1533     bytestream2_init(gb, avpkt->data, avpkt->size);
1534
1535     if ((res = extract_header(avctx, avpkt)) < 0)
1536         return res;
1537
1538     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1539         return res;
1540     s->frame = frame;
1541
1542     buf      += bytestream2_tell(gb);
1543     buf_size -= bytestream2_tell(gb);
1544     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1545
1546     if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1547         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1548         if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1549             return res;
1550     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1551                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1552         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1553             return res;
1554     }
1555     s->init = 1;
1556
1557     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1558         if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1559             memcpy(s->pal, s->frame->data[1], 256 * 4);
1560     }
1561
1562     switch (s->compression) {
1563     case 0x0:
1564         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1565             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1566                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1567                 for (plane = 0; plane < s->bpp; plane++) {
1568                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1569                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1570                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1571                         buf += s->planesize;
1572                     }
1573                 }
1574             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1575                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1576                 for (y = 0; y < avctx->height; y++) {
1577                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1578                     memset(s->ham_buf, 0, s->planesize * 8);
1579                     for (plane = 0; plane < s->bpp; plane++) {
1580                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1581                         if (start >= buf_end)
1582                             break;
1583                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1584                     }
1585                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1586                 }
1587             } else
1588                 return unsupported(avctx);
1589         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1590             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1591             int x;
1592             for (y = 0; y < avctx->height && buf < buf_end; y++) {
1593                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1594                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1595                 buf += raw_width;
1596                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1597                     for (x = 0; x < avctx->width; x++)
1598                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1599                 }
1600             }
1601         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1602                    avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1603             if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1604                 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1605             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1606                 for (y = 0; y < avctx->height; y++) {
1607                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1608                     memset(row, 0, avctx->width);
1609                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1610                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1611                         buf += s->planesize;
1612                     }
1613                 }
1614             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1615                 for (y = 0; y < avctx->height; y++) {
1616                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1617                     memset(s->ham_buf, 0, s->planesize * 8);
1618                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1619                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1620                         buf += s->planesize;
1621                     }
1622                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1623                 }
1624             } else { // AV_PIX_FMT_BGR32
1625                 for (y = 0; y < avctx->height; y++) {
1626                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1627                     memset(row, 0, avctx->width << 2);
1628                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1629                         decodeplane32((uint32_t *)row, buf,
1630                                       FFMIN(s->planesize, buf_end - buf), plane);
1631                         buf += s->planesize;
1632                     }
1633                 }
1634             }
1635         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1636             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1637                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1638                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1639                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1640                     buf += avctx->width + (avctx->width % 2); // padding if odd
1641                 }
1642             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1643                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1644                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1645                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1646                     buf += avctx->width + (avctx->width & 1); // padding if odd
1647                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1648                 }
1649             } else
1650                 return unsupported(avctx);
1651         } else {
1652             return unsupported(avctx);
1653         }
1654         break;
1655     case 0x1:
1656         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1657             avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1658             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1659                 uint8_t *video = s->video[0];
1660
1661                 for (y = 0; y < avctx->height; y++) {
1662                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1663                     memset(row, 0, avctx->width);
1664                     for (plane = 0; plane < s->bpp; plane++) {
1665                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1666                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1667                             memcpy(video, s->planebuf, s->planesize);
1668                             video += s->planesize;
1669                         }
1670                         decodeplane8(row, s->planebuf, s->planesize, plane);
1671                     }
1672                 }
1673             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1674                 for (y = 0; y < avctx->height; y++) {
1675                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1676                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1677                     for (plane = 0; plane < s->bpp; plane++) {
1678                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1679                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1680                     }
1681                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1682                 }
1683             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1684                 uint8_t *video = s->video[0];
1685                 for (y = 0; y < avctx->height; y++) {
1686                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1687                     memset(s->ham_buf, 0, s->planesize * 8);
1688                     for (plane = 0; plane < s->bpp; plane++) {
1689                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1690                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1691                             memcpy(video, s->planebuf, s->planesize);
1692                             video += s->planesize;
1693                         }
1694                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1695                     }
1696                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1697                 }
1698             } else { // AV_PIX_FMT_BGR32
1699                 for (y = 0; y < avctx->height; y++) {
1700                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1701                     memset(row, 0, avctx->width << 2);
1702                     for (plane = 0; plane < s->bpp; plane++) {
1703                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1704                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1705                     }
1706                 }
1707             }
1708         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1709             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1710                 for (y = 0; y < avctx->height; y++) {
1711                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1712                     buf += decode_byterun(row, avctx->width, gb);
1713                 }
1714             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1715                 for (y = 0; y < avctx->height; y++) {
1716                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1717                     buf += decode_byterun(s->ham_buf, avctx->width, gb);
1718                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1719                 }
1720             } else
1721                 return unsupported(avctx);
1722         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1723             if (av_get_bits_per_pixel(desc) == 32)
1724                 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1725             else
1726                 return unsupported(avctx);
1727         } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1728             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1729                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1730                 for (plane = 0; plane < s->bpp; plane++) {
1731                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1732                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1733                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1734                         buf += s->planesize;
1735                     }
1736                 }
1737             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1738                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1739                 for (y = 0; y < avctx->height; y++) {
1740                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1741                     memset(s->ham_buf, 0, s->planesize * 8);
1742                     for (plane = 0; plane < s->bpp; plane++) {
1743                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1744                         if (start >= buf_end)
1745                             break;
1746                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1747                     }
1748                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1749                 }
1750             } else {
1751                 return unsupported(avctx);
1752             }
1753         } else {
1754             return unsupported(avctx);
1755         }
1756         break;
1757     case 0x2:
1758         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1759             for (plane = 0; plane < s->bpp; plane++) {
1760                 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1761                 for (y = 0; y < avctx->height; y++) {
1762                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1763                     decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1764                 }
1765             }
1766         } else {
1767             return unsupported(avctx);
1768         }
1769         break;
1770     case 0x4:
1771         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1772             decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1773         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1774             decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1775         else
1776             return unsupported(avctx);
1777         break;
1778     case 0x5:
1779         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1780             if (av_get_bits_per_pixel(desc) == 32)
1781                 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1782             else
1783                 return unsupported(avctx);
1784         } else
1785             return unsupported(avctx);
1786         break;
1787     case 0x300:
1788     case 0x301:
1789         decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1790         break;
1791     case 0x500:
1792     case 0x501:
1793         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1794         break;
1795     case 0x700:
1796     case 0x701:
1797         if (s->is_short)
1798             decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1799         else
1800             decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1801         break;
1802     case 0x800:
1803     case 0x801:
1804         if (s->is_short)
1805             decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1806         else
1807             decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1808         break;
1809     case 0x4a00:
1810     case 0x4a01:
1811         decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1812         break;
1813     case 0x6400:
1814     case 0x6401:
1815         if (s->is_interlaced)
1816             return unsupported(avctx);
1817         decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1818         break;
1819     case 0x6500:
1820     case 0x6501:
1821         if (s->is_interlaced)
1822             return unsupported(avctx);
1823         decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1824         break;
1825     case 0x6c00:
1826     case 0x6c01:
1827         decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1828         break;
1829     default:
1830         return unsupported(avctx);
1831     }
1832
1833     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1834         memcpy(s->video[1], s->video[0], s->video_size);
1835     }
1836
1837     if (s->compression > 0xff) {
1838         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1839             buf = s->video[0];
1840             for (y = 0; y < avctx->height; y++) {
1841                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1842                 memset(row, 0, avctx->width);
1843                 for (plane = 0; plane < s->bpp; plane++) {
1844                     decodeplane8(row, buf, s->planesize, plane);
1845                     buf += s->planesize;
1846                 }
1847             }
1848             memcpy(frame->data[1], s->pal, 256 * 4);
1849         } else if (s->ham) {
1850             int i, count = 1 << s->ham;
1851
1852             buf = s->video[0];
1853             memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1854             for (i = 0; i < count; i++) {
1855                 s->ham_palbuf[i*2+1] = s->pal[i];
1856             }
1857             for (i = 0; i < count; i++) {
1858                 uint32_t tmp = i << (8 - s->ham);
1859                 tmp |= tmp >> s->ham;
1860                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
1861                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
1862                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
1863                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
1864                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1865                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1866             }
1867             if (s->masking == MASK_HAS_MASK) {
1868                 for (i = 0; i < 8 * (1 << s->ham); i++)
1869                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1870             }
1871             for (y = 0; y < avctx->height; y++) {
1872                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1873                 memset(s->ham_buf, 0, s->planesize * 8);
1874                 for (plane = 0; plane < s->bpp; plane++) {
1875                     decodeplane8(s->ham_buf, buf, s->planesize, plane);
1876                     buf += s->planesize;
1877                 }
1878                 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1879             }
1880         } else {
1881             return unsupported(avctx);
1882         }
1883
1884         if (!s->is_brush) {
1885             FFSWAP(uint8_t *, s->video[0], s->video[1]);
1886         }
1887     }
1888
1889     if (avpkt->flags & AV_PKT_FLAG_KEY) {
1890         frame->key_frame = 1;
1891         frame->pict_type = AV_PICTURE_TYPE_I;
1892     } else {
1893         frame->key_frame = 0;
1894         frame->pict_type = AV_PICTURE_TYPE_P;
1895     }
1896
1897     *got_frame = 1;
1898
1899     return buf_size;
1900 }
1901
1902 #if CONFIG_IFF_ILBM_DECODER
1903 AVCodec ff_iff_ilbm_decoder = {
1904     .name           = "iff",
1905     .long_name      = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1906     .type           = AVMEDIA_TYPE_VIDEO,
1907     .id             = AV_CODEC_ID_IFF_ILBM,
1908     .priv_data_size = sizeof(IffContext),
1909     .init           = decode_init,
1910     .close          = decode_end,
1911     .decode         = decode_frame,
1912     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1913     .capabilities   = AV_CODEC_CAP_DR1,
1914 };
1915 #endif