h264: remove obsolete comment.
[FFMpeg-mirror/mplayer-patches.git] / libavcodec / iff.c
blob584e7f983fcff0d7d6180cf11d04837bcedba725
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>
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
23 /**
24 * @file
25 * IFF PBM/ILBM bitmap decoder
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
30 #include "avcodec.h"
31 #include "get_bits.h"
32 #include "internal.h"
34 typedef struct {
35 AVFrame frame;
36 int planesize;
37 uint8_t * planebuf;
38 int init; // 1 if buffer and palette data already initialized, 0 otherwise
39 } IffContext;
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) { \
85 0, 0, 0, 0, \
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)
125 int count, i;
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);
135 if (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);
146 return 0;
149 static av_cold int decode_init(AVCodecContext *avctx)
151 IffContext *s = avctx->priv_data;
152 int err;
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
157 : AV_PIX_FMT_GRAY8;
158 } else if (avctx->bits_per_coded_sample <= 32) {
159 avctx->pix_fmt = AV_PIX_FMT_BGR32;
160 } else {
161 return AVERROR_INVALIDDATA;
164 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
165 return err;
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);
168 if (!s->planebuf)
169 return AVERROR(ENOMEM);
171 s->frame.reference = 1;
173 return 0;
177 * Decode interleaved plane buffer up to 8bpp
178 * @param dst Destination buffer
179 * @param buf Source buffer
180 * @param buf_size
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];
186 do {
187 uint64_t v = AV_RN64A(dst) | lut[*buf++];
188 AV_WN64A(dst, v);
189 dst += 8;
190 } while (--buf_size);
194 * Decode interleaved plane buffer up to 24bpp
195 * @param dst Destination buffer
196 * @param buf Source buffer
197 * @param buf_size
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];
203 do {
204 unsigned mask = (*buf >> 2) & ~3;
205 dst[0] |= lut[mask++];
206 dst[1] |= lut[mask++];
207 dst[2] |= lut[mask++];
208 dst[3] |= lut[mask];
209 mask = (*buf++ << 2) & 0x3F;
210 dst[4] |= lut[mask++];
211 dst[5] |= lut[mask++];
212 dst[6] |= lut[mask++];
213 dst[7] |= lut[mask];
214 dst += 8;
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;
230 unsigned x;
231 for (x = 0; x < dst_size && buf < buf_end;) {
232 unsigned length;
233 const int8_t value = *buf++;
234 if (value >= 0) {
235 length = value + 1;
236 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
237 buf += length;
238 } else if (value > -128) {
239 length = -value + 1;
240 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
241 } else { // noop
242 continue;
244 x += length;
246 return buf - buf_start;
249 static int decode_frame_ilbm(AVCodecContext *avctx,
250 void *data, int *got_frame,
251 AVPacket *avpkt)
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;
257 int y, plane, res;
259 if (s->init) {
260 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
261 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
262 return res;
264 } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
265 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
266 return res;
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)
269 return res;
271 s->init = 1;
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);
280 buf += s->planesize;
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);
289 buf += s->planesize;
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
301 *got_frame = 1;
302 *(AVFrame*)data = s->frame;
303 return buf_size;
306 static int decode_frame_byterun1(AVCodecContext *avctx,
307 void *data, int *got_frame,
308 AVPacket *avpkt)
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;
314 int y, plane, res;
316 if (s->init) {
317 if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
318 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
319 return res;
321 } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
322 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
323 return res;
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)
326 return res;
328 s->init = 1;
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);
350 } else {
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);
357 *got_frame = 1;
358 *(AVFrame*)data = s->frame;
359 return buf_size;
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);
368 return 0;
371 AVCodec ff_iff_ilbm_decoder = {
372 .name = "iff_ilbm",
373 .type = AVMEDIA_TYPE_VIDEO,
374 .id = AV_CODEC_ID_IFF_ILBM,
375 .priv_data_size = sizeof(IffContext),
376 .init = decode_init,
377 .close = decode_end,
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),
388 .init = decode_init,
389 .close = decode_end,
390 .decode = decode_frame_byterun1,
391 .capabilities = CODEC_CAP_DR1,
392 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),