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

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

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

2
    if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1535
2
        avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1536
2
        if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1537
            return res;
1538
    } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1539
               avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1540
        if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1541
            return res;
1542
    }
1543
2
    s->init = 1;
1544
1545

2
    if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1546
        if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1547
            memcpy(s->pal, s->frame->data[1], 256 * 4);
1548
    }
1549
1550



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

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

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

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

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