GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/iff.c Lines: 137 1077 12.7 %
Date: 2020-01-28 04:56:05 Branches: 78 810 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
336
            s->ham_buf = av_malloc((s->planesize * 8) + AV_INPUT_BUFFER_PADDING_SIZE);
337
            if (!s->ham_buf)
338
                return AVERROR(ENOMEM);
339
340
            ham_count = 8 * (1 << s->ham);
341
            s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
342
            if (!s->ham_palbuf) {
343
                av_freep(&s->ham_buf);
344
                return AVERROR(ENOMEM);
345
            }
346
347
            if (count) { // HAM with color palette attached
348
                // prefill with black and palette and set HAM take direct value mask to zero
349
                memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
350
                for (i=0; i < count; i++) {
351
                    s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
352
                }
353
                count = 1 << s->ham;
354
            } else { // HAM with grayscale color palette
355
                count = 1 << s->ham;
356
                for (i=0; i < count; i++) {
357
                    s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
358
                    s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
359
                }
360
            }
361
            for (i=0; i < count; i++) {
362
                uint32_t tmp = i << (8 - s->ham);
363
                tmp |= tmp >> s->ham;
364
                s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
365
                s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
366
                s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
367
                s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
368
                s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
369
                s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
370
            }
371
            if (s->masking == MASK_HAS_MASK) {
372
                for (i = 0; i < ham_count; i++)
373
                    s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
374
            }
375
        }
376
    }
377
378
6
    return 0;
379
}
380
381
4
static av_cold int decode_end(AVCodecContext *avctx)
382
{
383
4
    IffContext *s = avctx->priv_data;
384
4
    av_freep(&s->planebuf);
385
4
    av_freep(&s->ham_buf);
386
4
    av_freep(&s->ham_palbuf);
387
4
    av_freep(&s->mask_buf);
388
4
    av_freep(&s->mask_palbuf);
389
4
    av_freep(&s->video[0]);
390
4
    av_freep(&s->video[1]);
391
4
    av_freep(&s->pal);
392
4
    return 0;
393
}
394
395
4
static av_cold int decode_init(AVCodecContext *avctx)
396
{
397
4
    IffContext *s = avctx->priv_data;
398
    int err;
399
400
4
    if (avctx->bits_per_coded_sample <= 8) {
401
        int palette_size;
402
403
4
        if (avctx->extradata_size >= 2)
404
4
            palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
405
        else
406
            palette_size = 0;
407
4
        avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
408

4
                         (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
409
    } else if (avctx->bits_per_coded_sample <= 32) {
410
        if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
411
            avctx->pix_fmt = AV_PIX_FMT_RGB32;
412
        } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
413
            avctx->pix_fmt = AV_PIX_FMT_RGB444;
414
        } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
415
            if (avctx->bits_per_coded_sample == 24) {
416
                avctx->pix_fmt = AV_PIX_FMT_0BGR32;
417
            } else if (avctx->bits_per_coded_sample == 32) {
418
                avctx->pix_fmt = AV_PIX_FMT_BGR32;
419
            } else {
420
                avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
421
                return AVERROR_PATCHWELCOME;
422
            }
423
        }
424
    } else {
425
        return AVERROR_INVALIDDATA;
426
    }
427
428
4
    if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
429
        return err;
430
4
    s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
431
4
    s->planebuf  = av_malloc(s->planesize * avctx->height + AV_INPUT_BUFFER_PADDING_SIZE);
432
4
    if (!s->planebuf)
433
        return AVERROR(ENOMEM);
434
435
4
    s->bpp = avctx->bits_per_coded_sample;
436
437
4
    if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
438
        s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
439
        s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
440
        s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
441
        s->pal = av_calloc(256, sizeof(*s->pal));
442
        if (!s->video[0] || !s->video[1] || !s->pal)
443
            return AVERROR(ENOMEM);
444
    }
445
446
4
    if ((err = extract_header(avctx, NULL)) < 0)
447
        return err;
448
449
4
    return 0;
450
}
451
452
/**
453
 * Decode interleaved plane buffer up to 8bpp
454
 * @param dst Destination buffer
455
 * @param buf Source buffer
456
 * @param buf_size
457
 * @param plane plane number to decode as
458
 */
459
1920
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
460
{
461
    const uint64_t *lut;
462
1920
    if (plane >= 8) {
463
        av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
464
        return;
465
    }
466
1920
    lut = plane8_lut[plane];
467
    do {
468
76800
        uint64_t v = AV_RN64A(dst) | lut[*buf++];
469
76800
        AV_WN64A(dst, v);
470
76800
        dst += 8;
471
76800
    } while (--buf_size);
472
}
473
474
/**
475
 * Decode interleaved plane buffer up to 24bpp
476
 * @param dst Destination buffer
477
 * @param buf Source buffer
478
 * @param buf_size
479
 * @param plane plane number to decode as
480
 */
481
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
482
{
483
    const uint32_t *lut = plane32_lut[plane];
484
    do {
485
        unsigned mask = (*buf >> 2) & ~3;
486
        dst[0] |= lut[mask++];
487
        dst[1] |= lut[mask++];
488
        dst[2] |= lut[mask++];
489
        dst[3] |= lut[mask];
490
        mask    = (*buf++ << 2) & 0x3F;
491
        dst[4] |= lut[mask++];
492
        dst[5] |= lut[mask++];
493
        dst[6] |= lut[mask++];
494
        dst[7] |= lut[mask];
495
        dst    += 8;
496
    } while (--buf_size);
497
}
498
499
#define DECODE_HAM_PLANE32(x)       \
500
    first       = buf[x] << 1;      \
501
    second      = buf[(x)+1] << 1;  \
502
    delta      &= pal[first++];     \
503
    delta      |= pal[first];       \
504
    dst[x]      = delta;            \
505
    delta      &= pal[second++];    \
506
    delta      |= pal[second];      \
507
    dst[(x)+1]  = delta
508
509
/**
510
 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
511
 *
512
 * @param dst the destination 24bpp buffer
513
 * @param buf the source 8bpp chunky buffer
514
 * @param pal the HAM decode table
515
 * @param buf_size the plane size in bytes
516
 */
517
static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
518
                               const uint32_t *const pal, unsigned buf_size)
519
{
520
    uint32_t delta = pal[1]; /* first palette entry */
521
    do {
522
        uint32_t first, second;
523
        DECODE_HAM_PLANE32(0);
524
        DECODE_HAM_PLANE32(2);
525
        DECODE_HAM_PLANE32(4);
526
        DECODE_HAM_PLANE32(6);
527
        buf += 8;
528
        dst += 8;
529
    } while (--buf_size);
530
}
531
532
static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
533
                         const uint32_t *const pal, unsigned width)
534
{
535
    do {
536
        *dst++ = pal[*buf++];
537
    } while (--width);
538
}
539
540
/**
541
 * Decode one complete byterun1 encoded line.
542
 *
543
 * @param dst the destination buffer where to store decompressed bitstream
544
 * @param dst_size the destination plane size in bytes
545
 * @param buf the source byterun1 compressed bitstream
546
 * @param buf_end the EOF of source byterun1 compressed bitstream
547
 * @return number of consumed bytes in byterun1 compressed bitstream
548
 */
549
240
static int decode_byterun(uint8_t *dst, int dst_size,
550
                          GetByteContext *gb)
551
{
552
    unsigned x;
553

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

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

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



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

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

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

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

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