iff.c 14.0 KB
Newer Older
P
Peter Ross 已提交
1 2 3
/*
 * IFF PBM/ILBM bitmap decoder
 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4
 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
P
Peter Ross 已提交
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
24
 * @file
P
Peter Ross 已提交
25 26 27
 * IFF PBM/ILBM bitmap decoder
 */

28
#include "libavutil/imgutils.h"
P
Peter Ross 已提交
29 30
#include "bytestream.h"
#include "avcodec.h"
P
Peter Ross 已提交
31 32 33 34
#include "get_bits.h"

typedef struct {
    AVFrame frame;
35
    int planesize;
P
Peter Ross 已提交
36
    uint8_t * planebuf;
37
    int init; // 1 if buffer and palette data already initialized, 0 otherwise
P
Peter Ross 已提交
38
} IffContext;
P
Peter Ross 已提交
39

40
#define LUT8_PART(plane, v)                             \
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
    AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
    AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

#define LUT8(plane) {                           \
    LUT8_PART(plane, 0x0000000),                \
    LUT8_PART(plane, 0x1000000),                \
    LUT8_PART(plane, 0x0010000),                \
    LUT8_PART(plane, 0x1010000),                \
    LUT8_PART(plane, 0x0000100),                \
    LUT8_PART(plane, 0x1000100),                \
    LUT8_PART(plane, 0x0010100),                \
    LUT8_PART(plane, 0x1010100),                \
    LUT8_PART(plane, 0x0000001),                \
    LUT8_PART(plane, 0x1000001),                \
    LUT8_PART(plane, 0x0010001),                \
    LUT8_PART(plane, 0x1010001),                \
    LUT8_PART(plane, 0x0000101),                \
    LUT8_PART(plane, 0x1000101),                \
    LUT8_PART(plane, 0x0010101),                \
    LUT8_PART(plane, 0x1010101),                \
}

// 8 planes * 8-bit mask
static const uint64_t plane8_lut[8][256] = {
    LUT8(0), LUT8(1), LUT8(2), LUT8(3),
    LUT8(4), LUT8(5), LUT8(6), LUT8(7),
};

S
Sebastian Vater 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
#define LUT32(plane) {                                \
             0,          0,          0,          0,   \
             0,          0,          0, 1 << plane,   \
             0,          0, 1 << plane,          0,   \
             0,          0, 1 << plane, 1 << plane,   \
             0, 1 << plane,          0,          0,   \
             0, 1 << plane,          0, 1 << plane,   \
             0, 1 << plane, 1 << plane,          0,   \
             0, 1 << plane, 1 << plane, 1 << plane,   \
    1 << plane,          0,          0,          0,   \
    1 << plane,          0,          0, 1 << plane,   \
    1 << plane,          0, 1 << plane,          0,   \
    1 << plane,          0, 1 << plane, 1 << plane,   \
    1 << plane, 1 << plane,          0,          0,   \
    1 << plane, 1 << plane,          0, 1 << plane,   \
    1 << plane, 1 << plane, 1 << plane,          0,   \
    1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
}

// 32 planes * 4-bit mask * 4 lookup tables each
static const uint32_t plane32_lut[32][16*4] = {
    LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
    LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
    LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
    LUT32(12), LUT32(13), LUT32(14), LUT32(15),
    LUT32(16), LUT32(17), LUT32(18), LUT32(19),
    LUT32(20), LUT32(21), LUT32(22), LUT32(23),
    LUT32(24), LUT32(25), LUT32(26), LUT32(27),
    LUT32(28), LUT32(29), LUT32(30), LUT32(31),
};

114 115 116 117 118
// Gray to RGB, required for palette table of grayscale images with bpp < 8
static av_always_inline uint32_t gray2rgb(const uint32_t x) {
    return x << 16 | x << 8 | x;
}

P
Peter Ross 已提交
119 120 121
/**
 * Convert CMAP buffer (stored in extradata) to lavc palette format
 */
122
static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
P
Peter Ross 已提交
123
{
124
    int count, i;
P
Peter Ross 已提交
125 126 127 128 129 130 131

    if (avctx->bits_per_coded_sample > 8) {
        av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
        return AVERROR_INVALIDDATA;
    }

    count = 1 << avctx->bits_per_coded_sample;
132 133
    // If extradata is smaller than actually needed, fill the remaining with black.
    count = FFMIN(avctx->extradata_size / 3, count);
134
    if (count) {
135 136 137
        for (i=0; i < count; i++) {
            pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
        }
138 139 140 141 142 143 144
    } else { // Create gray-scale color palette for bps < 8
        count = 1 << avctx->bits_per_coded_sample;

        for (i=0; i < count; i++) {
            pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
        }
    }
P
Peter Ross 已提交
145 146 147 148 149
    return 0;
}

