GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/iff.c Lines: 137 1083 12.7 %
Date: 2020-07-13 04:22:34 Branches: 78 818 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
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
2
    if (count) {
169
514
        for (i = 0; i < count; i++)
170
512
            pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
171

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
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
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
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

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
6
    } else if (!avpkt) {
267
4
        buf = avctx->extradata;
268
4
        buf_size = bytestream_get_be16(&buf);
269

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
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
68
        for (i = 0; i < 16; i++)
285
64
            s->tvdc[i] = bytestream_get_be16(&buf);
286
287
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
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
                s->mask_buf = av_malloc((s->planesize * 32) + AV_INPUT_BUFFER_PADDING_SIZE);
303
                if (!s->mask_buf)
304
                    return AVERROR(ENOMEM);
305
                if (s->bpp > 16) {
306
                    av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
307
                    av_freep(&s->mask_buf);
308
                    return AVERROR(ENOMEM);
309
                }
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

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

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

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
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
4
    if (avctx->bits_per_coded_sample <= 8) {
405
        int palette_size;
406
407
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

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
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
4
    if (!s->planebuf)
437
        return AVERROR(ENOMEM);
438
439
4
    s->bpp = avctx->bits_per_coded_sample;
440
441
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
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
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
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

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
10125
        if (value >= 0) {
563
4486
            length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
564
4486
            bytestream2_get_buffer(gb, dst + x, length);
565
4486
            if (length < value + 1)
566
                bytestream2_skip(gb, value + 1 - length);
567
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
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
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
            offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1492
            if (cnt < 0) {
1493
                if (bytestream2_get_bytes_left(&dgb) < 2)
1494
                    break;
1495
                bytestream2_seek_p(&pb, offset, SEEK_SET);
1496
                cnt = -cnt;
1497
                data = bytestream2_get_be16(&dgb);
1498
                for (i = 0; i < cnt; i++) {
1499
                    bytestream2_put_be16(&pb, data);
1500
                    bytestream2_skip_p(&pb, dstpitch - 2);
1501
                }
1502
            } else {
1503
                if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1504
                    break;
1505
                bytestream2_seek_p(&pb, offset, SEEK_SET);
1506
                for (i = 0; i < cnt; i++) {
1507
                    data = bytestream2_get_be16(&dgb);
1508
                    bytestream2_put_be16(&pb, data);
1509
                    bytestream2_skip_p(&pb, dstpitch - 2);
1510
                }
1511
            }
1512
        }
1513
    }
1514
}
1515
1516
static int unsupported(AVCodecContext *avctx)
1517
{
1518
    IffContext *s = avctx->priv_data;
1519
    avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1520
    return AVERROR_INVALIDDATA;
1521
}
1522
1523
2
static int decode_frame(AVCodecContext *avctx,
1524
                        void *data, int *got_frame,
1525
                        AVPacket *avpkt)
1526
{
1527
2
    IffContext *s          = avctx->priv_data;
1528
2
    AVFrame *frame         = data;
1529
2
    const uint8_t *buf     = avpkt->data;
1530
2
    int buf_size           = avpkt->size;
1531
2
    const uint8_t *buf_end = buf + buf_size;
1532
    int y, plane, res;
1533
2
    GetByteContext *gb = &s->gb;
1534
    const AVPixFmtDescriptor *desc;
1535
1536
2
    bytestream2_init(gb, avpkt->data, avpkt->size);
1537
1538
2
    if ((res = extract_header(avctx, avpkt)) < 0)
1539
        return res;
1540
1541
2
    if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1542
        return res;
1543
2
    s->frame = frame;
1544
1545
2
    buf      += bytestream2_tell(gb);
1546
2
    buf_size -= bytestream2_tell(gb);
1547
2
    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1548
1549

2
    if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1550
2
        avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1551
2
        if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1552
            return res;
1553
    } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1554
               avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1555
        if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1556
            return res;
1557
    }
1558
2
    s->init = 1;
1559
1560

2
    if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1561
        if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1562
            memcpy(s->pal, s->frame->data[1], 256 * 4);
1563
    }
1564
1565



2
    switch (s->compression) {
1566
1
    case 0x0:
1567
1
        if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1568
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1569
                memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1570
                for (plane = 0; plane < s->bpp; plane++) {
1571
                    for (y = 0; y < avctx->height && buf < buf_end; y++) {
1572
                        uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1573
                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1574
                        buf += s->planesize;
1575
                    }
1576
                }
1577
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1578
                memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1579
                for (y = 0; y < avctx->height; y++) {
1580
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1581
                    memset(s->ham_buf, 0, s->planesize * 8);
1582
                    for (plane = 0; plane < s->bpp; plane++) {
1583
                        const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1584
                        if (start >= buf_end)
1585
                            break;
1586
                        decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1587
                    }
1588
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1589
                }
1590
            } else
1591
                return unsupported(avctx);
1592
1
        } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1593
            int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1594
            int x;
