Libav
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 <stdint.h>
29 
30 #include "libavutil/imgutils.h"
31 #include "bytestream.h"
32 #include "avcodec.h"
33 #include "get_bits.h"
34 #include "internal.h"
35 
36 typedef struct {
38  int planesize;
40  int init; // 1 if buffer and palette data already initialized, 0 otherwise
41 } IffContext;
42 
43 #define LUT8_PART(plane, v) \
44  AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
45  AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
46  AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
47  AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
48  AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
49  AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
50  AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
51  AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
52  AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
53  AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
54  AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
55  AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
56  AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
57  AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
58  AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
59  AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
60 
61 #define LUT8(plane) { \
62  LUT8_PART(plane, 0x0000000), \
63  LUT8_PART(plane, 0x1000000), \
64  LUT8_PART(plane, 0x0010000), \
65  LUT8_PART(plane, 0x1010000), \
66  LUT8_PART(plane, 0x0000100), \
67  LUT8_PART(plane, 0x1000100), \
68  LUT8_PART(plane, 0x0010100), \
69  LUT8_PART(plane, 0x1010100), \
70  LUT8_PART(plane, 0x0000001), \
71  LUT8_PART(plane, 0x1000001), \
72  LUT8_PART(plane, 0x0010001), \
73  LUT8_PART(plane, 0x1010001), \
74  LUT8_PART(plane, 0x0000101), \
75  LUT8_PART(plane, 0x1000101), \
76  LUT8_PART(plane, 0x0010101), \
77  LUT8_PART(plane, 0x1010101), \
78 }
79 
80 // 8 planes * 8-bit mask
81 static const uint64_t plane8_lut[8][256] = {
82  LUT8(0), LUT8(1), LUT8(2), LUT8(3),
83  LUT8(4), LUT8(5), LUT8(6), LUT8(7),
84 };
85 
86 #define LUT32(plane) { \
87  0, 0, 0, 0, \
88  0, 0, 0, 1 << plane, \
89  0, 0, 1 << plane, 0, \
90  0, 0, 1 << plane, 1 << plane, \
91  0, 1 << plane, 0, 0, \
92  0, 1 << plane, 0, 1 << plane, \
93  0, 1 << plane, 1 << plane, 0, \
94  0, 1 << plane, 1 << plane, 1 << plane, \
95  1 << plane, 0, 0, 0, \
96  1 << plane, 0, 0, 1 << plane, \
97  1 << plane, 0, 1 << plane, 0, \
98  1 << plane, 0, 1 << plane, 1 << plane, \
99  1 << plane, 1 << plane, 0, 0, \
100  1 << plane, 1 << plane, 0, 1 << plane, \
101  1 << plane, 1 << plane, 1 << plane, 0, \
102  1 << plane, 1 << plane, 1 << plane, 1 << plane, \
103 }
104 
105 // 32 planes * 4-bit mask * 4 lookup tables each
106 static const uint32_t plane32_lut[32][16*4] = {
107  LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
108  LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
109  LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
110  LUT32(12), LUT32(13), LUT32(14), LUT32(15),
111  LUT32(16), LUT32(17), LUT32(18), LUT32(19),
112  LUT32(20), LUT32(21), LUT32(22), LUT32(23),
113  LUT32(24), LUT32(25), LUT32(26), LUT32(27),
114  LUT32(28), LUT32(29), LUT32(30), LUT32(31),
115 };
116 
117 // Gray to RGB, required for palette table of grayscale images with bpp < 8
118 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
119  return x << 16 | x << 8 | x;
120 }
121 
125 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
126 {
127  int count, i;
128 
129  if (avctx->bits_per_coded_sample > 8) {
130  av_log(avctx, AV_LOG_ERROR, "bit_per_coded_sample > 8 not supported\n");
131  return AVERROR_INVALIDDATA;
132  }
133 
134  count = 1 << avctx->bits_per_coded_sample;
135  // If extradata is smaller than actually needed, fill the remaining with black.
136  count = FFMIN(avctx->extradata_size / 3, count);
137  if (count) {
138  for (i = 0; i < count; i++)
139  pal[i] = 0xFF000000 | AV_RB24(avctx->extradata + i * 3);
140  } else { // Create gray-scale color palette for bps < 8
141  count = 1 << avctx->bits_per_coded_sample;
142 
143  for (i = 0; i < count; i++)
144  pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
145  }
146  return 0;
147 }
148 
150 {
151  IffContext *s = avctx->priv_data;
152  av_frame_free(&s->frame);
153  av_freep(&s->planebuf);
154  return 0;
155 }
156 
158 {
159  IffContext *s = avctx->priv_data;
160  int err;
161 
162  if (avctx->bits_per_coded_sample <= 8) {
163  avctx->pix_fmt = (avctx->bits_per_coded_sample < 8 ||
166  } else if (avctx->bits_per_coded_sample <= 32) {
167  avctx->pix_fmt = AV_PIX_FMT_BGR32;
168  } else {
169  return AVERROR_INVALIDDATA;
170  }
171 
172  if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
173  return err;
174  s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
176  if (!s->planebuf)
177  return AVERROR(ENOMEM);
178 
179  s->frame = av_frame_alloc();
180  if (!s->frame) {
181  decode_end(avctx);
182  return AVERROR(ENOMEM);
183  }
184 
185  return 0;
186 }
187 
195 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
196 {
197  const uint64_t *lut = plane8_lut[plane];
198  do {
199  uint64_t v = AV_RN64A(dst) | lut[*buf++];
200  AV_WN64A(dst, v);
201  dst += 8;
202  } while (--buf_size);
203 }
204 
212 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
213 {
214  const uint32_t *lut = plane32_lut[plane];
215  do {
216  unsigned mask = (*buf >> 2) & ~3;
217  dst[0] |= lut[mask++];
218  dst[1] |= lut[mask++];
219  dst[2] |= lut[mask++];
220  dst[3] |= lut[mask];
221  mask = (*buf++ << 2) & 0x3F;
222  dst[4] |= lut[mask++];
223  dst[5] |= lut[mask++];
224  dst[6] |= lut[mask++];
225  dst[7] |= lut[mask];
226  dst += 8;
227  } while (--buf_size);
228 }
229 
239 static int decode_byterun(uint8_t *dst, int dst_size,
240  const uint8_t *buf, const uint8_t *const buf_end)
241 {
242  const uint8_t *const buf_start = buf;
243  unsigned x;
244  for (x = 0; x < dst_size && buf < buf_end;) {
245  unsigned length;
246  const int8_t value = *buf++;
247  if (value >= 0) {
248  length = value + 1;
249  memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
250  buf += length;
251  } else if (value > -128) {
252  length = -value + 1;
253  memset(dst + x, *buf++, FFMIN(length, dst_size - x));
254  } else { // noop
255  continue;
256  }
257  x += length;
258  }
259  return buf - buf_start;
260 }
261 
263  void *data, int *got_frame,
264  AVPacket *avpkt)
265 {
266  IffContext *s = avctx->priv_data;
267  const uint8_t *buf = avpkt->data;
268  int buf_size = avpkt->size;
269  const uint8_t *buf_end = buf + buf_size;
270  int y, plane, res;
271 
272  if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
273  return res;
274 
275  if (!s->init && avctx->bits_per_coded_sample <= 8 &&
276  avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
277  if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
278  return res;
279  }
280  s->init = 1;
281 
282  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
283  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
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);
287  for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
288  plane++) {
289  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
290  buf += s->planesize;
291  }
292  }
293  } else { // AV_PIX_FMT_BGR32
294  for (y = 0; y < avctx->height; y++) {
295  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
296  memset(row, 0, avctx->width << 2);
297  for (plane = 0; plane < avctx->bits_per_coded_sample && buf < buf_end;
298  plane++) {
299  decodeplane32((uint32_t *)row, buf,
300  FFMIN(s->planesize, buf_end - buf), plane);
301  buf += s->planesize;
302  }
303  }
304  }
305  } else if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) { // IFF-PBM
306  for (y = 0; y < avctx->height && buf < buf_end; y++) {
307  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
308  memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
309  buf += avctx->width + (avctx->width % 2); // padding if odd
310  }
311  }
312 
313  if ((res = av_frame_ref(data, s->frame)) < 0)
314  return res;
315 
316  *got_frame = 1;
317 
318  return buf_size;
319 }
320 
322  void *data, int *got_frame,
323  AVPacket *avpkt)
324 {
325  IffContext *s = avctx->priv_data;
326  const uint8_t *buf = avpkt->data;
327  int buf_size = avpkt->size;
328  const uint8_t *buf_end = buf + buf_size;
329  int y, plane, res;
330 
331  if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
332  return res;
333 
334  if (!s->init && avctx->bits_per_coded_sample <= 8 &&
335  avctx->pix_fmt != AV_PIX_FMT_GRAY8) {
336  if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
337  return res;
338  }
339  s->init = 1;
340 
341  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
342  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
343  for (y = 0; y < avctx->height; y++) {
344  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
345  memset(row, 0, avctx->width);
346  for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
347  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
348  decodeplane8(row, s->planebuf, s->planesize, plane);
349  }
350  }
351  } else { // AV_PIX_FMT_BGR32
352  for (y = 0; y < avctx->height; y++) {
353  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
354  memset(row, 0, avctx->width << 2);
355  for (plane = 0; plane < avctx->bits_per_coded_sample; plane++) {
356  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
357  decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
358  }
359  }
360  }
361  } else {
362  for (y = 0; y < avctx->height; y++) {
363  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
364  buf += decode_byterun(row, avctx->width, buf, buf_end);
365  }
366  }
367 
368  if ((res = av_frame_ref(data, s->frame)) < 0)
369  return res;
370 
371  *got_frame = 1;
372 
373  return buf_size;
374 }
375 
377  .name = "iff_ilbm",
378  .long_name = NULL_IF_CONFIG_SMALL("IFF ILBM"),
379  .type = AVMEDIA_TYPE_VIDEO,
380  .id = AV_CODEC_ID_IFF_ILBM,
381  .priv_data_size = sizeof(IffContext),
382  .init = decode_init,
383  .close = decode_end,
385  .capabilities = CODEC_CAP_DR1,
386 };
387 
389  .name = "iff_byterun1",
390  .long_name = NULL_IF_CONFIG_SMALL("IFF ByteRun1"),
391  .type = AVMEDIA_TYPE_VIDEO,
393  .priv_data_size = sizeof(IffContext),
394  .init = decode_init,
395  .close = decode_end,
397  .capabilities = CODEC_CAP_DR1,
398 };
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:62
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
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:212
This structure describes decoded (raw) audio or video data.
Definition: frame.h:107
misc image utilities
static int decode_frame_byterun1(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: iff.c:321
static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
Convert CMAP buffer (stored in extradata) to lavc palette format.
Definition: iff.c:125
int size
Definition: avcodec.h:974
#define AV_RB24
Definition: intreadwrite.h:64
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1247
AVCodec.
Definition: avcodec.h:2755
#define FFALIGN(x, a)
Definition: common.h:62
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:195
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:198
static av_cold int decode_end(AVCodecContext *avctx)
Definition: iff.c:149
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
Definition: mimic.c:269
uint8_t * planebuf
Definition: iff.c:39
uint8_t
#define av_cold
Definition: attributes.h:66
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:43
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
AVCodec ff_iff_byterun1_decoder
Definition: iff.c:388
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:174
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1162
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:711
const char data[16]
Definition: mxf.c:66
uint8_t * data
Definition: avcodec.h:973
#define FFMIN3(a, b, c)
Definition: common.h:58
bitstream reader API header.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2481
static int decode_frame_ilbm(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: iff.c:262
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
static const uint16_t mask[17]
Definition: lzw.c:38
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:55
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:142
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:148
const char * name
Name of the codec implementation.
Definition: avcodec.h:2762
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:509
#define LUT32(plane)
Definition: iff.c:86
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
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
Definition: utils.c:755
#define FFMIN(a, b)
Definition: common.h:57
Definition: iff.c:36
int width
picture width / height.
Definition: avcodec.h:1217
#define AV_WN64A(p, v)
Definition: intreadwrite.h:462
AVFrame * frame
Definition: iff.c:37
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:208
int init
Definition: iff.c:40
Libavcodec external API header.
AVCodec ff_iff_ilbm_decoder
Definition: iff.c:376
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:125
main external API structure.
Definition: avcodec.h:1054
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:489
int planesize
Definition: iff.c:38
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:1080
int extradata_size
Definition: avcodec.h:1163
static av_always_inline uint32_t gray2rgb(const uint32_t x)
Definition: iff.c:118
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:113
Y , 8bpp.
Definition: pixfmt.h:73
common internal api header.
static const uint32_t plane32_lut[32][16 *4]
Definition: iff.c:106
static av_cold int init(AVCodecParserContext *s)
Definition: h264_parser.c:498
#define LUT8(plane)
Definition: iff.c:61
static av_cold int decode_init(AVCodecContext *avctx)
Definition: iff.c:157
void * priv_data
Definition: avcodec.h:1090
static const uint64_t plane8_lut[8][256]
Definition: iff.c:81
#define av_always_inline
Definition: attributes.h:40
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:239
#define AV_RN64A(p)
Definition: intreadwrite.h:450
#define MKTAG(a, b, c, d)
Definition: common.h:238
This structure stores compressed data.
Definition: avcodec.h:950