Statistics
| Branch: | Revision:

ffmpeg / libavcodec / iff.c @ 2912e87a

History | View | Annotate | Download (13.9 KB)

1
/*
2
 * IFF PBM/ILBM 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 Libav.
7
 *
8
 * Libav 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
 * Libav 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 Libav; 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 PBM/ILBM bitmap decoder
26
 */
27

    
28
#include "libavutil/imgutils.h"
29
#include "bytestream.h"
30
#include "avcodec.h"
31
#include "get_bits.h"
32

    
33
typedef struct {
34
    AVFrame frame;
35
    int planesize;
36
    uint8_t * planebuf;
37
    int init; // 1 if buffer and palette data already initialized, 0 otherwise
38
} IffContext;
39

    
40
#define LUT8_PART(plane, v)                             \
41
    AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane,  \
42
    AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane,  \
43
    AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane,  \
44
    AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane,  \
45
    AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane,  \
46
    AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane,  \
47
    AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane,  \
48
    AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane,  \
49
    AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane,  \
50
    AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane,  \
51
    AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane,  \
52
    AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane,  \
53
    AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane,  \
54
    AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane,  \
55
    AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane,  \
56
    AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
57

    
58
#define LUT8(plane) {                           \
59
    LUT8_PART(plane, 0x0000000),                \
60
    LUT8_PART(plane, 0x1000000),                \
61
    LUT8_PART(plane, 0x0010000),                \
62
    LUT8_PART(plane, 0x1010000),                \
63
    LUT8_PART(plane, 0x0000100),                \
64
    LUT8_PART(plane, 0x1000100),                \
65
    LUT8_PART(plane, 0x0010100),                \
66
    LUT8_PART(plane, 0x1010100),                \
67
    LUT8_PART(plane, 0x0000001),                \
68
    LUT8_PART(plane, 0x1000001),                \
69
    LUT8_PART(plane, 0x0010001),                \
70
    LUT8_PART(plane, 0x1010001),                \
71
    LUT8_PART(plane, 0x0000101),                \
72
    LUT8_PART(plane, 0x1000101),                \
73
    LUT8_PART(plane, 0x0010101),                \
74
    LUT8_PART(plane, 0x1010101),                \
75
}
76

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

    
83
#define LUT32(plane) {                                \
84
             0,          0,          0,          0,   \
85
             0,          0,          0, 1 << plane,   \
86
             0,          0, 1 << plane,          0,   \
87
             0,          0, 1 << plane, 1 << plane,   \
88
             0, 1 << plane,          0,          0,   \
89
             0, 1 << plane,          0, 1 << plane,   \
90
             0, 1 << plane, 1 << plane,          0,   \
91
             0, 1 << plane, 1 << plane, 1 << plane,   \
92
    1 << plane,          0,          0,          0,   \
93
    1 << plane,          0,          0, 1 << plane,   \
94
    1 << plane,          0, 1 << plane,          0,   \
95
    1 << plane,          0, 1 << plane, 1 << plane,   \
96
    1 << plane, 1 << plane,          0,          0,   \
97
    1 << plane, 1 << plane,          0, 1 << plane,   \
98
    1 << plane, 1 << plane, 1 << plane,          0,   \
99
    1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
100
}
101

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

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

    
119
/**
120
 * Convert CMAP buffer (stored in extradata) to lavc palette format
121
 */
122
static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
123
{
124
    int count, i;
125

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

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

    
141
        for (i=0; i < count; i++) {
142
            pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
143
        }
144
    }
145
    return 0;
146
}
147

    
148
static av_cold int decode_init(AVCodecContext *avctx)
149
{
150
    IffContext *s = avctx->priv_data;
151
    int err;
152

    
153
    if (avctx->bits_per_coded_sample <= 8) {
154
        avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
155
                          avctx->extradata_size) ? PIX_FMT_PAL8
156
                                                 : PIX_FMT_GRAY8;
157
    } else if (avctx->bits_per_coded_sample <= 32) {
158
        avctx->pix_fmt = PIX_FMT_BGR32;
159
    } else {
160
        return AVERROR_INVALIDDATA;
161
    }
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
    s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
167
    if (!s->planebuf)
168
        return AVERROR(ENOMEM);
169

    
170
    s->frame.reference = 1;
171

    
172
    return 0;
173
}
174

    
175
/**
176
 * Decode interleaved plane buffer up to 8bpp
177
 * @param dst Destination buffer
178
 * @param buf Source buffer
179
 * @param buf_size
180
 * @param plane plane number to decode as
181
 */
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
        uint64_t v = AV_RN64A(dst) | lut[*buf++];
187
        AV_WN64A(dst, v);
188
        dst += 8;
189
    } while (--buf_size);
190
}
191

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

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

    
248
static int decode_frame_ilbm(AVCodecContext *avctx,
249
                            void *data, int *data_size,
250
                            AVPacket *avpkt)
251
{
252
    IffContext *s = avctx->priv_data;
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;
257

    
258
    if (s->init) {
259
        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
260
            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
261
            return res;
262
        }
263
    } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
264
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
265
        return res;
266
    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
267
        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
268
            return res;
269
    }
270
    s->init = 1;
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) {
274
            for(y = 0; y < avctx->height; y++ ) {
275
                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
276
                memset(row, 0, avctx->width);
277
                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
278
                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
279
                    buf += s->planesize;
280
                }
281
            }
282
        } else { // PIX_FMT_BGR32
283
            for(y = 0; y < avctx->height; y++ ) {
284
                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
285
                memset(row, 0, avctx->width << 2);
286
                for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
287
                    decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
288
                    buf += s->planesize;
289
                }
290
            }
291
        }
292
    } else if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { // IFF-PBM
293
        for(y = 0; y < avctx->height; y++ ) {
294
            uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
295
            memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
296
            buf += avctx->width + (avctx->width % 2); // padding if odd
297
        }
298
    }
299

    
300
    *data_size = sizeof(AVFrame);
301
    *(AVFrame*)data = s->frame;
302
    return buf_size;
303
}
304

    
305
static int decode_frame_byterun1(AVCodecContext *avctx,
306
                            void *data, int *data_size,
307
                            AVPacket *avpkt)
308
{
309
    IffContext *s = avctx->priv_data;
310
    const uint8_t *buf = avpkt->data;
311
    int buf_size = avpkt->size;
312
    const uint8_t *buf_end = buf+buf_size;
313
    int y, plane, res;
314

    
315
    if (s->init) {
316
        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
317
            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
318
            return res;
319
        }
320
    } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
321
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
322
        return res;
323
    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {
324
        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
325
            return res;
326
    }
327
    s->init = 1;
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) {
331
            for(y = 0; y < avctx->height ; y++ ) {
332
                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
333
                memset(row, 0, avctx->width);
334
                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
            }
339
        } else { //PIX_FMT_BGR32
340
            for(y = 0; y < avctx->height ; y++ ) {
341
                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
342
                memset(row, 0, avctx->width << 2);
343
                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
                }
347
            }
348
        }
349
    } else {
350
        for(y = 0; y < avctx->height ; y++ ) {
351
            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
352
            buf += decode_byterun(row, avctx->width, buf, buf_end);
353
        }
354
    }
355

    
356
    *data_size = sizeof(AVFrame);
357
    *(AVFrame*)data = s->frame;
358
    return buf_size;
359
}
360

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

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

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