GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/iff.c Lines: 137 1080 12.7 %
Date: 2020-04-02 05:41:20 Branches: 78 814 9.6 %

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
        s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
444
        s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
445
        s->pal = av_calloc(256, sizeof(*s->pal));
446
        if (!s->video[0] || !s->video[1] || !s->pal)
447
            return AVERROR(ENOMEM);
448
    }
449
450
4
    if ((err = extract_header(avctx, NULL)) < 0)
451
        return err;
452
453
4
    return 0;
454
}
455
456
/**
457
 * Decode interleaved plane buffer up to 8bpp
458
 * @param dst Destination buffer
459
 * @param buf Source buffer
460
 * @param buf_size
461
 * @param plane plane number to decode as
462
 */
463
1920
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
464
{
465
    const uint64_t *lut;
466
1920
    if (plane >= 8) {
467
        av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
468
        return;
469
    }
470
1920
    lut = plane8_lut[plane];
471
    do {
472
76800
        uint64_t v = AV_RN64A(dst) | lut[*buf++];
473
76800
        AV_WN64A(dst, v);
474
76800
        dst += 8;
475
76800
    } while (--buf_size);
476
}
477
478
/**
479
 * Decode interleaved plane buffer up to 24bpp
480
 * @param dst Destination buffer
481
 * @param buf Source buffer
482
 * @param buf_size
483
 * @param plane plane number to decode as
484
 */
485
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
486
{
487
    const uint32_t *lut = plane32_lut[plane];
488
    do {
489
        unsigned mask = (*buf >> 2) & ~3;
490
        dst[0] |= lut[mask++];
491
        dst[1] |= lut[mask++];
492
        dst[2] |= lut[mask++];
493
        dst[3] |= lut[mask];
494
        mask    = (*buf++ << 2) & 0x3F;
495
        dst[4] |= lut[mask++];
496
        dst[5] |= lut[mask++];
497
        dst[6] |= lut[mask++];
498
        dst[7] |= lut[mask];
499
        dst    += 8;
500
    } while (--buf_size);
501
}
502
503
#define DECODE_HAM_PLANE32(x)       \
504
    first       = buf[x] << 1;      \
505
    second      = buf[(x)+1] << 1;  \
506
    delta      &= pal[first++];     \
507
    delta      |= pal[first];       \
508
    dst[x]      = delta;            \
509
    delta      &= pal[second++];    \
510
    delta      |= pal[second];      \
511
    dst[(x)+1]  = delta
512
513
/**
514
 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
515
 *
516
 * @param dst the destination 24bpp buffer
517
 * @param buf the source 8bpp chunky buffer
518
 * @param pal the HAM decode table
519
 * @param buf_size the plane size in bytes
520
 */
521
static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
522
                               const uint32_t *const pal, unsigned buf_size)
523
{
524
    uint32_t delta = pal[1]; /* first palette entry */
525
    do {
526
        uint32_t first, second;
527
        DECODE_HAM_PLANE32(0);
528
        DECODE_HAM_PLANE32(2);
529
        DECODE_HAM_PLANE32(4);
530
        DECODE_HAM_PLANE32(6);
531
        buf += 8;
532
        dst += 8;
533
    } while (--buf_size);
534
}
535
536
static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
537
                         const uint32_t *const pal, unsigned width)
538
{
539
    do {
540
        *dst++ = pal[*buf++];
541
    } while (--width);
542
}
543
544
/**
545
 * Decode one complete byterun1 encoded line.
546
 *
547
 * @param dst the destination buffer where to store decompressed bitstream
548
 * @param dst_size the destination plane size in bytes
549
 * @param buf the source byterun1 compressed bitstream
550
 * @param buf_end the EOF of source byterun1 compressed bitstream
551
 * @return number of consumed bytes in byterun1 compressed bitstream
552
 */
553
240
static int decode_byterun(uint8_t *dst, int dst_size,
554
                          GetByteContext *gb)
555
{
556
    unsigned x;
557

10365
    for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
558
        unsigned length;
559
10125
        const int8_t value = bytestream2_get_byte(gb);
560
10125
        if (value >= 0) {
561
4486
            length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
562
4486
            bytestream2_get_buffer(gb, dst + x, length);
563
4486
            if (length < value + 1)
564
                bytestream2_skip(gb, value + 1 - length);
565
5639
        } else if (value > -128) {
566
5639
            length = FFMIN(-value + 1, dst_size - x);
567
5639
            memset(dst + x, bytestream2_get_byte(gb), length);
568
        } else { // noop
569
            continue;
570
        }
571
10125
        x += length;
572
    }
