Statistics
| Branch: | Revision:

ffmpeg / libavcodec / iff.c @ ebcf7c32

History | View | Annotate | Download (12.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 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 PBM/ILBM bitmap decoder
26
 */
27

    
28
#include "bytestream.h"
29
#include "avcodec.h"
30
#include "get_bits.h"
31
#include "iff.h"
32

    
33
typedef struct {
34
    AVFrame frame;
35
    int planesize;
36
    uint8_t * planebuf;
37
} IffContext;
38

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

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

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

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

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

    
113
/**
114
 * Convert CMAP buffer (stored in extradata) to lavc palette format
115
 */
116
int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
117
{
118
    int count, i;
119

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

    
125
    count = 1 << avctx->bits_per_coded_sample;
126
    // If extradata is smaller than actually needed, fill the remaining with black.
127
    count = FFMIN(avctx->extradata_size / 3, count);
128
    for (i=0; i < count; i++) {
129
        pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
130
    }
131
    return 0;
132
}
133

    
134
static av_cold int decode_init(AVCodecContext *avctx)
135
{
136
    IffContext *s = avctx->priv_data;
137
    int err;
138

    
139
    if (avctx->bits_per_coded_sample <= 8) {
140
        avctx->pix_fmt = PIX_FMT_PAL8;
141
    } else if (avctx->bits_per_coded_sample <= 32) {
142
        avctx->pix_fmt = PIX_FMT_BGR32;
143
    } else {
144
        return AVERROR_INVALIDDATA;
145
    }
146

    
147
    if ((err = avcodec_check_dimensions(avctx, avctx->width, avctx->height)))
148
        return err;
149
    s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
150
    s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
151
    if (!s->planebuf)
152
        return AVERROR(ENOMEM);
153

    
154
    s->frame.reference = 1;
155
    if ((err = avctx->get_buffer(avctx, &s->frame) < 0)) {
156
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
157
        return err;
158
    }
159

    
160
    return avctx->bits_per_coded_sample <= 8 ?
161
       ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0;
162
}
163

    
164
/**
165
 * Decode interleaved plane buffer up to 8bpp
166
 * @param dst Destination buffer
167
 * @param buf Source buffer
168
 * @param buf_size
169
 * @param plane plane number to decode as
170
 */
171
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
172
{
173
    const uint64_t *lut = plane8_lut[plane];
174
    do {
175
        uint64_t v = AV_RN64A(dst) | lut[*buf++];
176
        AV_WN64A(dst, v);
177
        dst += 8;
178
    } while (--buf_size);
179
}
180

    
181
/**
182
 * Decode interleaved plane buffer up to 24bpp
183
 * @param dst Destination buffer
184
 * @param buf Source buffer
185
 * @param buf_size
186
 * @param plane plane number to decode as
187
 */
188
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
189
{
190
    const uint32_t *lut = plane32_lut[plane];
191
    do {
192
        unsigned mask = (*buf >> 2) & ~3;
193
        dst[0] |= lut[mask++];
194
        dst[1] |= lut[mask++];
195
        dst[2] |= lut[mask++];
196
        dst[3] |= lut[mask];
197
        mask = (*buf++ << 2) & 0x3F;
198
        dst[4] |= lut[mask++];
199
        dst[5] |= lut[mask++];
200
        dst[6] |= lut[mask++];
201
        dst[7] |= lut[mask];
202
        dst += 8;
203
    } while (--buf_size);
204
}
205

    
206
static int decode_frame_ilbm(AVCodecContext *avctx,
207
                            void *data, int *data_size,
208
                            AVPacket *avpkt)
209
{
210
    IffContext *s = avctx->priv_data;
211
    const uint8_t *buf = avpkt->data;
212
    int buf_size = avpkt->size;
213
    const uint8_t *buf_end = buf+buf_size;
214
    int y, plane;
215

    
216
    if (avctx->reget_buffer(avctx, &s->frame) < 0){
217
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
218
        return -1;
219
    }
220

    
221
    if (avctx->pix_fmt == PIX_FMT_PAL8) {
222
        for(y = 0; y < avctx->height; y++ ) {
223
            uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
224
            memset(row, 0, avctx->width);
225
            for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
226
                decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
227
                buf += s->planesize;
228
            }
229
        }
230
    } else { // PIX_FMT_BGR32
231
        for(y = 0; y < avctx->height; y++ ) {
232
            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
233
            memset(row, 0, avctx->width << 2);
234
            for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
235
                decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
236
                buf += s->planesize;
237
            }
238
        }
239
    }
