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 FFmpeg.
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.
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.
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
25 * IFF PBM/ILBM bitmap decoder
28 #include "bytestream.h"
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
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), \
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),
83 * Convert CMAP buffer (stored in extradata) to lavc palette format
85 int ff_cmap_read_palette(AVCodecContext
*avctx
, uint32_t *pal
)
89 if (avctx
->bits_per_coded_sample
> 8) {
90 av_log(avctx
, AV_LOG_ERROR
, "bit_per_coded_sample > 8 not supported\n");
91 return AVERROR_INVALIDDATA
;
94 count
= 1 << avctx
->bits_per_coded_sample
;
95 if (avctx
->extradata_size
< count
* 3) {
96 av_log(avctx
, AV_LOG_ERROR
, "palette data underflow\n");
97 return AVERROR_INVALIDDATA
;
99 for (i
=0; i
< count
; i
++) {
100 pal
[i
] = 0xFF000000 | AV_RB24( avctx
->extradata
+ i
*3 );
105 static av_cold
int decode_init(AVCodecContext
*avctx
)
107 IffContext
*s
= avctx
->priv_data
;
110 if (avctx
->bits_per_coded_sample
<= 8) {
111 avctx
->pix_fmt
= PIX_FMT_PAL8
;
112 } else if (avctx
->bits_per_coded_sample
<= 32) {
113 avctx
->pix_fmt
= PIX_FMT_BGR32
;
115 return AVERROR_INVALIDDATA
;
118 s
->planesize
= FFALIGN(avctx
->width
, 16) >> 3; // Align plane size in bits to word-boundary
119 s
->planebuf
= av_malloc(s
->planesize
+ FF_INPUT_BUFFER_PADDING_SIZE
);
121 return AVERROR(ENOMEM
);
123 s
->frame
.reference
= 1;
124 if ((err
= avctx
->get_buffer(avctx
, &s
->frame
) < 0)) {
125 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
129 return avctx
->bits_per_coded_sample
<= 8 ?
130 ff_cmap_read_palette(avctx
, (uint32_t*)s
->frame
.data
[1]) : 0;
134 * Decode interleaved plane buffer up to 8bpp
135 * @param dst Destination buffer
136 * @param buf Source buffer
138 * @param bps bits_per_coded_sample (must be <= 8)
139 * @param plane plane number to decode as
141 static void decodeplane8(uint8_t *dst
, const uint8_t *buf
, int buf_size
, int bps
, int plane
)
143 const uint64_t *lut
= plane8_lut
[plane
];
144 for(; --buf_size
!= 0; dst
+= 8) {
145 uint64_t v
= AV_RN64A(dst
) | lut
[*buf
++];
151 * Decode interleaved plane buffer up to 24bpp
152 * @param dst Destination buffer
153 * @param buf Source buffer
155 * @param bps bits_per_coded_sample
156 * @param plane plane number to decode as
158 static void decodeplane32(uint32_t *dst
, const uint8_t *const buf
, int buf_size
, int bps
, int plane
)
162 const int b
= buf_size
* 8;
163 init_get_bits(&gb
, buf
, buf_size
* 8);
164 for(i
= 0; i
< b
; i
++) {
165 dst
[i
] |= get_bits1(&gb
) << plane
;
169 static int decode_frame_ilbm(AVCodecContext
*avctx
,
170 void *data
, int *data_size
,
173 IffContext
*s
= avctx
->priv_data
;
174 const uint8_t *buf
= avpkt
->data
;
175 int buf_size
= avpkt
->size
;
176 const uint8_t *buf_end
= buf
+buf_size
;
179 if (avctx
->reget_buffer(avctx
, &s
->frame
) < 0){
180 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
184 if (avctx
->pix_fmt
== PIX_FMT_PAL8
) {
185 for(y
= 0; y
< avctx
->height
; y
++ ) {
186 uint8_t *row
= &s
->frame
.data
[0][ y
*s
->frame
.linesize
[0] ];
187 memset(row
, 0, avctx
->width
);
188 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
&& buf
< buf_end
; plane
++) {
189 decodeplane8(row
, buf
, FFMIN(s
->planesize
, buf_end
- buf
), avctx
->bits_per_coded_sample
, plane
);
193 } else { // PIX_FMT_BGR32
194 for(y
= 0; y
< avctx
->height
; y
++ ) {
195 uint8_t *row
= &s
->frame
.data
[0][y
*s
->frame
.linesize
[0]];
196 memset(row
, 0, avctx
->width
<< 2);
197 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
&& buf
< buf_end
; plane
++) {
198 decodeplane32((uint32_t *) row
, buf
, FFMIN(s
->planesize
, buf_end
- buf
), avctx
->bits_per_coded_sample
, plane
);
204 *data_size
= sizeof(AVFrame
);
205 *(AVFrame
*)data
= s
->frame
;
209 static int decode_frame_byterun1(AVCodecContext
*avctx
,
210 void *data
, int *data_size
,
213 IffContext
*s
= avctx
->priv_data
;
214 const uint8_t *buf
= avpkt
->data
;
215 int buf_size
= avpkt
->size
;
216 const uint8_t *buf_end
= buf
+buf_size
;
219 if (avctx
->reget_buffer(avctx
, &s
->frame
) < 0){
220 av_log(avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
224 if (avctx
->codec_tag
== MKTAG('I','L','B','M')) { //interleaved
225 if (avctx
->pix_fmt
== PIX_FMT_PAL8
) {
226 for(y
= 0; y
< avctx
->height
; y
++ ) {
227 uint8_t *row
= &s
->frame
.data
[0][ y
*s
->frame
.linesize
[0] ];
228 memset(row
, 0, avctx
->width
);
229 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
; plane
++) {
230 for(x
= 0; x
< s
->planesize
&& buf
< buf_end
; ) {
231 int8_t value
= *buf
++;
235 memcpy(s
->planebuf
+ x
, buf
, FFMIN3(length
, s
->planesize
- x
, buf_end
- buf
));
237 } else if (value
> -128) {
239 memset(s
->planebuf
+ x
, *buf
++, FFMIN(length
, s
->planesize
- x
));
245 decodeplane8(row
, s
->planebuf
, s
->planesize
, avctx
->bits_per_coded_sample
, plane
);
248 } else { //PIX_FMT_BGR32
249 for(y
= 0; y
< avctx
->height
; y
++ ) {
250 uint8_t *row
= &s
->frame
.data
[0][y
*s
->frame
.linesize
[0]];
251 memset(row
, 0, avctx
->width
<< 2);
252 for (plane
= 0; plane
< avctx
->bits_per_coded_sample
; plane
++) {
253 for(x
= 0; x
< s
->planesize
&& buf
< buf_end
; ) {
254 int8_t value
= *buf
++;
258 memcpy(s
->planebuf
+ x
, buf
, FFMIN3(length
, s
->planesize
- x
, buf_end
- buf
));
260 } else if (value
> -128) {
262 memset(s
->planebuf
+ x
, *buf
++, FFMIN(length
, s
->planesize
- x
));
268 decodeplane32((uint32_t *) row
, s
->planebuf
, s
->planesize
, avctx
->bits_per_coded_sample
, plane
);
273 for(y
= 0; y
< avctx
->height
; y
++ ) {
274 uint8_t *row
= &s
->frame
.data
[0][y
*s
->frame
.linesize
[0]];
275 for(x
= 0; x
< avctx
->width
&& buf
< buf_end
; ) {
276 int8_t value
= *buf
++;
280 memcpy(row
+ x
, buf
, FFMIN3(length
, buf_end
- buf
, avctx
->width
- x
));
282 } else if (value
> -128) {
284 memset(row
+ x
, *buf
++, FFMIN(length
, avctx
->width
- x
));
293 *data_size
= sizeof(AVFrame
);
294 *(AVFrame
*)data
= s
->frame
;
298 static av_cold
int decode_end(AVCodecContext
*avctx
)
300 IffContext
*s
= avctx
->priv_data
;
301 if (s
->frame
.data
[0])
302 avctx
->release_buffer(avctx
, &s
->frame
);
303 av_freep(&s
->planebuf
);
307 AVCodec iff_ilbm_decoder
= {
317 .long_name
= NULL_IF_CONFIG_SMALL("IFF ILBM"),
320 AVCodec iff_byterun1_decoder
= {
323 CODEC_ID_IFF_BYTERUN1
,
328 decode_frame_byterun1
,
330 .long_name
= NULL_IF_CONFIG_SMALL("IFF ByteRun1"),