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