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>
6 * This file is part of Libav.
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.
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.
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
25 * IFF PBM/ILBM bitmap decoder
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
37 int init; // 1 if buffer and palette data already initialized, 0 otherwise
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
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), \
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),
83 #define LUT32(plane) { \
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, \
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),
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;
120 * Convert CMAP buffer (stored in extradata) to lavc palette format
122 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
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;
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);
135 for (i=0; i < count; i++) {
136 pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
138 } else { // Create gray-scale color palette for bps < 8
139 count = 1 << avctx->bits_per_coded_sample;
141 for (i=0; i < count; i++) {
142 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
148 static av_cold int decode_init(AVCodecContext *avctx)
150 IffContext *s = avctx->priv_data;
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
157 } else if (avctx->bits_per_coded_sample <= 32) {
158 avctx->pix_fmt = PIX_FMT_BGR32;
160 return AVERROR_INVALIDDATA;
163 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
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);
168 return AVERROR(ENOMEM);
170 s->frame.reference = 1;
176 * Decode interleaved plane buffer up to 8bpp
177 * @param dst Destination buffer
178 * @param buf Source buffer
180 * @param plane plane number to decode as
182 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
184 const uint64_t *lut = plane8_lut[plane];
186 uint64_t v = AV_RN64A(dst) | lut[*buf++];
189 } while (--buf_size);
193 * Decode interleaved plane buffer up to 24bpp
194 * @param dst Destination buffer
195 * @param buf Source buffer
197 * @param plane plane number to decode as
199 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
201 const uint32_t *lut = plane32_lut[plane];
203 unsigned mask = (*buf >> 2) & ~3;
204 dst[0] |= lut[mask++];
205 dst[1] |= lut[mask++];
206 dst[2] |= lut[mask++];
208 mask = (*buf++ << 2) & 0x3F;
209 dst[4] |= lut[mask++];
210 dst[5] |= lut[mask++];
211 dst[6] |= lut[mask++];
214 } while (--buf_size);
218 * Decode one complete byterun1 encoded line.
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
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;
230 for (x = 0; x < dst_size && buf < buf_end;) {
232 const int8_t value = *buf++;
235 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
237 } else if (value > -128) {
239 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
245 return buf - buf_start;
248 static int decode_frame_ilbm(AVCodecContext *avctx,
249 void *data, int *data_size,
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;
259 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
260 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
263 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
264 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
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)
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);
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);
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
300 *data_size = sizeof(AVFrame);
301 *(AVFrame*)data = s->frame;
305 static int decode_frame_byterun1(AVCodecContext *avctx,
306 void *data, int *data_size,
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;
316 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
317 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
320 } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {
321 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
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)
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);
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);
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);
356 *data_size = sizeof(AVFrame);
357 *(AVFrame*)data = s->frame;
361 static av_cold int decode_end(AVCodecContext *avctx)
363 IffContext *s = avctx->priv_data;
364 if (s->frame.data[0])
365 avctx->release_buffer(avctx, &s->frame);
366 av_freep(&s->planebuf);
370 AVCodec ff_iff_ilbm_decoder = {
372 .type = AVMEDIA_TYPE_VIDEO,
373 .id = CODEC_ID_IFF_ILBM,
374 .priv_data_size = sizeof(IffContext),
377 .decode = decode_frame_ilbm,
378 .capabilities = CODEC_CAP_DR1,
379 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
382 AVCodec ff_iff_byterun1_decoder = {
383 .name = "iff_byterun1",
384 .type = AVMEDIA_TYPE_VIDEO,
385 .id = CODEC_ID_IFF_BYTERUN1,
386 .priv_data_size = sizeof(IffContext),
389 .decode = decode_frame_byterun1,
390 .capabilities = CODEC_CAP_DR1,
391 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),