static av_cold int decode_init(AVCodecContext *avctx)
{
P
Peter Ross 已提交
150
    IffContext *s = avctx->priv_data;
151
    int err;
P
Peter Ross 已提交
152 153

    if (avctx->bits_per_coded_sample <= 8) {
154 155 156
        avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
                          avctx->extradata_size) ? PIX_FMT_PAL8
                                                 : PIX_FMT_GRAY8;
P
Peter Ross 已提交
157 158 159 160 161
    } else if (avctx->bits_per_coded_sample <= 32) {
        avctx->pix_fmt = PIX_FMT_BGR32;
    } else {
        return AVERROR_INVALIDDATA;
    }
P
Peter Ross 已提交
162

163
    if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
164
        return err;
165
    s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
P
Peter Ross 已提交
166 167 168
    s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!s->planebuf)
        return AVERROR(ENOMEM);
P
Peter Ross 已提交
169

P
Peter Ross 已提交
170
    s->frame.reference = 1;
P
Peter Ross 已提交
171

172
    return 0;
P
Peter Ross 已提交
173 174 175
}

/**
176 177 178 179 180 181
 * Decode interleaved plane buffer up to 8bpp
 * @param dst Destination buffer
 * @param buf Source buffer
 * @param buf_size
 * @param plane plane number to decode as
 */
182
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
183
{
184
    const uint64_t *lut = plane8_lut[plane];
185
    do {
186 187
        uint64_t v = AV_RN64A(dst) | lut[*buf++];
        AV_WN64A(dst, v);
188
        dst += 8;
189
    } while (--buf_size);
190 191 192 193
}

/**
 * Decode interleaved plane buffer up to 24bpp
P
Peter Ross 已提交
194 195 196 197
 * @param dst Destination buffer
 * @param buf Source buffer
 * @param buf_size
 * @param plane plane number to decode as
P
Peter Ross 已提交
198
 */
S
Sebastian Vater 已提交
199
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
200
{
S
Sebastian Vater 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214
    const uint32_t *lut = plane32_lut[plane];
    do {
        unsigned mask = (*buf >> 2) & ~3;
        dst[0] |= lut[mask++];
        dst[1] |= lut[mask++];
        dst[2] |= lut[mask++];
        dst[3] |= lut[mask];
        mask = (*buf++ << 2) & 0x3F;
        dst[4] |= lut[mask++];
        dst[5] |= lut[mask++];
        dst[6] |= lut[mask++];
        dst[7] |= lut[mask];
        dst += 8;
    } while (--buf_size);
P
Peter Ross 已提交
215 216
}

217
/**
218
 * Decode one complete byterun1 encoded line.
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
 *
 * @param dst the destination buffer where to store decompressed bitstream
 * @param dst_size the destination plane size in bytes
 * @param buf the source byterun1 compressed bitstream
 * @param buf_end the EOF of source byterun1 compressed bitstream
 * @return number of consumed bytes in byterun1 compressed bitstream
*/
static int decode_byterun(uint8_t *dst, int dst_size,
                          const uint8_t *buf, const uint8_t *const buf_end) {
    const uint8_t *const buf_start = buf;
    unsigned x;
    for (x = 0; x < dst_size && buf < buf_end;) {
        unsigned length;
        const int8_t value = *buf++;
        if (value >= 0) {
            length = value + 1;
            memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
            buf += length;
        } else if (value > -128) {
            length = -value + 1;
            memset(dst + x, *buf++, FFMIN(length, dst_size - x));
        } else { // noop
            continue;
        }
        x += length;
    }
    return buf - buf_start;
}

P
Peter Ross 已提交
248 249 250 251
static int decode_frame_ilbm(AVCodecContext *avctx,
                            void *data, int *data_size,
                            AVPacket *avpkt)
{
P
Peter Ross 已提交
252
    IffContext *s = avctx->priv_data;
P
Peter Ross 已提交
253
    const uint8_t *buf = avpkt->data;
254
    int buf_size = avpkt->size;
255
    const uint8_t *buf_end = buf+buf_size;
256
    int y, plane, res;
P
Peter Ross 已提交
257

258 259 260 261 262 263
    if (s->init) {
        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
            return res;
        }
    } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
P
Peter Ross 已提交
264
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
265 266 267 268
        return res;
    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
            return res;
P
Peter Ross 已提交
269
    }
