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 "codec_internal.h"
36 #include "internal.h"
37 #include "mathops.h"
38 
39 // TODO: masking bits
40 typedef enum {
41     MASK_NONE,
42     MASK_HAS_MASK,
43     MASK_HAS_TRANSPARENT_COLOR,
44     MASK_LASSO
45 } mask_type;
46 
47 typedef struct IffContext {
48     AVFrame *frame;
49     int planesize;
50     uint8_t * planebuf;
51     uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
52     uint32_t *ham_palbuf;   ///< HAM decode table
53     uint32_t *mask_buf;     ///< temporary buffer for palette indices
54     uint32_t *mask_palbuf;  ///< masking palette table
55     unsigned  compression;  ///< delta compression method used
56     unsigned  is_short;     ///< short compression method used
57     unsigned  is_interlaced;///< video is interlaced
58     unsigned  is_brush;     ///< video is in ANBR format
59     unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
60     unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
61     unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
62     unsigned  transparency; ///< TODO: transparency color index in palette
63     unsigned  masking;      ///< TODO: masking method used
64     int init; // 1 if buffer and palette data already initialized, 0 otherwise
65     int16_t   tvdc[16];     ///< TVDC lookup table
66     GetByteContext gb;
67     uint8_t *video[2];
68     unsigned video_size;
69     uint32_t *pal;
70 } IffContext;
71 
72 #define LUT8_PART(plane, v)                             \
73     AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
74     AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
75     AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
76     AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
77     AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
78     AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
79     AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
80     AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
81     AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
82     AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
83     AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
84     AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
85     AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
86     AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
87     AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
88     AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
89 
90 #define LUT8(plane) {                           \
91     LUT8_PART(plane, 0x0000000),                \
92     LUT8_PART(plane, 0x1000000),                \
93     LUT8_PART(plane, 0x0010000),                \
94     LUT8_PART(plane, 0x1010000),                \
95     LUT8_PART(plane, 0x0000100),                \
96     LUT8_PART(plane, 0x1000100),                \
97     LUT8_PART(plane, 0x0010100),                \
98     LUT8_PART(plane, 0x1010100),                \
99     LUT8_PART(plane, 0x0000001),                \
100     LUT8_PART(plane, 0x1000001),                \
101     LUT8_PART(plane, 0x0010001),                \
102     LUT8_PART(plane, 0x1010001),                \
103     LUT8_PART(plane, 0x0000101),                \
104     LUT8_PART(plane, 0x1000101),                \
105     LUT8_PART(plane, 0x0010101),                \
106     LUT8_PART(plane, 0x1010101),                \
107 }
108 
109 // 8 planes * 8-bit mask
110 static const uint64_t plane8_lut[8][256] = {
111     LUT8(0), LUT8(1), LUT8(2), LUT8(3),
112     LUT8(4), LUT8(5), LUT8(6), LUT8(7),
113 };
114 
115 #define LUT32(plane) {                                    \
116               0,           0,           0,           0,   \
117               0,           0,           0, 1U << plane,   \
118               0,           0, 1U << plane,           0,   \
119               0,           0, 1U << plane, 1U << plane,   \
120               0, 1U << plane,           0,           0,   \
121               0, 1U << plane,           0, 1U << plane,   \
122               0, 1U << plane, 1U << plane,           0,   \
123               0, 1U << plane, 1U << plane, 1U << plane,   \
124     1U << plane,           0,           0,           0,   \
125     1U << plane,           0,           0, 1U << plane,   \
126     1U << plane,           0, 1U << plane,           0,   \
127     1U << plane,           0, 1U << plane, 1U << plane,   \
128     1U << plane, 1U << plane,           0,           0,   \
129     1U << plane, 1U << plane,           0, 1U << plane,   \
130     1U << plane, 1U << plane, 1U << plane,           0,   \
131     1U << plane, 1U << plane, 1U << plane, 1U << plane,   \
132 }
133 
134 // 32 planes * 4-bit mask * 4 lookup tables each
135 static const uint32_t plane32_lut[32][16*4] = {
136     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
137     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
138     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
139     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
140     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
141     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
142     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
143     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
144 };
145 
146 // Gray to RGB, required for palette table of grayscale images with bpp < 8
gray2rgb(const uint32_t x)147 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
148     return x << 16 | x << 8 | x;
149 }
150 
151 /**
152  * Convert CMAP buffer (stored in extradata) to lavc palette format
153  */
cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)154 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
155 {
156     IffContext *s = avctx->priv_data;
157     int count, i;
158     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
159     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
160 
161     if (avctx->bits_per_coded_sample > 8) {
162         av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
163         return AVERROR_INVALIDDATA;
164     }
165 
166     count = 1 << avctx->bits_per_coded_sample;
167     // If extradata is smaller than actually needed, fill the remaining with black.
168     count = FFMIN(palette_size / 3, count);
169     if (count) {
170         for (i = 0; i < count; i++)
171             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
172         if (s->flags && count >= 32) { // EHB
173             for (i = 0; i < 32; i++)
174                 pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
175             count = FFMAX(count, 64);
176         }
177     } else { // Create gray-scale color palette for bps < 8
178         count = 1 << avctx->bits_per_coded_sample;
179 
180         for (i = 0; i < count; i++)
181             pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
182     }
183     if (s->masking == MASK_HAS_MASK) {
184         if ((1 << avctx->bits_per_coded_sample) < count) {
185             avpriv_request_sample(avctx, "overlapping mask");
186             return AVERROR_PATCHWELCOME;
187         }
188         memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
189         for (i = 0; i < count; i++)
190             pal[i] &= 0xFFFFFF;
191     } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
192         s->transparency < 1 << avctx->bits_per_coded_sample)
193         pal[s->transparency] &= 0xFFFFFF;
194     return 0;
195 }
196 
197 /**
198  * Extracts the IFF extra context and updates internal
199  * decoder structures.
200  *
201  * @param avctx the AVCodecContext where to extract extra context to
202  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
203  * @return >= 0 in case of success, a negative error code otherwise
204  */
extract_header(AVCodecContext *const avctx, const AVPacket *const avpkt)205 static int extract_header(AVCodecContext *const avctx,
206                           const AVPacket *const avpkt)
207 {
208     IffContext *s = avctx->priv_data;
209     const uint8_t *buf;
210     unsigned buf_size = 0;
211     int i, palette_size;
212 
213     if (avctx->extradata_size < 2) {
214         av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
215         return AVERROR_INVALIDDATA;
216     }
217     palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
218 
219     if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
220         uint32_t chunk_id;
221         uint64_t data_size;
222         GetByteContext *gb = &s->gb;
223 
224         bytestream2_skip(gb, 4);
225         while (bytestream2_get_bytes_left(gb) >= 1) {
226             chunk_id  = bytestream2_get_le32(gb);
227             data_size = bytestream2_get_be32(gb);
228 
229             if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
230                 bytestream2_skip(gb, data_size + (data_size & 1));
231             } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
232                 unsigned extra;
233                 if (data_size < 40)
234                     return AVERROR_INVALIDDATA;
235 
236                 s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
237                 bytestream2_skip(gb, 19);
238                 extra = bytestream2_get_be32(gb);
239                 s->is_short = !(extra & 1);
240                 s->is_brush = extra == 2;
241                 s->is_interlaced = !!(extra & 0x40);
242                 data_size -= 24;
243                 bytestream2_skip(gb, data_size + (data_size & 1));
244             } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
245                        chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
246                 if (chunk_id == MKTAG('B','O','D','Y'))
247                     s->compression &= 0xFF;
248                 break;
249             } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
250                 int count = data_size / 3;
251                 uint32_t *pal = s->pal;
252 
253                 if (count > 256)
254                     return AVERROR_INVALIDDATA;
255                 if (s->ham) {
256                     for (i = 0; i < count; i++)
257                         pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
258                 } else {
259                     for (i = 0; i < count; i++)
260                         pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
261                 }
262                 bytestream2_skip(gb, data_size & 1);
263             } else {
264                 bytestream2_skip(gb, data_size + (data_size&1));
265             }
266         }
267     } else if (!avpkt) {
268         buf = avctx->extradata;
269         buf_size = bytestream_get_be16(&buf);
270         if (buf_size <= 1 || palette_size < 0) {
271             av_log(avctx, AV_LOG_ERROR,
272                    "Invalid palette size received: %u -> palette data offset: %d\n",
273                    buf_size, palette_size);
274             return AVERROR_INVALIDDATA;
275         }
276     }
277 
278     if (buf_size >= 41) {
279         s->compression  = bytestream_get_byte(&buf);
280         s->bpp          = bytestream_get_byte(&buf);
281         s->ham          = bytestream_get_byte(&buf);
282         s->flags        = bytestream_get_byte(&buf);
283         s->transparency = bytestream_get_be16(&buf);
284         s->masking      = bytestream_get_byte(&buf);
285         for (i = 0; i < 16; i++)
286             s->tvdc[i] = bytestream_get_be16(&buf);
287 
288         if (s->ham) {
289             if (s->bpp > 8) {
290                 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
291                 return AVERROR_INVALIDDATA;
292             } else if (s->ham != (s->bpp > 6 ? 6 : 4)) {
293                 av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
294                 return AVERROR_INVALIDDATA;
295             }
296         }
297 
298         if (s->masking == MASK_HAS_MASK) {
299             if (s->bpp >= 8 && !s->ham) {
300                 avctx->pix_fmt = AV_PIX_FMT_RGB32;
301                 av_freep(&s->mask_buf);
302                 av_freep(&s->mask_palbuf);
303                 if (s->bpp > 16) {
304                     av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
305                     return AVERROR(ENOMEM);
306                 }
307                 s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
308                 if (!s->mask_buf)
309                     return AVERROR(ENOMEM);
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 
decode_end(AVCodecContext *avctx)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 
decode_init(AVCodecContext *avctx)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  */
decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)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  */
decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)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  */
decode_ham_plane32(uint32_t *dst, const uint8_t *buf, const uint32_t *const pal, unsigned buf_size)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 
lookup_pal_indicies(uint32_t *dst, const uint32_t *buf, const uint32_t *const pal, unsigned width)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  */
decode_byterun(uint8_t *dst, int dst_size, GetByteContext *gb)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 
decode_byterun2(uint8_t *dst, int height, int line_size, GetByteContext *gb)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  */
decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)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  */
decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)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  */
decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)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  */
decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)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 
decode_short_horizontal_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)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 
decode_byte_vertical_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int xor, int bpp, int dst_size)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 
decode_delta_j(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int h, int bpp, int dst_size)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 
decode_short_vertical_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)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 
decode_long_vertical_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)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 
decode_short_vertical_delta2(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)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 
decode_long_vertical_delta2(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)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 
decode_delta_d(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int flag, int bpp, int dst_size)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 
decode_delta_e(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int flag, int bpp, int dst_size)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 
decode_delta_l(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int flag, int bpp, int dst_size)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     int count = 0;
1461 
1462     if (buf_end - buf <= 64)
1463         return;
1464 
1465     bytestream2_init(&off0, buf, buf_end - buf);
1466     bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1467     bytestream2_init_writer(&pb, dst, dst_size);
1468 
1469     dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1470 
1471     for (k = 0; k < bpp; k++) {
1472         poff0 = bytestream2_get_be32(&off0);
1473         poff1 = bytestream2_get_be32(&off1);
1474 
1475         if (!poff0)
1476             continue;
1477 
1478         if (2LL * poff0 >= buf_end - buf)
1479             return;
1480 
1481         if (2LL * poff1 >= buf_end - buf)
1482             return;
1483 
1484         bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1485         bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1486 
1487         while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1488             uint32_t offset = bytestream2_get_be16(&ogb);
1489             int16_t cnt = bytestream2_get_be16(&ogb);
1490             uint16_t data;
1491 
1492             if (count > dst_size)
1493                 break;
1494             offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1495             if (cnt < 0) {
1496                 if (bytestream2_get_bytes_left(&dgb) < 2)
1497                     break;
1498                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1499                 cnt = -cnt;
1500                 data = bytestream2_get_be16(&dgb);
1501                 count += cnt;
1502                 for (i = 0; i < cnt; i++) {
1503                     bytestream2_put_be16(&pb, data);
1504                     bytestream2_skip_p(&pb, dstpitch - 2);
1505                 }
1506             } else {
1507                 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1508                     break;
1509                 bytestream2_seek_p(&pb, offset, SEEK_SET);
1510                 count += cnt;
1511                 for (i = 0; i < cnt; i++) {
1512                     data = bytestream2_get_be16(&dgb);
1513                     bytestream2_put_be16(&pb, data);
1514                     bytestream2_skip_p(&pb, dstpitch - 2);
1515                 }
1516             }
1517         }
1518     }
1519 }
1520 
unsupported(AVCodecContext *avctx)1521 static int unsupported(AVCodecContext *avctx)
1522 {
1523     IffContext *s = avctx->priv_data;
1524     avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1525     return AVERROR_INVALIDDATA;
1526 }
1527 
decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *avpkt)1528 static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
1529                         int *got_frame, AVPacket *avpkt)
1530 {
1531     IffContext *s          = avctx->priv_data;
1532     const uint8_t *buf     = avpkt->data;
1533     int buf_size           = avpkt->size;
1534     const uint8_t *buf_end = buf + buf_size;
1535     int y, plane, res;
1536     GetByteContext *gb = &s->gb;
1537     const AVPixFmtDescriptor *desc;
1538 
1539     bytestream2_init(gb, avpkt->data, avpkt->size);
1540 
1541     if ((res = extract_header(avctx, avpkt)) < 0)
1542         return res;
1543 
1544     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1545         return res;
1546     s->frame = frame;
1547 
1548     buf      += bytestream2_tell(gb);
1549     buf_size -= bytestream2_tell(gb);
1550     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1551 
1552     if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1553         avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1554         if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1555             return res;
1556     } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1557                avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1558         if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1559             return res;
1560     }
1561     s->init = 1;
1562 
1563     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1564         if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1565             memcpy(s->pal, s->frame->data[1], 256 * 4);
1566     }
1567 
1568     switch (s->compression) {
1569     case 0x0:
1570         if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1571             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1572                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1573                 for (plane = 0; plane < s->bpp; plane++) {
1574                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1575                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1576                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1577                         buf += s->planesize;
1578                     }
1579                 }
1580             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1581                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1582                 for (y = 0; y < avctx->height; y++) {
1583                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1584                     memset(s->ham_buf, 0, s->planesize * 8);
1585                     for (plane = 0; plane < s->bpp; plane++) {
1586                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1587                         if (start >= buf_end)
1588                             break;
1589                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1590                     }
1591                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1592                 }
1593             } else
1594                 return unsupported(avctx);
1595         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1596             int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1597             int x;
1598             for (y = 0; y < avctx->height && buf < buf_end; y++) {
1599                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1600                 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1601                 buf += raw_width;
1602                 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1603                     for (x = 0; x < avctx->width; x++)
1604                         row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1605                 }
1606             }
1607         } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1608                    avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1609             if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1610                 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1611             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1612                 for (y = 0; y < avctx->height; y++) {
1613                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1614                     memset(row, 0, avctx->width);
1615                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1616                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1617                         buf += s->planesize;
1618                     }
1619                 }
1620             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1621                 for (y = 0; y < avctx->height; y++) {
1622                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1623                     memset(s->ham_buf, 0, s->planesize * 8);
1624                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1625                         decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1626                         buf += s->planesize;
1627                     }
1628                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1629                 }
1630             } else { // AV_PIX_FMT_BGR32
1631                 for (y = 0; y < avctx->height; y++) {
1632                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1633                     memset(row, 0, avctx->width << 2);
1634                     for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1635                         decodeplane32((uint32_t *)row, buf,
1636                                       FFMIN(s->planesize, buf_end - buf), plane);
1637                         buf += s->planesize;
1638                     }
1639                 }
1640             }
1641         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1642             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1643                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1644                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1645                     memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1646                     buf += avctx->width + (avctx->width % 2); // padding if odd
1647                 }
1648             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1649                 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1650                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1651                     memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1652                     buf += avctx->width + (avctx->width & 1); // padding if odd
1653                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1654                 }
1655             } else
1656                 return unsupported(avctx);
1657         } else {
1658             return unsupported(avctx);
1659         }
1660         break;
1661     case 0x1:
1662         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1663             avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1664             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1665                 uint8_t *video = s->video[0];
1666 
1667                 for (y = 0; y < avctx->height; y++) {
1668                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1669                     memset(row, 0, avctx->width);
1670                     for (plane = 0; plane < s->bpp; plane++) {
1671                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1672                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1673                             memcpy(video, s->planebuf, s->planesize);
1674                             video += s->planesize;
1675                         }
1676                         decodeplane8(row, s->planebuf, s->planesize, plane);
1677                     }
1678                 }
1679             } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1680                 for (y = 0; y < avctx->height; y++) {
1681                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1682                     memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1683                     for (plane = 0; plane < s->bpp; plane++) {
1684                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1685                         decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1686                     }
1687                     lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1688                 }
1689             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1690                 uint8_t *video = s->video[0];
1691                 for (y = 0; y < avctx->height; y++) {
1692                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1693                     memset(s->ham_buf, 0, s->planesize * 8);
1694                     for (plane = 0; plane < s->bpp; plane++) {
1695                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1696                         if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1697                             memcpy(video, s->planebuf, s->planesize);
1698                             video += s->planesize;
1699                         }
1700                         decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1701                     }
1702                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1703                 }
1704             } else { // AV_PIX_FMT_BGR32
1705                 for (y = 0; y < avctx->height; y++) {
1706                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1707                     memset(row, 0, avctx->width << 2);
1708                     for (plane = 0; plane < s->bpp; plane++) {
1709                         buf += decode_byterun(s->planebuf, s->planesize, gb);
1710                         decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1711                     }
1712                 }
1713             }
1714         } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1715             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1716                 for (y = 0; y < avctx->height; y++) {
1717                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1718                     buf += decode_byterun(row, avctx->width, gb);
1719                 }
1720             } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1721                 for (y = 0; y < avctx->height; y++) {
1722                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1723                     buf += decode_byterun(s->ham_buf, avctx->width, gb);
1724                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1725                 }
1726             } else
1727                 return unsupported(avctx);
1728         } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1729             if (av_get_bits_per_pixel(desc) == 32)
1730                 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1731             else
1732                 return unsupported(avctx);
1733         } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1734             if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1735                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1736                 for (plane = 0; plane < s->bpp; plane++) {
1737                     for (y = 0; y < avctx->height && buf < buf_end; y++) {
1738                         uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1739                         decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1740                         buf += s->planesize;
1741                     }
1742                 }
1743             } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1744                 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1745                 for (y = 0; y < avctx->height; y++) {
1746                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1747                     memset(s->ham_buf, 0, s->planesize * 8);
1748                     for (plane = 0; plane < s->bpp; plane++) {
1749                         const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1750                         if (start >= buf_end)
1751                             break;
1752                         decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1753                     }
1754                     decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1755                 }
1756             } else {
1757                 return unsupported(avctx);
1758             }
1759         } else {
1760             return unsupported(avctx);
1761         }
1762         break;
1763     case 0x2:
1764         if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1765             for (plane = 0; plane < s->bpp; plane++) {
1766                 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1767                 for (y = 0; y < avctx->height; y++) {
1768                     uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1769                     decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1770                 }
1771             }
1772         } else {
1773             return unsupported(avctx);
1774         }
1775         break;
1776     case 0x4:
1777         if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1778             decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1779         else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1780             decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1781         else
1782             return unsupported(avctx);
1783         break;
1784     case 0x5:
1785         if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1786             if (av_get_bits_per_pixel(desc) == 32)
1787                 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1788             else
1789                 return unsupported(avctx);
1790         } else
1791             return unsupported(avctx);
1792         break;
1793     case 0x300:
1794     case 0x301:
1795         decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1796         break;
1797     case 0x500:
1798     case 0x501:
1799         decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1800         break;
1801     case 0x700:
1802     case 0x701:
1803         if (s->is_short)
1804             decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1805         else
1806             decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1807         break;
1808     case 0x800:
1809     case 0x801:
1810         if (s->is_short)
1811             decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1812         else
1813             decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1814         break;
1815     case 0x4a00:
1816     case 0x4a01:
1817         decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1818         break;
1819     case 0x6400:
1820     case 0x6401:
1821         if (s->is_interlaced)
1822             return unsupported(avctx);
1823         decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1824         break;
1825     case 0x6500:
1826     case 0x6501:
1827         if (s->is_interlaced)
1828             return unsupported(avctx);
1829         decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1830         break;
1831     case 0x6c00:
1832     case 0x6c01:
1833         decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1834         break;
1835     default:
1836         return unsupported(avctx);
1837     }
1838 
1839     if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1840         memcpy(s->video[1], s->video[0], s->video_size);
1841     }
1842 
1843     if (s->compression > 0xff) {
1844         if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1845             buf = s->video[0];
1846             for (y = 0; y < avctx->height; y++) {
1847                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1848                 memset(row, 0, avctx->width);
1849                 for (plane = 0; plane < s->bpp; plane++) {
1850                     decodeplane8(row, buf, s->planesize, plane);
1851                     buf += s->planesize;
1852                 }
1853             }
1854             if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1855                 memcpy(frame->data[1], s->pal, 256 * 4);
1856         } else if (s->ham) {
1857             int i, count = 1 << s->ham;
1858 
1859             buf = s->video[0];
1860             memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1861             for (i = 0; i < count; i++) {
1862                 s->ham_palbuf[i*2+1] = s->pal[i];
1863             }
1864             for (i = 0; i < count; i++) {
1865                 uint32_t tmp = i << (8 - s->ham);
1866                 tmp |= tmp >> s->ham;
1867                 s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
1868                 s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
1869                 s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
1870                 s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
1871                 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1872                 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1873             }
1874             if (s->masking == MASK_HAS_MASK) {
1875                 for (i = 0; i < 8 * (1 << s->ham); i++)
1876                     s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1877             }
1878             for (y = 0; y < avctx->height; y++) {
1879                 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1880                 memset(s->ham_buf, 0, s->planesize * 8);
1881                 for (plane = 0; plane < s->bpp; plane++) {
1882                     decodeplane8(s->ham_buf, buf, s->planesize, plane);
1883                     buf += s->planesize;
1884                 }
1885                 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1886             }
1887         } else {
1888             return unsupported(avctx);
1889         }
1890 
1891         if (!s->is_brush) {
1892             FFSWAP(uint8_t *, s->video[0], s->video[1]);
1893         }
1894     }
1895 
1896     if (avpkt->flags & AV_PKT_FLAG_KEY) {
1897         frame->key_frame = 1;
1898         frame->pict_type = AV_PICTURE_TYPE_I;
1899     } else {
1900         frame->key_frame = 0;
1901         frame->pict_type = AV_PICTURE_TYPE_P;
1902     }
1903 
1904     *got_frame = 1;
1905 
1906     return buf_size;
1907 }
1908 
1909 const FFCodec ff_iff_ilbm_decoder = {
1910     .p.name         = "iff",
1911     .p.long_name    = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1912     .p.type         = AVMEDIA_TYPE_VIDEO,
1913     .p.id           = AV_CODEC_ID_IFF_ILBM,
1914     .priv_data_size = sizeof(IffContext),
1915     .init           = decode_init,
1916     .close          = decode_end,
1917     FF_CODEC_DECODE_CB(decode_frame),
1918     .p.capabilities = AV_CODEC_CAP_DR1,
1919     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1920 };
1921