iff.c 14.2 KB
Newer Older
Peter Ross's avatar
Peter Ross committed
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>
Peter Ross's avatar
Peter Ross committed
5
 *
6
 * This file is part of Libav.
Peter Ross's avatar
Peter Ross committed
7
 *
8
 * Libav is free software; you can redistribute it and/or
Peter Ross's avatar
Peter Ross committed
9 10 11 12
 * 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.
 *
13
 * Libav is distributed in the hope that it will be useful,
Peter Ross's avatar
Peter Ross committed
14 15 16 17 18
 * 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
19
 * License along with Libav; if not, write to the Free Software
Peter Ross's avatar
Peter Ross committed
20 21 22 23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
24
 * @file
Peter Ross's avatar
Peter Ross committed
25 26 27
 * IFF PBM/ILBM bitmap decoder
 */

28
#include "libavutil/imgutils.h"
Peter Ross's avatar
Peter Ross committed
29 30
#include "bytestream.h"
#include "avcodec.h"
31 32 33 34
#include "get_bits.h"

typedef struct {
    AVFrame frame;
35
    int planesize;
36
    uint8_t * planebuf;
37
    int init; // 1 if buffer and palette data already initialized, 0 otherwise
38
} IffContext;
Peter Ross's avatar
Peter Ross committed
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),
};

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;
}

Peter Ross's avatar
Peter Ross committed
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)
Peter Ross's avatar
Peter Ross committed
123
{
124
    int count, i;
Peter Ross's avatar
Peter Ross committed
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);
        }
    }
Peter Ross's avatar
Peter Ross committed
145 146 147 148 149
    return 0;
}

static av_cold int decode_init(AVCodecContext *avctx)
{
150
    IffContext *s = avctx->priv_data;
151
    int err;
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;
157 158 159 160 161
    } else if (avctx->bits_per_coded_sample <= 32) {
        avctx->pix_fmt = PIX_FMT_BGR32;
    } else {
        return AVERROR_INVALIDDATA;
    }
Peter Ross's avatar
Peter Ross committed
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
166 167 168
    s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!s->planebuf)
        return AVERROR(ENOMEM);
Peter Ross's avatar
Peter Ross committed
169

170
    s->frame.reference = 1;
Peter Ross's avatar
Peter Ross committed
171

172
    return 0;
Peter Ross's avatar
Peter Ross committed
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
194 195 196 197
 * @param dst Destination buffer
 * @param buf Source buffer
 * @param buf_size
 * @param plane plane number to decode as
Peter Ross's avatar
Peter Ross committed
198
 */
199
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
200
{
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);
Peter Ross's avatar
Peter Ross committed
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;
}

Peter Ross's avatar
Peter Ross committed
248 249 250 251
static int decode_frame_ilbm(AVCodecContext *avctx,
                            void *data, int *data_size,
                            AVPacket *avpkt)
{
252
    IffContext *s = avctx->priv_data;
Peter Ross's avatar
Peter Ross committed
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;
Peter Ross's avatar
Peter Ross committed
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) {
Peter Ross's avatar
Peter Ross committed
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;
Peter Ross's avatar
Peter Ross committed
269
    }
270
    s->init = 1;
Peter Ross's avatar
Peter Ross committed
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) {
Sebastian Vater's avatar
Sebastian Vater committed
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
            }
Sebastian Vater's avatar
Sebastian Vater committed
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
            }
Peter Ross's avatar
Peter Ross committed
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
        }
    }
Peter Ross's avatar
Peter Ross committed
299 300

    *data_size = sizeof(AVFrame);
301
    *(AVFrame*)data = s->frame;
Peter Ross's avatar
Peter Ross committed
302 303 304 305 306 307 308
    return buf_size;
}

static int decode_frame_byterun1(AVCodecContext *avctx,
                            void *data, int *data_size,
                            AVPacket *avpkt)
{
309
    IffContext *s = avctx->priv_data;
Peter Ross's avatar
Peter Ross committed
310
    const uint8_t *buf = avpkt->data;
311
    int buf_size = avpkt->size;
Peter Ross's avatar
Peter Ross committed
312
    const uint8_t *buf_end = buf+buf_size;
313
    int y, plane, res;
Peter Ross's avatar
Peter Ross committed
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) {
Peter Ross's avatar
Peter Ross committed
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;
Peter Ross's avatar
Peter Ross committed
326
    }
327
    s->init = 1;
Peter Ross's avatar
Peter Ross committed
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) {
Sebastian Vater's avatar
Sebastian Vater committed
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
                }
            }
Sebastian Vater's avatar
Sebastian Vater committed
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);
346
                }
Peter Ross's avatar
Peter Ross committed
347
            }
348
        }
Sebastian Vater's avatar
Sebastian Vater committed
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);
Peter Ross's avatar
Peter Ross committed
353 354 355 356
        }
    }

    *data_size = sizeof(AVFrame);
357
    *(AVFrame*)data = s->frame;
Peter Ross's avatar
Peter Ross committed
358 359 360 361 362
    return buf_size;
}

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

370
AVCodec ff_iff_ilbm_decoder = {
371 372 373 374 375 376 377 378
    .name           = "iff_ilbm",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_IFF_ILBM,
    .priv_data_size = sizeof(IffContext),
    .init           = decode_init,
    .close          = decode_end,
    .decode         = decode_frame_ilbm,
    .capabilities   = CODEC_CAP_DR1,
Peter Ross's avatar
Peter Ross committed
379 380 381
    .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
};

382
AVCodec ff_iff_byterun1_decoder = {
383 384 385 386 387 388 389 390
    .name           = "iff_byterun1",
    .type           = AVMEDIA_TYPE_VIDEO,
    .id             = CODEC_ID_IFF_BYTERUN1,
    .priv_data_size = sizeof(IffContext),
    .init           = decode_init,
    .close          = decode_end,
    .decode         = decode_frame_byterun1,
    .capabilities   = CODEC_CAP_DR1,
Peter Ross's avatar
Peter Ross committed
391 392
    .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
};