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"
38 int init; // 1 if buffer and palette data already initialized, 0 otherwise
41 #define LUT8_PART(plane, v) \
42 AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
43 AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
44 AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
45 AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
46 AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
47 AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
48 AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
49 AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
50 AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
51 AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
52 AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
53 AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
54 AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
55 AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
56 AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
57 AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
59 #define LUT8(plane) { \
60 LUT8_PART(plane, 0x0000000), \
61 LUT8_PART(plane, 0x1000000), \
62 LUT8_PART(plane, 0x0010000), \
63 LUT8_PART(plane, 0x1010000), \
64 LUT8_PART(plane, 0x0000100), \
65 LUT8_PART(plane, 0x1000100), \
66 LUT8_PART(plane, 0x0010100), \
67 LUT8_PART(plane, 0x1010100), \
68 LUT8_PART(plane, 0x0000001), \
69 LUT8_PART(plane, 0x1000001), \
70 LUT8_PART(plane, 0x0010001), \
71 LUT8_PART(plane, 0x1010001), \
72 LUT8_PART(plane, 0x0000101), \
73 LUT8_PART(plane, 0x1000101), \
74 LUT8_PART(plane, 0x0010101), \
75 LUT8_PART(plane, 0x1010101), \
78 // 8 planes * 8-bit mask
79 static const uint64_t plane8_lut[8][256] = {
80 LUT8(0), LUT8(1), LUT8(2), LUT8(3),
81 LUT8(4), LUT8(5), LUT8(6), LUT8(7),
84 #define LUT32(plane) { \
86 0, 0, 0, 1 << plane, \
87 0, 0, 1 << plane, 0, \
88 0, 0, 1 << plane, 1 << plane, \
89 0, 1 << plane, 0, 0, \
90 0, 1 << plane, 0, 1 << plane, \
91 0, 1 << plane, 1 << plane, 0, \
92 0, 1 << plane, 1 << plane, 1 << plane, \
93 1 << plane, 0, 0, 0, \
94 1 << plane, 0, 0, 1 << plane, \
95 1 << plane, 0, 1 << plane, 0, \
96 1 << plane, 0, 1 << plane, 1 << plane, \
97 1 << plane, 1 << plane, 0, 0, \
98 1 << plane, 1 << plane, 0, 1 << plane, \
99 1 << plane, 1 << plane, 1 << plane, 0, \
100 1 << plane, 1 << plane, 1 << plane, 1 << plane, \
103 // 32 planes * 4-bit mask * 4 lookup tables each
104 static const uint32_t plane32_lut[32][16*4] = {
105 LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
106 LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
107 LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
108 LUT32(12), LUT32(13), LUT32(14), LUT32(15),
109 LUT32(16), LUT32(17), LUT32(18), LUT32(19),
110 LUT32(20), LUT32(21), LUT32(22), LUT32(23),
111 LUT32(24), LUT32(25), LUT32(26), LUT32(27),
112 LUT32(28), LUT32(29), LUT32(30), LUT32(31),
115 // Gray to RGB, required for palette table of grayscale images with bpp < 8
116 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
117 return x << 16 | x << 8 | x;
121 * Convert CMAP buffer (stored in extradata) to lavc palette format
123 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
127 if (avctx->bits_per_coded_sample > 8) {
128 av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
129 return AVERROR_INVALIDDATA;
132 count = 1 << avctx->bits_per_coded_sample;
133 // If extradata is smaller than actually needed, fill the remaining with black.
134 count = FFMIN(avctx->extradata_size / 3, count);
136 for (i = 0; i < count; i++)
137 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);
147 static av_cold int decode_init(AVCodecContext *avctx)
149 IffContext *s = avctx->priv_data;
152 if (avctx->bits_per_coded_sample <= 8) {
153 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
154 avctx->extradata_size) ? AV_PIX_FMT_PAL8
156 } else if (avctx->bits_per_coded_sample <= 32) {
157 avctx->pix_fmt = AV_PIX_FMT_BGR32;
159 return AVERROR_INVALIDDATA;
162 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
164 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
165 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
167 return AVERROR(ENOMEM);
169 avcodec_get_frame_defaults(&s->frame);
175 * Decode interleaved plane buffer up to 8bpp
176 * @param dst Destination buffer
177 * @param buf Source buffer
179 * @param plane plane number to decode as
181 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
183 const uint64_t *lut = plane8_lut[plane];
185 uint64_t v = AV_RN64A(dst) | lut[*buf++];
188 } while (--buf_size);
192 * Decode interleaved plane buffer up to 24bpp
193 * @param dst Destination buffer
194 * @param buf Source buffer
196 * @param plane plane number to decode as
198 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
200 const uint32_t *lut = plane32_lut[plane];
202 unsigned mask = (*buf >> 2) & ~3;
203 dst[0] |= lut[mask++];
204 dst[1] |= lut[mask++];
205 dst[2] |= lut[mask++];
207 mask = (*buf++ << 2) & 0x3F;
208 dst[4] |= lut[mask++];
209 dst[5] |= lut[mask++];
210 dst[6] |= lut[mask++];
213 } while (--buf_size);
217 * Decode one complete byterun1 encoded line.
219 * @param dst the destination buffer where to store decompressed bitstream
220 * @param dst_size the destination plane size in bytes
221 * @param buf the source byterun1 compressed bitstream
222 * @param buf_end the EOF of source byterun1 compressed bitstream
223 * @return number of consumed bytes in byterun1 compressed bitstream
225 static int decode_byterun(uint8_t *dst, int dst_size,
226 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 *got_frame,
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;
258 if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
261 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
262 avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
263 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame.data[1])) < 0)
268 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
269 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
270 for (y = 0; y < avctx->height; y++) {
271 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
272 memset(row, 0, avctx->width);
273 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
275 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
279 } else { // AV_PIX_FMT_BGR32
280 for (y = 0; y < avctx->height; y++) {
281 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
282 memset(row, 0, avctx->width << 2);
283 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
285 decodeplane32((uint32_t *)row, buf,
286 FFMIN(s->planesize, buf_end - buf), plane);
291 } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { // IFF-PBM
292 for (y = 0; y < avctx->height && buf < buf_end; y++) {
293 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
294 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
295 buf += avctx->width + (avctx->width % 2); // padding if odd
299 if ((res = av_frame_ref(data, &s->frame)) < 0)
307 static int decode_frame_byterun1(AVCodecContext *avctx,
308 void *data, int *got_frame,
311 IffContext *s = avctx->priv_data;
312 const uint8_t *buf = avpkt->data;
313 int buf_size = avpkt->size;
314 const uint8_t *buf_end = buf + buf_size;
317 if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
320 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
321 avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
322 if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame.data[1])) < 0)
327 if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
328 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
329 for (y = 0; y < avctx->height; y++) {
330 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
331 memset(row, 0, avctx->width);
332 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
333 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
334 decodeplane8(row, s->planebuf, s->planesize, plane);
337 } else { // AV_PIX_FMT_BGR32
338 for (y = 0; y < avctx->height; y++) {
339 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
340 memset(row, 0, avctx->width << 2);
341 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
342 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
343 decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
348 for (y = 0; y < avctx->height; y++) {
349 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
350 buf += decode_byterun(row, avctx->width, buf, buf_end);
354 if ((res = av_frame_ref(data, &s->frame)) < 0)
362 static av_cold int decode_end(AVCodecContext *avctx)
364 IffContext *s = avctx->priv_data;
365 av_frame_unref(&s->frame);
366 av_freep(&s->planebuf);
370 AVCodec ff_iff_ilbm_decoder = {
372 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
373 .type = AVMEDIA_TYPE_VIDEO,
374 .id = AV_CODEC_ID_IFF_ILBM,
375 .priv_data_size = sizeof(IffContext),
378 .decode = decode_frame_ilbm,
379 .capabilities = CODEC_CAP_DR1,
382 AVCodec ff_iff_byterun1_decoder = {
383 .name = "iff_byterun1",
384 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
385 .type = AVMEDIA_TYPE_VIDEO,
386 .id = AV_CODEC_ID_IFF_BYTERUN1,
387 .priv_data_size = sizeof(IffContext),
390 .decode = decode_frame_byterun1,
391 .capabilities = CODEC_CAP_DR1,