]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
avcodec/iff: Check length before memcpy() 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                 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                 opcode = -opcode;
1382                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1383                     bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1384                     bytestream2_skip_p(&pb, pitch - 4);
1385                     opcode--;
1386                 }
1387             }
1388             entries--;
1389         }
1390     }
1391 }
1392
1393 static void decode_delta_e(uint8_t *dst,
1394                            const uint8_t *buf, const uint8_t *buf_end,
1395                            int w, int flag, int bpp, int dst_size)
1396 {
1397     int planepitch = FFALIGN(w, 16) >> 3;
1398     int pitch = planepitch * bpp;
1399     int planepitch_byte = (w + 7) / 8;
1400     unsigned entries, ofssrc;
1401     GetByteContext gb, ptrs;
1402     PutByteContext pb;
1403     int k;
1404
1405     if (buf_end - buf <= 4 * bpp)
1406         return;
1407
1408     bytestream2_init_writer(&pb, dst, dst_size);
1409     bytestream2_init(&ptrs, buf, bpp * 4);
1410
1411     for (k = 0; k < bpp; k++) {
1412         ofssrc = bytestream2_get_be32(&ptrs);
1413
1414         if (!ofssrc)
1415             continue;
1416
1417         if (ofssrc >= buf_end - buf)
1418             continue;
1419
1420         bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1421
1422         entries = bytestream2_get_be16(&gb);
1423         while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1424             int16_t opcode  = bytestream2_get_be16(&gb);
1425             unsigned offset = bytestream2_get_be32(&gb);
1426
1427             bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1428             if (opcode >= 0) {
1429                 uint16_t x = bytestream2_get_be16(&gb);
1430                 while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1431                     bytestream2_put_be16(&pb, x);
1432                     bytestream2_skip_p(&pb, pitch - 2);
1433                     opcode--;
1434                 }
1435             } else {
1436                 opcode = -opcode;
1437                 while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1438                     bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1439                     bytestream2_skip_p(&pb, pitch - 2);
1440                     opcode--;
1441                 }
1442             }
1443             entries--;
1444         }
1445     }
1446 }
1447
1448 static void decode_delta_l(uint8_t *dst,
1449                            const uint8_t *buf, const uint8_t *buf_end,
1450                            int w, int flag, int bpp, int dst_size)
1451 {
1452     GetByteContext off0, off1, dgb, ogb;
1453     PutByteContext pb;
1454     unsigned poff0, poff1;
1455     int i, k, dstpitch;
1456     int planepitch_byte = (w + 7) / 8;
1457     int planepitch = ((w + 15) / 16) * 2;
1458     int pitch = planepitch * bpp;
1459
1460     if (buf_end - buf <= 64)
1461         return;
1462
1463     bytestream2_init(&off0, buf, buf_end - buf);
1464     bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1465     bytestream2_init_writer(&pb, dst, dst_size);
1466
1467     dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1468
1469     for (k = 0; k < bpp; k++) {
1470         poff0 = bytestream2_get_be32(&off0);
1471         poff1 = bytestream2_get_be32(&off1);
1472
1473         if (!poff0)
1474             continue;
1475
1476         if (2LL * poff0 >= buf_end - buf)
1477             return;
1478
1479         if (2LL * poff1 >= buf_end - buf)
1480             return;
1481
1482         bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1483         bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1484
1485         while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1486             uint32_t offset = bytestream2_get_be16(&ogb);
1487             int16_t cnt = bytestream2_get_be16(&ogb);
1488             uint16_t data;
1489
1490             offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1491             if (cnt < 0) {
1492                 if (bytestream2_get_bytes_left(&dgb) < 2)
1493                     break;
1494                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1495                 cnt = -cnt;
1496                 data = bytestream2_get_be16(&dgb);
1497                 for (i = 0; i < cnt; i++) {
1498                     bytestream2_put_be16(&pb, data);
1499                     bytestream2_skip_p(&pb, dstpitch - 2);
1500                 }
1501             } else {
1502                 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1503                     break;
1504                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1505                 for (i = 0; i < cnt; i++) {
1506                     data = bytestream2_get_be16(&dgb);
1507                     bytestream2_put_be16(&pb, data);
1508                     bytestream2_skip_p(&pb, dstpitch - 2);
1509                 }
1510             }
1511         }
1512     }
1513 }
1514
1515 static int unsupported(AVCodecContext *avctx)
1516 {
1517     IffContext *s = avctx->priv_data;
1518     avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1519     return AVERROR_INVALIDDATA;
1520 }
1521
1522 static int decode_frame(AVCodecContext *avctx,
1523                         void *data, int *got_frame,
1524                         AVPacket *avpkt)
1525 {
1526     IffContext *s          = avctx->priv_data;
1527     AVFrame *frame         = data;
1528     const uint8_t *buf     = avpkt->data;
1529     int buf_size           = avpkt->size;
1530     const uint8_t *buf_end = buf + buf_size;
1531     int y, plane, res;
1532     GetByteContext *gb = &s->gb;
1533     const AVPixFmtDescriptor *desc;
1534
1535     bytestream2_init(gb, avpkt->data, avpkt->size);
1536
1537     if ((res = extract_header(avctx, avpkt)) < 0)
1538         return res;
1539
1540     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1541         return res;
1542     s->frame = frame;
1543
1544     buf      += bytestream2_tell(gb);
1545     buf_size -= bytestream2_tell(gb);
1546     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1547
1548     if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1549         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1550         if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1551             return res;
1552     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1553                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1554         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1555             return res;
1556     }
1557     s->init = 1;
1558
1559     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1560         if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1561             memcpy(s->pal, s->frame->data[1], 256 * 4);
1562     }
1563
1564     switch (s->compression) {
1565     case 0x0:
1566         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1567             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1568                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1569                 for (plane = 0; plane < s->bpp; plane++) {
1570                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1571                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1572                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1573                         buf += s->planesize;
1574                     }
1575                 }
1576             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1577                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1578                 for (y = 0; y < avctx->height; y++) {
1579                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1580                     memset(s->ham_buf, 0, s->planesize * 8);
1581                     for (plane = 0; plane < s->bpp; plane++) {
1582                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1583                         if (start >= buf_end)
1584                             break;
1585                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1586                     }
1587                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1588                 }
1589             } else
1590                 return unsupported(avctx);
1591         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1592             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1593             int x;
1594             for (y = 0; y < avctx->height && buf < buf_end; y++) {
1595                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1596                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1597                 buf += raw_width;
1598                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1599                     for (x = 0; x < avctx->width; x++)
1600                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1601                 }
1602             }
1603         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1604                    avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1605             if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1606                 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1607             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1608                 for (y = 0; y < avctx->height; y++) {
1609                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1610                     memset(row, 0, avctx->width);
1611                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1612                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1613                         buf += s->planesize;
1614                     }
1615                 }
1616             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1617                 for (y = 0; y < avctx->height; y++) {
1618                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1619                     memset(s->ham_buf, 0, s->planesize * 8);
1620                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1621                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1622                         buf += s->planesize;
1623                     }
1624                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1625                 }
1626             } else { // AV_PIX_FMT_BGR32
1627                 for (y = 0; y < avctx->height; y++) {
1628                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1629                     memset(row, 0, avctx->width << 2);
1630                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1631                         decodeplane32((uint32_t *)row, buf,
1632                                       FFMIN(s->planesize, buf_end - buf), plane);
1633                         buf += s->planesize;
1634                     }
1635                 }
1636             }
1637         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1638             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1639                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1640                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1641                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1642                     buf += avctx->width + (avctx->width % 2); // padding if odd
1643                 }
1644             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1645                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1646                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1647                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1648                     buf += avctx->width + (avctx->width & 1); // padding if odd
1649                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1650                 }
1651             } else
1652                 return unsupported(avctx);
1653         } else {
1654             return unsupported(avctx);
1655         }
1656         break;
1657     case 0x1:
1658         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1659             avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1660             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1661                 uint8_t *video = s->video[0];
1662
1663                 for (y = 0; y < avctx->height; y++) {
1664                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1665                     memset(row, 0, avctx->width);
1666                     for (plane = 0; plane < s->bpp; plane++) {
1667                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1668                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1669                             memcpy(video, s->planebuf, s->planesize);
1670                             video += s->planesize;
1671                         }
1672                         decodeplane8(row, s->planebuf, s->planesize, plane);
1673                     }
1674                 }
1675             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1676                 for (y = 0; y < avctx->height; y++) {
1677                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1678                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1679                     for (plane = 0; plane < s->bpp; plane++) {
1680                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1681                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1682                     }
1683                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1684                 }
1685             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1686                 uint8_t *video = s->video[0];
1687                 for (y = 0; y < avctx->height; y++) {
1688                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1689                     memset(s->ham_buf, 0, s->planesize * 8);
1690                     for (plane = 0; plane < s->bpp; plane++) {
1691                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1692                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1693                             memcpy(video, s->planebuf, s->planesize);
1694                             video += s->planesize;
1695                         }
1696                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1697                     }
1698                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1699                 }
1700             } else { // AV_PIX_FMT_BGR32
1701                 for (y = 0; y < avctx->height; y++) {
1702                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1703                     memset(row, 0, avctx->width << 2);
1704                     for (plane = 0; plane < s->bpp; plane++) {
1705                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1706                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1707                     }
1708                 }
1709             }
1710         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1711             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1712                 for (y = 0; y < avctx->height; y++) {
1713                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1714                     buf += decode_byterun(row, avctx->width, gb);
1715                 }
1716             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1717                 for (y = 0; y < avctx->height; y++) {
1718                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1719                     buf += decode_byterun(s->ham_buf, avctx->width, gb);
1720                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1721                 }
1722             } else
1723                 return unsupported(avctx);
1724         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1725             if (av_get_bits_per_pixel(desc) == 32)
1726                 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1727             else
1728                 return unsupported(avctx);
1729         } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1730             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1731                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1732                 for (plane = 0; plane < s->bpp; plane++) {
1733                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1734                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1735                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1736                         buf += s->planesize;
1737                     }
1738                 }
1739             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1740                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1741                 for (y = 0; y < avctx->height; y++) {
1742                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1743                     memset(s->ham_buf, 0, s->planesize * 8);
1744                     for (plane = 0; plane < s->bpp; plane++) {
1745                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1746                         if (start >= buf_end)
1747                             break;
1748                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1749                     }
1750                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1751                 }
1752             } else {
1753                 return unsupported(avctx);
1754             }
1755         } else {
1756             return unsupported(avctx);
1757         }
1758         break;
1759     case 0x2:
1760         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1761             for (plane = 0; plane < s->bpp; plane++) {
1762                 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1763                 for (y = 0; y < avctx->height; y++) {
1764                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1765                     decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1766                 }
1767             }
1768         } else {
1769             return unsupported(avctx);
1770         }
1771         break;
1772     case 0x4:
1773         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1774             decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1775         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1776             decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1777         else
1778             return unsupported(avctx);
1779         break;
1780     case 0x5:
1781         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1782             if (av_get_bits_per_pixel(desc) == 32)
1783                 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1784             else
1785                 return unsupported(avctx);
1786         } else
1787             return unsupported(avctx);
1788         break;
1789     case 0x300:
1790     case 0x301:
1791         decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1792         break;
1793     case 0x500:
1794     case 0x501:
1795         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1796         break;
1797     case 0x700:
1798     case 0x701:
1799         if (s->is_short)
1800             decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1801         else
1802             decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1803         break;
1804     case 0x800:
1805     case 0x801:
1806         if (s->is_short)
1807             decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1808         else
1809             decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1810         break;
1811     case 0x4a00:
1812     case 0x4a01:
1813         decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1814         break;
1815     case 0x6400:
1816     case 0x6401:
1817         if (s->is_interlaced)
1818             return unsupported(avctx);
1819         decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1820         break;
1821     case 0x6500:
1822     case 0x6501:
1823         if (s->is_interlaced)
1824             return unsupported(avctx);
1825         decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1826         break;
1827     case 0x6c00:
1828     case 0x6c01:
1829         decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1830         break;
1831     default:
1832         return unsupported(avctx);
1833     }
1834
1835     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1836         memcpy(s->video[1], s->video[0], s->video_size);
1837     }
1838
1839     if (s->compression > 0xff) {
1840         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1841             buf = s->video[0];
1842             for (y = 0; y < avctx->height; y++) {
1843                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1844                 memset(row, 0, avctx->width);
1845                 for (plane = 0; plane < s->bpp; plane++) {
1846                     decodeplane8(row, buf, s->planesize, plane);
1847                     buf += s->planesize;
1848                 }
1849             }
1850             memcpy(frame->data[1], s->pal, 256 * 4);
1851         } else if (s->ham) {
1852             int i, count = 1 << s->ham;
1853
1854             buf = s->video[0];
1855             memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1856             for (i = 0; i < count; i++) {
1857                 s->ham_palbuf[i*2+1] = s->pal[i];
1858             }
1859             for (i = 0; i < count; i++) {
1860                 uint32_t tmp = i << (8 - s->ham);
1861                 tmp |= tmp >> s->ham;
1862                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
1863                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
1864                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
1865                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
1866                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1867                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1868             }
1869             if (s->masking == MASK_HAS_MASK) {
1870                 for (i = 0; i < 8 * (1 << s->ham); i++)
1871                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1872             }
1873             for (y = 0; y < avctx->height; y++) {
1874                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1875                 memset(s->ham_buf, 0, s->planesize * 8);
1876                 for (plane = 0; plane < s->bpp; plane++) {
1877                     decodeplane8(s->ham_buf, buf, s->planesize, plane);
1878                     buf += s->planesize;
1879                 }
1880                 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1881             }
1882         } else {
1883             return unsupported(avctx);
1884         }
1885
1886         if (!s->is_brush) {
1887             FFSWAP(uint8_t *, s->video[0], s->video[1]);
1888         }
1889     }
1890
1891     if (avpkt->flags & AV_PKT_FLAG_KEY) {
1892         frame->key_frame = 1;
1893         frame->pict_type = AV_PICTURE_TYPE_I;
1894     } else {
1895         frame->key_frame = 0;
1896         frame->pict_type = AV_PICTURE_TYPE_P;
1897     }
1898
1899     *got_frame = 1;
1900
1901     return buf_size;
1902 }
1903
1904 #if CONFIG_IFF_ILBM_DECODER
1905 AVCodec ff_iff_ilbm_decoder = {
1906     .name           = "iff",
1907     .long_name      = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1908     .type           = AVMEDIA_TYPE_VIDEO,
1909     .id             = AV_CODEC_ID_IFF_ILBM,
1910     .priv_data_size = sizeof(IffContext),
1911     .init           = decode_init,
1912     .close          = decode_end,
1913     .decode         = decode_frame,
1914     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1915     .capabilities   = AV_CODEC_CAP_DR1,
1916 };
1917 #endif