FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/iff.c
Date: 2022-01-23 21:51:25
Exec Total Coverage
Lines: 137 1088 12.6%
Branches: 78 822 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 int count = 0;
1460
1461 if (buf_end - buf <= 64)
1462 return;
1463
1464 bytestream2_init(&off0, buf, buf_end - buf);
1465 bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1466 bytestream2_init_writer(&pb, dst, dst_size);
1467
1468 dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1469
1470 for (k = 0; k < bpp; k++) {
1471 poff0 = bytestream2_get_be32(&off0);
1472 poff1 = bytestream2_get_be32(&off1);
1473
1474 if (!poff0)
1475 continue;
1476
1477 if (2LL * poff0 >= buf_end - buf)
1478 return;
1479
1480 if (2LL * poff1 >= buf_end - buf)
1481 return;
1482
1483 bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1484 bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1485
1486 while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1487 uint32_t offset = bytestream2_get_be16(&ogb);
1488 int16_t cnt = bytestream2_get_be16(&ogb);
1489 uint16_t data;
1490
1491 if (count > dst_size)
1492 break;
1493 offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1494 if (cnt < 0) {
1495 if (bytestream2_get_bytes_left(&dgb) < 2)
1496 break;
1497 bytestream2_seek_p(&pb, offset, SEEK_SET);
1498 cnt = -cnt;
1499 data = bytestream2_get_be16(&dgb);
1500 count += cnt;
1501 for (i = 0; i < cnt; i++) {
1502 bytestream2_put_be16(&pb, data);
1503 bytestream2_skip_p(&pb, dstpitch - 2);
1504 }
1505 } else {
1506 if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1507 break;
1508 bytestream2_seek_p(&pb, offset, SEEK_SET);
1509 count += cnt;
1510 for (i = 0; i < cnt; i++) {
1511 data = bytestream2_get_be16(&dgb);
1512 bytestream2_put_be16(&pb, data);
1513 bytestream2_skip_p(&pb, dstpitch - 2);
1514 }
1515 }
1516 }
1517 }
1518 }
1519
1520 static int unsupported(AVCodecContext *avctx)
1521 {
1522 IffContext *s = avctx->priv_data;
1523 avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1524 return AVERROR_INVALIDDATA;
1525 }
1526
1527 2 static int decode_frame(AVCodecContext *avctx,
1528 void *data, int *got_frame,
1529 AVPacket *avpkt)
1530 {
1531 2 IffContext *s = avctx->priv_data;
1532 2 AVFrame *frame = data;
1533 2 const uint8_t *buf = avpkt->data;
1534 2 int buf_size = avpkt->size;
1535 2 const uint8_t *buf_end = buf + buf_size;
1536 int y, plane, res;
1537 2 GetByteContext *gb = &s->gb;
1538 const AVPixFmtDescriptor *desc;
1539
1540 2 bytestream2_init(gb, avpkt->data, avpkt->size);
1541
1542
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((res = extract_header(avctx, avpkt)) < 0)
1543 return res;
1544
1545
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1546 return res;
1547 2 s->frame = frame;
1548
1549 2 buf += bytestream2_tell(gb);
1550 2 buf_size -= bytestream2_tell(gb);
1551 2 desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1552
1553
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) &&
1554
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1555
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1556 return res;
1557 } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1558 avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1559 if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1560 return res;
1561 }
1562 2 s->init = 1;
1563
1564
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'))) {
1565 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1566 memcpy(s->pal, s->frame->data[1], 256 * 4);
1567 }
1568
1569
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) {
1570 1 case 0x0:
1571
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1572 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1573 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1574 for (plane = 0; plane < s->bpp; plane++) {
1575 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1576 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1577 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1578 buf += s->planesize;
1579 }
1580 }
1581 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1582 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1583 for (y = 0; y < avctx->height; y++) {
1584 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1585 memset(s->ham_buf, 0, s->planesize * 8);
1586 for (plane = 0; plane < s->bpp; plane++) {
1587 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1588 if (start >= buf_end)
1589 break;
1590 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1591 }
1592 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1593 }
1594 } else
1595 return unsupported(avctx);
1596
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1597 int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1598 int x;
1599 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1600 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1601 memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1602 buf += raw_width;
1603 if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1604 for (x = 0; x < avctx->width; x++)
1605 row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1606 }
1607 }
1608
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1609 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1611 memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1612
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) {
1613
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 1 times.
241 for (y = 0; y < avctx->height; y++) {
1614 240 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1615 240 memset(row, 0, avctx->width);
1616
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++) {
1617 1920 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1618 1920 buf += s->planesize;
1619 }
1620 }
1621 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1622 for (y = 0; y < avctx->height; y++) {
1623 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1624 memset(s->ham_buf, 0, s->planesize * 8);
1625 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1626 decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1627 buf += s->planesize;
1628 }
1629 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1630 }
1631 } else { // AV_PIX_FMT_BGR32
1632 for (y = 0; y < avctx->height; y++) {
1633 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1634 memset(row, 0, avctx->width << 2);
1635 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1636 decodeplane32((uint32_t *)row, buf,
1637 FFMIN(s->planesize, buf_end - buf), plane);
1638 buf += s->planesize;
1639 }
1640 }
1641 }
1642 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1643 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1644 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1645 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1646 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1647 buf += avctx->width + (avctx->width % 2); // padding if odd
1648 }
1649 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1650 for (y = 0; y < avctx->height && buf_end > buf; y++) {
1651 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1652 memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1653 buf += avctx->width + (avctx->width & 1); // padding if odd
1654 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1655 }
1656 } else
1657 return unsupported(avctx);
1658 } else {
1659 return unsupported(avctx);
1660 }
1661 1 break;
1662 1 case 0x1:
1663
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1665 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1666 uint8_t *video = s->video[0];
1667
1668 for (y = 0; y < avctx->height; y++) {
1669 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1670 memset(row, 0, avctx->width);
1671 for (plane = 0; plane < s->bpp; plane++) {
1672 buf += decode_byterun(s->planebuf, s->planesize, gb);
1673 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1674 memcpy(video, s->planebuf, s->planesize);
1675 video += s->planesize;
1676 }
1677 decodeplane8(row, s->planebuf, s->planesize, plane);
1678 }
1679 }
1680 } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1681 for (y = 0; y < avctx->height; y++) {
1682 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1683 memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1684 for (plane = 0; plane < s->bpp; plane++) {
1685 buf += decode_byterun(s->planebuf, s->planesize, gb);
1686 decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1687 }
1688 lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1689 }
1690 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1691 uint8_t *video = s->video[0];
1692 for (y = 0; y < avctx->height; y++) {
1693 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1694 memset(s->ham_buf, 0, s->planesize * 8);
1695 for (plane = 0; plane < s->bpp; plane++) {
1696 buf += decode_byterun(s->planebuf, s->planesize, gb);
1697 if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1698 memcpy(video, s->planebuf, s->planesize);
1699 video += s->planesize;
1700 }
1701 decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1702 }
1703 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1704 }
1705 } else { // AV_PIX_FMT_BGR32
1706 for (y = 0; y < avctx->height; y++) {
1707 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1708 memset(row, 0, avctx->width << 2);
1709 for (plane = 0; plane < s->bpp; plane++) {
1710 buf += decode_byterun(s->planebuf, s->planesize, gb);
1711 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1712 }
1713 }
1714 }
1715
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1716
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) {
1717
2/2
✓ Branch 0 taken 240 times.
✓ Branch 1 taken 1 times.
241 for (y = 0; y < avctx->height; y++) {
1718 240 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1719 240 buf += decode_byterun(row, avctx->width, gb);
1720 }
1721 } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1722 for (y = 0; y < avctx->height; y++) {
1723 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1724 buf += decode_byterun(s->ham_buf, avctx->width, gb);
1725 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1726 }
1727 } else
1728 return unsupported(avctx);
1729 } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1730 if (av_get_bits_per_pixel(desc) == 32)
1731 decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1732 else
1733 return unsupported(avctx);
1734 } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1735 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1736 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1737 for (plane = 0; plane < s->bpp; plane++) {
1738 for (y = 0; y < avctx->height && buf < buf_end; y++) {
1739 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1740 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1741 buf += s->planesize;
1742 }
1743 }
1744 } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1745 memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1746 for (y = 0; y < avctx->height; y++) {
1747 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1748 memset(s->ham_buf, 0, s->planesize * 8);
1749 for (plane = 0; plane < s->bpp; plane++) {
1750 const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1751 if (start >= buf_end)
1752 break;
1753 decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1754 }
1755 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1756 }
1757 } else {
1758 return unsupported(avctx);
1759 }
1760 } else {
1761 return unsupported(avctx);
1762 }
1763 1 break;
1764 case 0x2:
1765 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1766 for (plane = 0; plane < s->bpp; plane++) {
1767 decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1768 for (y = 0; y < avctx->height; y++) {
1769 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1770 decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1771 }
1772 }
1773 } else {
1774 return unsupported(avctx);
1775 }
1776 break;
1777 case 0x4:
1778 if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1779 decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1780 else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1781 decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1782 else
1783 return unsupported(avctx);
1784 break;
1785 case 0x5:
1786 if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1787 if (av_get_bits_per_pixel(desc) == 32)
1788 decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1789 else
1790 return unsupported(avctx);
1791 } else
1792 return unsupported(avctx);
1793 break;
1794 case 0x300:
1795 case 0x301:
1796 decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1797 break;
1798 case 0x500:
1799 case 0x501:
1800 decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1801 break;
1802 case 0x700:
1803 case 0x701:
1804 if (s->is_short)
1805 decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1806 else
1807 decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1808 break;
1809 case 0x800:
1810 case 0x801:
1811 if (s->is_short)
1812 decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1813 else
1814 decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1815 break;
1816 case 0x4a00:
1817 case 0x4a01:
1818 decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1819 break;
1820 case 0x6400:
1821 case 0x6401:
1822 if (s->is_interlaced)
1823 return unsupported(avctx);
1824 decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1825 break;
1826 case 0x6500:
1827 case 0x6501:
1828 if (s->is_interlaced)
1829 return unsupported(avctx);
1830 decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1831 break;
1832 case 0x6c00:
1833 case 0x6c01:
1834 decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1835 break;
1836 default:
1837 return unsupported(avctx);
1838 }
1839
1840
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'))) {
1841 memcpy(s->video[1], s->video[0], s->video_size);
1842 }
1843
1844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (s->compression > 0xff) {
1845 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1846 buf = s->video[0];
1847 for (y = 0; y < avctx->height; y++) {
1848 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1849 memset(row, 0, avctx->width);
1850 for (plane = 0; plane < s->bpp; plane++) {
1851 decodeplane8(row, buf, s->planesize, plane);
1852 buf += s->planesize;
1853 }
1854 }
1855 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1856 memcpy(frame->data[1], s->pal, 256 * 4);
1857 } else if (s->ham) {
1858 int i, count = 1 << s->ham;
1859
1860 buf = s->video[0];
1861 memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1862 for (i = 0; i < count; i++) {
1863 s->ham_palbuf[i*2+1] = s->pal[i];
1864 }
1865 for (i = 0; i < count; i++) {
1866 uint32_t tmp = i << (8 - s->ham);
1867 tmp |= tmp >> s->ham;
1868 s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1869 s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1870 s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1871 s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1872 s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1873 s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1874 }
1875 if (s->masking == MASK_HAS_MASK) {
1876 for (i = 0; i < 8 * (1 << s->ham); i++)
1877 s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1878 }
1879 for (y = 0; y < avctx->height; y++) {
1880 uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1881 memset(s->ham_buf, 0, s->planesize * 8);
1882 for (plane = 0; plane < s->bpp; plane++) {
1883 decodeplane8(s->ham_buf, buf, s->planesize, plane);
1884 buf += s->planesize;
1885 }
1886 decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1887 }
1888 } else {
1889 return unsupported(avctx);
1890 }
1891
1892 if (!s->is_brush) {
1893 FFSWAP(uint8_t *, s->video[0], s->video[1]);
1894 }
1895 }
1896
1897
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (avpkt->flags & AV_PKT_FLAG_KEY) {
1898 2 frame->key_frame = 1;
1899 2 frame->pict_type = AV_PICTURE_TYPE_I;
1900 } else {
1901 frame->key_frame = 0;
1902 frame->pict_type = AV_PICTURE_TYPE_P;
1903 }
1904
1905 2 *got_frame = 1;
1906
1907 2 return buf_size;
1908 }
1909
1910 #if CONFIG_IFF_ILBM_DECODER
1911 const AVCodec ff_iff_ilbm_decoder = {
1912 .name = "iff",
1913 .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1914 .type = AVMEDIA_TYPE_VIDEO,
1915 .id = AV_CODEC_ID_IFF_ILBM,
1916 .priv_data_size = sizeof(IffContext),
1917 .init = decode_init,
1918 .close = decode_end,
1919 .decode = decode_frame,
1920 .capabilities = AV_CODEC_CAP_DR1,
1921 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
1922 };
1923 #endif
1924