573
240
    if (x < dst_size) {
574
        av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
575
        memset(dst+x, 0, dst_size - x);
576
    }
577
240
    return bytestream2_tell(gb);
578
}
579
580
static int decode_byterun2(uint8_t *dst, int height, int line_size,
581
                           GetByteContext *gb)
582
{
583
    GetByteContext cmds;
584
    unsigned count;
585
    int i, y_pos = 0, x_pos = 0;
586
587
    if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
588
        return 0;
589
590
    bytestream2_skip(gb, 4);
591
    count = bytestream2_get_be16(gb) - 2;
592
    if (bytestream2_get_bytes_left(gb) < count)
593
        return 0;
594
595
    bytestream2_init(&cmds, gb->buffer, count);
596
    bytestream2_skip(gb, count);
597
598
    for (i = 0; i < count && x_pos < line_size; i++) {
599
        int8_t cmd = bytestream2_get_byte(&cmds);
600
        int l, r;
601
602
        if (cmd == 0) {
603
            l = bytestream2_get_be16(gb);
604
            while (l-- > 0 && x_pos < line_size) {
605
                dst[x_pos + y_pos   * line_size    ] = bytestream2_get_byte(gb);
606
                dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
607
                if (y_pos >= height) {
608
                    y_pos  = 0;
609
                    x_pos += 2;
610
                }
611
            }
612
        } else if (cmd < 0) {
613
            l = -cmd;
614
            while (l-- > 0 && x_pos < line_size) {
615
                dst[x_pos + y_pos   * line_size    ] = bytestream2_get_byte(gb);
616
                dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
617
                if (y_pos >= height) {
618
                    y_pos  = 0;
619
                    x_pos += 2;
620
                }
621
            }
622
        } else if (cmd == 1) {
623
            l = bytestream2_get_be16(gb);
624
            r = bytestream2_get_be16(gb);
625
            while (l-- > 0 && x_pos < line_size) {
626
                dst[x_pos + y_pos   * line_size    ] = r >> 8;
627
                dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
628
                if (y_pos >= height) {
629
                    y_pos  = 0;
630
                    x_pos += 2;
631
                }
632
            }
633
        } else {
634
            l = cmd;
635
            r = bytestream2_get_be16(gb);
636
            while (l-- > 0 && x_pos < line_size) {
637
                dst[x_pos + y_pos   * line_size    ] = r >> 8;
638
                dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
639
                if (y_pos >= height) {
640
                    y_pos  = 0;
641
                    x_pos += 2;
642
                }
643
            }
644
        }
645
    }
646
647
    return bytestream2_tell(gb);
648
}
649
650
#define DECODE_RGBX_COMMON(type) \
651
    if (!length) { \
652
        length = bytestream2_get_byte(gb); \
653
        if (!length) { \
654
            length = bytestream2_get_be16(gb); \
655
            if (!length) \
656
                return; \
657
        } \
658
    } \
659
    for (i = 0; i < length; i++) { \
660
        *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
661
        x += 1; \
662
        if (x >= width) { \
663
            y += 1; \
664
            if (y >= height) \
665
                return; \
666
            x = 0; \
667
        } \
668
    }
669
670
/**
671
 * Decode RGB8 buffer
672
 * @param[out] dst Destination buffer
673
 * @param width Width of destination buffer (pixels)
674
 * @param height Height of destination buffer (pixels)
675
 * @param linesize Line size of destination buffer (bytes)
676
 */
677
static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
678
{
679
    int x = 0, y = 0, i, length;
680
    while (bytestream2_get_bytes_left(gb) >= 4) {
681
        uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
682
        length = bytestream2_get_byte(gb) & 0x7F;
683
        DECODE_RGBX_COMMON(uint32_t)
684
    }
685
}
686
687
/**
688
 * Decode RGBN buffer
689
 * @param[out] dst Destination buffer
690
 * @param width Width of destination buffer (pixels)
691
 * @param height Height of destination buffer (pixels)
692
 * @param linesize Line size of destination buffer (bytes)
693
 */
694
static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
695
{
696
    int x = 0, y = 0, i, length;
697
    while (bytestream2_get_bytes_left(gb) >= 2) {
698
        uint32_t pixel = bytestream2_get_be16u(gb);
699
        length = pixel & 0x7;
700
        pixel >>= 4;
701
        DECODE_RGBX_COMMON(uint16_t)
702
    }
703
}
704
705
/**
706
 * Decode DEEP RLE 32-bit buffer
707
 * @param[out] dst Destination buffer
708
 * @param[in] src Source buffer
709
 * @param src_size Source buffer size (bytes)
710
 * @param width Width of destination buffer (pixels)
711
 * @param height Height of destination buffer (pixels)
712
 * @param linesize Line size of destination buffer (bytes)
713
 */
