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