Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6148 serge 1
/*
2
 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
3
 * Copyright (c) 2010 Peter Ross 
4
 * Copyright (c) 2010 Sebastian Vater 
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
 
23
/**
24
 * @file
25
 * IFF ACBM/DEEP/ILBM/PBM bitmap decoder
26
 */
27
 
28
#include "libavutil/imgutils.h"
29
#include "bytestream.h"
30
#include "avcodec.h"
31
#include "get_bits.h"
32
#include "internal.h"
33
 
34
// TODO: masking bits
35
typedef enum {
36
    MASK_NONE,
37
    MASK_HAS_MASK,
38
    MASK_HAS_TRANSPARENT_COLOR,
39
    MASK_LASSO
40
} mask_type;
41
 
42
typedef struct {
43
    AVFrame *frame;
44
    int planesize;
45
    uint8_t * planebuf;
46
    uint8_t * ham_buf;      ///< temporary buffer for planar to chunky conversation
47
    uint32_t *ham_palbuf;   ///< HAM decode table
48
    uint32_t *mask_buf;     ///< temporary buffer for palette indices
49
    uint32_t *mask_palbuf;  ///< masking palette table
50
    unsigned  compression;  ///< delta compression method used
51
    unsigned  bpp;          ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
52
    unsigned  ham;          ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
53
    unsigned  flags;        ///< 1 for EHB, 0 is no extra half darkening
54
    unsigned  transparency; ///< TODO: transparency color index in palette
55
    unsigned  masking;      ///< TODO: masking method used
56
    int init; // 1 if buffer and palette data already initialized, 0 otherwise
57
    int16_t   tvdc[16];     ///< TVDC lookup table
58
} IffContext;
59
 
60
#define LUT8_PART(plane, v)                             \
61
    AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
62
    AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
63
    AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
64
    AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
65
    AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
66
    AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
67
    AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
68
    AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
69
    AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
70
    AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
71
    AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
72
    AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
73
    AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
74
    AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
75
    AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
76
    AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
77
 
78
#define LUT8(plane) {                           \
79
    LUT8_PART(plane, 0x0000000),                \
80
    LUT8_PART(plane, 0x1000000),                \
81
    LUT8_PART(plane, 0x0010000),                \
82
    LUT8_PART(plane, 0x1010000),                \
83
    LUT8_PART(plane, 0x0000100),                \
84
    LUT8_PART(plane, 0x1000100),                \
85
    LUT8_PART(plane, 0x0010100),                \
86
    LUT8_PART(plane, 0x1010100),                \
87
    LUT8_PART(plane, 0x0000001),                \
88
    LUT8_PART(plane, 0x1000001),                \
89
    LUT8_PART(plane, 0x0010001),                \
90
    LUT8_PART(plane, 0x1010001),                \
91
    LUT8_PART(plane, 0x0000101),                \
92
    LUT8_PART(plane, 0x1000101),                \
93
    LUT8_PART(plane, 0x0010101),                \
94
    LUT8_PART(plane, 0x1010101),                \
95
}
96
 
97
// 8 planes * 8-bit mask
98
static const uint64_t plane8_lut[8][256] = {
99
    LUT8(0), LUT8(1), LUT8(2), LUT8(3),
100
    LUT8(4), LUT8(5), LUT8(6), LUT8(7),
101
};
102
 
103
#define LUT32(plane) {                                \
104
             0,          0,          0,          0,   \
105
             0,          0,          0, 1 << plane,   \
106
             0,          0, 1 << plane,          0,   \
107
             0,          0, 1 << plane, 1 << plane,   \
108
             0, 1 << plane,          0,          0,   \
109
             0, 1 << plane,          0, 1 << plane,   \
110
             0, 1 << plane, 1 << plane,          0,   \
111
             0, 1 << plane, 1 << plane, 1 << plane,   \
112
    1 << plane,          0,          0,          0,   \
113
    1 << plane,          0,          0, 1 << plane,   \
114
    1 << plane,          0, 1 << plane,          0,   \
115
    1 << plane,          0, 1 << plane, 1 << plane,   \
116
    1 << plane, 1 << plane,          0,          0,   \
117
    1 << plane, 1 << plane,          0, 1 << plane,   \
118
    1 << plane, 1 << plane, 1 << plane,          0,   \
119
    1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
120
}
121
 
