iff.c
Go to the documentation of this file.
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 
28 #include "libavutil/imgutils.h"
29 #include "bytestream.h"
30 #include "avcodec.h"
31 #include "get_bits.h"
32 
33 typedef struct {
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 
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 
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
167  if (!s->planebuf)
168  return AVERROR(ENOMEM);
169 
170  s->frame.reference = 1;
171 
172  return 0;
173 }
174 
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 
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 
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 
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 && buf < buf_end; 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 
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 
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 
371  .name = "iff_ilbm",
372  .type = AVMEDIA_TYPE_VIDEO,
373  .id = CODEC_ID_IFF_ILBM,
374  .priv_data_size = sizeof(IffContext),
375  .init = decode_init,
376  .close = decode_end,
378  .capabilities = CODEC_CAP_DR1,
379  .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
380 };
381 
383  .name = "iff_byterun1",
384  .type = AVMEDIA_TYPE_VIDEO,
385  .id = CODEC_ID_IFF_BYTERUN1,
386  .priv_data_size = sizeof(IffContext),
387  .init = decode_init,
388  .close = decode_end,
390  .capabilities = CODEC_CAP_DR1,
391  .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
392 };