714
static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
715
{
716
    const uint8_t *src_end = src + src_size;
717
    int x = 0, y = 0, i;
718
    while (src + 5 <= src_end) {
719
        int opcode;
720
        opcode = *(int8_t *)src++;
721
        if (opcode >= 0) {
722
            int size = opcode + 1;
723
            for (i = 0; i < size; i++) {
724
                int length = FFMIN(size - i, width);
725
                memcpy(dst + y*linesize + x * 4, src, length * 4);
726
                src += length * 4;
727
                x += length;
728
                i += length;
729
                if (x >= width) {
730
                    x = 0;
731
                    y += 1;
732
                    if (y >= height)
733
                        return;
734
                }
735
            }
736
        } else {
737
            int size = -opcode + 1;
738
            uint32_t pixel = AV_RN32(src);
739
            for (i = 0; i < size; i++) {
740
                *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
741
                x += 1;
742
                if (x >= width) {
743
                    x = 0;
744
                    y += 1;
745
                    if (y >= height)
746
                        return;
747
                }
748
            }
749
            src += 4;
750
        }
751
    }
752
}
753
754
/**
755
 * Decode DEEP TVDC 32-bit buffer
756
 * @param[out] dst Destination buffer
757
 * @param[in] src Source buffer
758
 * @param src_size Source buffer size (bytes)
759
 * @param width Width of destination buffer (pixels)
760
 * @param height Height of destination buffer (pixels)
761
 * @param linesize Line size of destination buffer (bytes)
762
 * @param[int] tvdc TVDC lookup table
763
 */
764
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)
765
{
766
    int x = 0, y = 0, plane = 0;
767
    int8_t pixel = 0;
768
    int i, j;
769
770
    for (i = 0; i < src_size * 2;) {
771
#define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
772
        int d = tvdc[GETNIBBLE];
773
        i++;
774
        if (d) {
775
            pixel += d;
776
            dst[y * linesize + x*4 + plane] = pixel;
777
            x++;
778
        } else {
779
            if (i >= src_size * 2)
780
                return;
781
            d = GETNIBBLE + 1;
782
            i++;
783
            d = FFMIN(d, width - x);
784
            for (j = 0; j < d; j++) {
785
                dst[y * linesize + x*4 + plane] = pixel;
786
                x++;
787
            }
788
        }
789
        if (x >= width) {
790
            plane++;
791
            if (plane >= 4) {
792
                y++;
793
                if (y >= height)
794
                    return;
795
                plane = 0;
796
            }
797
            x = 0;
798
            pixel = 0;
799
            i = (i + 1) & ~1;
800
        }
801
    }
802
}
803
804
static void decode_short_horizontal_delta(uint8_t *dst,
805
                                          const uint8_t *buf, const uint8_t *buf_end,
806
                                          int w, int bpp, int dst_size)
807
{
808
    int planepitch = FFALIGN(w, 16) >> 3;
809
    int pitch = planepitch * bpp;
810
    GetByteContext ptrs, gb;
811
    PutByteContext pb;
812
    unsigned ofssrc, pos;
813
    int i, k;
814
815
    bytestream2_init(&ptrs, buf, buf_end - buf);
816
    bytestream2_init_writer(&pb, dst, dst_size);
817
818
    for (k = 0; k < bpp; k++) {
819
        ofssrc = bytestream2_get_be32(&ptrs);
820
        pos = 0;
821
822
        if (!ofssrc)
823
            continue;
824
825
        if (ofssrc >= buf_end - buf)
826
            continue;
827
828
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
829
        while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
830
            int16_t offset = bytestream2_get_be16(&gb);
831
            unsigned noffset;
832
833
            if (offset >= 0) {
834
                unsigned data = bytestream2_get_be16(&gb);
835
836
                pos += offset * 2;
837
                noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
838
                bytestream2_seek_p(&pb, noffset, SEEK_SET);
839
                bytestream2_put_be16(&pb, data);
840
            } else {
841
                uint16_t count = bytestream2_get_be16(&gb);
842
843
                pos += 2 * -(offset + 2);
844
                for (i = 0; i < count; i++) {
845
                    uint16_t data = bytestream2_get_be16(&gb);
846
847
                    pos += 2;
848
                    noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
849
                    bytestream2_seek_p(&pb, noffset, SEEK_SET);
850
                    bytestream2_put_be16(&pb, data);
851
                }
852
            }
853
        }
854
    }
