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