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