lavc decoders: work with refcounted frames.
[libav.git] / libavcodec / iff.c
CommitLineData
b9e06ddd
PR
1/*
2 * IFF PBM/ILBM bitmap decoder
3 * Copyright (c) 2010 Peter Ross <pross@xvid.org>
473147be 4 * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
b9e06ddd 5 *
2912e87a 6 * This file is part of Libav.
b9e06ddd 7 *
2912e87a 8 * Libav is free software; you can redistribute it and/or
b9e06ddd
PR
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 *
2912e87a 13 * Libav is distributed in the hope that it will be useful,
b9e06ddd
PR
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
2912e87a 19 * License along with Libav; if not, write to the Free Software
b9e06ddd
PR
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23/**
ba87f080 24 * @file
b9e06ddd
PR
25 * IFF PBM/ILBM bitmap decoder
26 */
27
737eb597 28#include "libavutil/imgutils.h"
b9e06ddd
PR
29#include "bytestream.h"
30#include "avcodec.h"
005caa34 31#include "get_bits.h"
594d4d5d 32#include "internal.h"
005caa34
PR
33
34typedef struct {
35 AVFrame frame;
4fe4bb61 36 int planesize;
005caa34 37 uint8_t * planebuf;
522d3930 38 int init; // 1 if buffer and palette data already initialized, 0 otherwise
005caa34 39} IffContext;
b9e06ddd 40
0a9cb385 41#define LUT8_PART(plane, v) \
e6b22522
MR
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
0a9cb385
SV
58
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), \
76}
77
78// 8 planes * 8-bit mask
79static 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),
82};
83
dce2f7d3
SV
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, \
101}
102
103// 32 planes * 4-bit mask * 4 lookup tables each
104static 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),
113};
114
7a0e859c
SV
115// Gray to RGB, required for palette table of grayscale images with bpp < 8
116static av_always_inline uint32_t gray2rgb(const uint32_t x) {
117 return x << 16 | x << 8 | x;
118}
119
b9e06ddd
PR
120/**
121 * Convert CMAP buffer (stored in extradata) to lavc palette format
122 */
04e12496 123static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
b9e06ddd 124{
4fe4bb61 125 int count, i;
b9e06ddd
PR
126
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;
130 }
131
132 count = 1 << avctx->bits_per_coded_sample;
ebcf7c32
SV
133 // If extradata is smaller than actually needed, fill the remaining with black.
134 count = FFMIN(avctx->extradata_size / 3, count);
7a0e859c 135 if (count) {
6d810162
SV
136 for (i=0; i < count; i++) {
137 pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
138 }
7a0e859c
SV
139 } else { // Create gray-scale color palette for bps < 8
140 count = 1 << avctx->bits_per_coded_sample;
141
142 for (i=0; i < count; i++) {
143 pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
144 }
145 }
b9e06ddd
PR
146 return 0;
147}
148
149static av_cold int decode_init(AVCodecContext *avctx)
150{
005caa34 151 IffContext *s = avctx->priv_data;
0edfa79b 152 int err;
005caa34
PR
153
154 if (avctx->bits_per_coded_sample <= 8) {
7a0e859c 155 avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
716d413c
AK
156 avctx->extradata_size) ? AV_PIX_FMT_PAL8
157 : AV_PIX_FMT_GRAY8;
005caa34 158 } else if (avctx->bits_per_coded_sample <= 32) {
716d413c 159 avctx->pix_fmt = AV_PIX_FMT_BGR32;
005caa34
PR
160 } else {
161 return AVERROR_INVALIDDATA;
162 }
b9e06ddd 163
e16f217c 164 if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
59cca504 165 return err;
cfdaee45 166 s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
005caa34
PR
167 s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
168 if (!s->planebuf)
169 return AVERROR(ENOMEM);
b9e06ddd 170
522d3930 171 return 0;
b9e06ddd
PR
172}
173
174/**
687dc355
SV
175 * Decode interleaved plane buffer up to 8bpp
176 * @param dst Destination buffer
177 * @param buf Source buffer
178 * @param buf_size
687dc355
SV
179 * @param plane plane number to decode as
180 */
9d45a32b 181static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
687dc355 182{
0a9cb385 183 const uint64_t *lut = plane8_lut[plane];
2f955ea4 184 do {
0a9cb385
SV
185 uint64_t v = AV_RN64A(dst) | lut[*buf++];
186 AV_WN64A(dst, v);
79a9672d 187 dst += 8;
2f955ea4 188 } while (--buf_size);
687dc355
SV
189}
190
191/**
192 * Decode interleaved plane buffer up to 24bpp
005caa34
PR
193 * @param dst Destination buffer
194 * @param buf Source buffer
195 * @param buf_size
005caa34 196 * @param plane plane number to decode as
b9e06ddd 197 */
dce2f7d3 198static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
687dc355 199{
dce2f7d3
SV
200 const uint32_t *lut = plane32_lut[plane];
201 do {
202 unsigned mask = (*buf >> 2) & ~3;
203 dst[0] |= lut[mask++];
204 dst[1] |= lut[mask++];
205 dst[2] |= lut[mask++];
206 dst[3] |= lut[mask];
207 mask = (*buf++ << 2) & 0x3F;
208 dst[4] |= lut[mask++];
209 dst[5] |= lut[mask++];
210 dst[6] |= lut[mask++];
211 dst[7] |= lut[mask];
212 dst += 8;
213 } while (--buf_size);
b9e06ddd
PR
214}
215
ec1d1afc 216/**
49bd8e4b 217 * Decode one complete byterun1 encoded line.
ec1d1afc
SV
218 *
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
224*/
225static int decode_byterun(uint8_t *dst, int dst_size,
226 const uint8_t *buf, const uint8_t *const buf_end) {
227 const uint8_t *const buf_start = buf;
228 unsigned x;
229 for (x = 0; x < dst_size && buf < buf_end;) {
230 unsigned length;
231 const int8_t value = *buf++;
232 if (value >= 0) {
233 length = value + 1;
234 memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
235 buf += length;
236 } else if (value > -128) {
237 length = -value + 1;
238 memset(dst + x, *buf++, FFMIN(length, dst_size - x));
239 } else { // noop
240 continue;
241 }
242 x += length;
243 }
244 return buf - buf_start;
245}
246
b9e06ddd 247static int decode_frame_ilbm(AVCodecContext *avctx,
df9b9567 248 void *data, int *got_frame,
b9e06ddd
PR
249 AVPacket *avpkt)
250{
005caa34 251 IffContext *s = avctx->priv_data;
b9e06ddd 252 const uint8_t *buf = avpkt->data;
4fe4bb61 253 int buf_size = avpkt->size;
cbba8fec 254 const uint8_t *buf_end = buf+buf_size;
522d3930 255 int y, plane, res;
b9e06ddd 256
759001c5 257 if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
522d3930 258 return res;
759001c5
AK
259
260 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
261 avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
04e12496 262 if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
522d3930 263 return res;
b9e06ddd 264 }
522d3930 265 s->init = 1;
b9e06ddd 266
65d213ec 267 if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
716d413c 268 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
299ac811
SV
269 for(y = 0; y < avctx->height; y++ ) {
270 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
271 memset(row, 0, avctx->width);
272 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
273 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
274 buf += s->planesize;
275 }
fe51b5ce 276 }
716d413c 277 } else { // AV_PIX_FMT_BGR32
299ac811
SV
278 for(y = 0; y < avctx->height; y++ ) {
279 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
280 memset(row, 0, avctx->width << 2);
281 for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
282 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
283 buf += s->planesize;
284 }
fe51b5ce 285 }
b9e06ddd 286 }
716d413c 287 } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { // IFF-PBM
65d213ec
SV
288 for(y = 0; y < avctx->height; y++ ) {
289 uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
290 memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
e10412a3 291 buf += avctx->width + (avctx->width % 2); // padding if odd
65d213ec
SV
292 }
293 }
b9e06ddd 294
759001c5
AK
295 if ((res = av_frame_ref(data, &s->frame)) < 0)
296 return res;
297
df9b9567 298 *got_frame = 1;
759001c5 299
b9e06ddd
PR
300 return buf_size;
301}
302
303static int decode_frame_byterun1(AVCodecContext *avctx,
df9b9567 304 void *data, int *got_frame,
b9e06ddd
PR
305 AVPacket *avpkt)
306{
005caa34 307 IffContext *s = avctx->priv_data;
b9e06ddd 308 const uint8_t *buf = avpkt->data;
4fe4bb61 309 int buf_size = avpkt->size;
b9e06ddd 310 const uint8_t *buf_end = buf+buf_size;
522d3930 311 int y, plane, res;
b9e06ddd 312
759001c5 313 if ((res = ff_reget_buffer(avctx, &s->frame)) < 0)
522d3930 314 return res;
759001c5
AK
315
316 if (!s->init && avctx->bits_per_coded_sample <= 8 &&
317 avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
04e12496 318 if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
522d3930 319 return res;
b9e06ddd 320 }
522d3930 321 s->init = 1;
b9e06ddd 322
fe51b5ce 323 if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
716d413c 324 if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
726dc061
SV
325 for(y = 0; y < avctx->height ; y++ ) {
326 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
327 memset(row, 0, avctx->width);
328 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
ec1d1afc 329 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
9d45a32b 330 decodeplane8(row, s->planebuf, s->planesize, plane);
fe51b5ce
SV
331 }
332 }
716d413c 333 } else { //AV_PIX_FMT_BGR32
fe51b5ce
SV
334 for(y = 0; y < avctx->height ; y++ ) {
335 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
336 memset(row, 0, avctx->width << 2);
337 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
ec1d1afc 338 buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
9d45a32b 339 decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
005caa34 340 }
b9e06ddd 341 }
fe51b5ce 342 }
726dc061
SV
343 } else {
344 for(y = 0; y < avctx->height ; y++ ) {
345 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
ec1d1afc 346 buf += decode_byterun(row, avctx->width, buf, buf_end);
b9e06ddd
PR
347 }
348 }
349
759001c5
AK
350 if ((res = av_frame_ref(data, &s->frame)) < 0)
351 return res;
352
df9b9567 353 *got_frame = 1;
759001c5 354
b9e06ddd
PR
355 return buf_size;
356}
357
358static av_cold int decode_end(AVCodecContext *avctx)
359{
005caa34 360 IffContext *s = avctx->priv_data;
759001c5 361 av_frame_unref(&s->frame);
005caa34 362 av_freep(&s->planebuf);
b9e06ddd
PR
363 return 0;
364}
365
d36beb3f 366AVCodec ff_iff_ilbm_decoder = {
ec6402b7
AK
367 .name = "iff_ilbm",
368 .type = AVMEDIA_TYPE_VIDEO,
36ef5369 369 .id = AV_CODEC_ID_IFF_ILBM,
ec6402b7
AK
370 .priv_data_size = sizeof(IffContext),
371 .init = decode_init,
372 .close = decode_end,
373 .decode = decode_frame_ilbm,
374 .capabilities = CODEC_CAP_DR1,
00c3b67b 375 .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
b9e06ddd
PR
376};
377
d36beb3f 378AVCodec ff_iff_byterun1_decoder = {
ec6402b7
AK
379 .name = "iff_byterun1",
380 .type = AVMEDIA_TYPE_VIDEO,
36ef5369 381 .id = AV_CODEC_ID_IFF_BYTERUN1,
ec6402b7
AK
382 .priv_data_size = sizeof(IffContext),
383 .init = decode_init,
384 .close = decode_end,
385 .decode = decode_frame_byterun1,
386 .capabilities = CODEC_CAP_DR1,
00c3b67b 387 .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
b9e06ddd 388};