122
// 32 planes * 4-bit mask * 4 lookup tables each
123
static const uint32_t plane32_lut[32][16*4] = {
124
    LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
125
    LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
126
    LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
127
    LUT32(12), LUT32(13), LUT32(14), LUT32(15),
128
    LUT32(16), LUT32(17), LUT32(18), LUT32(19),
129
    LUT32(20), LUT32(21), LUT32(22), LUT32(23),
130
    LUT32(24), LUT32(25), LUT32(26), LUT32(27),
131
    LUT32(28), LUT32(29), LUT32(30), LUT32(31),
132
};
133
 
134
// Gray to RGB, required for palette table of grayscale images with bpp < 8
135
static av_always_inline uint32_t gray2rgb(const uint32_t x) {
136
    return x << 16 | x << 8 | x;
137
}
138
 
139
/**
140
 * Convert CMAP buffer (stored in extradata) to lavc palette format
141
 */
142
static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
143
{
144
    IffContext *s = avctx->priv_data;
145
    int count, i;
146
    const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
147
    int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
148
 
149
    if (avctx->bits_per_coded_sample > 8) {
150
        av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
151
        return AVERROR_INVALIDDATA;
152
    }
153
 
154
    count = 1 << avctx->bits_per_coded_sample;
155
    // If extradata is smaller than actually needed, fill the remaining with black.
156
    count = FFMIN(palette_size / 3, count);
157
    if (count) {
158
        for (i = 0; i < count; i++)
159
            pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
160
        if (s->flags && count >= 32) { // EHB
161
            for (i = 0; i < 32; i++)
162
                pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
163
            count = FFMAX(count, 64);
164
        }
165
    } else { // Create gray-scale color palette for bps < 8
166
        count = 1 << avctx->bits_per_coded_sample;
167
 
168
        for (i = 0; i < count; i++)
169
            pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
170
    }
171
    if (s->masking == MASK_HAS_MASK) {
172
        memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
173
        for (i = 0; i < count; i++)
174
            pal[i] &= 0xFFFFFF;
175
    } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
176
        s->transparency < 1 << avctx->bits_per_coded_sample)
177
        pal[s->transparency] &= 0xFFFFFF;
178
    return 0;
179
}
180
 
181
/**
182
 * Extracts the IFF extra context and updates internal
183
 * decoder structures.
184
 *
185
 * @param avctx the AVCodecContext where to extract extra context to
186
 * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
187
 * @return >= 0 in case of success, a negative error code otherwise
188
 */
