]> git.sesse.net Git - ffmpeg/blob - libavcodec/iff.c
4bbb5dda1f698300afab39aeaf191f290d15612a
[ffmpeg] / 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 #include "internal.h"
33
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;
40
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
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
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),
82 };
83
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
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),
113 };
114
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;
118 }
119
120 /**
121  * Convert CMAP buffer (stored in extradata) to lavc palette format
122  */
123 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
124 {
125     int count, i;
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;
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 );
138         }
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     }
146     return 0;
147 }
148
149 static av_cold int decode_init(AVCodecContext *avctx)
150 {
151     IffContext *s = avctx->priv_data;
152     int err;
153
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;
162     }
163
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);
170
171     s->frame.reference = 1;
172
173     return 0;
174 }
175
176 /**
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
182  */
183 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
184 {
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);
191 }
192
193 /**
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
199  */
200 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
201 {
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);
216 }
217
218 /**
219  * Decode one complete byterun1 encoded line.
220  *
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
226 */
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;
243         }
244         x += length;
245     }
246     return buf - buf_start;
247 }
248
249 static int decode_frame_ilbm(AVCodecContext *avctx,
250                             void *data, int *data_size,
251                             AVPacket *avpkt)
252 {
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;
258
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;
263         }
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 = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
269             return res;
270     }
271     s->init = 1;
272
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;
281                 }
282             }
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;
290                 }
291             }
292         }
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
298         }
299     }
300
301     *data_size = sizeof(AVFrame);
302     *(AVFrame*)data = s->frame;
303     return buf_size;
304 }
305
306 static int decode_frame_byterun1(AVCodecContext *avctx,
307                             void *data, int *data_size,
308                             AVPacket *avpkt)
309 {
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;
315
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;
320         }
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 = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
326             return res;
327     }
328     s->init = 1;
329
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);
338                 }
339             }
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);
347                 }
348             }
349         }
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);
354         }
355     }
356
357     *data_size = sizeof(AVFrame);
358     *(AVFrame*)data = s->frame;
359     return buf_size;
360 }
361
362 static av_cold int decode_end(AVCodecContext *avctx)
363 {
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;
369 }
370
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"),
381 };
382
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"),
393 };