270
    s->init = 1;
P
Peter Ross 已提交
271

272
    if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
273
        if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
S
Sebastian Vater 已提交
274 275 276 277 278 279 280
            for(y = 0; y < avctx->height; y++ ) {
                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
                memset(row, 0, avctx->width);
                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                    buf += s->planesize;
                }
281
            }
S
Sebastian Vater 已提交
282 283 284 285 286 287 288 289
        } else { // PIX_FMT_BGR32
            for(y = 0; y < avctx->height; y++ ) {
                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
                memset(row, 0, avctx->width << 2);
                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
                    decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
                    buf += s->planesize;
                }
290
            }
P
Peter Ross 已提交
291
        }
292
    } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
293 294 295
        for(y = 0; y < avctx->height; y++ ) {
            uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
            memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
296
            buf += avctx->width + (avctx->width % 2); // padding if odd
297 298
        }
    }
P
Peter Ross 已提交
299 300

    *data_size = sizeof(AVFrame);
P
Peter Ross 已提交
301
    *(AVFrame*)data = s->frame;
P
Peter Ross 已提交
302 303 304 305 306 307 308
    return buf_size;
}

static int decode_frame_byterun1(AVCodecContext *avctx,
                            void *data, int *data_size,
                            AVPacket *avpkt)
{
P
Peter Ross 已提交
309
    IffContext *s = avctx->priv_data;
P
Peter Ross 已提交
310
    const uint8_t *buf = avpkt->data;
311
    int buf_size = avpkt->size;
P
Peter Ross 已提交
312
    const uint8_t *buf_end = buf+buf_size;
313
    int y, plane, res;
P
Peter Ross 已提交
314

315 316 317 318 319 320
    if (s->init) {
        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
            return res;
        }
    } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
P
Peter Ross 已提交
321
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
322 323 324 325
        return res;
    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
            return res;
P
Peter Ross 已提交
326
    }
327
    s->init = 1;
P
Peter Ross 已提交
328

329
    if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
330
        if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
S
Sebastian Vater 已提交
331 332 333 334
            for(y = 0; y < avctx->height ; y++ ) {
                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
                memset(row, 0, avctx->width);
                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
335
                    buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
336
                    decodeplane8(row, s->planebuf, s->planesize, plane);
337 338
                }
            }
S
Sebastian Vater 已提交
339
        } else { //PIX_FMT_BGR32
340 341 342 343
            for(y = 0; y < avctx->height ; y++ ) {
                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
                memset(row, 0, avctx->width << 2);
                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
344
                    buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
345
                    decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
P
Peter Ross 已提交
346
                }
P
Peter Ross 已提交
347
            }
348
        }
S
Sebastian Vater 已提交
349 350 351
    } else {
        for(y = 0; y < avctx->height ; y++ ) {
            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
352
            buf += decode_byterun(row, avctx->width, buf, buf_end);
P
Peter Ross 已提交
353 354 355 356
        }
    }

    *data_size = sizeof(AVFrame);
P
Peter Ross 已提交
357
    *(AVFrame*)data = s->frame;
P
Peter Ross 已提交
358 359 360 361 362
    return buf_size;
}

static av_cold int decode_end(AVCodecContext *avctx)
{
P
Peter Ross 已提交
363 364 365 366
    IffContext *s = avctx->priv_data;
    if (s->frame.data[0])
        avctx->release_buffer(avctx, &s->frame);
    av_freep(&s->planebuf);
P
Peter Ross 已提交
367 368 369
    return 0;
}

370
AVCodec ff_iff_ilbm_decoder = {
P
Peter Ross 已提交
371
    "iff_ilbm",
372
    AVMEDIA_TYPE_VIDEO,
P
Peter Ross 已提交
373
    CODEC_ID_IFF_ILBM,
P
Peter Ross 已提交
374
    sizeof(IffContext),
P
Peter Ross 已提交
375 376 377 378 379 380 381 382
    decode_init,
    NULL,
    decode_end,
    decode_frame_ilbm,
    CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
};

383
AVCodec ff_iff_byterun1_decoder = {
P
Peter Ross 已提交
384
    "iff_byterun1",
385
    AVMEDIA_TYPE_VIDEO,
P
Peter Ross 已提交
386
    CODEC_ID_IFF_BYTERUN1,
P
Peter Ross 已提交
387
    sizeof(IffContext),
P
Peter Ross 已提交
388 389 390 391 392 393 394
    decode_init,
    NULL,
    decode_end,
    decode_frame_byterun1,
    CODEC_CAP_DR1,
    .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
};