189
static int extract_header(AVCodecContext *const avctx,
190
                          const AVPacket *const avpkt) {
191
    const uint8_t *buf;
192
    unsigned buf_size;
193
    IffContext *s = avctx->priv_data;
194
    int i, palette_size;
195
 
196
    if (avctx->extradata_size < 2) {
197
        av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
198
        return AVERROR_INVALIDDATA;
199
    }
200
    palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
201
 
202
    if (avpkt) {
203
        int image_size;
204
        if (avpkt->size < 2)
205
            return AVERROR_INVALIDDATA;
206
        image_size = avpkt->size - AV_RB16(avpkt->data);
207
        buf = avpkt->data;
208
        buf_size = bytestream_get_be16(&buf);
209
        if (buf_size <= 1 || image_size <= 1) {
210
            av_log(avctx, AV_LOG_ERROR,
211
                   "Invalid image size received: %u -> image data offset: %d\n",
212
                   buf_size, image_size);
213
            return AVERROR_INVALIDDATA;
214
        }
215
    } else {
216
        buf = avctx->extradata;
217
        buf_size = bytestream_get_be16(&buf);
218
        if (buf_size <= 1 || palette_size < 0) {
219
            av_log(avctx, AV_LOG_ERROR,
220
                   "Invalid palette size received: %u -> palette data offset: %d\n",
221
                   buf_size, palette_size);
222
            return AVERROR_INVALIDDATA;
223
        }
224
    }
225
 
226
    if (buf_size >= 41) {
227
        s->compression  = bytestream_get_byte(&buf);
228
        s->bpp          = bytestream_get_byte(&buf);
229
        s->ham          = bytestream_get_byte(&buf);
230
        s->flags        = bytestream_get_byte(&buf);
231
        s->transparency = bytestream_get_be16(&buf);
232
        s->masking      = bytestream_get_byte(&buf);
233
        for (i = 0; i < 16; i++)
234
            s->tvdc[i] = bytestream_get_be16(&buf);
235
 
236
        if (s->masking == MASK_HAS_MASK) {
237
            if (s->bpp >= 8 && !s->ham) {
238
                avctx->pix_fmt = AV_PIX_FMT_RGB32;
239
                av_freep(&s->mask_buf);
240
                av_freep(&s->mask_palbuf);
241
                s->mask_buf = av_malloc((s->planesize * 32) + FF_INPUT_BUFFER_PADDING_SIZE);
242
                if (!s->mask_buf)
243
                    return AVERROR(ENOMEM);
244
                if (s->bpp > 16) {
245
                    av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
246
                    av_freep(&s->mask_buf);
247
                    return AVERROR(ENOMEM);
248
                }
249
                s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
250
                if (!s->mask_palbuf) {
251
                    av_freep(&s->mask_buf);
252
                    return AVERROR(ENOMEM);
253
                }
254
            }
255
            s->bpp++;
256
        } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
257
            av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
258
            return AVERROR_PATCHWELCOME;
259
        }
260
        if (!s->bpp || s->bpp > 32) {
261
            av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
262
            return AVERROR_INVALIDDATA;
263
        } else if (s->ham >= 8) {
264
            av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
265
            return AVERROR_INVALIDDATA;
266
        }
267
 
268
        av_freep(&s->ham_buf);
269
        av_freep(&s->ham_palbuf);
270
 
271
        if (s->ham) {
272
            int i, count = FFMIN(palette_size / 3, 1 << s->ham);
273
            int ham_count;
274
            const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
275
 
276
            s->ham_buf = av_malloc((s->planesize * 8) + FF_INPUT_BUFFER_PADDING_SIZE);
277
            if (!s->ham_buf)
278
                return AVERROR(ENOMEM);
279
 
280
            ham_count = 8 * (1 << s->ham);
281
            s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
282
            if (!s->ham_palbuf) {
283
                av_freep(&s->ham_buf);
284
                return AVERROR(ENOMEM);
285
            }
286
 
287
            if (count) { // HAM with color palette attached
288
                // prefill with black and palette and set HAM take direct value mask to zero
289
                memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
290
                for (i=0; i < count; i++) {
291
                    s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
292
                }
293
                count = 1 << s->ham;
294
            } else { // HAM with grayscale color palette
295
                count = 1 << s->ham;
296
                for (i=0; i < count; i++) {
297
                    s->ham_palbuf[i*2]   = 0xFF000000; // take direct color value from palette
298
                    s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
299
                }
300
            }
301
            for (i=0; i < count; i++) {
302
                uint32_t tmp = i << (8 - s->ham);
303
                tmp |= tmp >> s->ham;
304
                s->ham_palbuf[(i+count)*2]     = 0xFF00FFFF; // just modify blue color component
305
                s->ham_palbuf[(i+count*2)*2]   = 0xFFFFFF00; // just modify red color component
306
                s->ham_palbuf[(i+count*3)*2]   = 0xFFFF00FF; // just modify green color component
307
                s->ham_palbuf[(i+count)*2+1]   = 0xFF000000 | tmp << 16;
308
                s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
309
                s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
310
            }
311
            if (s->masking == MASK_HAS_MASK) {
312
                for (i = 0; i < ham_count; i++)
313
                    s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
314
            }
315
        }
316
    }
317
 
318
    return 0;
319
}
320
 
321
static av_cold int decode_init(AVCodecContext *avctx)
322
{
323
    IffContext *s = avctx->priv_data;
324
    int err;
325
 
326
    if (avctx->bits_per_coded_sample <= 8) {
327
        int palette_size;
328
 
329
        if (avctx->extradata_size >= 2)
330
            palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
331
        else
332
            palette_size = 0;
333
        avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
334
                         (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
335
    } else if (avctx->bits_per_coded_sample <= 32) {
336
        if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
337
            avctx->pix_fmt = AV_PIX_FMT_RGB32;
338
        } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
339
            avctx->pix_fmt = AV_PIX_FMT_RGB444;
340
        } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
341
            if (avctx->bits_per_coded_sample == 24) {
342
                avctx->pix_fmt = AV_PIX_FMT_0BGR32;
343
            } else if (avctx->bits_per_coded_sample == 32) {
344
                avctx->pix_fmt = AV_PIX_FMT_BGR32;
345
            } else {
346
                avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
347
                return AVERROR_PATCHWELCOME;
348
            }
349
        }
