FFmpeg coverage


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