855
}
856
857
static void decode_byte_vertical_delta(uint8_t *dst,
858
                                       const uint8_t *buf, const uint8_t *buf_end,
859
                                       int w, int xor, int bpp, int dst_size)
860
{
861
    int ncolumns = ((w + 15) / 16) * 2;
862
    int dstpitch = ncolumns * bpp;
863
    unsigned ofsdst, ofssrc, opcode, x;
864
    GetByteContext ptrs, gb;
865
    PutByteContext pb;
866
    int i, j, k;
867
868
    bytestream2_init(&ptrs, buf, buf_end - buf);
869
    bytestream2_init_writer(&pb, dst, dst_size);
870
871
    for (k = 0; k < bpp; k++) {
872
        ofssrc = bytestream2_get_be32(&ptrs);
873
874
        if (!ofssrc)
875
            continue;
876
877
        if (ofssrc >= buf_end - buf)
878
            continue;
879
880
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
881
        for (j = 0; j < ncolumns; j++) {
882
            ofsdst = j + k * ncolumns;
883
884
            i = bytestream2_get_byte(&gb);
885
            while (i > 0) {
886
                opcode = bytestream2_get_byte(&gb);
887
888
                if (opcode == 0) {
889
                    opcode  = bytestream2_get_byte(&gb);
890
                    x = bytestream2_get_byte(&gb);
891
892
                    while (opcode) {
893
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
894
                        if (xor && ofsdst < dst_size) {
895
                            bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
896
                        } else {
897
                            bytestream2_put_byte(&pb, x);
898
                        }
899
                        ofsdst += dstpitch;
900
                        opcode--;
901
                    }
902
                } else if (opcode < 0x80) {
903
                    ofsdst += opcode * dstpitch;
904
                } else {
905
                    opcode &= 0x7f;
906
907
                    while (opcode) {
908
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
909
                        if (xor && ofsdst < dst_size) {
910
                            bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
911
                        } else {
912
                            bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
913
                        }
914
                        ofsdst += dstpitch;
915
                        opcode--;
916
                    }
917
                }
918
                i--;
919
            }
920
        }
921
    }
922
}
923
924
static void decode_delta_j(uint8_t *dst,
925
                           const uint8_t *buf, const uint8_t *buf_end,
926
                           int w, int h, int bpp, int dst_size)
927
{
928
    int32_t pitch;
929
    uint8_t *ptr;
930
    uint32_t type, flag, cols, groups, rows, bytes;
931
    uint32_t offset;
932
    int planepitch_byte = (w + 7) / 8;
933
    int planepitch = ((w + 15) / 16) * 2;
934
    int kludge_j, b, g, r, d;
935
    GetByteContext gb;
936
937
    pitch = planepitch * bpp;
938
    kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
939
940
    bytestream2_init(&gb, buf, buf_end - buf);
941
942
    while (bytestream2_get_bytes_left(&gb) >= 2) {
943
        type = bytestream2_get_be16(&gb);
944
945
        switch (type) {
946
        case 0:
947
            return;
948
        case 1:
949
            flag   = bytestream2_get_be16(&gb);
950
            cols   = bytestream2_get_be16(&gb);
951
            groups = bytestream2_get_be16(&gb);
952
953
            for (g = 0; g < groups; g++) {
954
                offset = bytestream2_get_be16(&gb);
955
956
                if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
957
                    av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
958
                    return;
959
                }
960
961
                if (kludge_j)
962
                    offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
963
                else
964
                    offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
965
966
                for (b = 0; b < cols; b++) {
967
                    for (d = 0; d < bpp; d++) {
968
                        uint8_t value = bytestream2_get_byte(&gb);
969
970
                        if (offset >= dst_size)
971
                            return;
972
                        ptr = dst + offset;
973
974
                        if (flag)
975
                            ptr[0] ^= value;
976
                        else
977
                            ptr[0]  = value;
978
979
                        offset += planepitch;
980
                    }
981
                }
982
                if ((cols * bpp) & 1)
983
                    bytestream2_skip(&gb, 1);
984
            }
985
            break;
986
        case 2:
987
            flag   = bytestream2_get_be16(&gb);
988
            rows   = bytestream2_get_be16(&gb);
989
            bytes  = bytestream2_get_be16(&gb);
990
            groups = bytestream2_get_be16(&gb);
991
992
            for (g = 0; g < groups; g++) {
993
                offset = bytestream2_get_be16(&gb);
994
995
                if (kludge_j)
996
                    offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
997
                else
998
                    offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
999
1000
                for (r = 0; r < rows; r++) {
1001
                    for (d = 0; d < bpp; d++) {
1002
                        unsigned noffset = offset + (r * pitch) + d * planepitch;
1003
1004
                        if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1005
                            av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1006
                            return;
1007
                        }
1008
1009
                        for (b = 0; b < bytes; b++) {
1010
                            uint8_t value = bytestream2_get_byte(&gb);
1011
1012
                            if (noffset >= dst_size)
1013
                                return;
1014
                            ptr = dst + noffset;
1015
1016
                            if (flag)
1017
                                ptr[0] ^= value;
1018
                            else
1019
                                ptr[0]  = value;
1020
1021
                            noffset++;
1022
                        }
1023
                    }
1024
                }
1025
                if ((rows * bytes * bpp) & 1)
1026
                    bytestream2_skip(&gb, 1);
1027
            }
1028
            break;
1029
        default:
1030
            return;
1031
        }