350
    } else {
351
        return AVERROR_INVALIDDATA;
352
    }
353
 
354
    if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
355
        return err;
356
    s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
357
    s->planebuf  = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
358
    if (!s->planebuf)
359
        return AVERROR(ENOMEM);
360
 
361
    s->bpp = avctx->bits_per_coded_sample;
362
    s->frame = av_frame_alloc();
363
    if (!s->frame)
364
        return AVERROR(ENOMEM);
365
 
366
    if ((err = extract_header(avctx, NULL)) < 0)
367
        return err;
368
 
369
    return 0;
370
}
371
 
372
/**
373
 * Decode interleaved plane buffer up to 8bpp
374
 * @param dst Destination buffer
375
 * @param buf Source buffer
376
 * @param buf_size
377
 * @param plane plane number to decode as
378
 */
379
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
380
{
381
    const uint64_t *lut = plane8_lut[plane];
382
    if (plane >= 8) {
383
        av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
384
        return;
385
    }
386
    do {
387
        uint64_t v = AV_RN64A(dst) | lut[*buf++];
388
        AV_WN64A(dst, v);
389
        dst += 8;
390
    } while (--buf_size);
391
}
392
 
393
/**
394
 * Decode interleaved plane buffer up to 24bpp
395
 * @param dst Destination buffer
396
 * @param buf Source buffer
397
 * @param buf_size
398
 * @param plane plane number to decode as
399
 */
400
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
401
{
402
    const uint32_t *lut = plane32_lut[plane];
403
    do {
404
        unsigned mask = (*buf >> 2) & ~3;
405
        dst[0] |= lut[mask++];
406
        dst[1] |= lut[mask++];
407
        dst[2] |= lut[mask++];
408
        dst[3] |= lut[mask];
409
        mask    = (*buf++ << 2) & 0x3F;
410
        dst[4] |= lut[mask++];
411
        dst[5] |= lut[mask++];
412
        dst[6] |= lut[mask++];
413
        dst[7] |= lut[mask];
414
        dst    += 8;
415
    } while (--buf_size);
416
}
417
 
418
#define DECODE_HAM_PLANE32(x)       \
419
    first       = buf[x] << 1;      \
420
    second      = buf[(x)+1] << 1;  \
421
    delta      &= pal[first++];     \
422
    delta      |= pal[first];       \
423
    dst[x]      = delta;            \
424
    delta      &= pal[second++];    \
425
    delta      |= pal[second];      \
426
    dst[(x)+1]  = delta
427
 
428
/**
429
 * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
430
 *
431
 * @param dst the destination 24bpp buffer
432
 * @param buf the source 8bpp chunky buffer
433
 * @param pal the HAM decode table
434
 * @param buf_size the plane size in bytes
435
 */
436
static void decode_ham_plane32(uint32_t *dst, const uint8_t  *buf,
437
                               const uint32_t *const pal, unsigned buf_size)
438
{
439
    uint32_t delta = pal[1]; /* first palette entry */
440
    do {
441
        uint32_t first, second;
442
        DECODE_HAM_PLANE32(0);
443
        DECODE_HAM_PLANE32(2);
444
        DECODE_HAM_PLANE32(4);
445
        DECODE_HAM_PLANE32(6);
446
        buf += 8;
447
        dst += 8;
448
    } while (--buf_size);
449
}
450
 
451
static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
452
                         const uint32_t *const pal, unsigned width)
453
{
454
    do {
455
        *dst++ = pal[*buf++];
456
    } while (--width);
457
}
458
 
459
/**
460
 * Decode one complete byterun1 encoded line.
461
 *
462
 * @param dst the destination buffer where to store decompressed bitstream
463
 * @param dst_size the destination plane size in bytes
464
 * @param buf the source byterun1 compressed bitstream
465
 * @param buf_end the EOF of source byterun1 compressed bitstream
466
 * @return number of consumed bytes in byterun1 compressed bitstream
467
 */
468
static int decode_byterun(uint8_t *dst, int dst_size,
469
                          const uint8_t *buf, const uint8_t *const buf_end)
