FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/iff.c
Date: 2021-09-23 20:34:37
Exec Total Coverage
Lines: 137 1083 12.7%
Branches: 78 820 9.5%

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