1032
    }
1033
}
1034
1035
static void decode_short_vertical_delta(uint8_t *dst,
1036
                                        const uint8_t *buf, const uint8_t *buf_end,
1037
                                        int w, int bpp, int dst_size)
1038
{
1039
    int ncolumns = (w + 15) >> 4;
1040
    int dstpitch = ncolumns * bpp * 2;
1041
    unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1042
    GetByteContext ptrs, gb, dptrs, dgb;
1043
    PutByteContext pb;
1044
    int i, j, k;
1045
1046
    if (buf_end - buf <= 64)
1047
        return;
1048
1049
    bytestream2_init(&ptrs, buf, buf_end - buf);
1050
    bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1051
    bytestream2_init_writer(&pb, dst, dst_size);
1052
1053
    for (k = 0; k < bpp; k++) {
1054
        ofssrc = bytestream2_get_be32(&ptrs);
1055
        ofsdata = bytestream2_get_be32(&dptrs);
1056
1057
        if (!ofssrc)
1058
            continue;
1059
1060
        if (ofssrc >= buf_end - buf)
1061
            return;
1062
1063
        if (ofsdata >= buf_end - buf)
1064
            return;
1065
1066
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1067
        bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1068
        for (j = 0; j < ncolumns; j++) {
1069
            ofsdst = (j + k * ncolumns) * 2;
1070
1071
            i = bytestream2_get_byte(&gb);
1072
            while (i > 0) {
1073
                opcode = bytestream2_get_byte(&gb);
1074
1075
                if (opcode == 0) {
1076
                    opcode = bytestream2_get_byte(&gb);
1077
                    x = bytestream2_get_be16(&dgb);
1078
1079
                    while (opcode) {
1080
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1081
                        bytestream2_put_be16(&pb, x);
1082
                        ofsdst += dstpitch;
1083
                        opcode--;
1084
                    }
1085
                } else if (opcode < 0x80) {
1086
                    ofsdst += opcode * dstpitch;
1087
                } else {
1088
                    opcode &= 0x7f;
1089
1090
                    while (opcode) {
1091
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1092
                        bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1093
                        ofsdst += dstpitch;
1094
                        opcode--;
1095
                    }
1096
                }
1097
                i--;
1098
            }
1099
        }
1100
    }
1101
}
1102
1103
static void decode_long_vertical_delta(uint8_t *dst,
1104
                                       const uint8_t *buf, const uint8_t *buf_end,
1105
                                       int w, int bpp, int dst_size)