470
{
471
    const uint8_t *const buf_start = buf;
472
    unsigned x;
473
    for (x = 0; x < dst_size && buf < buf_end;) {
474
        unsigned length;
475
        const int8_t value = *buf++;
476
        if (value >= 0) {
477
            length = value + 1;
478
            memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
479
            buf += length;
480
        } else if (value > -128) {
481
            length = -value + 1;
482
            memset(dst + x, *buf++, FFMIN(length, dst_size - x));
483
        } else { // noop
484
            continue;
485
        }
486
        x += length;
487
    }
488
    return buf - buf_start;
489
}
490
 
491
#define DECODE_RGBX_COMMON(type) \
492
    if (!length) { \
493
        length = bytestream2_get_byte(gb); \
494
        if (!length) { \
495
            length = bytestream2_get_be16(gb); \
496
            if (!length) \
497
                return; \
498
        } \
499
    } \
500
    for (i = 0; i < length; i++) { \
501
        *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
502
        x += 1; \
503
        if (x >= width) { \
504
            y += 1; \
505
            if (y >= height) \
506
                return; \
507
            x = 0; \
508
        } \
509
    }
510
 
511
/**
512
 * Decode RGB8 buffer
513
 * @param[out] dst Destination buffer
514
 * @param width Width of destination buffer (pixels)
515
 * @param height Height of destination buffer (pixels)
516
 * @param linesize Line size of destination buffer (bytes)
517
 */
518
static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
519
{
520
    int x = 0, y = 0, i, length;
521
    while (bytestream2_get_bytes_left(gb) >= 4) {
522
        uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
523
        length = bytestream2_get_byte(gb) & 0x7F;
524
        DECODE_RGBX_COMMON(uint32_t)
525
    }
526
}
527
 
528
/**
529
 * Decode RGBN buffer
530
 * @param[out] dst Destination buffer
531
 * @param width Width of destination buffer (pixels)
532
 * @param height Height of destination buffer (pixels)
533
 * @param linesize Line size of destination buffer (bytes)
534
 */
535
static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
536
{
537
    int x = 0, y = 0, i, length;
538
    while (bytestream2_get_bytes_left(gb) >= 2) {
539
        uint32_t pixel = bytestream2_get_be16u(gb);
540
        length = pixel & 0x7;
541
        pixel >>= 4;
542
        DECODE_RGBX_COMMON(uint16_t)
543
    }
544
}
545
 
546
/**
547
 * Decode DEEP RLE 32-bit buffer
548
 * @param[out] dst Destination buffer
549
 * @param[in] src Source buffer
550
 * @param src_size Source buffer size (bytes)
551
 * @param width Width of destination buffer (pixels)
552
 * @param height Height of destination buffer (pixels)
553
 * @param linesize Line size of destination buffer (bytes)
554
 */
555
static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
556
{
557
    const uint8_t *src_end = src + src_size;
558
    int x = 0, y = 0, i;
559
    while (src + 5 <= src_end) {
560
        int opcode;
561
        opcode = *(int8_t *)src++;
562
        if (opcode >= 0) {
563
            int size = opcode + 1;
564
            for (i = 0; i < size; i++) {
565
                int length = FFMIN(size - i, width);
566
                memcpy(dst + y*linesize + x * 4, src, length * 4);
567
                src += length * 4;
568
                x += length;
569
                i += length;
570
                if (x >= width) {
571
                    x = 0;
572
                    y += 1;
573
                    if (y >= height)
574
                        return;
575
                }
576
            }
577
        } else {
578
            int size = -opcode + 1;
579
            uint32_t pixel = AV_RN32(src);
580
            for (i = 0; i < size; i++) {
581
                *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
582
                x += 1;
583
                if (x >= width) {
584
                    x = 0;
585
                    y += 1;
586
                    if (y >= height)
587
                        return;
588
                }
589
            }
590
            src += 4;
591
        }
592
    }
593
}
594
 
595
/**
596
 * Decode DEEP TVDC 32-bit buffer
597
 * @param[out] dst Destination buffer
598
 * @param[in] src Source buffer
599
 * @param src_size Source buffer size (bytes)
600
 * @param width Width of destination buffer (pixels)
601
 * @param height Height of destination buffer (pixels)
602
 * @param linesize Line size of destination buffer (bytes)
603
 * @param[int] tvdc TVDC lookup table
604
 */
