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