240

    
241
    *data_size = sizeof(AVFrame);
242
    *(AVFrame*)data = s->frame;
243
    return buf_size;
244
}
245

    
246
static int decode_frame_byterun1(AVCodecContext *avctx,
247
                            void *data, int *data_size,
248
                            AVPacket *avpkt)
249
{
250
    IffContext *s = avctx->priv_data;
251
    const uint8_t *buf = avpkt->data;
252
    int buf_size = avpkt->size;
253
    const uint8_t *buf_end = buf+buf_size;
254
    int y, plane, x;
255

    
256
    if (avctx->reget_buffer(avctx, &s->frame) < 0){
257
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
258
        return -1;
259
    }
260

    
261
    if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
262
        if (avctx->pix_fmt == PIX_FMT_PAL8) {
263
            for(y = 0; y < avctx->height ; y++ ) {
264
                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
265
                memset(row, 0, avctx->width);
266
                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
267
                    for(x = 0; x < s->planesize && buf < buf_end; ) {
268
                        int8_t value = *buf++;
269
                        unsigned length;
270
                        if (value >= 0) {
271
                            length = value + 1;
272
                            memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf));
273
                            buf += length;
274
                        } else if (value > -128) {
275
                            length = -value + 1;
276
                            memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x));
277
                        } else { //noop
278
                            continue;
279
                        }
280
                        x += length;
281
                    }
282
                    decodeplane8(row, s->planebuf, s->planesize, plane);
283
                }
284
            }
285
        } else { //PIX_FMT_BGR32
286
            for(y = 0; y < avctx->height ; y++ ) {
287
                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
288
                memset(row, 0, avctx->width << 2);
289
                for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
290
                    for(x = 0; x < s->planesize && buf < buf_end; ) {
291
                        int8_t value = *buf++;
292
                        unsigned length;
293
                        if (value >= 0) {
294
                            length = value + 1;
295
                            memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf));
296
                            buf += length;
297
                        } else if (value > -128) {
298
                            length = -value + 1;
299
                            memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x));
300
                        } else { // noop
301
                            continue;
302
                        }
303
                        x += length;
304
                    }
305
                    decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
306
                }
307
            }
308
        }
309
    } else {
310
        for(y = 0; y < avctx->height ; y++ ) {
311
            uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
312
            for(x = 0; x < avctx->width && buf < buf_end; ) {
313
                int8_t value = *buf++;
314
                unsigned length;
315
                if (value >= 0) {
316
                    length = value + 1;
317
                    memcpy(row + x, buf, FFMIN3(length, buf_end - buf, avctx->width - x));
318
                    buf += length;
319
                } else if (value > -128) {
320
                    length = -value + 1;
321
                    memset(row + x, *buf++, FFMIN(length, avctx->width - x));
322
                } else { //noop
323
                    continue;
324
                }
325
                x += length;
326
            }
327
        }
328
    }
329

    
330
    *data_size = sizeof(AVFrame);
331
    *(AVFrame*)data = s->frame;
332
    return buf_size;
333
}
334

    
335
static av_cold int decode_end(AVCodecContext *avctx)
336
{
337
    IffContext *s = avctx->priv_data;
338
    if (s->frame.data[0])
339
        avctx->release_buffer(avctx, &s->frame);
340
    av_freep(&s->planebuf);
341
    return 0;
342
}
343

    
344
AVCodec iff_ilbm_decoder = {
345
    "iff_ilbm",
346
    AVMEDIA_TYPE_VIDEO,
347
    CODEC_ID_IFF_ILBM,
348
    sizeof(IffContext),
349
    decode_init,
350
    NULL,
351
    decode_end,
352
    decode_frame_ilbm,
353
    CODEC_CAP_DR1,
354
    .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
355
};
356

    
357
AVCodec iff_byterun1_decoder = {
358
    "iff_byterun1",
359
    AVMEDIA_TYPE_VIDEO,
360
    CODEC_ID_IFF_BYTERUN1,
361
    sizeof(IffContext),
362
    decode_init,
363
    NULL,
364
    decode_end,
365
    decode_frame_byterun1,
366
    CODEC_CAP_DR1,
367
    .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
368
};