605
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)
606
{
607
    int x = 0, y = 0, plane = 0;
608
    int8_t pixel = 0;
609
    int i, j;
610
 
611
    for (i = 0; i < src_size * 2;) {
612
#define GETNIBBLE ((i & 1) ?  (src[i>>1] & 0xF) : (src[i>>1] >> 4))
613
        int d = tvdc[GETNIBBLE];
614
        i++;
615
        if (d) {
616
            pixel += d;
617
            dst[y * linesize + x*4 + plane] = pixel;
618
            x++;
619
        } else {
620
            if (i >= src_size * 2)
621
                return;
622
            d = GETNIBBLE + 1;
623
            i++;
624
            d = FFMIN(d, width - x);
625
            for (j = 0; j < d; j++) {
626
                dst[y * linesize + x*4 + plane] = pixel;
627
                x++;
628
            }
629
        }
630
        if (x >= width) {
631
            plane++;
632
            if (plane >= 4) {
633
                y++;
634
                if (y >= height)
635
                    return;
636
                plane = 0;
637
            }
638
            x = 0;
639
            pixel = 0;
640
            i = (i + 1) & ~1;
641
        }
642
    }
643
}
644
 
645
static int unsupported(AVCodecContext *avctx)
646
{
647
    IffContext *s = avctx->priv_data;
648
    avpriv_request_sample(avctx, "bitmap (compression %i, bpp %i, ham %i)", s->compression, s->bpp, s->ham);
649
    return AVERROR_INVALIDDATA;
650
}
651
 
652
static int decode_frame(AVCodecContext *avctx,
653
                        void *data, int *got_frame,
654
                        AVPacket *avpkt)
655
{
656
    IffContext *s          = avctx->priv_data;
657
    const uint8_t *buf     = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
658
    const int buf_size     = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
659
    const uint8_t *buf_end = buf + buf_size;
660
    int y, plane, res;
661
    GetByteContext gb;
662
 
663
    if ((res = extract_header(avctx, avpkt)) < 0)
664
        return res;
665
    if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
666
        return res;
667
    if (!s->init && avctx->bits_per_coded_sample <= 8 &&
668
        avctx->pix_fmt == AV_PIX_FMT_PAL8) {
669
        if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
670
            return res;
671
    } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
672
               avctx->pix_fmt == AV_PIX_FMT_RGB32) {
673
        if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
674
            return res;
675
    }
676
    s->init = 1;
677
 
678
    switch (s->compression) {
679
    case 0:
680
        if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
681
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
682
                memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
683
                for (plane = 0; plane < s->bpp; plane++) {
684
                    for (y = 0; y < avctx->height && buf < buf_end; y++) {
685
                        uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
686
                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
687
                        buf += s->planesize;
688
                    }
689
                }
690
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
691
                memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
692
                for (y = 0; y < avctx->height; y++) {
693
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
694
                    memset(s->ham_buf, 0, s->planesize * 8);
695
                    for (plane = 0; plane < s->bpp; plane++) {
696
                        const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
697
                        if (start >= buf_end)
698
                            break;
699
                        decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
700
                    }
701
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
702
                }
703
            } else
704
                return unsupported(avctx);
705
        } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
706
            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
707
            int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
708
            int x;
709
            for (y = 0; y < avctx->height && buf < buf_end; y++) {
710
                uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
711
                memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
712
                buf += raw_width;
713
                if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
714
                    for (x = 0; x < avctx->width; x++)
715
                        row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
716
                }
717
            }
718
        } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
719
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
720
                for (y = 0; y < avctx->height; y++) {
721
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
722
                    memset(row, 0, avctx->width);
723
                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
724
                        decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
725
                        buf += s->planesize;
726
                    }
727
                }
728
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
729
                for (y = 0; y < avctx->height; y++) {
730
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
731
                    memset(s->ham_buf, 0, s->planesize * 8);
732
                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
733
                        decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
734
                        buf += s->planesize;
735
                    }
736
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
737
                }
738
            } else { // AV_PIX_FMT_BGR32
739
                for (y = 0; y < avctx->height; y++) {
740
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
741
                    memset(row, 0, avctx->width << 2);
742
                    for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
743
                        decodeplane32((uint32_t *)row, buf,
744
                                      FFMIN(s->planesize, buf_end - buf), plane);
745
                        buf += s->planesize;
746
                    }
747
                }
748
            }
749
        } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
750
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
751
                for (y = 0; y < avctx->height && buf_end > buf; y++) {
752
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
753
                    memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
754
                    buf += avctx->width + (avctx->width % 2); // padding if odd
755
                }
