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 );
139 } else { // Create gray-scale color palette for bps < 8
140 count
= 1 << avctx
->bits_per_coded_sample
;
142 for (i
=0; i
< count
; i
++) {
143 pal
[i
] = 0xFF000000 | gray2rgb((i
* 255) >> avctx
->bits_per_coded_sample
);
149 static av_cold
int decode_init(AVCodecContext
*avctx
)
151 IffContext
*s
= avctx
->priv_data
;
154 if (avctx
->bits_per_coded_sample
<= 8) {
155 avctx
->pix_fmt
= (avctx
->bits_per_coded_sample
< 8 ||
156 avctx
->extradata_size
) ? AV_PIX_FMT_PAL8
158 } else if (avctx
->bits_per_coded_sample
<= 32) {
159 avctx
->pix_fmt
= AV_PIX_FMT_BGR32
;
161 return AVERROR_INVALIDDATA
;
164 if ((err
= av_image_check_size(avctx
->width
, avctx
->height
, 0, avctx
)))
166 s
->planesize
= FFALIGN(avctx
->width
, 16) >> 3; // Align plane size in bits to word-boundary
167 s
->planebuf
= av_malloc(s
->planesize
+ FF_INPUT_BUFFER_PADDING_SIZE
);
169 return AVERROR(ENOMEM
);
171 s
->frame
.reference
= 1;
177 * Decode interleaved plane buffer up to 8bpp
178 * @param dst Destination buffer
179 * @param buf Source buffer
181 * @param plane plane number to decode as
183 static void decodeplane8(uint8_t *dst
, const uint8_t *buf
, int buf_size
, int plane
)
185 const uint64_t *lut
= plane8_lut
[plane
];
187 uint64_t v
= AV_RN64A(dst
) | lut
[*buf
++];
190 } while (--buf_size
);
194 * Decode interleaved plane buffer up to 24bpp
195 * @param dst Destination buffer
196 * @param buf Source buffer
198 * @param plane plane number to decode as
200 static void decodeplane32(uint32_t *dst
, const uint8_t *buf
, int buf_size
, int plane
)
202 const uint32_t *lut
= plane32_lut
[plane
];
204 unsigned mask
= (*buf
>> 2) & ~3;
205 dst
[0] |= lut
[mask
++];
206 dst
[1] |= lut
[mask
++];
207 dst
[2] |= lut
[mask
++];
209 mask
= (*buf
++ << 2) & 0x3F;
210 dst
[4] |= lut
[mask
++];
211 dst
[5] |= lut
[mask
++];
212 dst
[6] |= lut
[mask
++];
215 } while (--buf_size
);
219 * Decode one complete byterun1 encoded line.
221 * @param dst the destination buffer where to store decompressed bitstream
222 * @param dst_size the destination plane size in bytes
223 * @param buf the source byterun1 compressed bitstream
224 * @param buf_end the EOF of source byterun1 compressed bitstream
225 * @return number of consumed bytes in byterun1 compressed bitstream
227 static int decode_byterun(uint8_t *dst
, int dst_size
,
228 const uint8_t *buf
, const uint8_t *const buf_end
) {
229 const uint8_t *const buf_start
= buf
;
231 for (x
= 0; x
< dst_size
&& buf
< buf_end
;) {
233 const int8_t value
= *buf
++;
236 memcpy(dst
+ x
, buf
, FFMIN3(length
, dst_size
- x
, buf_end
- buf
));
238 } else if (value
> -128) {
240 memset(dst
+ x
, *buf
++, FFMIN(length
, dst_size
- x
));
246 return buf
- buf_start
;
249 static int decode_frame_ilbm(AVCodecContext
*avctx
,
250 void *data
, int *got_frame
,
253 IffContext
*s
= avctx
->priv_data
;
254 const uint8_t *buf
= avpkt
->data
;
255 int buf_size
= avpkt
->size
;
256 const uint8_t *buf_end
= buf
+buf_size
;
260 if ((res
= avctx
->reget_buffer(avctx
, &s
->frame
)) < 0) {
261 av_log(avctx
, AV_LOG_ERROR
, "reget_buffer() failed\n");
264 } else if ((res
= ff_get_buffer(avctx
, &s
->frame
)) < 0) {
265 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
267 } else if (avctx
->bits_per_coded_sample
<= 8 && avctx
->pix_fmt
!= AV_PIX_FMT_GRAY8
) {
268 if ((res
= cmap_read_palette(avctx
, (uint32_t*)s
->frame
.data
[1])) < 0)
273 if (avctx
->codec_tag
== MKTAG('I','L','B','M')) { // interleaved
274 if (avctx
->pix_fmt
== AV_PIX_FMT_PAL8
|| avctx
->pix_fmt
== AV_PIX_FMT_GRAY8
) {
275 for(y
= 0; y
< avctx
->height
; y
++ ) {
276 uint8_t *row
= &s
->frame
.data
[0][ y
*s
->frame
.linesize
[0] ];
277 memset(row
, 0, avctx
->width
);
278 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
&& buf
< buf_end
; plane
++) {
279 decodeplane8(row
, buf
, FFMIN(s
->planesize
, buf_end
- buf
), plane
);
283 } else { // AV_PIX_FMT_BGR32
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
<< 2);
287 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
&& buf
< buf_end
; plane
++) {
288 decodeplane32((uint32_t *) row
, buf
, FFMIN(s
->planesize
, buf_end
- buf
), plane
);
293 } else if (avctx
->pix_fmt
== AV_PIX_FMT_PAL8
|| avctx
->pix_fmt
== AV_PIX_FMT_GRAY8
) { // IFF-PBM
294 for(y
= 0; y
< avctx
->height
; y
++ ) {
295 uint8_t *row
= &s
->frame
.data
[0][y
* s
->frame
.linesize
[0]];
296 memcpy(row
, buf
, FFMIN(avctx
->width
, buf_end
- buf
));
297 buf
+= avctx
->width
+ (avctx
->width
% 2); // padding if odd
302 *(AVFrame
*)data
= s
->frame
;
306 static int decode_frame_byterun1(AVCodecContext
*avctx
,
307 void *data
, int *got_frame
,
310 IffContext
*s
= avctx
->priv_data
;
311 const uint8_t *buf
= avpkt
->data
;
312 int buf_size
= avpkt
->size
;
313 const uint8_t *buf_end
= buf
+buf_size
;
317 if ((res
= avctx
->reget_buffer(avctx
, &s
->frame
)) < 0) {
318 av_log(avctx
, AV_LOG_ERROR
, "reget_buffer() failed\n");
321 } else if ((res
= ff_get_buffer(avctx
, &s
->frame
)) < 0) {
322 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
324 } else if (avctx
->bits_per_coded_sample
<= 8 && avctx
->pix_fmt
!= AV_PIX_FMT_GRAY8
) {
325 if ((res
= cmap_read_palette(avctx
, (uint32_t*)s
->frame
.data
[1])) < 0)
330 if (avctx
->codec_tag
== MKTAG('I','L','B','M')) { //interleaved
331 if (avctx
->pix_fmt
== AV_PIX_FMT_PAL8
|| avctx
->pix_fmt
== AV_PIX_FMT_GRAY8
) {
332 for(y
= 0; y
< avctx
->height
; y
++ ) {
333 uint8_t *row
= &s
->frame
.data
[0][ y
*s
->frame
.linesize
[0] ];
334 memset(row
, 0, avctx
->width
);
335 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
; plane
++) {
336 buf
+= decode_byterun(s
->planebuf
, s
->planesize
, buf
, buf_end
);
337 decodeplane8(row
, s
->planebuf
, s
->planesize
, plane
);
340 } else { //AV_PIX_FMT_BGR32
341 for(y
= 0; y
< avctx
->height
; y
++ ) {
342 uint8_t *row
= &s
->frame
.data
[0][y
*s
->frame
.linesize
[0]];
343 memset(row
, 0, avctx
->width
<< 2);
344 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
; plane
++) {
345 buf
+= decode_byterun(s
->planebuf
, s
->planesize
, buf
, buf_end
);
346 decodeplane32((uint32_t *) row
, s
->planebuf
, s
->planesize
, plane
);
351 for(y
= 0; y
< avctx
->height
; y
++ ) {
352 uint8_t *row
= &s
->frame
.data
[0][y
*s
->frame
.linesize
[0]];
353 buf
+= decode_byterun(row
, avctx
->width
, buf
, buf_end
);
358 *(AVFrame
*)data
= s
->frame
;
362 static av_cold
int decode_end(AVCodecContext
*avctx
)
364 IffContext
*s
= avctx
->priv_data
;
365 if (s
->frame
.data
[0])
366 avctx
->release_buffer(avctx
, &s
->frame
);
367 av_freep(&s
->planebuf
);
371 AVCodec ff_iff_ilbm_decoder
= {
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
,
380 .long_name
= NULL_IF_CONFIG_SMALL("IFF ILBM"),
383 AVCodec ff_iff_byterun1_decoder
= {
384 .name
= "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
,
392 .long_name
= NULL_IF_CONFIG_SMALL("IFF ByteRun1"),