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