FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
iff.c
Go to the documentation of this file.
1 /*
2  * IFF ACBM/DEEP/ILBM/PBM 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 ACBM/DEEP/ILBM/PBM 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 // TODO: masking bits
35 typedef enum {
40 } mask_type;
41 
42 typedef struct {
44  int planesize;
46  uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
47  uint32_t *ham_palbuf; ///< HAM decode table
48  uint32_t *mask_buf; ///< temporary buffer for palette indices
49  uint32_t *mask_palbuf; ///< masking palette table
50  unsigned compression; ///< delta compression method used
51  unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
52  unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
53  unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
54  unsigned transparency; ///< TODO: transparency color index in palette
55  unsigned masking; ///< TODO: masking method used
56  int init; // 1 if buffer and palette data already initialized, 0 otherwise
57  int16_t tvdc[16]; ///< TVDC lookup table
58 } IffContext;
59 
60 #define LUT8_PART(plane, v) \
61  AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
62  AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
63  AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
64  AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
65  AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
66  AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
67  AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
68  AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
69  AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
70  AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
71  AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
72  AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
73  AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
74  AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
75  AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
76  AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
77 
78 #define LUT8(plane) { \
79  LUT8_PART(plane, 0x0000000), \
80  LUT8_PART(plane, 0x1000000), \
81  LUT8_PART(plane, 0x0010000), \
82  LUT8_PART(plane, 0x1010000), \
83  LUT8_PART(plane, 0x0000100), \
84  LUT8_PART(plane, 0x1000100), \
85  LUT8_PART(plane, 0x0010100), \
86  LUT8_PART(plane, 0x1010100), \
87  LUT8_PART(plane, 0x0000001), \
88  LUT8_PART(plane, 0x1000001), \
89  LUT8_PART(plane, 0x0010001), \
90  LUT8_PART(plane, 0x1010001), \
91  LUT8_PART(plane, 0x0000101), \
92  LUT8_PART(plane, 0x1000101), \
93  LUT8_PART(plane, 0x0010101), \
94  LUT8_PART(plane, 0x1010101), \
95 }
96 
97 // 8 planes * 8-bit mask
98 static const uint64_t plane8_lut[8][256] = {
99  LUT8(0), LUT8(1), LUT8(2), LUT8(3),
100  LUT8(4), LUT8(5), LUT8(6), LUT8(7),
101 };
102 
103 #define LUT32(plane) { \
104  0, 0, 0, 0, \
105  0, 0, 0, 1 << plane, \
106  0, 0, 1 << plane, 0, \
107  0, 0, 1 << plane, 1 << plane, \
108  0, 1 << plane, 0, 0, \
109  0, 1 << plane, 0, 1 << plane, \
110  0, 1 << plane, 1 << plane, 0, \
111  0, 1 << plane, 1 << plane, 1 << plane, \
112  1 << plane, 0, 0, 0, \
113  1 << plane, 0, 0, 1 << plane, \
114  1 << plane, 0, 1 << plane, 0, \
115  1 << plane, 0, 1 << plane, 1 << plane, \
116  1 << plane, 1 << plane, 0, 0, \
117  1 << plane, 1 << plane, 0, 1 << plane, \
118  1 << plane, 1 << plane, 1 << plane, 0, \
119  1 << plane, 1 << plane, 1 << plane, 1 << plane, \
120 }
121 
122 // 32 planes * 4-bit mask * 4 lookup tables each
123 static const uint32_t plane32_lut[32][16*4] = {
124  LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
125  LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
126  LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
127  LUT32(12), LUT32(13), LUT32(14), LUT32(15),
128  LUT32(16), LUT32(17), LUT32(18), LUT32(19),
129  LUT32(20), LUT32(21), LUT32(22), LUT32(23),
130  LUT32(24), LUT32(25), LUT32(26), LUT32(27),
131  LUT32(28), LUT32(29), LUT32(30), LUT32(31),
132 };
133 
134 // Gray to RGB, required for palette table of grayscale images with bpp < 8
135 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
136  return x << 16 | x << 8 | x;
137 }
138 
139 /**
140  * Convert CMAP buffer (stored in extradata) to lavc palette format
141  */
142 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
143 {
144  IffContext *s = avctx->priv_data;
145  int count, i;
146  const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
147  int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
148 
149  if (avctx->bits_per_coded_sample > 8) {
150  av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
151  return AVERROR_INVALIDDATA;
152  }
153 
154  count = 1 << avctx->bits_per_coded_sample;
155  // If extradata is smaller than actually needed, fill the remaining with black.
156  count = FFMIN(palette_size / 3, count);
157  if (count) {
158  for (i=0; i < count; i++) {
159  pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
160  }
161  if (s->flags && count >= 32) { // EHB
162  for (i = 0; i < 32; i++)
163  pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
164  count = FFMAX(count, 64);
165  }
166  } else { // Create gray-scale color palette for bps < 8
167  count = 1 << avctx->bits_per_coded_sample;
168 
169  for (i=0; i < count; i++) {
170  pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
171  }
172  }
173  if (s->masking == MASK_HAS_MASK) {
174  memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
175  for (i = 0; i < count; i++)
176  pal[i] &= 0xFFFFFF;
177  } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
178  s->transparency < 1 << avctx->bits_per_coded_sample)
179  pal[s->transparency] &= 0xFFFFFF;
180  return 0;
181 }
182 
183 /**
184  * Extracts the IFF extra context and updates internal
185  * decoder structures.
186  *
187  * @param avctx the AVCodecContext where to extract extra context to
188  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
189  * @return 0 in case of success, a negative error code otherwise
190  */
191 static int extract_header(AVCodecContext *const avctx,
192  const AVPacket *const avpkt) {
193  const uint8_t *buf;
194  unsigned buf_size;
195  IffContext *s = avctx->priv_data;
196  int i, palette_size;
197 
198  if (avctx->extradata_size < 2) {
199  av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
200  return AVERROR_INVALIDDATA;
201  }
202  palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
203 
204  if (avpkt) {
205  int image_size;
206  if (avpkt->size < 2)
207  return AVERROR_INVALIDDATA;
208  image_size = avpkt->size - AV_RB16(avpkt->data);
209  buf = avpkt->data;
210  buf_size = bytestream_get_be16(&buf);
211  if (buf_size <= 1 || image_size <= 1) {
212  av_log(avctx, AV_LOG_ERROR,
213  "Invalid image size received: %u -> image data offset: %d\n",
214  buf_size, image_size);
215  return AVERROR_INVALIDDATA;
216  }
217  } else {
218  buf = avctx->extradata;
219  buf_size = bytestream_get_be16(&buf);
220  if (buf_size <= 1 || palette_size < 0) {
221  av_log(avctx, AV_LOG_ERROR,
222  "Invalid palette size received: %u -> palette data offset: %d\n",
223  buf_size, palette_size);
224  return AVERROR_INVALIDDATA;
225  }
226  }
227 
228  if (buf_size >= 41) {
229  s->compression = bytestream_get_byte(&buf);
230  s->bpp = bytestream_get_byte(&buf);
231  s->ham = bytestream_get_byte(&buf);
232  s->flags = bytestream_get_byte(&buf);
233  s->transparency = bytestream_get_be16(&buf);
234  s->masking = bytestream_get_byte(&buf);
235  for (i = 0; i < 16; i++)
236  s->tvdc[i] = bytestream_get_be16(&buf);
237 
238  if (s->masking == MASK_HAS_MASK) {
239  if (s->bpp >= 8 && !s->ham) {
240  avctx->pix_fmt = AV_PIX_FMT_RGB32;
241  av_freep(&s->mask_buf);
242  av_freep(&s->mask_palbuf);
244  if (!s->mask_buf)
245  return AVERROR(ENOMEM);
246  if (s->bpp > 16) {
247  av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
248  av_freep(&s->mask_buf);
249  return AVERROR(ENOMEM);
250  }
251  s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
252  if (!s->mask_palbuf) {
253  av_freep(&s->mask_buf);
254  return AVERROR(ENOMEM);
255  }
256  }
257  s->bpp++;
258  } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
259  av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
260  return AVERROR_PATCHWELCOME;
261  }
262  if (!s->bpp || s->bpp > 32) {
263  av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
264  return AVERROR_INVALIDDATA;
265  } else if (s->ham >= 8) {
266  av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
267  return AVERROR_INVALIDDATA;
268  }
269 
270  av_freep(&s->ham_buf);
271  av_freep(&s->ham_palbuf);
272 
273  if (s->ham) {
274  int i, count = FFMIN(palette_size / 3, 1 << s->ham);
275  int ham_count;
276  const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
277 
279  if (!s->ham_buf)
280  return AVERROR(ENOMEM);
281 
282  ham_count = 8 * (1 << s->ham);
283  s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + FF_INPUT_BUFFER_PADDING_SIZE);
284  if (!s->ham_palbuf) {
285  av_freep(&s->ham_buf);
286  return AVERROR(ENOMEM);
287  }
288 
289  if (count) { // HAM with color palette attached
290  // prefill with black and palette and set HAM take direct value mask to zero
291  memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
292  for (i=0; i < count; i++) {
293  s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
294  }
295  count = 1 << s->ham;
296  } else { // HAM with grayscale color palette
297  count = 1 << s->ham;
298  for (i=0; i < count; i++) {
299  s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
300  s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
301  }
302  }
303  for (i=0; i < count; i++) {
304  uint32_t tmp = i << (8 - s->ham);
305  tmp |= tmp >> s->ham;
306  s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
307  s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
308  s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
309  s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
310  s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
311  s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
312  }
313  if (s->masking == MASK_HAS_MASK) {
314  for (i = 0; i < ham_count; i++)
315  s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
316  }
317  }
318  }
319 
320  return 0;
321 }
322 
324 {
325  IffContext *s = avctx->priv_data;
326  int err;
327 
328  if (avctx->bits_per_coded_sample <= 8) {
329  int palette_size;
330 
331  if (avctx->extradata_size >= 2)
332  palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
333  else
334  palette_size = 0;
335  avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
336  (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
337  } else if (avctx->bits_per_coded_sample <= 32) {
338  if (avctx->codec_tag == MKTAG('R','G','B','8')) {
339  avctx->pix_fmt = AV_PIX_FMT_RGB32;
340  } else if (avctx->codec_tag == MKTAG('R','G','B','N')) {
341  avctx->pix_fmt = AV_PIX_FMT_RGB444;
342  } else if (avctx->codec_tag != MKTAG('D','E','E','P')) {
343  if (avctx->bits_per_coded_sample == 24) {
344  avctx->pix_fmt = AV_PIX_FMT_0BGR32;
345  } else if (avctx->bits_per_coded_sample == 32) {
346  avctx->pix_fmt = AV_PIX_FMT_BGR32;
347  } else {
348  av_log_ask_for_sample(avctx, "unknown bits_per_coded_sample\n");
349  return AVERROR_PATCHWELCOME;
350  }
351  }
352  } else {
353  return AVERROR_INVALIDDATA;
354  }
355 
356  if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
357  return err;
358  s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
360  if (!s->planebuf)
361  return AVERROR(ENOMEM);
362 
363  s->bpp = avctx->bits_per_coded_sample;
365 
366  if ((err = extract_header(avctx, NULL)) < 0)
367  return err;
368  s->frame.reference = 3;
369 
370  return 0;
371 }
372 
373 /**
374  * Decode interleaved plane buffer up to 8bpp
375  * @param dst Destination buffer
376  * @param buf Source buffer
377  * @param buf_size
378  * @param plane plane number to decode as
379  */
380 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
381 {
382  const uint64_t *lut = plane8_lut[plane];
383  if (plane >= 8) {
384  av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
385  return;
386  }
387  do {
388  uint64_t v = AV_RN64A(dst) | lut[*buf++];
389  AV_WN64A(dst, v);
390  dst += 8;
391  } while (--buf_size);
392 }
393 
394 /**
395  * Decode interleaved plane buffer up to 24bpp
396  * @param dst Destination buffer
397  * @param buf Source buffer
398  * @param buf_size
399  * @param plane plane number to decode as
400  */
401 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
402 {
403  const uint32_t *lut = plane32_lut[plane];
404  do {
405  unsigned mask = (*buf >> 2) & ~3;
406  dst[0] |= lut[mask++];
407  dst[1] |= lut[mask++];
408  dst[2] |= lut[mask++];
409  dst[3] |= lut[mask];
410  mask = (*buf++ << 2) & 0x3F;
411  dst[4] |= lut[mask++];
412  dst[5] |= lut[mask++];
413  dst[6] |= lut[mask++];
414  dst[7] |= lut[mask];
415  dst += 8;
416  } while (--buf_size);
417 }
418 
419 #define DECODE_HAM_PLANE32(x) \
420  first = buf[x] << 1; \
421  second = buf[(x)+1] << 1; \
422  delta &= pal[first++]; \
423  delta |= pal[first]; \
424  dst[x] = delta; \
425  delta &= pal[second++]; \
426  delta |= pal[second]; \
427  dst[(x)+1] = delta
428 
429 /**
430  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
431  *
432  * @param dst the destination 24bpp buffer
433  * @param buf the source 8bpp chunky buffer
434  * @param pal the HAM decode table
435  * @param buf_size the plane size in bytes
436  */
437 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
438  const uint32_t *const pal, unsigned buf_size)
439 {
440  uint32_t delta = pal[1]; /* first palette entry */
441  do {
442  uint32_t first, second;
447  buf += 8;
448  dst += 8;
449  } while (--buf_size);
450 }
451 
452 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
453  const uint32_t *const pal, unsigned width)
454 {
455  do {
456  *dst++ = pal[*buf++];
457  } while (--width);
458 }
459 
460 /**
461  * Decode one complete byterun1 encoded line.
462  *
463  * @param dst the destination buffer where to store decompressed bitstream
464  * @param dst_size the destination plane size in bytes
465  * @param buf the source byterun1 compressed bitstream
466  * @param buf_end the EOF of source byterun1 compressed bitstream
467  * @return number of consumed bytes in byterun1 compressed bitstream
468 */
469 static int decode_byterun(uint8_t *dst, int dst_size,
470  const uint8_t *buf, const uint8_t *const buf_end) {
471  const uint8_t *const buf_start = buf;
472  unsigned x;
473  for (x = 0; x < dst_size && buf < buf_end;) {
474  unsigned length;
475  const int8_t value = *buf++;
476  if (value >= 0) {
477  length = value + 1;
478  memcpy(dst + x, buf, FFMIN3(length, dst_size - x, buf_end - buf));
479  buf += length;
480  } else if (value > -128) {
481  length = -value + 1;
482  memset(dst + x, *buf++, FFMIN(length, dst_size - x));
483  } else { // noop
484  continue;
485  }
486  x += length;
487  }
488  return buf - buf_start;
489 }
490 
491 #define DECODE_RGBX_COMMON(type) \
492  if (!length) { \
493  length = bytestream2_get_byte(gb); \
494  if (!length) { \
495  length = bytestream2_get_be16(gb); \
496  if (!length) \
497  return; \
498  } \
499  } \
500  for (i = 0; i < length; i++) { \
501  *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
502  x += 1; \
503  if (x >= width) { \
504  y += 1; \
505  if (y >= height) \
506  return; \
507  x = 0; \
508  } \
509  }
510 
511 /**
512  * Decode RGB8 buffer
513  * @param[out] dst Destination buffer
514  * @param width Width of destination buffer (pixels)
515  * @param height Height of destination buffer (pixels)
516  * @param linesize Line size of destination buffer (bytes)
517  */
518 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
519 {
520  int x = 0, y = 0, i, length;
521  while (bytestream2_get_bytes_left(gb) >= 4) {
522  uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
523  length = bytestream2_get_byte(gb) & 0x7F;
524  DECODE_RGBX_COMMON(uint32_t)
525  }
526 }
527 
528 /**
529  * Decode RGBN buffer
530  * @param[out] dst Destination buffer
531  * @param width Width of destination buffer (pixels)
532  * @param height Height of destination buffer (pixels)
533  * @param linesize Line size of destination buffer (bytes)
534  */
535 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
536 {
537  int x = 0, y = 0, i, length;
538  while (bytestream2_get_bytes_left(gb) >= 2) {
539  uint32_t pixel = bytestream2_get_be16u(gb);
540  length = pixel & 0x7;
541  pixel >>= 4;
542  DECODE_RGBX_COMMON(uint16_t)
543  }
544 }
545 
546 /**
547  * Decode DEEP RLE 32-bit buffer
548  * @param[out] dst Destination buffer
549  * @param[in] src Source buffer
550  * @param src_size Source buffer size (bytes)
551  * @param width Width of destination buffer (pixels)
552  * @param height Height of destination buffer (pixels)
553  * @param linesize Line size of destination buffer (bytes)
554  */
555 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
556 {
557  const uint8_t *src_end = src + src_size;
558  int x = 0, y = 0, i;
559  while (src + 5 <= src_end) {
560  int opcode;
561  opcode = *(int8_t *)src++;
562  if (opcode >= 0) {
563  int size = opcode + 1;
564  for (i = 0; i < size; i++) {
565  int length = FFMIN(size - i, width);
566  memcpy(dst + y*linesize + x * 4, src, length * 4);
567  src += length * 4;
568  x += length;
569  i += length;
570  if (x >= width) {
571  x = 0;
572  y += 1;
573  if (y >= height)
574  return;
575  }
576  }
577  } else {
578  int size = -opcode + 1;
579  uint32_t pixel = AV_RN32(src);
580  for (i = 0; i < size; i++) {
581  *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
582  x += 1;
583  if (x >= width) {
584  x = 0;
585  y += 1;
586  if (y >= height)
587  return;
588  }
589  }
590  src += 4;
591  }
592  }
593 }
594 
595 /**
596  * Decode DEEP TVDC 32-bit buffer
597  * @param[out] dst Destination buffer
598  * @param[in] src Source buffer
599  * @param src_size Source buffer size (bytes)
600  * @param width Width of destination buffer (pixels)
601  * @param height Height of destination buffer (pixels)
602  * @param linesize Line size of destination buffer (bytes)
603  * @param[int] tvdc TVDC lookup table
604  */
605 static void decode_deep_tvdc32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize, const int16_t *tvdc)
606 {
607  int x = 0, y = 0, plane = 0;
608  int8_t pixel = 0;
609  int i, j;
610 
611  for (i = 0; i < src_size * 2;) {
612 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
613  int d = tvdc[GETNIBBLE];
614  i++;
615  if (d) {
616  pixel += d;
617  dst[y * linesize + x*4 + plane] = pixel;
618  x++;
619  } else {
620  if (i >= src_size * 2)
621  return;
622  d = GETNIBBLE + 1;
623  i++;
624  d = FFMIN(d, width - x);
625  for (j = 0; j < d; j++) {
626  dst[y * linesize + x*4 + plane] = pixel;
627  x++;
628  }
629  }
630  if (x >= width) {
631  plane++;
632  if (plane >= 4) {
633  y++;
634  if (y >= height)
635  return;
636  plane = 0;
637  }
638  x = 0;
639  pixel = 0;
640  i = (i + 1) & ~1;
641  }
642  }
643 }
644 
645 static int unsupported(AVCodecContext *avctx)
646 {
647  IffContext *s = avctx->priv_data;
648  av_log_ask_for_sample(avctx, "unsupported bitmap (compression %i, bpp %i, ham %i)\n", s->compression, s->bpp, s->ham);
649  return AVERROR_INVALIDDATA;
650 }
651 
652 static int decode_frame(AVCodecContext *avctx,
653  void *data, int *got_frame,
654  AVPacket *avpkt)
655 {
656  IffContext *s = avctx->priv_data;
657  const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;
658  const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;
659  const uint8_t *buf_end = buf+buf_size;
660  int y, plane, res;
661  GetByteContext gb;
662 
663  if ((res = extract_header(avctx, avpkt)) < 0)
664  return res;
665  if (s->init) {
666  if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {
667  av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
668  return res;
669  }
670  } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) {
671  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
672  return res;
673  } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
674  if ((res = cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)
675  return res;
676  } else if (avctx->pix_fmt == AV_PIX_FMT_RGB32 && avctx->bits_per_coded_sample <= 8) {
677  if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
678  return res;
679  }
680  s->init = 1;
681 
682  switch (s->compression) {
683  case 0:
684  if (avctx->codec_tag == MKTAG('A','C','B','M')) {
685  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
686  memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
687  for (plane = 0; plane < s->bpp; plane++) {
688  for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
689  uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
690  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
691  buf += s->planesize;
692  }
693  }
694  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
695  memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
696  for(y = 0; y < avctx->height; y++) {
697  uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
698  memset(s->ham_buf, 0, s->planesize * 8);
699  for (plane = 0; plane < s->bpp; plane++) {
700  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
701  if (start >= buf_end)
702  break;
703  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
704  }
705  decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
706  }
707  } else
708  return unsupported(avctx);
709  } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {
710  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
711  int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
712  int x;
713  for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
714  uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
715  memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
716  buf += raw_width;
717  if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
718  for(x = 0; x < avctx->width; x++)
719  row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
720  }
721  }
722  } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
723  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
724  for(y = 0; y < avctx->height; y++ ) {
725  uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
726  memset(row, 0, avctx->width);
727  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
728  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
729  buf += s->planesize;
730  }
731  }
732  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
733  for (y = 0; y < avctx->height; y++) {
734  uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
735  memset(s->ham_buf, 0, s->planesize * 8);
736  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
737  decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
738  buf += s->planesize;
739  }
740  decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
741  }
742  } else { // AV_PIX_FMT_BGR32
743  for(y = 0; y < avctx->height; y++ ) {
744  uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
745  memset(row, 0, avctx->width << 2);
746  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
747  decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);
748  buf += s->planesize;
749  }
750  }
751  }
752  } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
753  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
754  for(y = 0; y < avctx->height && buf_end > buf; y++ ) {
755  uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
756  memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
757  buf += avctx->width + (avctx->width % 2); // padding if odd
758  }
759  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
760  for (y = 0; y < avctx->height && buf_end > buf; y++) {
761  uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
762  memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
763  buf += avctx->width + (avctx->width & 1); // padding if odd
764  decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
765  }
766  } else
767  return unsupported(avctx);
768  }
769  break;
770  case 1:
771  if (avctx->codec_tag == MKTAG('I','L','B','M')) { //interleaved
772  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
773  for(y = 0; y < avctx->height ; y++ ) {
774  uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
775  memset(row, 0, avctx->width);
776  for (plane = 0; plane < s->bpp; plane++) {
777  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
778  decodeplane8(row, s->planebuf, s->planesize, plane);
779  }
780  }
781  } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
782  for (y = 0; y < avctx->height ; y++ ) {
783  uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
784  memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
785  for (plane = 0; plane < s->bpp; plane++) {
786  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
787  decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
788  }
789  lookup_pal_indicies((uint32_t *) row, s->mask_buf, s->mask_palbuf, avctx->width);
790  }
791  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
792  for (y = 0; y < avctx->height ; y++) {
793  uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
794  memset(s->ham_buf, 0, s->planesize * 8);
795  for (plane = 0; plane < s->bpp; plane++) {
796  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
797  decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
798  }
799  decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
800  }
801  } else { //AV_PIX_FMT_BGR32
802  for(y = 0; y < avctx->height ; y++ ) {
803  uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
804  memset(row, 0, avctx->width << 2);
805  for (plane = 0; plane < s->bpp; plane++) {
806  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
807  decodeplane32((uint32_t *) row, s->planebuf, s->planesize, plane);
808  }
809  }
810  }
811  } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM
812  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
813  for(y = 0; y < avctx->height ; y++ ) {
814  uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
815  buf += decode_byterun(row, avctx->width, buf, buf_end);
816  }
817  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
818  for (y = 0; y < avctx->height ; y++) {
819  uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
820  buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
821  decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
822  }
823  } else
824  return unsupported(avctx);
825  } else if (avctx->codec_tag == MKTAG('D','E','E','P')) { // IFF-DEEP
826  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
827  if (av_get_bits_per_pixel(desc) == 32)
828  decode_deep_rle32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0]);
829  else
830  return unsupported(avctx);
831  }
832  break;
833  case 4:
834  bytestream2_init(&gb, buf, buf_size);
835  if (avctx->codec_tag == MKTAG('R','G','B','8'))
836  decode_rgb8(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
837  else if (avctx->codec_tag == MKTAG('R','G','B','N'))
838  decode_rgbn(&gb, s->frame.data[0], avctx->width, avctx->height, s->frame.linesize[0]);
839  else
840  return unsupported(avctx);
841  break;
842  case 5:
843  if (avctx->codec_tag == MKTAG('D','E','E','P')) {
844  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
845  if (av_get_bits_per_pixel(desc) == 32)
846  decode_deep_tvdc32(s->frame.data[0], buf, buf_size, avctx->width, avctx->height, s->frame.linesize[0], s->tvdc);
847  else
848  return unsupported(avctx);
849  } else
850  return unsupported(avctx);
851  break;
852  default:
853  return unsupported(avctx);
854  }
855 
856  *got_frame = 1;
857  *(AVFrame*)data = s->frame;
858  return buf_size;
859 }
860 
862 {
863  IffContext *s = avctx->priv_data;
864  if (s->frame.data[0])
865  avctx->release_buffer(avctx, &s->frame);
866  av_freep(&s->planebuf);
867  av_freep(&s->ham_buf);
868  av_freep(&s->ham_palbuf);
869  return 0;
870 }
871 
872 #if CONFIG_IFF_ILBM_DECODER
873 AVCodec ff_iff_ilbm_decoder = {
874  .name = "iff",
875  .type = AVMEDIA_TYPE_VIDEO,
876  .id = AV_CODEC_ID_IFF_ILBM,
877  .priv_data_size = sizeof(IffContext),
878  .init = decode_init,
879  .close = decode_end,
880  .decode = decode_frame,
881  .capabilities = CODEC_CAP_DR1,
882  .long_name = NULL_IF_CONFIG_SMALL("IFF"),
883 };
884 #endif
885 #if CONFIG_IFF_BYTERUN1_DECODER
886 AVCodec ff_iff_byterun1_decoder = {
887  .name = "iff",
888  .type = AVMEDIA_TYPE_VIDEO,
890  .priv_data_size = sizeof(IffContext),
891  .init = decode_init,
892  .close = decode_end,
893  .decode = decode_frame,
894  .capabilities = CODEC_CAP_DR1,
895  .long_name = NULL_IF_CONFIG_SMALL("IFF"),
896 };
897 #endif