1106
{
1107
    int ncolumns = (w + 31) >> 5;
1108
    int dstpitch = ((w + 15) / 16 * 2) * bpp;
1109
    unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1110
    GetByteContext ptrs, gb, dptrs, dgb;
1111
    PutByteContext pb;
1112
    int i, j, k, h;
1113
1114
    if (buf_end - buf <= 64)
1115
        return;
1116
1117
    h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1118
    bytestream2_init(&ptrs, buf, buf_end - buf);
1119
    bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1120
    bytestream2_init_writer(&pb, dst, dst_size);
1121
1122
    for (k = 0; k < bpp; k++) {
1123
        ofssrc = bytestream2_get_be32(&ptrs);
1124
        ofsdata = bytestream2_get_be32(&dptrs);
1125
1126
        if (!ofssrc)
1127
            continue;
1128
1129
        if (ofssrc >= buf_end - buf)
1130
            return;
1131
1132
        if (ofsdata >= buf_end - buf)
1133
            return;
1134
1135
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1136
        bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1137
        for (j = 0; j < ncolumns; j++) {
1138
            ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1139
1140
            i = bytestream2_get_byte(&gb);
1141
            while (i > 0) {
1142
                opcode = bytestream2_get_byte(&gb);
1143
1144
                if (opcode == 0) {
1145
                    opcode = bytestream2_get_byte(&gb);
1146
                    if (h && (j == (ncolumns - 1))) {
1147
                        x = bytestream2_get_be16(&dgb);
1148
                        bytestream2_skip(&dgb, 2);
1149
                    } else {
1150
                        x = bytestream2_get_be32(&dgb);
1151
                    }
1152
1153
                    if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1154
                        return;
1155
1156
                    while (opcode) {
1157
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1158
                        if (h && (j == (ncolumns - 1))) {
1159
                            bytestream2_put_be16(&pb, x);
1160
                        } else {
1161
                            bytestream2_put_be32(&pb, x);
1162
                        }
1163
                        ofsdst += dstpitch;
1164
                        opcode--;
1165
                    }
1166
                } else if (opcode < 0x80) {
1167
                    ofsdst += opcode * dstpitch;
1168
                } else {
1169
                    opcode &= 0x7f;
1170
1171
                    while (opcode) {
1172
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1173
                        if (h && (j == (ncolumns - 1))) {
1174
                            bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1175
                            bytestream2_skip(&dgb, 2);
1176
                        } else {
1177
                            bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1178
                        }
1179
                        ofsdst += dstpitch;
1180
                        opcode--;
1181
                    }
1182
                }
1183
                i--;
1184
            }
1185
        }
1186
    }
1187
}
1188
1189
static void decode_short_vertical_delta2(uint8_t *dst,
1190
                                         const uint8_t *buf, const uint8_t *buf_end,
1191
                                         int w, int bpp, int dst_size)
1192
{
1193
    int ncolumns = (w + 15) >> 4;
1194
    int dstpitch = ncolumns * bpp * 2;
1195
    unsigned ofsdst, ofssrc, opcode, x;
1196
    GetByteContext ptrs, gb;
1197
    PutByteContext pb;
1198
    int i, j, k;
1199
1200
    bytestream2_init(&ptrs, buf, buf_end - buf);
1201
    bytestream2_init_writer(&pb, dst, dst_size);
1202
1203
    for (k = 0; k < bpp; k++) {
1204
        ofssrc = bytestream2_get_be32(&ptrs);
1205
1206
        if (!ofssrc)
1207
            continue;
1208
1209
        if (ofssrc >= buf_end - buf)
1210
            continue;
1211
1212
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1213
        for (j = 0; j < ncolumns; j++) {
1214
            ofsdst = (j + k * ncolumns) * 2;
1215
1216
            i = bytestream2_get_be16(&gb);
1217
            while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1218
                opcode = bytestream2_get_be16(&gb);
1219
1220
                if (opcode == 0) {
1221
                    opcode = bytestream2_get_be16(&gb);
1222
                    x = bytestream2_get_be16(&gb);
1223
1224
                    while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1225
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1226
                        bytestream2_put_be16(&pb, x);
1227
                        ofsdst += dstpitch;
1228
                        opcode--;
1229
                    }
1230
                } else if (opcode < 0x8000) {
1231
                    ofsdst += opcode * dstpitch;
1232
                } else {
1233
                    opcode &= 0x7fff;
1234
1235
                    while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1236
                           bytestream2_get_bytes_left_p(&pb) > 1) {
1237
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1238
                        bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1239
                        ofsdst += dstpitch;
1240
                        opcode--;
1241
                    }
1242
                }
1243
                i--;
1244
            }
1245
        }
1246
    }
1247
}
1248
1249
static void decode_long_vertical_delta2(uint8_t *dst,
1250
                                        const uint8_t *buf, const uint8_t *buf_end,
1251
                                        int w, int bpp, int dst_size)