1595
            for (y = 0; y < avctx->height && buf < buf_end; y++) {
1596
                uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1597
                memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1598
                buf += raw_width;
1599
                if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1600
                    for (x = 0; x < avctx->width; x++)
1601
                        row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1602
                }
1603
            }
1604
1
        } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1605
                   avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1606
1
            if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1607
                memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1608

1
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1609
241
                for (y = 0; y < avctx->height; y++) {
1610
240
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1611
240
                    memset(row, 0, avctx->width);
1612

2160
                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1613
1920
                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1614
1920
                        buf += s->planesize;
1615
                    }
1616
                }
1617
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1618
                for (y = 0; y < avctx->height; y++) {
1619
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1620
                    memset(s->ham_buf, 0, s->planesize * 8);
1621
                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1622
                        decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1623
                        buf += s->planesize;
1624
                    }
1625
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1626
                }
1627
            } else { // AV_PIX_FMT_BGR32
1628
                for (y = 0; y < avctx->height; y++) {
1629
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1630
                    memset(row, 0, avctx->width << 2);
1631
                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1632
                        decodeplane32((uint32_t *)row, buf,
1633
                                      FFMIN(s->planesize, buf_end - buf), plane);
1634
                        buf += s->planesize;
1635
                    }
1636
                }
1637
            }
1638
        } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1639
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1640
                for (y = 0; y < avctx->height && buf_end > buf; y++) {
1641
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1642
                    memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1643
                    buf += avctx->width + (avctx->width % 2); // padding if odd
1644
                }
1645
            } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1646
                for (y = 0; y < avctx->height && buf_end > buf; y++) {
1647
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1648
                    memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1649
                    buf += avctx->width + (avctx->width & 1); // padding if odd
1650
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1651
                }
1652
            } else
1653
                return unsupported(avctx);
1654
        } else {
1655
            return unsupported(avctx);
1656
        }
1657
1
        break;
1658
1
    case 0x1:
1659
1
        if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1660
1
            avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1661
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1662
                uint8_t *video = s->video[0];
1663
1664
                for (y = 0; y < avctx->height; y++) {
1665
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1666
                    memset(row, 0, avctx->width);
1667
                    for (plane = 0; plane < s->bpp; plane++) {
1668
                        buf += decode_byterun(s->planebuf, s->planesize, gb);
1669
                        if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1670
                            memcpy(video, s->planebuf, s->planesize);
1671
                            video += s->planesize;
1672
                        }
1673
                        decodeplane8(row, s->planebuf, s->planesize, plane);
1674
                    }
1675
                }
1676
            } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1677
                for (y = 0; y < avctx->height; y++) {
1678
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1679
                    memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1680
                    for (plane = 0; plane < s->bpp; plane++) {
1681
                        buf += decode_byterun(s->planebuf, s->planesize, gb);
1682
                        decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1683
                    }
1684
                    lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1685
                }
1686
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1687
                uint8_t *video = s->video[0];
1688
                for (y = 0; y < avctx->height; y++) {
1689
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1690
                    memset(s->ham_buf, 0, s->planesize * 8);
1691
                    for (plane = 0; plane < s->bpp; plane++) {
1692
                        buf += decode_byterun(s->planebuf, s->planesize, gb);
1693
                        if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1694
                            memcpy(video, s->planebuf, s->planesize);
1695
                            video += s->planesize;
1696
                        }
1697
                        decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1698
                    }
1699
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1700
                }
1701
            } else { // AV_PIX_FMT_BGR32
1702
                for (y = 0; y < avctx->height; y++) {
1703
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1704
                    memset(row, 0, avctx->width << 2);
1705
                    for (plane = 0; plane < s->bpp; plane++) {
1706
                        buf += decode_byterun(s->planebuf, s->planesize, gb);
1707
                        decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1708
                    }
1709
                }
1710
            }
1711
1
        } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1712

1
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1713
241
                for (y = 0; y < avctx->height; y++) {
1714
240
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1715
240
                    buf += decode_byterun(row, avctx->width, gb);
1716
                }
1717
            } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1718
                for (y = 0; y < avctx->height; y++) {
1719
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1720
                    buf += decode_byterun(s->ham_buf, avctx->width, gb);
1721
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1722
                }
1723
            } else
1724
                return unsupported(avctx);
1725
        } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1726
            if (av_get_bits_per_pixel(desc) == 32)
1727
                decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1728
            else
1729
                return unsupported(avctx);
1730
        } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1731
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1732
                memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1733
                for (plane = 0; plane < s->bpp; plane++) {
1734
                    for (y = 0; y < avctx->height && buf < buf_end; y++) {
1735
                        uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1736
                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1737
                        buf += s->planesize;
1738
                    }
1739
                }
1740
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1741
                memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1742
                for (y = 0; y < avctx->height; y++) {
1743
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1744
                    memset(s->ham_buf, 0, s->planesize * 8);
1745
                    for (plane = 0; plane < s->bpp; plane++) {
1746
                        const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1747
                        if (start >= buf_end)
1748
                            break;
1749
                        decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1750
                    }
1751
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1752
                }
1753
            } else {
1754
                return unsupported(avctx);
1755
            }
