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 #include "internal.h"
33 
34 typedef struct {
36  int planesize;
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 
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 
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 ||
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
168  if (!s->planebuf)
169  return AVERROR(ENOMEM);
170 
171  s->frame.reference = 1;
172 
173  return 0;
174 }
175 
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 
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 
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 
250  void *data, int *got_frame,
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 && buf < buf_end; 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  *got_frame = 1;
302  *(AVFrame*)data = s->frame;
303  return buf_size;
304 }
305 
307  void *data, int *got_frame,
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  *got_frame = 1;
358  *(AVFrame*)data = s->frame;
359  return buf_size;
360 }
361 
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 
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,
379  .capabilities = CODEC_CAP_DR1,
380  .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
381 };
382 
384  .name = "iff_byterun1",
385  .type = AVMEDIA_TYPE_VIDEO,
387  .priv_data_size = sizeof(IffContext),
388  .init = decode_init,
389  .close = decode_end,
391  .capabilities = CODEC_CAP_DR1,
392  .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
393 };
static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
Convert CMAP buffer (stored in extradata) to lavc palette format.
Definition: iff.c:123
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:61
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
Decode interleaved plane buffer up to 24bpp.
Definition: iff.c:200
This structure describes decoded (raw) audio or video data.
Definition: avcodec.h:989
void(* release_buffer)(struct AVCodecContext *c, AVFrame *pic)
Called to release buffers which were allocated with get_buffer.
Definition: avcodec.h:2259
misc image utilities
static int decode_frame_byterun1(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: iff.c:306
int size
Definition: avcodec.h:916
#define AV_RB24
Definition: intreadwrite.h:64
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1533
AVCodec.
Definition: avcodec.h:2960
int(* reget_buffer)(struct AVCodecContext *c, AVFrame *pic)
Called at the beginning of a frame to get cr buffer for it.
Definition: avcodec.h:2273
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
Decode interleaved plane buffer up to 8bpp.
Definition: iff.c:183
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:151
static av_cold int decode_end(AVCodecContext *avctx)
Definition: iff.c:362
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
Definition: mimic.c:228
uint8_t * planebuf
Definition: iff.c:37
uint8_t
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
AVCodec ff_iff_byterun1_decoder
Definition: iff.c:383
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1454
const char data[16]
Definition: mxf.c:66
uint8_t * data
Definition: avcodec.h:915
bitstream reader API header.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2704
static int init(AVCodecParserContext *s)
Definition: h264_parser.c:335
static int decode_frame_ilbm(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: iff.c:249
static const uint16_t mask[17]
Definition: lzw.c:38
int reference
is this picture used as reference The values for this are the same as the MpegEncContext.picture_structure variable, that is 1->top field, 2->bottom field, 3->frame/both fields.
Definition: avcodec.h:1132
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:88
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
const char * name
Name of the codec implementation.
Definition: avcodec.h:2967
#define LUT32(plane)
Definition: iff.c:84
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:220
Definition: iff.c:34
int width
picture width / height.
Definition: avcodec.h:1508
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame)
Get a buffer for a frame.
Definition: utils.c:464
#define AV_WN64A(p, v)
Definition: intreadwrite.h:462
int init
Definition: iff.c:38
external API header
AVCodec ff_iff_ilbm_decoder
Definition: iff.c:371
int linesize[AV_NUM_DATA_POINTERS]
Size, in bytes, of the data for each picture/channel plane.
Definition: avcodec.h:1008
main external API structure.
Definition: avcodec.h:1339
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:326
int planesize
Definition: iff.c:36
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:1365
int extradata_size
Definition: avcodec.h:1455
static av_always_inline uint32_t gray2rgb(const uint32_t x)
Definition: iff.c:116
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: avcodec.h:997
Y , 8bpp.
Definition: pixfmt.h:73
common internal api header.
static const uint32_t plane32_lut[32][16 *4]
Definition: iff.c:104
#define LUT8(plane)
Definition: iff.c:59
static av_cold int decode_init(AVCodecContext *avctx)
Definition: iff.c:149
void * priv_data
Definition: avcodec.h:1382
AVFrame frame
Definition: iff.c:35
static const uint64_t plane8_lut[8][256]
Definition: iff.c:79
static int decode_byterun(uint8_t *dst, int dst_size, const uint8_t *buf, const uint8_t *const buf_end)
Decode one complete byterun1 encoded line.
Definition: iff.c:227
#define AV_RN64A(p)
Definition: intreadwrite.h:450
This structure stores compressed data.
Definition: avcodec.h:898