dsputil: template get_pixels() for different bit depths
[ffmpeg.git] / libavcodec / iff.c
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 Libav.
7  *
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.
12  *
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.
17  *
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
21  */
22
23 /**
24  * @file
25  * IFF PBM/ILBM bitmap decoder
26  */
27
28 #include "libavutil/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 };