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