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  const AVPixFmtDescriptor *desc;
681 
682  if ((res = extract_header(avctx, avpkt)) < 0)
683  return res;
684  if ((res = ff_reget_buffer(avctx, s->frame)) < 0)
685  return res;
686 
687  desc = av_pix_fmt_desc_get(avctx->pix_fmt);
688 
689  if (!s->init && avctx->bits_per_coded_sample <= 8 &&
690  avctx->pix_fmt == AV_PIX_FMT_PAL8) {
691  if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0)
692  return res;
693  } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
694  avctx->pix_fmt == AV_PIX_FMT_RGB32) {
695  if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
696  return res;
697  }
698  s->init = 1;
699 
700  switch (s->compression) {
701  case 0:
702  if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
703  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
704  memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
705  for (plane = 0; plane < s->bpp; plane++) {
706  for (y = 0; y < avctx->height && buf < buf_end; y++) {
707  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
708  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
709  buf += s->planesize;
710  }
711  }
712  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
713  memset(s->frame->data[0], 0, avctx->height * s->frame->linesize[0]);
714  for (y = 0; y < avctx->height; y++) {
715  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
716  memset(s->ham_buf, 0, s->planesize * 8);
717  for (plane = 0; plane < s->bpp; plane++) {
718  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
719  if (start >= buf_end)
720  break;
721  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
722  }
723  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
724  }
725  } else
726  return unsupported(avctx);
727  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
728  int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
729  int x;
730  for (y = 0; y < avctx->height && buf < buf_end; y++) {
731  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
732  memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
733  buf += raw_width;
734  if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
735  for (x = 0; x < avctx->width; x++)
736  row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
737  }
738  }
739  } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
740  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
741  for (y = 0; y < avctx->height; y++) {
742  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
743  memset(row, 0, avctx->width);
744  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
745  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
746  buf += s->planesize;
747  }
748  }
749  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
750  for (y = 0; y < avctx->height; y++) {
751  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
752  memset(s->ham_buf, 0, s->planesize * 8);
753  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
754  decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
755  buf += s->planesize;
756  }
757  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
758  }
759  } else { // AV_PIX_FMT_BGR32
760  for (y = 0; y < avctx->height; y++) {
761  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
762  memset(row, 0, avctx->width << 2);
763  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
764  decodeplane32((uint32_t *)row, buf,
765  FFMIN(s->planesize, buf_end - buf), plane);
766  buf += s->planesize;
767  }
768  }
769  }
770  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
771  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
772  for (y = 0; y < avctx->height && buf_end > buf; y++) {
773  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
774  memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
775  buf += avctx->width + (avctx->width % 2); // padding if odd
776  }
777  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
778  for (y = 0; y < avctx->height && buf_end > buf; y++) {
779  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
780  memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
781  buf += avctx->width + (avctx->width & 1); // padding if odd
782  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
783  }
784  } else
785  return unsupported(avctx);
786  }
787  break;
788  case 1:
789  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M')) { // interleaved
790  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
791  for (y = 0; y < avctx->height; y++) {
792  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
793  memset(row, 0, avctx->width);
794  for (plane = 0; plane < s->bpp; plane++) {
795  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
796  decodeplane8(row, s->planebuf, s->planesize, plane);
797  }
798  }
799  } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
800  for (y = 0; y < avctx->height; y++) {
801  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
802  memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
803  for (plane = 0; plane < s->bpp; plane++) {
804  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
805  decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
806  }
807  lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
808  }
809  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
810  for (y = 0; y < avctx->height; y++) {
811  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
812  memset(s->ham_buf, 0, s->planesize * 8);
813  for (plane = 0; plane < s->bpp; plane++) {
814  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
815  decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
816  }
817  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
818  }
819  } else { // AV_PIX_FMT_BGR32
820  for (y = 0; y < avctx->height; y++) {
821  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
822  memset(row, 0, avctx->width << 2);
823  for (plane = 0; plane < s->bpp; plane++) {
824  buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
825  decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
826  }
827  }
828  }
829  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
830  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
831  for (y = 0; y < avctx->height; y++) {
832  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
833  buf += decode_byterun(row, avctx->width, buf, buf_end);
834  }
835  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
836  for (y = 0; y < avctx->height; y++) {
837  uint8_t *row = &s->frame->data[0][y * s->frame->linesize[0]];
838  buf += decode_byterun(s->ham_buf, avctx->width, buf, buf_end);
839  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
840  }
841  } else
842  return unsupported(avctx);
843  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
844  if (av_get_bits_per_pixel(desc) == 32)
845  decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]);
846  else
847  return unsupported(avctx);
848  }
849  break;
850  case 4:
851  bytestream2_init(&gb, buf, buf_size);
852  if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
853  decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
854  else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
855  decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]);
856  else
857  return unsupported(avctx);
858  break;
859  case 5:
860  if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
861  if (av_get_bits_per_pixel(desc) == 32)
862  decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc);
863  else
864  return unsupported(avctx);
865  } else
866  return unsupported(avctx);
867  break;
868  default:
869  return unsupported(avctx);
870  }
871 
872  if ((res = av_frame_ref(data, s->frame)) < 0)
873  return res;
874 
875  *got_frame = 1;
876 
877  return buf_size;
878 }
879 
880 #if CONFIG_IFF_ILBM_DECODER
881 AVCodec ff_iff_ilbm_decoder = {
882  .name = "iff",
883  .long_name = NULL_IF_CONFIG_SMALL("IFF"),
884  .type = AVMEDIA_TYPE_VIDEO,
885  .id = AV_CODEC_ID_IFF_ILBM,
886  .priv_data_size = sizeof(IffContext),
887  .init = decode_init,
888  .close = decode_end,
889  .decode = decode_frame,
890  .capabilities = CODEC_CAP_DR1,
891 };
892 #endif
893 #if CONFIG_IFF_BYTERUN1_DECODER
894 AVCodec ff_iff_byterun1_decoder = {
895  .name = "iff",
896  .long_name = NULL_IF_CONFIG_SMALL("IFF"),
897  .type = AVMEDIA_TYPE_VIDEO,
899  .priv_data_size = sizeof(IffContext),
900  .init = decode_init,
901  .close = decode_end,
902  .decode = decode_frame,
903  .capabilities = CODEC_CAP_DR1,
904 };
905 #endif