1756
        } else {
1757
            return unsupported(avctx);
1758
        }
1759
1
        break;
1760
    case 0x2:
1761
        if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1762
            for (plane = 0; plane < s->bpp; plane++) {
1763
                decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1764
                for (y = 0; y < avctx->height; y++) {
1765
                    uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1766
                    decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1767
                }
1768
            }
1769
        } else {
1770
            return unsupported(avctx);
1771
        }
1772
        break;
1773
    case 0x4:
1774
        if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1775
            decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1776
        else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1777
            decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1778
        else
1779
            return unsupported(avctx);
1780
        break;
1781
    case 0x5:
1782
        if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1783
            if (av_get_bits_per_pixel(desc) == 32)
1784
                decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1785
            else
1786
                return unsupported(avctx);
1787
        } else
1788
            return unsupported(avctx);
1789
        break;
1790
    case 0x300:
1791
    case 0x301:
1792
        decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1793
        break;
1794
    case 0x500:
1795
    case 0x501:
1796
        decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1797
        break;
1798
    case 0x700:
1799
    case 0x701:
1800
        if (s->is_short)
1801
            decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1802
        else
1803
            decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1804
        break;
1805
    case 0x800:
1806
    case 0x801:
1807
        if (s->is_short)
1808
            decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1809
        else
1810
            decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1811
        break;
1812
    case 0x4a00:
1813
    case 0x4a01:
1814
        decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1815
        break;
1816
    case 0x6400:
1817
    case 0x6401:
1818
        if (s->is_interlaced)
1819
            return unsupported(avctx);
1820
        decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1821
        break;
1822
    case 0x6500:
1823
    case 0x6501:
1824
        if (s->is_interlaced)
1825
            return unsupported(avctx);
1826
        decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1827
        break;
1828
    case 0x6c00:
1829
    case 0x6c01:
1830
        decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1831
        break;
1832
    default:
1833
        return unsupported(avctx);
1834
    }
1835
1836

2
    if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1837
        memcpy(s->video[1], s->video[0], s->video_size);
1838
    }
1839
1840
2
    if (s->compression > 0xff) {
1841
        if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1842
            buf = s->video[0];
1843
            for (y = 0; y < avctx->height; y++) {
1844
                uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1845
                memset(row, 0, avctx->width);
1846
                for (plane = 0; plane < s->bpp; plane++) {
1847
                    decodeplane8(row, buf, s->planesize, plane);
1848
                    buf += s->planesize;
1849
                }
1850
            }
1851
            memcpy(frame->data[1], s->pal, 256 * 4);
1852
        } else if (s->ham) {
1853
            int i, count = 1 << s->ham;
1854
1855
            buf = s->video[0];
1856
            memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1857
            for (i = 0; i < count; i++) {
1858
                s->ham_palbuf[i*2+1] = s->pal[i];
1859
            }
1860
            for (i = 0; i < count; i++) {
1861
                uint32_t tmp = i << (8 - s->ham);
1862
                tmp |= tmp >> s->ham;
1863
                s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF;
1864
                s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00;
1865
                s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF;
1866
                s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
1867
                s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1868
                s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1869
            }
1870
            if (s->masking == MASK_HAS_MASK) {
1871
                for (i = 0; i < 8 * (1 << s->ham); i++)
1872
                    s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1873
            }
1874
            for (y = 0; y < avctx->height; y++) {
1875
                uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1876
                memset(s->ham_buf, 0, s->planesize * 8);
1877
                for (plane = 0; plane < s->bpp; plane++) {
1878
                    decodeplane8(s->ham_buf, buf, s->planesize, plane);
1879
                    buf += s->planesize;
1880
                }
1881
                decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1882
            }
1883
        } else {
1884
            return unsupported(avctx);
1885
        }
1886
1887
        if (!s->is_brush) {
1888
            FFSWAP(uint8_t *, s->video[0], s->video[1]);
1889
        }
1890
    }
1891
1892
2
    if (avpkt->flags & AV_PKT_FLAG_KEY) {
1893
2
        frame->key_frame = 1;
1894
2
        frame->pict_type = AV_PICTURE_TYPE_I;
1895
    } else {
1896
        frame->key_frame = 0;
1897
        frame->pict_type = AV_PICTURE_TYPE_P;
1898
    }
1899
1900
2
    *got_frame = 1;
1901
1902
2
    return buf_size;
1903
}
1904
1905
#if CONFIG_IFF_ILBM_DECODER
1906
AVCodec ff_iff_ilbm_decoder = {
1907
    .name           = "iff",
1908
    .long_name      = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1909
    .type           = AVMEDIA_TYPE_VIDEO,
1910
    .id             = AV_CODEC_ID_IFF_ILBM,
1911
    .priv_data_size = sizeof(IffContext),
1912
    .init           = decode_init,
1913
    .close          = decode_end,
1914
    .decode         = decode_frame,
1915
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
1916
    .capabilities   = AV_CODEC_CAP_DR1,
1917
};
1918
#endif