019af4dbfeacf57cab125bb1fa72c3a9f6b28bc0
[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 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 "bytestream.h"
29 #include "avcodec.h"
30 #include "get_bits.h"
31 #include "iff.h"
32
33 typedef struct {
34     AVFrame frame;
35     int planesize;
36     uint8_t * planebuf;
37 } IffContext;
38
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
56
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),                \
74 }
75
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),
80 };
81
82 #define LUT32(plane) {                                \
83              0,          0,          0,          0,   \
84              0,          0,          0, 1 << plane,   \
85              0,          0, 1 << plane,          0,   \
86              0,          0, 1 << plane, 1 << plane,   \
87              0, 1 << plane,          0,          0,   \
88              0, 1 << plane,          0, 1 << plane,   \
89              0, 1 << plane, 1 << plane,          0,   \
90              0, 1 << plane, 1 << plane, 1 << plane,   \
91     1 << plane,          0,          0,          0,   \
92     1 << plane,          0,          0, 1 << plane,   \
93     1 << plane,          0, 1 << plane,          0,   \
94     1 << plane,          0, 1 << plane, 1 << plane,   \
95     1 << plane, 1 << plane,          0,          0,   \
96     1 << plane, 1 << plane,          0, 1 << plane,   \
97     1 << plane, 1 << plane, 1 << plane,          0,   \
98     1 << plane, 1 << plane, 1 << plane, 1 << plane,   \
99 }
100
101 // 32 planes * 4-bit mask * 4 lookup tables each
102 static const uint32_t plane32_lut[32][16*4] = {
103     LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
104     LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
105     LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
106     LUT32(12), LUT32(13), LUT32(14), LUT32(15),
107     LUT32(16), LUT32(17), LUT32(18), LUT32(19),
108     LUT32(20), LUT32(21), LUT32(22), LUT32(23),
109     LUT32(24), LUT32(25), LUT32(26), LUT32(27),
110     LUT32(28), LUT32(29), LUT32(30), LUT32(31),
111 };
112
113 /**
114  * Convert CMAP buffer (stored in extradata) to lavc palette format
115  */
116 int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
117 {
118     int count, i;
119
120     if (avctx->bits_per_coded_sample > 8) {
121         av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
122         return AVERROR_INVALIDDATA;
123     }
124
125     count = 1 << avctx->bits_per_coded_sample;
126     // If extradata is smaller than actually needed, fill the remaining with black.
127     count = FFMIN(avctx->extradata_size / 3, count);
128     for (i=0; i < count; i++) {
129         pal[i] = 0xFF000000 | AV_RB24( avctx->extradata + i*3 );
130     }
131     return 0;
132 }
133
134 static av_cold int decode_init(AVCodecContext *avctx)
135 {
136     IffContext *s = avctx->priv_data;
137     int err;
138
139     if (avctx->bits_per_coded_sample <= 8) {
140         avctx->pix_fmt = PIX_FMT_PAL8;
141     } else if (avctx->bits_per_coded_sample <= 32) {
142         avctx->pix_fmt = PIX_FMT_BGR32;
143     } else {
144         return AVERROR_INVALIDDATA;
145     }
146
147     if ((err = avcodec_check_dimensions(avctx, avctx->width, avctx->height)))
148         return err;
149     s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
150     s->planebuf = av_malloc(s->planesize + FF_INPUT_BUFFER_PADDING_SIZE);
151     if (!s->planebuf)
152         return AVERROR(ENOMEM);
153
154     s->frame.reference = 1;
155     if ((err = avctx->get_buffer(avctx, &s->frame) < 0)) {
156         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
157         return err;
158     }
159
160     return avctx->bits_per_coded_sample <= 8 ?
161        ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1]) : 0;
162 }
163
164 /**
165  * Decode interleaved plane buffer up to 8bpp
166  * @param dst Destination buffer
167  * @param buf Source buffer
168  * @param buf_size
169  * @param plane plane number to decode as
170  */
171 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
172 {
173     const uint64_t *lut = plane8_lut[plane];
174     do {
175         uint64_t v = AV_RN64A(dst) | lut[*buf++];
176         AV_WN64A(dst, v);
177         dst += 8;
178     } while (--buf_size);
179 }
180
181 /**
182  * Decode interleaved plane buffer up to 24bpp
183  * @param dst Destination buffer
184  * @param buf Source buffer
185  * @param buf_size
186  * @param plane plane number to decode as
187  */
188 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
189 {
190     const uint32_t *lut = plane32_lut[plane];
191     do {
192         unsigned mask = (*buf >> 2) & ~3;
193         dst[0] |= lut[mask++];
194         dst[1] |= lut[mask++];
195         dst[2] |= lut[mask++];
196         dst[3] |= lut[mask];
197         mask = (*buf++ << 2) & 0x3F;
198         dst[4] |= lut[mask++];
199         dst[5] |= lut[mask++];
200         dst[6] |= lut[mask++];
201         dst[7] |= lut[mask];
202         dst += 8;
203     } while (--buf_size);
204 }
205
206 static int decode_frame_ilbm(AVCodecContext *avctx,
207                             void *data, int *data_size,
208                             AVPacket *avpkt)
209 {
210     IffContext *s = avctx->priv_data;
211     const uint8_t *buf = avpkt->data;
212     int buf_size = avpkt->size;
213     const uint8_t *buf_end = buf+buf_size;
214     int y, plane;
215
216     if (avctx->reget_buffer(avctx, &s->frame) < 0){
217         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
218         return -1;
219     }
220
221     if (avctx->pix_fmt == PIX_FMT_PAL8) {
222         for(y = 0; y < avctx->height; y++ ) {
223             uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
224             memset(row, 0, avctx->width);
225             for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
226                 decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
227                 buf += s->planesize;
228             }
229         }
230     } else { // PIX_FMT_BGR32
231         for(y = 0; y < avctx->height; y++ ) {
232             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
233             memset(row, 0, avctx->width << 2);
234             for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end; plane++) {
235                 decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
236                 buf += s->planesize;
237             }
238         }
239     }
240
241     *data_size = sizeof(AVFrame);
242     *(AVFrame*)data = s->frame;
243     return buf_size;
244 }
245
246 static int decode_frame_byterun1(AVCodecContext *avctx,
247                             void *data, int *data_size,
248                             AVPacket *avpkt)
249 {
250     IffContext *s = avctx->priv_data;
251     const uint8_t *buf = avpkt->data;
252     int buf_size = avpkt->size;
253     const uint8_t *buf_end = buf+buf_size;
254     int y, plane, x;
255
256     if (avctx->reget_buffer(avctx, &s->frame) < 0){
257         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
258         return -1;
259     }
260
261     if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
262         if (avctx->pix_fmt == PIX_FMT_PAL8) {
263             for(y = 0; y < avctx->height ; y++ ) {
264                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
265                 memset(row, 0, avctx->width);
266                 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
267                     for(x = 0; x < s->planesize && buf < buf_end; ) {
268                         int8_t value = *buf++;
269                         unsigned length;
270                         if (value >= 0) {
271                             length = value + 1;
272                             memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf));
273                             buf += length;
274                         } else if (value > -128) {
275                             length = -value + 1;
276                             memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x));
277                         } else { //noop
278                             continue;
279                         }
280                         x += length;
281                     }
282                     decodeplane8(row, s->planebuf, s->planesize, plane);
283                 }
284             }
285         } else { //PIX_FMT_BGR32
286             for(y = 0; y < avctx->height ; y++ ) {
287                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
288                 memset(row, 0, avctx->width << 2);
289                 for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
290                     for(x = 0; x < s->planesize && buf < buf_end; ) {
291                         int8_t value = *buf++;
292                         unsigned length;
293                         if (value >= 0) {
294                             length = value + 1;
295                             memcpy(s->planebuf + x, buf, FFMIN3(length, s->planesize - x, buf_end - buf));
296                             buf += length;
297                         } else if (value > -128) {
298                             length = -value + 1;
299                             memset(s->planebuf + x, *buf++, FFMIN(length, s->planesize - x));
300                         } else { // noop
301                             continue;
302                         }
303                         x += length;
304                     }
305                     decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
306                 }
307             }
308         }
309     } else {
310         for(y = 0; y < avctx->height ; y++ ) {
311             uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
312             for(x = 0; x < avctx->width && buf < buf_end; ) {
313                 int8_t value = *buf++;
314                 unsigned length;
315                 if (value >= 0) {
316                     length = value + 1;
317                     memcpy(row + x, buf, FFMIN3(length, buf_end - buf, avctx->width - x));
318                     buf += length;
319                 } else if (value > -128) {
320                     length = -value + 1;
321                     memset(row + x, *buf++, FFMIN(length, avctx->width - x));
322                 } else { //noop
323                     continue;
324                 }
325                 x += length;
326             }
327         }
328     }
329
330     *data_size = sizeof(AVFrame);
331     *(AVFrame*)data = s->frame;
332     return buf_size;
333 }
334
335 static av_cold int decode_end(AVCodecContext *avctx)
336 {
337     IffContext *s = avctx->priv_data;
338     if (s->frame.data[0])
339         avctx->release_buffer(avctx, &s->frame);
340     av_freep(&s->planebuf);
341     return 0;
342 }
343
344 AVCodec iff_ilbm_decoder = {
345     "iff_ilbm",
346     AVMEDIA_TYPE_VIDEO,
347     CODEC_ID_IFF_ILBM,
348     sizeof(IffContext),
349     decode_init,
350     NULL,
351     decode_end,
352     decode_frame_ilbm,
353     CODEC_CAP_DR1,
354     .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
355 };
356
357 AVCodec iff_byterun1_decoder = {
358     "iff_byterun1",
359     AVMEDIA_TYPE_VIDEO,
360     CODEC_ID_IFF_BYTERUN1,
361     sizeof(IffContext),
362     decode_init,
363     NULL,
364     decode_end,
365     decode_frame_byterun1,
366     CODEC_CAP_DR1,
367     .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
368 };