756
            } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
757
                for (y = 0; y < avctx->height && buf_end > buf; y++) {
758
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
759
                    memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
760
                    buf += avctx->width + (avctx->width & 1); // padding if odd
761
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
762
                }
763
            } else
764
                return unsupported(avctx);
765
        }
766
        break;
767
    case 1:
768
        if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
769
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
770
                for (y = 0; y < avctx->height; y++) {
771
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
772
                    memset(row, 0, avctx->width);
773
                    for (plane = 0; plane < s->bpp; plane++) {
774
                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
775
                        decodeplane8(row, s->planebuf, s->planesize, plane);
776
                    }
777
                }
778
            } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
779
                for (y = 0; y < avctx->height; y++) {
780
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
781
                    memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
782
                    for (plane = 0; plane < s->bpp; plane++) {
783
                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
784
                        decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
785
                    }
786
                    lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
787
                }
788
            } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
789
                for (y = 0; y < avctx->height; y++) {
790
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
791
                    memset(s->ham_buf, 0, s->planesize * 8);
792
                    for (plane = 0; plane < s->bpp; plane++) {
793
                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
794
                        decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
795
                    }
796
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
797
                }
798
            } else { // AV_PIX_FMT_BGR32
799
                for (y = 0; y < avctx->height; y++) {
800
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
801
                    memset(row, 0, avctx->width << 2);
802
                    for (plane = 0; plane < s->bpp; plane++) {
803
                        buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
804
                        decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
805
                    }
806
                }
807
            }
808
        } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
809
            if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
810
                for (y = 0; y < avctx->height; y++) {
811
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
812
                    buf += decode_byterun(row, avctx->width, buf, buf_end);
813
                }
814
            } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
815
                for (y = 0; y < avctx->height; y++) {
816
                    uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
817
                    buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
818
                    decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
819
                }
820
            } else
821
                return unsupported(avctx);
822
        } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
823
            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
824
            if (av_get_bits_per_pixel(desc) == 32)
825
                decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
826
            else
827
                return unsupported(avctx);
828
        }
829
        break;
830
    case 4:
831
        bytestream2_init(&gb, buf, buf_size);
832
        if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8'))
833
            decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
834
        else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N'))
835
            decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
836
        else
837
            return unsupported(avctx);
838
        break;
839
    case 5:
840
        if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
841
            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
842
            if (av_get_bits_per_pixel(desc) == 32)
843
                decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
844
            else
845
                return unsupported(avctx);
846
        } else
847
            return unsupported(avctx);
848
        break;
849
    default:
850
        return unsupported(avctx);
851
    }
852
 
853
    if ((res = av_frame_ref(data, s->frame)) < 0)
854
        return res;
855
 
856
    *got_frame = 1;
857
 
858
    return buf_size;
859
}
860
 
861
static av_cold int decode_end(AVCodecContext *avctx)
862
{
863
    IffContext *s = avctx->priv_data;
864
    av_frame_free(&s->frame);
865
    av_freep(&s->planebuf);
866
    av_freep(&s->ham_buf);
867
    av_freep(&s->ham_palbuf);
868
    return 0;
869
}
870
 
871
#if CONFIG_IFF_ILBM_DECODER
872
AVCodec ff_iff_ilbm_decoder = {
873
    .name           = "iff",
874
    .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
875
    .type           = AVMEDIA_TYPE_VIDEO,
876
    .id             = AV_CODEC_ID_IFF_ILBM,
877
    .priv_data_size = sizeof(IffContext),
878
    .init           = decode_init,
879
    .close          = decode_end,
880
    .decode         = decode_frame,
881
    .capabilities   = CODEC_CAP_DR1,
882
};
883
#endif
884
#if CONFIG_IFF_BYTERUN1_DECODER
885
AVCodec ff_iff_byterun1_decoder = {
886
    .name           = "iff",
887
    .long_name      = NULL_IF_CONFIG_SMALL("IFF"),
888
    .type           = AVMEDIA_TYPE_VIDEO,
889
    .id             = AV_CODEC_ID_IFF_BYTERUN1,
890
    .priv_data_size = sizeof(IffContext),
891
    .init           = decode_init,
892
    .close          = decode_end,
893
    .decode         = decode_frame,
894
    .capabilities   = CODEC_CAP_DR1,
895
};
896
#endif