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