ffmpeg / libavcodec / iff.c @ d36beb3f
History | View | Annotate | Download (14 KB)
1 |
/*
|
---|---|
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>
|
5 |
*
|
6 |
* This file is part of FFmpeg.
|
7 |
*
|
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.
|
12 |
*
|
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.
|
17 |
*
|
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
|
21 |
*/
|
22 |
|
23 |
/**
|
24 |
* @file
|
25 |
* IFF PBM/ILBM bitmap decoder
|
26 |
*/
|
27 |
|
28 |
#include "libavcore/imgutils.h" |
29 |
#include "bytestream.h" |
30 |
#include "avcodec.h" |
31 |
#include "get_bits.h" |
32 |
|
33 |
typedef struct { |
34 |
AVFrame frame; |
35 |
int planesize;
|
36 |
uint8_t * planebuf; |
37 |
int init; // 1 if buffer and palette data already initialized, 0 otherwise |
38 |
} IffContext; |
39 |
|
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 |
57 |
|
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), \
|
75 |
} |
76 |
|
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), |
81 |
}; |
82 |
|
83 |
#define LUT32(plane) { \
|
84 |
0, 0, 0, 0, \ |
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, \ |
100 |
} |
101 |
|
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), |
112 |
}; |
113 |
|
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; |
117 |
} |
118 |
|
119 |
/**
|
120 |
* Convert CMAP buffer (stored in extradata) to lavc palette format
|
121 |
*/
|
122 |
static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal) |
123 |
{ |
124 |
int count, i;
|
125 |
|
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;
|
129 |
} |
130 |
|
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);
|
134 |
if (count) {
|
135 |
for (i=0; i < count; i++) { |
136 |
pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 ); |
137 |
} |
138 |
} else { // Create gray-scale color palette for bps < 8 |
139 |
count = 1 << avctx->bits_per_coded_sample;
|
140 |
|
141 |
for (i=0; i < count; i++) { |
142 |
pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample); |
143 |
} |
144 |
} |
145 |
return 0; |
146 |
} |
147 |
|
148 |
static av_cold int decode_init(AVCodecContext *avctx) |
149 |
{ |
150 |
IffContext *s = avctx->priv_data; |
151 |
int err;
|
152 |
|
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 |
156 |
: PIX_FMT_GRAY8; |
157 |
} else if (avctx->bits_per_coded_sample <= 32) { |
158 |
avctx->pix_fmt = PIX_FMT_BGR32; |
159 |
} else {
|
160 |
return AVERROR_INVALIDDATA;
|
161 |
} |
162 |
|
163 |
if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx))) |
164 |
return err;
|
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); |
167 |
if (!s->planebuf)
|
168 |
return AVERROR(ENOMEM);
|
169 |
|
170 |
s->frame.reference = 1;
|
171 |
|
172 |
return 0; |
173 |
} |
174 |
|
175 |
/**
|
176 |
* Decode interleaved plane buffer up to 8bpp
|
177 |
* @param dst Destination buffer
|
178 |
* @param buf Source buffer
|
179 |
* @param buf_size
|
180 |
* @param plane plane number to decode as
|
181 |
*/
|
182 |
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane) |
183 |
{ |
184 |
const uint64_t *lut = plane8_lut[plane];
|
185 |
do {
|
186 |
uint64_t v = AV_RN64A(dst) | lut[*buf++]; |
187 |
AV_WN64A(dst, v); |
188 |
dst += 8;
|
189 |
} while (--buf_size);
|
190 |
} |
191 |
|
192 |
/**
|
193 |
* Decode interleaved plane buffer up to 24bpp
|
194 |
* @param dst Destination buffer
|
195 |
* @param buf Source buffer
|
196 |
* @param buf_size
|
197 |
* @param plane plane number to decode as
|
198 |
*/
|
199 |
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane) |
200 |
{ |
201 |
const uint32_t *lut = plane32_lut[plane];
|
202 |
do {
|
203 |
unsigned mask = (*buf >> 2) & ~3; |
204 |
dst[0] |= lut[mask++];
|
205 |
dst[1] |= lut[mask++];
|
206 |
dst[2] |= lut[mask++];
|
207 |
dst[3] |= lut[mask];
|
208 |
mask = (*buf++ << 2) & 0x3F; |
209 |
dst[4] |= lut[mask++];
|
210 |
dst[5] |= lut[mask++];
|
211 |
dst[6] |= lut[mask++];
|
212 |
dst[7] |= lut[mask];
|
213 |
dst += 8;
|
214 |
} while (--buf_size);
|
215 |
} |
216 |
|
217 |
/**
|
218 |
* Decode one complete byterun1 encoded line.
|
219 |
*
|
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
|
225 |
*/
|
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; |
229 |
unsigned x;
|
230 |
for (x = 0; x < dst_size && buf < buf_end;) { |
231 |
unsigned length;
|
232 |
const int8_t value = *buf++;
|
233 |
if (value >= 0) { |
234 |
length = value + 1;
|
235 |
memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf)); |
236 |
buf += length; |
237 |
} else if (value > -128) { |
238 |
length = -value + 1;
|
239 |
memset(dst + x, *buf++, FFMIN(length, dst_size - x)); |
240 |
} else { // noop |
241 |
continue;
|
242 |
} |
243 |
x += length; |
244 |
} |
245 |
return buf - buf_start;
|
246 |
} |
247 |
|
248 |
static int decode_frame_ilbm(AVCodecContext *avctx, |
249 |
void *data, int *data_size, |
250 |
AVPacket *avpkt) |
251 |
{ |
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;
|
256 |
int y, plane, res;
|
257 |
|
258 |
if (s->init) {
|
259 |
if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) { |
260 |
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
|
261 |
return res;
|
262 |
} |
263 |
} else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { |
264 |
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
265 |
return res;
|
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) |
268 |
return res;
|
269 |
} |
270 |
s->init = 1;
|
271 |
|
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); |
279 |
buf += s->planesize; |
280 |
} |
281 |
} |
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); |
288 |
buf += s->planesize; |
289 |
} |
290 |
} |
291 |
} |
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 |
297 |
} |
298 |
} |
299 |
|
300 |
*data_size = sizeof(AVFrame);
|
301 |
*(AVFrame*)data = s->frame; |
302 |
return buf_size;
|
303 |
} |
304 |
|
305 |
static int decode_frame_byterun1(AVCodecContext *avctx, |
306 |
void *data, int *data_size, |
307 |
AVPacket *avpkt) |
308 |
{ |
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;
|
313 |
int y, plane, res;
|
314 |
|
315 |
if (s->init) {
|
316 |
if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) { |
317 |
av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
|
318 |
return res;
|
319 |
} |
320 |
} else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { |
321 |
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
322 |
return res;
|
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) |
325 |
return res;
|
326 |
} |
327 |
s->init = 1;
|
328 |
|
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); |
337 |
} |
338 |
} |
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); |
346 |
} |
347 |
} |
348 |
} |
349 |
} else {
|
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); |
353 |
} |
354 |
} |
355 |
|
356 |
*data_size = sizeof(AVFrame);
|
357 |
*(AVFrame*)data = s->frame; |
358 |
return buf_size;
|
359 |
} |
360 |
|
361 |
static av_cold int decode_end(AVCodecContext *avctx) |
362 |
{ |
363 |
IffContext *s = avctx->priv_data; |
364 |
if (s->frame.data[0]) |
365 |
avctx->release_buffer(avctx, &s->frame); |
366 |
av_freep(&s->planebuf); |
367 |
return 0; |
368 |
} |
369 |
|
370 |
AVCodec ff_iff_ilbm_decoder = { |
371 |
"iff_ilbm",
|
372 |
AVMEDIA_TYPE_VIDEO, |
373 |
CODEC_ID_IFF_ILBM, |
374 |
sizeof(IffContext),
|
375 |
decode_init, |
376 |
NULL,
|
377 |
decode_end, |
378 |
decode_frame_ilbm, |
379 |
CODEC_CAP_DR1, |
380 |
.long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
|
381 |
}; |
382 |
|
383 |
AVCodec ff_iff_byterun1_decoder = { |
384 |
"iff_byterun1",
|
385 |
AVMEDIA_TYPE_VIDEO, |
386 |
CODEC_ID_IFF_BYTERUN1, |
387 |
sizeof(IffContext),
|
388 |
decode_init, |
389 |
NULL,
|
390 |
decode_end, |
391 |
decode_frame_byterun1, |
392 |
CODEC_CAP_DR1, |
393 |
.long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
|
394 |
}; |