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
30 #include "libavutil/imgutils.h"
31 #include "bytestream.h"
40 int init; // 1 if buffer and palette data already initialized, 0 otherwise
43 #define LUT8_PART(plane, v) \
44 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
45 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
46 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
47 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
48 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
49 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
50 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
51 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
52 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
53 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
54 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
55 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
56 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
57 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
58 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
59 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
61 #define LUT8(plane) { \
62 LUT8_PART(plane, 0x0000000), \
63 LUT8_PART(plane, 0x1000000), \
64 LUT8_PART(plane, 0x0010000), \
65 LUT8_PART(plane, 0x1010000), \
66 LUT8_PART(plane, 0x0000100), \
67 LUT8_PART(plane, 0x1000100), \
68 LUT8_PART(plane, 0x0010100), \
69 LUT8_PART(plane, 0x1010100), \
70 LUT8_PART(plane, 0x0000001), \
71 LUT8_PART(plane, 0x1000001), \
72 LUT8_PART(plane, 0x0010001), \
73 LUT8_PART(plane, 0x1010001), \
74 LUT8_PART(plane, 0x0000101), \
75 LUT8_PART(plane, 0x1000101), \
76 LUT8_PART(plane, 0x0010101), \
77 LUT8_PART(plane, 0x1010101), \
80 // 8 planes * 8-bit mask
81 static const uint64_t plane8_lut[8][256] = {
82 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
83 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
86 #define LUT32(plane) { \
88 0, 0, 0, 1 << plane, \
89 0, 0, 1 << plane, 0, \
90 0, 0, 1 << plane, 1 << plane, \
91 0, 1 << plane, 0, 0, \
92 0, 1 << plane, 0, 1 << plane, \
93 0, 1 << plane, 1 << plane, 0, \
94 0, 1 << plane, 1 << plane, 1 << plane, \
95 1 << plane, 0, 0, 0, \
96 1 << plane, 0, 0, 1 << plane, \
97 1 << plane, 0, 1 << plane, 0, \
98 1 << plane, 0, 1 << plane, 1 << plane, \
99 1 << plane, 1 << plane, 0, 0, \
100 1 << plane, 1 << plane, 0, 1 << plane, \
101 1 << plane, 1 << plane, 1 << plane, 0, \
102 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
105 // 32 planes * 4-bit mask * 4 lookup tables each
106 static const uint32_t plane32_lut[32][16*4] = {
107 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
108 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
109 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
110 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
111 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
112 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
113 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
114 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
117 // Gray to RGB, required for palette table of grayscale images with bpp < 8
118 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
119 return x << 16 | x << 8 | x;
123 * Convert CMAP buffer (stored in extradata) to lavc palette format
125 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
129 if (avctx->bits_per_coded_sample > 8) {
130 av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
131 return AVERROR_INVALIDDATA;
134 count = 1 << avctx->bits_per_coded_sample;
135 // If extradata is smaller than actually needed, fill the remaining with black.
136 count = FFMIN(avctx->extradata_size / 3, count);
138 for (i = 0; i < count; i++)
139 pal[i] = 0xFF000000 | AV_RB24(avctx->extradata + i * 3);
140 } else { // Create gray-scale color palette for bps < 8
141 count = 1 << avctx->bits_per_coded_sample;
143 for (i = 0; i < count; i++)
144 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
149 static av_cold int decode_end(AVCodecContext *avctx)
151 IffContext *s = avctx->priv_data;
152 av_frame_free(&s->frame);
153 av_freep(&s->planebuf);
157 static av_cold int decode_init(AVCodecContext *avctx)
159 IffContext *s = avctx->priv_data;
162 if (avctx->bits_per_coded_sample <= 8) {
163 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
164 avctx->extradata_size) ? AV_PIX_FMT_PAL8
166 } else if (avctx->bits_per_coded_sample <= 32) {
167 avctx->pix_fmt = AV_PIX_FMT_BGR32;
169 return AVERROR_INVALIDDATA;
172 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
174 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
175 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
177 return AVERROR(ENOMEM);
179 s->frame = av_frame_alloc();
182 return AVERROR(ENOMEM);
189 * Decode interleaved plane buffer up to 8bpp
190 * @param dst Destination buffer
191 * @param buf Source buffer
193 * @param plane plane number to decode as
195 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
197 const uint64_t *lut = plane8_lut[plane];
199 uint64_t v = AV_RN64A(dst) | lut[*buf++];
202 } while (--buf_size);
206 * Decode interleaved plane buffer up to 24bpp
207 * @param dst Destination buffer
208 * @param buf Source buffer
210 * @param plane plane number to decode as
212 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
214 const uint32_t *lut = plane32_lut[plane];
216 unsigned mask = (*buf >> 2) & ~3;
217 dst[0] |= lut[mask++];
218 dst[1] |= lut[mask++];
219 dst[2] |= lut[mask++];
221 mask = (*buf++ << 2) & 0x3F;
222 dst[4] |= lut[mask++];
223 dst[5] |= lut[mask++];
224 dst[6] |= lut[mask++];
227 } while (--buf_size);
231 * Decode one complete byterun1 encoded line.
233 * @param dst the destination buffer where to store decompressed bitstream
234 * @param dst_size the destination plane size in bytes
235 * @param buf the source byterun1 compressed bitstream
236 * @param buf_end the EOF of source byterun1 compressed bitstream
237 * @return number of consumed bytes in byterun1 compressed bitstream
239 static int decode_byterun(uint8_t *dst, int dst_size,
240 const uint8_t *buf, const uint8_t *const buf_end)
242 const uint8_t *const buf_start = buf;
244 for (x = 0; x < dst_size && buf < buf_end;) {
246 const int8_t value = *buf++;
249 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
251 } else if (value > -128) {
253 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
259 return buf - buf_start;
262 static int decode_frame_ilbm(AVCodecContext *avctx,
263 void *data, int *got_frame,
266 IffContext *s = avctx->priv_data;
267 const uint8_t *buf = avpkt->data;
268 int buf_size = avpkt->size;
269 const uint8_t *buf_end = buf + buf_size;
272 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
275 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
276 avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
277 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
282 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
283 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
284 for (y = 0; y < avctx->height; y++) {
285 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
286 memset(row, 0, avctx->width);
287 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
289 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
293 } else { // AV_PIX_FMT_BGR32
294 for (y = 0; y < avctx->height; y++) {
295 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
296 memset(row, 0, avctx->width << 2);
297 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
299 decodeplane32((uint32_t *)row, buf,
300 FFMIN(s->planesize, buf_end - buf), plane);
305 } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { // IFF-PBM
306 for (y = 0; y < avctx->height && buf < buf_end; y++) {
307 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
308 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
309 buf += avctx->width + (avctx->width % 2); // padding if odd
313 if ((res = av_frame_ref(data, s->frame)) < 0)
321 static int decode_frame_byterun1(AVCodecContext *avctx,
322 void *data, int *got_frame,
325 IffContext *s = avctx->priv_data;
326 const uint8_t *buf = avpkt->data;
327 int buf_size = avpkt->size;
328 const uint8_t *buf_end = buf + buf_size;
331 if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
334 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
335 avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
336 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
341 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
342 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
343 for (y = 0; y < avctx->height; y++) {
344 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
345 memset(row, 0, avctx->width);
346 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
347 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
348 decodeplane8(row, s->planebuf, s->planesize, plane);
351 } else { // AV_PIX_FMT_BGR32
352 for (y = 0; y < avctx->height; y++) {
353 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
354 memset(row, 0, avctx->width << 2);
355 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
356 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
357 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
362 for (y = 0; y < avctx->height; y++) {
363 uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
364 buf += decode_byterun(row, avctx->width, buf, buf_end);
368 if ((res = av_frame_ref(data, s->frame)) < 0)
376 AVCodec ff_iff_ilbm_decoder = {
378 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
379 .type = AVMEDIA_TYPE_VIDEO,
380 .id = AV_CODEC_ID_IFF_ILBM,
381 .priv_data_size = sizeof(IffContext),
384 .decode = decode_frame_ilbm,
385 .capabilities = CODEC_CAP_DR1,
388 AVCodec ff_iff_byterun1_decoder = {
389 .name = "iff_byterun1",
390 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
391 .type = AVMEDIA_TYPE_VIDEO,
392 .id = AV_CODEC_ID_IFF_BYTERUN1,
393 .priv_data_size = sizeof(IffContext),
396 .decode = decode_frame_byterun1,
397 .capabilities = CODEC_CAP_DR1,