1252
{
1253
    int ncolumns = (w + 31) >> 5;
1254
    int dstpitch = ((w + 15) / 16 * 2) * bpp;
1255
    unsigned ofsdst, ofssrc, opcode, x;
1256
    unsigned skip = 0x80000000, mask = skip - 1;
1257
    GetByteContext ptrs, gb;
1258
    PutByteContext pb;
1259
    int i, j, k, h;
1260
1261
    h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1262
    bytestream2_init(&ptrs, buf, buf_end - buf);
1263
    bytestream2_init_writer(&pb, dst, dst_size);
1264
1265
    for (k = 0; k < bpp; k++) {
1266
        ofssrc = bytestream2_get_be32(&ptrs);
1267
1268
        if (!ofssrc)
1269
            continue;
1270
1271
        if (ofssrc >= buf_end - buf)
1272
            continue;
1273
1274
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1275
        for (j = 0; j < ncolumns; j++) {
1276
            ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1277
1278
            if (h && (j == (ncolumns - 1))) {
1279
                skip = 0x8000;
1280
                mask = skip - 1;
1281
            }
1282
1283
            i = bytestream2_get_be32(&gb);
1284
            while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1285
                opcode = bytestream2_get_be32(&gb);
1286
1287
                if (opcode == 0) {
1288
                    if (h && (j == ncolumns - 1)) {
1289
                        opcode = bytestream2_get_be16(&gb);
1290
                        x = bytestream2_get_be16(&gb);
1291
                    } else {
1292
                        opcode = bytestream2_get_be32(&gb);
1293
                        x = bytestream2_get_be32(&gb);
1294
                    }
1295
1296
                    if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1297
                        return;
1298
1299
                    while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1300
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1301
                        if (h && (j == ncolumns - 1))
1302
                            bytestream2_put_be16(&pb, x);
1303
                        else
1304
                            bytestream2_put_be32(&pb, x);
1305
                        ofsdst += dstpitch;
1306
                        opcode--;
1307
                    }
1308
                } else if (opcode < skip) {
1309
                    ofsdst += opcode * dstpitch;
1310
                } else {
1311
                    opcode &= mask;
1312
1313
                    while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1314
                           bytestream2_get_bytes_left_p(&pb) > 1) {
1315
                        bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1316
                        if (h && (j == ncolumns - 1)) {
1317
                            bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1318
                        } else {
1319
                            bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1320
                        }
1321
                        ofsdst += dstpitch;
1322
                        opcode--;
1323
                    }
1324
                }
1325
                i--;
1326
            }
1327
        }
1328
    }
1329
}
1330
1331
static void decode_delta_d(uint8_t *dst,
1332
                           const uint8_t *buf, const uint8_t *buf_end,
1333
                           int w, int flag, int bpp, int dst_size)
1334
{
1335
    int planepitch = FFALIGN(w, 16) >> 3;
1336
    int pitch = planepitch * bpp;
1337
    int planepitch_byte = (w + 7) / 8;
1338
    unsigned entries, ofssrc;
1339
    GetByteContext gb, ptrs;
1340
    PutByteContext pb;
1341
    int k;
1342
1343
    if (buf_end - buf <= 4 * bpp)
1344
        return;
1345
1346
    bytestream2_init_writer(&pb, dst, dst_size);
1347
    bytestream2_init(&ptrs, buf, bpp * 4);
1348
1349
    for (k = 0; k < bpp; k++) {
1350
        ofssrc = bytestream2_get_be32(&ptrs);
1351
1352
        if (!ofssrc)
1353
            continue;
1354
1355
        if (ofssrc >= buf_end - buf)
1356
            continue;
1357
1358
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1359
1360
        entries = bytestream2_get_be32(&gb);
1361
        if (entries * 8LL > bytestream2_get_bytes_left(&gb))
1362
            return;
1363
1364
        while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1365
            int32_t opcode  = bytestream2_get_be32(&gb);
1366
            unsigned offset = bytestream2_get_be32(&gb);
1367
1368
            bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1369
            if (opcode >= 0) {
1370
                uint32_t x = bytestream2_get_be32(&gb);
1371
                if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1372
                    continue;
1373
                while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1374
                    bytestream2_put_be32(&pb, x);
1375
                    bytestream2_skip_p(&pb, pitch - 4);
1376
                    opcode--;
1377
                }
1378
            } else {
1379
                opcode = -opcode;
1380
                while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1381
                    bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1382
                    bytestream2_skip_p(&pb, pitch - 4);
1383
                    opcode--;
1384
                }
1385
            }
1386
            entries--;
1387
        }
1388
    }
1389
}
1390
1391
static void decode_delta_e(uint8_t *dst,
1392
                           const uint8_t *buf, const uint8_t *buf_end,
1393
                           int w, int flag, int bpp, int dst_size)
1394
{
1395
    int planepitch = FFALIGN(w, 16) >> 3;
1396
    int pitch = planepitch * bpp;
1397
    int planepitch_byte = (w + 7) / 8;
1398
    unsigned entries, ofssrc;
1399
    GetByteContext gb, ptrs;
1400
    PutByteContext pb;
1401
    int k;
1402
1403
    if (buf_end - buf <= 4 * bpp)
1404
        return;
1405
1406
    bytestream2_init_writer(&pb, dst, dst_size);
1407
    bytestream2_init(&ptrs, buf, bpp * 4);
1408
1409
    for (k = 0; k < bpp; k++) {
1410
        ofssrc = bytestream2_get_be32(&ptrs);
1411
1412
        if (!ofssrc)
1413
            continue;
1414
1415
        if (ofssrc >= buf_end - buf)
1416
            continue;
1417
1418
        bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1419
1420
        entries = bytestream2_get_be16(&gb);
1421
        while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1422
            int16_t opcode  = bytestream2_get_be16(&gb);
1423
            unsigned offset = bytestream2_get_be32(&gb);
1424
1425
            bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1426
            if (opcode >= 0) {
1427
                uint16_t x = bytestream2_get_be16(&gb);
1428
                while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1429
                    bytestream2_put_be16(&pb, x);
1430
                    bytestream2_skip_p(&pb, pitch - 2);
1431
                    opcode--;
1432
                }
1433
            } else {
1434
                opcode = -opcode;
1435
                while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1436
                    bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1437
                    bytestream2_skip_p(&pb, pitch - 2);
1438
                    opcode--;
1439
                }
1440
            }
1441
            entries--;
1442
        }
1443
    }
1444
}
1445
1446
static void decode_delta_l(uint8_t *dst,
1447
                           const uint8_t *buf, const uint8_t *buf_end,
1448
                           int w, int flag, int bpp, int dst_size)
1449
{
1450
    GetByteContext off0, off1, dgb, ogb;
1451
    PutByteContext pb;
1452
    unsigned poff0, poff1;
1453
    int i, k, dstpitch;
1454
    int planepitch_byte = (w + 7) / 8;
1455
    int planepitch = ((w + 15) / 16) * 2;
1456
    int pitch = planepitch * bpp;
1457
1458
    if (buf_end - buf <= 64)
1459
        return;
1460
1461
    bytestream2_init(&off0, buf, buf_end - buf);
1462
    bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1463
    bytestream2_init_writer(&pb, dst, dst_size);
1464
1465
    dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1466
1467
    for (k = 0; k < bpp; k++) {
1468
        poff0 = bytestream2_get_be32(&off0);
1469
        poff1 = bytestream2_get_be32(&off1);
1470
1471
        if (!poff0)
1472
            continue;
1473
1474
        if (2LL * poff0 >= buf_end - buf)
1475
            return;
1476
1477
        if (2LL * poff1 >= buf_end - buf)
1478
            return;
1479
1480
        bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1481
        bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1482
1483
        while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1484
            uint32_t offset = bytestream2_get_be16(&ogb);
1485
            int16_t cnt = bytestream2_get_be16(&ogb);
1486
            uint16_t data;
1487
1488
            offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1489
            if (cnt < 0) {
1490
                if (bytestream2_get_bytes_left(&dgb) < 2)
1491
                    break;
1492
                bytestream2_seek_p(&pb, offset, SEEK_SET);
1493
                cnt = -cnt;
1494
                data = bytestream2_get_be16(&dgb);
1495
                for (i = 0; i < cnt; i++) {
1496
                    bytestream2_put_be16(&pb, data);
1497
                    bytestream2_skip_p(&pb, dstpitch - 2);
1498
                }
1499
            } else {
1500
                if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1501
                    break;
1502
                bytestream2_seek_p(&pb, offset, SEEK_SET);
1503
                for (i = 0; i < cnt; i++) {
1504
                    data = bytestream2_get_be16(&dgb);
1505
                    bytestream2_put_be16(&pb, data);
1506
                    bytestream2_skip_p(&pb, dstpitch - 2);
1507
                }
1508
            }
1509
        }
1510
    }
1511
}
1512
1513
static int unsupported(AVCodecContext *avctx)
1514
{
1515
    IffContext *s = avctx->priv_data;
1516
    avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1517
    return AVERROR_INVALIDDATA;
1518
}
1519
1520
2
static int decode_frame(AVCodecContext *avctx,
1521
                        void *data, int *got_frame,
1522
                        AVPacket *avpkt)
1523
{
1524
2
    IffContext *s          = avctx->priv_data;
1525
2
    AVFrame *frame         = data;
1526
2
    const uint8_t *buf     = avpkt->data;
1527
2
    int buf_size           = avpkt->size;
1528
2
    const uint8_t *buf_end = buf + buf_size;
1529
    int y, plane, res;
1530
2
    GetByteContext *gb = &s->gb;
1531
    const AVPixFmtDescriptor *desc;
1532
1533
2
    bytestream2_init(gb, avpkt->data, avpkt->size);
1534
1535
2
    if ((res = extract_header(avctx, avpkt)) < 0)
1536
        return res;
1537
1538
2
    if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1539
        return res;
1540
2
    s->frame = frame;
1541
1542
2
    buf      += bytestream2_tell(gb);
1543
2
    buf_size -= bytestream2_tell(gb);
1544
2
    desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1545
1546

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

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



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

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

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

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

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