FFmpeg
iff.c
Go to the documentation of this file.
1 /*
2  * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
3  * Copyright (c) 2010 Peter Ross <pross@xvid.org>
4  * Copyright (c) 2010 Sebastian Vater <cdgs.basty@googlemail.com>
5  * Copyright (c) 2016 Paul B Mahol
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file
26  * IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN bitmap decoder
27  */
28 
29 #include <stdint.h>
30 
31 #include "libavutil/imgutils.h"
32 
33 #include "bytestream.h"
34 #include "avcodec.h"
35 #include "internal.h"
36 #include "mathops.h"
37 
38 // TODO: masking bits
39 typedef enum {
44 } mask_type;
45 
46 typedef struct IffContext {
48  int planesize;
50  uint8_t * ham_buf; ///< temporary buffer for planar to chunky conversation
51  uint32_t *ham_palbuf; ///< HAM decode table
52  uint32_t *mask_buf; ///< temporary buffer for palette indices
53  uint32_t *mask_palbuf; ///< masking palette table
54  unsigned compression; ///< delta compression method used
55  unsigned is_short; ///< short compression method used
56  unsigned is_interlaced;///< video is interlaced
57  unsigned is_brush; ///< video is in ANBR format
58  unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM)
59  unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
60  unsigned flags; ///< 1 for EHB, 0 is no extra half darkening
61  unsigned transparency; ///< TODO: transparency color index in palette
62  unsigned masking; ///< TODO: masking method used
63  int init; // 1 if buffer and palette data already initialized, 0 otherwise
64  int16_t tvdc[16]; ///< TVDC lookup table
67  unsigned video_size;
68  uint32_t *pal;
69 } IffContext;
70 
71 #define LUT8_PART(plane, v) \
72  AV_LE2NE64C(UINT64_C(0x0000000)<<32 | v) << plane, \
73  AV_LE2NE64C(UINT64_C(0x1000000)<<32 | v) << plane, \
74  AV_LE2NE64C(UINT64_C(0x0010000)<<32 | v) << plane, \
75  AV_LE2NE64C(UINT64_C(0x1010000)<<32 | v) << plane, \
76  AV_LE2NE64C(UINT64_C(0x0000100)<<32 | v) << plane, \
77  AV_LE2NE64C(UINT64_C(0x1000100)<<32 | v) << plane, \
78  AV_LE2NE64C(UINT64_C(0x0010100)<<32 | v) << plane, \
79  AV_LE2NE64C(UINT64_C(0x1010100)<<32 | v) << plane, \
80  AV_LE2NE64C(UINT64_C(0x0000001)<<32 | v) << plane, \
81  AV_LE2NE64C(UINT64_C(0x1000001)<<32 | v) << plane, \
82  AV_LE2NE64C(UINT64_C(0x0010001)<<32 | v) << plane, \
83  AV_LE2NE64C(UINT64_C(0x1010001)<<32 | v) << plane, \
84  AV_LE2NE64C(UINT64_C(0x0000101)<<32 | v) << plane, \
85  AV_LE2NE64C(UINT64_C(0x1000101)<<32 | v) << plane, \
86  AV_LE2NE64C(UINT64_C(0x0010101)<<32 | v) << plane, \
87  AV_LE2NE64C(UINT64_C(0x1010101)<<32 | v) << plane
88 
89 #define LUT8(plane) { \
90  LUT8_PART(plane, 0x0000000), \
91  LUT8_PART(plane, 0x1000000), \
92  LUT8_PART(plane, 0x0010000), \
93  LUT8_PART(plane, 0x1010000), \
94  LUT8_PART(plane, 0x0000100), \
95  LUT8_PART(plane, 0x1000100), \
96  LUT8_PART(plane, 0x0010100), \
97  LUT8_PART(plane, 0x1010100), \
98  LUT8_PART(plane, 0x0000001), \
99  LUT8_PART(plane, 0x1000001), \
100  LUT8_PART(plane, 0x0010001), \
101  LUT8_PART(plane, 0x1010001), \
102  LUT8_PART(plane, 0x0000101), \
103  LUT8_PART(plane, 0x1000101), \
104  LUT8_PART(plane, 0x0010101), \
105  LUT8_PART(plane, 0x1010101), \
106 }
107 
108 // 8 planes * 8-bit mask
109 static const uint64_t plane8_lut[8][256] = {
110  LUT8(0), LUT8(1), LUT8(2), LUT8(3),
111  LUT8(4), LUT8(5), LUT8(6), LUT8(7),
112 };
113 
114 #define LUT32(plane) { \
115  0, 0, 0, 0, \
116  0, 0, 0, 1U << plane, \
117  0, 0, 1U << plane, 0, \
118  0, 0, 1U << plane, 1U << plane, \
119  0, 1U << plane, 0, 0, \
120  0, 1U << plane, 0, 1U << plane, \
121  0, 1U << plane, 1U << plane, 0, \
122  0, 1U << plane, 1U << plane, 1U << plane, \
123  1U << plane, 0, 0, 0, \
124  1U << plane, 0, 0, 1U << plane, \
125  1U << plane, 0, 1U << plane, 0, \
126  1U << plane, 0, 1U << plane, 1U << plane, \
127  1U << plane, 1U << plane, 0, 0, \
128  1U << plane, 1U << plane, 0, 1U << plane, \
129  1U << plane, 1U << plane, 1U << plane, 0, \
130  1U << plane, 1U << plane, 1U << plane, 1U << plane, \
131 }
132 
133 // 32 planes * 4-bit mask * 4 lookup tables each
134 static const uint32_t plane32_lut[32][16*4] = {
135  LUT32( 0), LUT32( 1), LUT32( 2), LUT32( 3),
136  LUT32( 4), LUT32( 5), LUT32( 6), LUT32( 7),
137  LUT32( 8), LUT32( 9), LUT32(10), LUT32(11),
138  LUT32(12), LUT32(13), LUT32(14), LUT32(15),
139  LUT32(16), LUT32(17), LUT32(18), LUT32(19),
140  LUT32(20), LUT32(21), LUT32(22), LUT32(23),
141  LUT32(24), LUT32(25), LUT32(26), LUT32(27),
142  LUT32(28), LUT32(29), LUT32(30), LUT32(31),
143 };
144 
145 // Gray to RGB, required for palette table of grayscale images with bpp < 8
146 static av_always_inline uint32_t gray2rgb(const uint32_t x) {
147  return x << 16 | x << 8 | x;
148 }
149 
150 /**
151  * Convert CMAP buffer (stored in extradata) to lavc palette format
152  */
153 static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
154 {
155  IffContext *s = avctx->priv_data;
156  int count, i;
157  const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
158  int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
159 
160  if (avctx->bits_per_coded_sample > 8) {
161  av_log(avctx, AV_LOG_ERROR, "bits_per_coded_sample > 8 not supported\n");
162  return AVERROR_INVALIDDATA;
163  }
164 
165  count = 1 << avctx->bits_per_coded_sample;
166  // If extradata is smaller than actually needed, fill the remaining with black.
167  count = FFMIN(palette_size / 3, count);
168  if (count) {
169  for (i = 0; i < count; i++)
170  pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
171  if (s->flags && count >= 32) { // EHB
172  for (i = 0; i < 32; i++)
173  pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
174  count = FFMAX(count, 64);
175  }
176  } else { // Create gray-scale color palette for bps < 8
177  count = 1 << avctx->bits_per_coded_sample;
178 
179  for (i = 0; i < count; i++)
180  pal[i] = 0xFF000000 | gray2rgb((i * 255) >> avctx->bits_per_coded_sample);
181  }
182  if (s->masking == MASK_HAS_MASK) {
183  if ((1 << avctx->bits_per_coded_sample) < count) {
184  avpriv_request_sample(avctx, "overlapping mask");
185  return AVERROR_PATCHWELCOME;
186  }
187  memcpy(pal + (1 << avctx->bits_per_coded_sample), pal, count * 4);
188  for (i = 0; i < count; i++)
189  pal[i] &= 0xFFFFFF;
190  } else if (s->masking == MASK_HAS_TRANSPARENT_COLOR &&
191  s->transparency < 1 << avctx->bits_per_coded_sample)
192  pal[s->transparency] &= 0xFFFFFF;
193  return 0;
194 }
195 
196 /**
197  * Extracts the IFF extra context and updates internal
198  * decoder structures.
199  *
200  * @param avctx the AVCodecContext where to extract extra context to
201  * @param avpkt the AVPacket to extract extra context from or NULL to use avctx
202  * @return >= 0 in case of success, a negative error code otherwise
203  */
204 static int extract_header(AVCodecContext *const avctx,
205  const AVPacket *const avpkt)
206 {
207  IffContext *s = avctx->priv_data;
208  const uint8_t *buf;
209  unsigned buf_size = 0;
210  int i, palette_size;
211 
212  if (avctx->extradata_size < 2) {
213  av_log(avctx, AV_LOG_ERROR, "not enough extradata\n");
214  return AVERROR_INVALIDDATA;
215  }
216  palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
217 
218  if (avpkt && avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
219  uint32_t chunk_id;
220  uint64_t data_size;
221  GetByteContext *gb = &s->gb;
222 
223  bytestream2_skip(gb, 4);
224  while (bytestream2_get_bytes_left(gb) >= 1) {
225  chunk_id = bytestream2_get_le32(gb);
226  data_size = bytestream2_get_be32(gb);
227 
228  if (chunk_id == MKTAG('B', 'M', 'H', 'D')) {
229  bytestream2_skip(gb, data_size + (data_size & 1));
230  } else if (chunk_id == MKTAG('A', 'N', 'H', 'D')) {
231  unsigned extra;
232  if (data_size < 40)
233  return AVERROR_INVALIDDATA;
234 
235  s->compression = (bytestream2_get_byte(gb) << 8) | (s->compression & 0xFF);
236  bytestream2_skip(gb, 19);
237  extra = bytestream2_get_be32(gb);
238  s->is_short = !(extra & 1);
239  s->is_brush = extra == 2;
240  s->is_interlaced = !!(extra & 0x40);
241  data_size -= 24;
242  bytestream2_skip(gb, data_size + (data_size & 1));
243  } else if (chunk_id == MKTAG('D', 'L', 'T', 'A') ||
244  chunk_id == MKTAG('B', 'O', 'D', 'Y')) {
245  if (chunk_id == MKTAG('B','O','D','Y'))
246  s->compression &= 0xFF;
247  break;
248  } else if (chunk_id == MKTAG('C', 'M', 'A', 'P')) {
249  int count = data_size / 3;
250  uint32_t *pal = s->pal;
251 
252  if (count > 256)
253  return AVERROR_INVALIDDATA;
254  if (s->ham) {
255  for (i = 0; i < count; i++)
256  pal[i] = 0xFF000000 | bytestream2_get_le24(gb);
257  } else {
258  for (i = 0; i < count; i++)
259  pal[i] = 0xFF000000 | bytestream2_get_be24(gb);
260  }
261  bytestream2_skip(gb, data_size & 1);
262  } else {
263  bytestream2_skip(gb, data_size + (data_size&1));
264  }
265  }
266  } else if (!avpkt) {
267  buf = avctx->extradata;
268  buf_size = bytestream_get_be16(&buf);
269  if (buf_size <= 1 || palette_size < 0) {
270  av_log(avctx, AV_LOG_ERROR,
271  "Invalid palette size received: %u -> palette data offset: %d\n",
272  buf_size, palette_size);
273  return AVERROR_INVALIDDATA;
274  }
275  }
276 
277  if (buf_size >= 41) {
278  s->compression = bytestream_get_byte(&buf);
279  s->bpp = bytestream_get_byte(&buf);
280  s->ham = bytestream_get_byte(&buf);
281  s->flags = bytestream_get_byte(&buf);
282  s->transparency = bytestream_get_be16(&buf);
283  s->masking = bytestream_get_byte(&buf);
284  for (i = 0; i < 16; i++)
285  s->tvdc[i] = bytestream_get_be16(&buf);
286 
287  if (s->ham) {
288  if (s->bpp > 8) {
289  av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u\n", s->ham);
290  return AVERROR_INVALIDDATA;
291  } else if (s->ham != (s->bpp > 6 ? 6 : 4)) {
292  av_log(avctx, AV_LOG_ERROR, "Invalid number of hold bits for HAM: %u, BPP: %u\n", s->ham, s->bpp);
293  return AVERROR_INVALIDDATA;
294  }
295  }
296 
297  if (s->masking == MASK_HAS_MASK) {
298  if (s->bpp >= 8 && !s->ham) {
299  avctx->pix_fmt = AV_PIX_FMT_RGB32;
300  av_freep(&s->mask_buf);
301  av_freep(&s->mask_palbuf);
303  if (!s->mask_buf)
304  return AVERROR(ENOMEM);
305  if (s->bpp > 16) {
306  av_log(avctx, AV_LOG_ERROR, "bpp %d too large for palette\n", s->bpp);
307  av_freep(&s->mask_buf);
308  return AVERROR(ENOMEM);
309  }
310  s->mask_palbuf = av_malloc((2 << s->bpp) * sizeof(uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
311  if (!s->mask_palbuf) {
312  av_freep(&s->mask_buf);
313  return AVERROR(ENOMEM);
314  }
315  }
316  s->bpp++;
317  } else if (s->masking != MASK_NONE && s->masking != MASK_HAS_TRANSPARENT_COLOR) {
318  av_log(avctx, AV_LOG_ERROR, "Masking not supported\n");
319  return AVERROR_PATCHWELCOME;
320  }
321  if (!s->bpp || s->bpp > 32) {
322  av_log(avctx, AV_LOG_ERROR, "Invalid number of bitplanes: %u\n", s->bpp);
323  return AVERROR_INVALIDDATA;
324  }
325 
326  av_freep(&s->ham_buf);
327  av_freep(&s->ham_palbuf);
328 
329  if (s->ham) {
330  int i, count = FFMIN(palette_size / 3, 1 << s->ham);
331  int ham_count;
332  const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
333 
335  if (!s->ham_buf)
336  return AVERROR(ENOMEM);
337 
338  ham_count = 8 * (1 << s->ham);
339  s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
340  if (!s->ham_palbuf) {
341  av_freep(&s->ham_buf);
342  return AVERROR(ENOMEM);
343  }
344 
345  if (count) { // HAM with color palette attached
346  // prefill with black and palette and set HAM take direct value mask to zero
347  memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
348  for (i=0; i < count; i++) {
349  s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
350  }
351  count = 1 << s->ham;
352  } else { // HAM with grayscale color palette
353  count = 1 << s->ham;
354  for (i=0; i < count; i++) {
355  s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
356  s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
357  }
358  }
359  for (i=0; i < count; i++) {
360  uint32_t tmp = i << (8 - s->ham);
361  tmp |= tmp >> s->ham;
362  s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
363  s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
364  s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
365  s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
366  s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
367  s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
368  }
369  if (s->masking == MASK_HAS_MASK) {
370  for (i = 0; i < ham_count; i++)
371  s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
372  }
373  }
374  }
375 
376  return 0;
377 }
378 
380 {
381  IffContext *s = avctx->priv_data;
382  av_freep(&s->planebuf);
383  av_freep(&s->ham_buf);
384  av_freep(&s->ham_palbuf);
385  av_freep(&s->mask_buf);
386  av_freep(&s->mask_palbuf);
387  av_freep(&s->video[0]);
388  av_freep(&s->video[1]);
389  av_freep(&s->pal);
390  return 0;
391 }
392 
394 {
395  IffContext *s = avctx->priv_data;
396  int err;
397 
398  if (avctx->bits_per_coded_sample <= 8) {
399  int palette_size;
400 
401  if (avctx->extradata_size >= 2)
402  palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
403  else
404  palette_size = 0;
405  avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
406  (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
407  } else if (avctx->bits_per_coded_sample <= 32) {
408  if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
409  avctx->pix_fmt = AV_PIX_FMT_RGB32;
410  } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
411  avctx->pix_fmt = AV_PIX_FMT_RGB444;
412  } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
413  if (avctx->bits_per_coded_sample == 24) {
414  avctx->pix_fmt = AV_PIX_FMT_0BGR32;
415  } else if (avctx->bits_per_coded_sample == 32) {
416  avctx->pix_fmt = AV_PIX_FMT_BGR32;
417  } else {
418  avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
419  return AVERROR_PATCHWELCOME;
420  }
421  }
422  } else {
423  return AVERROR_INVALIDDATA;
424  }
425 
426  if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
427  return err;
428  s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
430  if (!s->planebuf)
431  return AVERROR(ENOMEM);
432 
433  s->bpp = avctx->bits_per_coded_sample;
434 
435  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
436  s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
437  s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
438  s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
439  s->pal = av_calloc(256, sizeof(*s->pal));
440  if (!s->video[0] || !s->video[1] || !s->pal)
441  return AVERROR(ENOMEM);
442  }
443 
444  if ((err = extract_header(avctx, NULL)) < 0)
445  return err;
446 
447  return 0;
448 }
449 
450 /**
451  * Decode interleaved plane buffer up to 8bpp
452  * @param dst Destination buffer
453  * @param buf Source buffer
454  * @param buf_size
455  * @param plane plane number to decode as
456  */
457 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
458 {
459  const uint64_t *lut = plane8_lut[plane];
460  if (plane >= 8) {
461  av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
462  return;
463  }
464  do {
465  uint64_t v = AV_RN64A(dst) | lut[*buf++];
466  AV_WN64A(dst, v);
467  dst += 8;
468  } while (--buf_size);
469 }
470 
471 /**
472  * Decode interleaved plane buffer up to 24bpp
473  * @param dst Destination buffer
474  * @param buf Source buffer
475  * @param buf_size
476  * @param plane plane number to decode as
477  */
478 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
479 {
480  const uint32_t *lut = plane32_lut[plane];
481  do {
482  unsigned mask = (*buf >> 2) & ~3;
483  dst[0] |= lut[mask++];
484  dst[1] |= lut[mask++];
485  dst[2] |= lut[mask++];
486  dst[3] |= lut[mask];
487  mask = (*buf++ << 2) & 0x3F;
488  dst[4] |= lut[mask++];
489  dst[5] |= lut[mask++];
490  dst[6] |= lut[mask++];
491  dst[7] |= lut[mask];
492  dst += 8;
493  } while (--buf_size);
494 }
495 
496 #define DECODE_HAM_PLANE32(x) \
497  first = buf[x] << 1; \
498  second = buf[(x)+1] << 1; \
499  delta &= pal[first++]; \
500  delta |= pal[first]; \
501  dst[x] = delta; \
502  delta &= pal[second++]; \
503  delta |= pal[second]; \
504  dst[(x)+1] = delta
505 
506 /**
507  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
508  *
509  * @param dst the destination 24bpp buffer
510  * @param buf the source 8bpp chunky buffer
511  * @param pal the HAM decode table
512  * @param buf_size the plane size in bytes
513  */
514 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
515  const uint32_t *const pal, unsigned buf_size)
516 {
517  uint32_t delta = pal[1]; /* first palette entry */
518  do {
519  uint32_t first, second;
524  buf += 8;
525  dst += 8;
526  } while (--buf_size);
527 }
528 
529 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
530  const uint32_t *const pal, unsigned width)
531 {
532  do {
533  *dst++ = pal[*buf++];
534  } while (--width);
535 }
536 
537 /**
538  * Decode one complete byterun1 encoded line.
539  *
540  * @param dst the destination buffer where to store decompressed bitstream
541  * @param dst_size the destination plane size in bytes
542  * @param buf the source byterun1 compressed bitstream
543  * @param buf_end the EOF of source byterun1 compressed bitstream
544  * @return number of consumed bytes in byterun1 compressed bitstream
545  */
546 static int decode_byterun(uint8_t *dst, int dst_size,
548 {
549  unsigned x;
550  for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
551  unsigned length;
552  const int8_t value = bytestream2_get_byte(gb);
553  if (value >= 0) {
554  length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
555  bytestream2_get_buffer(gb, dst + x, length);
556  if (length < value + 1)
557  bytestream2_skip(gb, value + 1 - length);
558  } else if (value > -128) {
559  length = FFMIN(-value + 1, dst_size - x);
560  memset(dst + x, bytestream2_get_byte(gb), length);
561  } else { // noop
562  continue;
563  }
564  x += length;
565  }
566  if (x < dst_size) {
567  av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
568  memset(dst+x, 0, dst_size - x);
569  }
570  return bytestream2_tell(gb);
571 }
572 
573 static int decode_byterun2(uint8_t *dst, int height, int line_size,
575 {
577  unsigned count;
578  int i, y_pos = 0, x_pos = 0;
579 
580  if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
581  return 0;
582 
583  bytestream2_skip(gb, 4);
584  count = bytestream2_get_be16(gb) - 2;
585  if (bytestream2_get_bytes_left(gb) < count)
586  return 0;
587 
588  bytestream2_init(&cmds, gb->buffer, count);
589  bytestream2_skip(gb, count);
590 
591  for (i = 0; i < count && x_pos < line_size; i++) {
592  int8_t cmd = bytestream2_get_byte(&cmds);
593  int l, r;
594 
595  if (cmd == 0) {
596  l = bytestream2_get_be16(gb);
597  while (l-- > 0 && x_pos < line_size) {
598  dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
599  dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
600  if (y_pos >= height) {
601  y_pos = 0;
602  x_pos += 2;
603  }
604  }
605  } else if (cmd < 0) {
606  l = -cmd;
607  while (l-- > 0 && x_pos < line_size) {
608  dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
609  dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
610  if (y_pos >= height) {
611  y_pos = 0;
612  x_pos += 2;
613  }
614  }
615  } else if (cmd == 1) {
616  l = bytestream2_get_be16(gb);
617  r = bytestream2_get_be16(gb);
618  while (l-- > 0 && x_pos < line_size) {
619  dst[x_pos + y_pos * line_size ] = r >> 8;
620  dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
621  if (y_pos >= height) {
622  y_pos = 0;
623  x_pos += 2;
624  }
625  }
626  } else {
627  l = cmd;
628  r = bytestream2_get_be16(gb);
629  while (l-- > 0 && x_pos < line_size) {
630  dst[x_pos + y_pos * line_size ] = r >> 8;
631  dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
632  if (y_pos >= height) {
633  y_pos = 0;
634  x_pos += 2;
635  }
636  }
637  }
638  }
639 
640  return bytestream2_tell(gb);
641 }
642 
643 #define DECODE_RGBX_COMMON(type) \
644  if (!length) { \
645  length = bytestream2_get_byte(gb); \
646  if (!length) { \
647  length = bytestream2_get_be16(gb); \
648  if (!length) \
649  return; \
650  } \
651  } \
652  for (i = 0; i < length; i++) { \
653  *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
654  x += 1; \
655  if (x >= width) { \
656  y += 1; \
657  if (y >= height) \
658  return; \
659  x = 0; \
660  } \
661  }
662 
663 /**
664  * Decode RGB8 buffer
665  * @param[out] dst Destination buffer
666  * @param width Width of destination buffer (pixels)
667  * @param height Height of destination buffer (pixels)
668  * @param linesize Line size of destination buffer (bytes)
669  */
670 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
671 {
672  int x = 0, y = 0, i, length;
673  while (bytestream2_get_bytes_left(gb) >= 4) {
674  uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
675  length = bytestream2_get_byte(gb) & 0x7F;
676  DECODE_RGBX_COMMON(uint32_t)
677  }
678 }
679 
680 /**
681  * Decode RGBN buffer
682  * @param[out] dst Destination buffer
683  * @param width Width of destination buffer (pixels)
684  * @param height Height of destination buffer (pixels)
685  * @param linesize Line size of destination buffer (bytes)
686  */
687 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
688 {
689  int x = 0, y = 0, i, length;
690  while (bytestream2_get_bytes_left(gb) >= 2) {
691  uint32_t pixel = bytestream2_get_be16u(gb);
692  length = pixel & 0x7;
693  pixel >>= 4;
694  DECODE_RGBX_COMMON(uint16_t)
695  }
696 }
697 
698 /**
699  * Decode DEEP RLE 32-bit buffer
700  * @param[out] dst Destination buffer
701  * @param[in] src Source buffer
702  * @param src_size Source buffer size (bytes)
703  * @param width Width of destination buffer (pixels)
704  * @param height Height of destination buffer (pixels)
705  * @param linesize Line size of destination buffer (bytes)
706  */
707 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
708 {
709  const uint8_t *src_end = src + src_size;
710  int x = 0, y = 0, i;
711  while (src + 5 <= src_end) {
712  int opcode;
713  opcode = *(int8_t *)src++;
714  if (opcode >= 0) {
715  int size = opcode + 1;
716  for (i = 0; i < size; i++) {
717  int length = FFMIN(size - i, width);
718  memcpy(dst + y*linesize + x * 4, src, length * 4);
719  src += length * 4;
720  x += length;
721  i += length;
722  if (x >= width) {
723  x = 0;
724  y += 1;
725  if (y >= height)
726  return;
727  }
728  }
729  } else {
730  int size = -opcode + 1;
731  uint32_t pixel = AV_RN32(src);
732  for (i = 0; i < size; i++) {
733  *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
734  x += 1;
735  if (x >= width) {
736  x = 0;
737  y += 1;
738  if (y >= height)
739  return;
740  }
741  }
742  src += 4;
743  }
744  }
745 }
746 
747 /**
748  * Decode DEEP TVDC 32-bit buffer
749  * @param[out] dst Destination buffer
750  * @param[in] src Source buffer
751  * @param src_size Source buffer size (bytes)
752  * @param width Width of destination buffer (pixels)
753  * @param height Height of destination buffer (pixels)
754  * @param linesize Line size of destination buffer (bytes)
755  * @param[int] tvdc TVDC lookup table
756  */
757 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)
758 {
759  int x = 0, y = 0, plane = 0;
760  int8_t pixel = 0;
761  int i, j;
762 
763  for (i = 0; i < src_size * 2;) {
764 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
765  int d = tvdc[GETNIBBLE];
766  i++;
767  if (d) {
768  pixel += d;
769  dst[y * linesize + x*4 + plane] = pixel;
770  x++;
771  } else {
772  if (i >= src_size * 2)
773  return;
774  d = GETNIBBLE + 1;
775  i++;
776  d = FFMIN(d, width - x);
777  for (j = 0; j < d; j++) {
778  dst[y * linesize + x*4 + plane] = pixel;
779  x++;
780  }
781  }
782  if (x >= width) {
783  plane++;
784  if (plane >= 4) {
785  y++;
786  if (y >= height)
787  return;
788  plane = 0;
789  }
790  x = 0;
791  pixel = 0;
792  i = (i + 1) & ~1;
793  }
794  }
795 }
796 
798  const uint8_t *buf, const uint8_t *buf_end,
799  int w, int bpp, int dst_size)
800 {
801  int planepitch = FFALIGN(w, 16) >> 3;
802  int pitch = planepitch * bpp;
803  GetByteContext ptrs, gb;
804  PutByteContext pb;
805  unsigned ofssrc, pos;
806  int i, k;
807 
808  bytestream2_init(&ptrs, buf, buf_end - buf);
809  bytestream2_init_writer(&pb, dst, dst_size);
810 
811  for (k = 0; k < bpp; k++) {
812  ofssrc = bytestream2_get_be32(&ptrs);
813  pos = 0;
814 
815  if (!ofssrc)
816  continue;
817 
818  if (ofssrc >= buf_end - buf)
819  continue;
820 
821  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
822  while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
823  int16_t offset = bytestream2_get_be16(&gb);
824  unsigned noffset;
825 
826  if (offset >= 0) {
827  unsigned data = bytestream2_get_be16(&gb);
828 
829  pos += offset * 2;
830  noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
831  bytestream2_seek_p(&pb, noffset, SEEK_SET);
832  bytestream2_put_be16(&pb, data);
833  } else {
834  uint16_t count = bytestream2_get_be16(&gb);
835 
836  pos += 2 * -(offset + 2);
837  for (i = 0; i < count; i++) {
838  uint16_t data = bytestream2_get_be16(&gb);
839 
840  pos += 2;
841  noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
842  bytestream2_seek_p(&pb, noffset, SEEK_SET);
843  bytestream2_put_be16(&pb, data);
844  }
845  }
846  }
847  }
848 }
849 
851  const uint8_t *buf, const uint8_t *buf_end,
852  int w, int xor, int bpp, int dst_size)
853 {
854  int ncolumns = ((w + 15) / 16) * 2;
855  int dstpitch = ncolumns * bpp;
856  unsigned ofsdst, ofssrc, opcode, x;
857  GetByteContext ptrs, gb;
858  PutByteContext pb;
859  int i, j, k;
860 
861  bytestream2_init(&ptrs, buf, buf_end - buf);
862  bytestream2_init_writer(&pb, dst, dst_size);
863 
864  for (k = 0; k < bpp; k++) {
865  ofssrc = bytestream2_get_be32(&ptrs);
866 
867  if (!ofssrc)
868  continue;
869 
870  if (ofssrc >= buf_end - buf)
871  continue;
872 
873  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
874  for (j = 0; j < ncolumns; j++) {
875  ofsdst = j + k * ncolumns;
876 
877  i = bytestream2_get_byte(&gb);
878  while (i > 0) {
879  opcode = bytestream2_get_byte(&gb);
880 
881  if (opcode == 0) {
882  opcode = bytestream2_get_byte(&gb);
883  x = bytestream2_get_byte(&gb);
884 
885  while (opcode) {
886  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
887  if (xor && ofsdst < dst_size) {
888  bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
889  } else {
890  bytestream2_put_byte(&pb, x);
891  }
892  ofsdst += dstpitch;
893  opcode--;
894  }
895  } else if (opcode < 0x80) {
896  ofsdst += opcode * dstpitch;
897  } else {
898  opcode &= 0x7f;
899 
900  while (opcode) {
901  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
902  if (xor && ofsdst < dst_size) {
903  bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
904  } else {
905  bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
906  }
907  ofsdst += dstpitch;
908  opcode--;
909  }
910  }
911  i--;
912  }
913  }
914  }
915 }
916 
917 static void decode_delta_j(uint8_t *dst,
918  const uint8_t *buf, const uint8_t *buf_end,
919  int w, int h, int bpp, int dst_size)
920 {
921  int32_t pitch;
922  uint8_t *ptr;
923  uint32_t type, flag, cols, groups, rows, bytes;
924  uint32_t offset;
925  int planepitch_byte = (w + 7) / 8;
926  int planepitch = ((w + 15) / 16) * 2;
927  int kludge_j, b, g, r, d;
929 
930  pitch = planepitch * bpp;
931  kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
932 
933  bytestream2_init(&gb, buf, buf_end - buf);
934 
935  while (bytestream2_get_bytes_left(&gb) >= 2) {
936  type = bytestream2_get_be16(&gb);
937 
938  switch (type) {
939  case 0:
940  return;
941  case 1:
942  flag = bytestream2_get_be16(&gb);
943  cols = bytestream2_get_be16(&gb);
944  groups = bytestream2_get_be16(&gb);
945 
946  for (g = 0; g < groups; g++) {
947  offset = bytestream2_get_be16(&gb);
948 
949  if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
950  av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
951  return;
952  }
953 
954  if (kludge_j)
955  offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
956  else
957  offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
958 
959  for (b = 0; b < cols; b++) {
960  for (d = 0; d < bpp; d++) {
961  uint8_t value = bytestream2_get_byte(&gb);
962 
963  if (offset >= dst_size)
964  return;
965  ptr = dst + offset;
966 
967  if (flag)
968  ptr[0] ^= value;
969  else
970  ptr[0] = value;
971 
972  offset += planepitch;
973  }
974  }
975  if ((cols * bpp) & 1)
976  bytestream2_skip(&gb, 1);
977  }
978  break;
979  case 2:
980  flag = bytestream2_get_be16(&gb);
981  rows = bytestream2_get_be16(&gb);
982  bytes = bytestream2_get_be16(&gb);
983  groups = bytestream2_get_be16(&gb);
984 
985  for (g = 0; g < groups; g++) {
986  offset = bytestream2_get_be16(&gb);
987 
988  if (kludge_j)
989  offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
990  else
991  offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
992 
993  for (r = 0; r < rows; r++) {
994  for (d = 0; d < bpp; d++) {
995  unsigned noffset = offset + (r * pitch) + d * planepitch;
996 
997  if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
998  av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
999  return;
1000  }
1001 
1002  for (b = 0; b < bytes; b++) {
1003  uint8_t value = bytestream2_get_byte(&gb);
1004 
1005  if (noffset >= dst_size)
1006  return;
1007  ptr = dst + noffset;
1008 
1009  if (flag)
1010  ptr[0] ^= value;
1011  else
1012  ptr[0] = value;
1013 
1014  noffset++;
1015  }
1016  }
1017  }
1018  if ((rows * bytes * bpp) & 1)
1019  bytestream2_skip(&gb, 1);
1020  }
1021  break;
1022  default:
1023  return;
1024  }
1025  }
1026 }
1027 
1029  const uint8_t *buf, const uint8_t *buf_end,
1030  int w, int bpp, int dst_size)
1031 {
1032  int ncolumns = (w + 15) >> 4;
1033  int dstpitch = ncolumns * bpp * 2;
1034  unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1035  GetByteContext ptrs, gb, dptrs, dgb;
1036  PutByteContext pb;
1037  int i, j, k;
1038 
1039  if (buf_end - buf <= 64)
1040  return;
1041 
1042  bytestream2_init(&ptrs, buf, buf_end - buf);
1043  bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1044  bytestream2_init_writer(&pb, dst, dst_size);
1045 
1046  for (k = 0; k < bpp; k++) {
1047  ofssrc = bytestream2_get_be32(&ptrs);
1048  ofsdata = bytestream2_get_be32(&dptrs);
1049 
1050  if (!ofssrc)
1051  continue;
1052 
1053  if (ofssrc >= buf_end - buf)
1054  return;
1055 
1056  if (ofsdata >= buf_end - buf)
1057  return;
1058 
1059  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1060  bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1061  for (j = 0; j < ncolumns; j++) {
1062  ofsdst = (j + k * ncolumns) * 2;
1063 
1064  i = bytestream2_get_byte(&gb);
1065  while (i > 0) {
1066  opcode = bytestream2_get_byte(&gb);
1067 
1068  if (opcode == 0) {
1069  opcode = bytestream2_get_byte(&gb);
1070  x = bytestream2_get_be16(&dgb);
1071 
1072  while (opcode) {
1073  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1074  bytestream2_put_be16(&pb, x);
1075  ofsdst += dstpitch;
1076  opcode--;
1077  }
1078  } else if (opcode < 0x80) {
1079  ofsdst += opcode * dstpitch;
1080  } else {
1081  opcode &= 0x7f;
1082 
1083  while (opcode) {
1084  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1085  bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1086  ofsdst += dstpitch;
1087  opcode--;
1088  }
1089  }
1090  i--;
1091  }
1092  }
1093  }
1094 }
1095 
1097  const uint8_t *buf, const uint8_t *buf_end,
1098  int w, int bpp, int dst_size)
1099 {
1100  int ncolumns = (w + 31) >> 5;
1101  int dstpitch = ((w + 15) / 16 * 2) * bpp;
1102  unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1103  GetByteContext ptrs, gb, dptrs, dgb;
1104  PutByteContext pb;
1105  int i, j, k, h;
1106 
1107  if (buf_end - buf <= 64)
1108  return;
1109 
1110  h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1111  bytestream2_init(&ptrs, buf, buf_end - buf);
1112  bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1113  bytestream2_init_writer(&pb, dst, dst_size);
1114 
1115  for (k = 0; k < bpp; k++) {
1116  ofssrc = bytestream2_get_be32(&ptrs);
1117  ofsdata = bytestream2_get_be32(&dptrs);
1118 
1119  if (!ofssrc)
1120  continue;
1121 
1122  if (ofssrc >= buf_end - buf)
1123  return;
1124 
1125  if (ofsdata >= buf_end - buf)
1126  return;
1127 
1128  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1129  bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1130  for (j = 0; j < ncolumns; j++) {
1131  ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1132 
1133  i = bytestream2_get_byte(&gb);
1134  while (i > 0) {
1135  opcode = bytestream2_get_byte(&gb);
1136 
1137  if (opcode == 0) {
1138  opcode = bytestream2_get_byte(&gb);
1139  if (h && (j == (ncolumns - 1))) {
1140  x = bytestream2_get_be16(&dgb);
1141  bytestream2_skip(&dgb, 2);
1142  } else {
1143  x = bytestream2_get_be32(&dgb);
1144  }
1145 
1146  while (opcode) {
1147  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1148  if (h && (j == (ncolumns - 1))) {
1149  bytestream2_put_be16(&pb, x);
1150  } else {
1151  bytestream2_put_be32(&pb, x);
1152  }
1153  ofsdst += dstpitch;
1154  opcode--;
1155  }
1156  } else if (opcode < 0x80) {
1157  ofsdst += opcode * dstpitch;
1158  } else {
1159  opcode &= 0x7f;
1160 
1161  while (opcode) {
1162  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1163  if (h && (j == (ncolumns - 1))) {
1164  bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1165  bytestream2_skip(&dgb, 2);
1166  } else {
1167  bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1168  }
1169  ofsdst += dstpitch;
1170  opcode--;
1171  }
1172  }
1173  i--;
1174  }
1175  }
1176  }
1177 }
1178 
1180  const uint8_t *buf, const uint8_t *buf_end,
1181  int w, int bpp, int dst_size)
1182 {
1183  int ncolumns = (w + 15) >> 4;
1184  int dstpitch = ncolumns * bpp * 2;
1185  unsigned ofsdst, ofssrc, opcode, x;
1186  GetByteContext ptrs, gb;
1187  PutByteContext pb;
1188  int i, j, k;
1189 
1190  bytestream2_init(&ptrs, buf, buf_end - buf);
1191  bytestream2_init_writer(&pb, dst, dst_size);
1192 
1193  for (k = 0; k < bpp; k++) {
1194  ofssrc = bytestream2_get_be32(&ptrs);
1195 
1196  if (!ofssrc)
1197  continue;
1198 
1199  if (ofssrc >= buf_end - buf)
1200  continue;
1201 
1202  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1203  for (j = 0; j < ncolumns; j++) {
1204  ofsdst = (j + k * ncolumns) * 2;
1205 
1206  i = bytestream2_get_be16(&gb);
1207  while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1208  opcode = bytestream2_get_be16(&gb);
1209 
1210  if (opcode == 0) {
1211  opcode = bytestream2_get_be16(&gb);
1212  x = bytestream2_get_be16(&gb);
1213 
1214  while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1215  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1216  bytestream2_put_be16(&pb, x);
1217  ofsdst += dstpitch;
1218  opcode--;
1219  }
1220  } else if (opcode < 0x8000) {
1221  ofsdst += opcode * dstpitch;
1222  } else {
1223  opcode &= 0x7fff;
1224 
1225  while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1226  bytestream2_get_bytes_left_p(&pb) > 1) {
1227  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1228  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1229  ofsdst += dstpitch;
1230  opcode--;
1231  }
1232  }
1233  i--;
1234  }
1235  }
1236  }
1237 }
1238 
1240  const uint8_t *buf, const uint8_t *buf_end,
1241  int w, int bpp, int dst_size)
1242 {
1243  int ncolumns = (w + 31) >> 5;
1244  int dstpitch = ((w + 15) / 16 * 2) * bpp;
1245  unsigned ofsdst, ofssrc, opcode, x;
1246  unsigned skip = 0x80000000, mask = skip - 1;
1247  GetByteContext ptrs, gb;
1248  PutByteContext pb;
1249  int i, j, k, h;
1250 
1251  h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1252  bytestream2_init(&ptrs, buf, buf_end - buf);
1253  bytestream2_init_writer(&pb, dst, dst_size);
1254 
1255  for (k = 0; k < bpp; k++) {
1256  ofssrc = bytestream2_get_be32(&ptrs);
1257 
1258  if (!ofssrc)
1259  continue;
1260 
1261  if (ofssrc >= buf_end - buf)
1262  continue;
1263 
1264  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1265  for (j = 0; j < ncolumns; j++) {
1266  ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1267 
1268  if (h && (j == (ncolumns - 1))) {
1269  skip = 0x8000;
1270  mask = skip - 1;
1271  }
1272 
1273  i = bytestream2_get_be32(&gb);
1274  while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1275  opcode = bytestream2_get_be32(&gb);
1276 
1277  if (opcode == 0) {
1278  if (h && (j == ncolumns - 1)) {
1279  opcode = bytestream2_get_be16(&gb);
1280  x = bytestream2_get_be16(&gb);
1281  } else {
1282  opcode = bytestream2_get_be32(&gb);
1283  x = bytestream2_get_be32(&gb);
1284  }
1285 
1286  while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1287  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1288  if (h && (j == ncolumns - 1))
1289  bytestream2_put_be16(&pb, x);
1290  else
1291  bytestream2_put_be32(&pb, x);
1292  ofsdst += dstpitch;
1293  opcode--;
1294  }
1295  } else if (opcode < skip) {
1296  ofsdst += opcode * dstpitch;
1297  } else {
1298  opcode &= mask;
1299 
1300  while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1301  bytestream2_get_bytes_left_p(&pb) > 1) {
1302  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1303  if (h && (j == ncolumns - 1)) {
1304  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1305  } else {
1306  bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1307  }
1308  ofsdst += dstpitch;
1309  opcode--;
1310  }
1311  }
1312  i--;
1313  }
1314  }
1315  }
1316 }
1317 
1318 static void decode_delta_d(uint8_t *dst,
1319  const uint8_t *buf, const uint8_t *buf_end,
1320  int w, int flag, int bpp, int dst_size)
1321 {
1322  int planepitch = FFALIGN(w, 16) >> 3;
1323  int pitch = planepitch * bpp;
1324  int planepitch_byte = (w + 7) / 8;
1325  unsigned entries, ofssrc;
1326  GetByteContext gb, ptrs;
1327  PutByteContext pb;
1328  int k;
1329 
1330  if (buf_end - buf <= 4 * bpp)
1331  return;
1332 
1333  bytestream2_init_writer(&pb, dst, dst_size);
1334  bytestream2_init(&ptrs, buf, bpp * 4);
1335 
1336  for (k = 0; k < bpp; k++) {
1337  ofssrc = bytestream2_get_be32(&ptrs);
1338 
1339  if (!ofssrc)
1340  continue;
1341 
1342  if (ofssrc >= buf_end - buf)
1343  continue;
1344 
1345  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1346 
1347  entries = bytestream2_get_be32(&gb);
1348  while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1349  int32_t opcode = bytestream2_get_be32(&gb);
1350  unsigned offset = bytestream2_get_be32(&gb);
1351 
1352  bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1353  if (opcode >= 0) {
1354  uint32_t x = bytestream2_get_be32(&gb);
1355  while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1356  bytestream2_put_be32(&pb, x);
1357  bytestream2_skip_p(&pb, pitch - 4);
1358  opcode--;
1359  }
1360  } else {
1361  opcode = -opcode;
1362  while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1363  bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1364  bytestream2_skip_p(&pb, pitch - 4);
1365  opcode--;
1366  }
1367  }
1368  entries--;
1369  }
1370  }
1371 }
1372 
1373 static void decode_delta_e(uint8_t *dst,
1374  const uint8_t *buf, const uint8_t *buf_end,
1375  int w, int flag, int bpp, int dst_size)
1376 {
1377  int planepitch = FFALIGN(w, 16) >> 3;
1378  int pitch = planepitch * bpp;
1379  int planepitch_byte = (w + 7) / 8;
1380  unsigned entries, ofssrc;
1381  GetByteContext gb, ptrs;
1382  PutByteContext pb;
1383  int k;
1384 
1385  if (buf_end - buf <= 4 * bpp)
1386  return;
1387 
1388  bytestream2_init_writer(&pb, dst, dst_size);
1389  bytestream2_init(&ptrs, buf, bpp * 4);
1390 
1391  for (k = 0; k < bpp; k++) {
1392  ofssrc = bytestream2_get_be32(&ptrs);
1393 
1394  if (!ofssrc)
1395  continue;
1396 
1397  if (ofssrc >= buf_end - buf)
1398  continue;
1399 
1400  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1401 
1402  entries = bytestream2_get_be16(&gb);
1403  while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1404  int16_t opcode = bytestream2_get_be16(&gb);
1405  unsigned offset = bytestream2_get_be32(&gb);
1406 
1407  bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1408  if (opcode >= 0) {
1409  uint16_t x = bytestream2_get_be16(&gb);
1410  while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1411  bytestream2_put_be16(&pb, x);
1412  bytestream2_skip_p(&pb, pitch - 2);
1413  opcode--;
1414  }
1415  } else {
1416  opcode = -opcode;
1417  while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1418  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1419  bytestream2_skip_p(&pb, pitch - 2);
1420  opcode--;
1421  }
1422  }
1423  entries--;
1424  }
1425  }
1426 }
1427 
1428 static void decode_delta_l(uint8_t *dst,
1429  const uint8_t *buf, const uint8_t *buf_end,
1430  int w, int flag, int bpp, int dst_size)
1431 {
1432  GetByteContext off0, off1, dgb, ogb;
1433  PutByteContext pb;
1434  unsigned poff0, poff1;
1435  int i, k, dstpitch;
1436  int planepitch_byte = (w + 7) / 8;
1437  int planepitch = ((w + 15) / 16) * 2;
1438  int pitch = planepitch * bpp;
1439 
1440  if (buf_end - buf <= 64)
1441  return;
1442 
1443  bytestream2_init(&off0, buf, buf_end - buf);
1444  bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1445  bytestream2_init_writer(&pb, dst, dst_size);
1446 
1447  dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1448 
1449  for (k = 0; k < bpp; k++) {
1450  poff0 = bytestream2_get_be32(&off0);
1451  poff1 = bytestream2_get_be32(&off1);
1452 
1453  if (!poff0)
1454  continue;
1455 
1456  if (2LL * poff0 >= buf_end - buf)
1457  return;
1458 
1459  if (2LL * poff1 >= buf_end - buf)
1460  return;
1461 
1462  bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1463  bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1464 
1465  while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1466  uint32_t offset = bytestream2_get_be16(&ogb);
1467  int16_t cnt = bytestream2_get_be16(&ogb);
1468  uint16_t data;
1469 
1470  offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1471  if (cnt < 0) {
1472  if (bytestream2_get_bytes_left(&dgb) < 2)
1473  break;
1474  bytestream2_seek_p(&pb, offset, SEEK_SET);
1475  cnt = -cnt;
1476  data = bytestream2_get_be16(&dgb);
1477  for (i = 0; i < cnt; i++) {
1478  bytestream2_put_be16(&pb, data);
1479  bytestream2_skip_p(&pb, dstpitch - 2);
1480  }
1481  } else {
1482  if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1483  break;
1484  bytestream2_seek_p(&pb, offset, SEEK_SET);
1485  for (i = 0; i < cnt; i++) {
1486  data = bytestream2_get_be16(&dgb);
1487  bytestream2_put_be16(&pb, data);
1488  bytestream2_skip_p(&pb, dstpitch - 2);
1489  }
1490  }
1491  }
1492  }
1493 }
1494 
1495 static int unsupported(AVCodecContext *avctx)
1496 {
1497  IffContext *s = avctx->priv_data;
1498  avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1499  return AVERROR_INVALIDDATA;
1500 }
1501 
1502 static int decode_frame(AVCodecContext *avctx,
1503  void *data, int *got_frame,
1504  AVPacket *avpkt)
1505 {
1506  IffContext *s = avctx->priv_data;
1507  AVFrame *frame = data;
1508  const uint8_t *buf = avpkt->data;
1509  int buf_size = avpkt->size;
1510  const uint8_t *buf_end = buf + buf_size;
1511  int y, plane, res;
1512  GetByteContext *gb = &s->gb;
1513  const AVPixFmtDescriptor *desc;
1514 
1515  bytestream2_init(gb, avpkt->data, avpkt->size);
1516 
1517  if ((res = extract_header(avctx, avpkt)) < 0)
1518  return res;
1519 
1520  if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1521  return res;
1522  s->frame = frame;
1523 
1524  buf += bytestream2_tell(gb);
1525  buf_size -= bytestream2_tell(gb);
1526  desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1527 
1528  if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1529  avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1530  if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1531  return res;
1532  } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1533  avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1534  if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1535  return res;
1536  }
1537  s->init = 1;
1538 
1539  if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1540  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1541  memcpy(s->pal, s->frame->data[1], 256 * 4);
1542  }
1543 
1544  switch (s->compression) {
1545  case 0x0:
1546  if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1547  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1548  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1549  for (plane = 0; plane < s->bpp; plane++) {
1550  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1551  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1552  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1553  buf += s->planesize;
1554  }
1555  }
1556  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1557  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1558  for (y = 0; y < avctx->height; y++) {
1559  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1560  memset(s->ham_buf, 0, s->planesize * 8);
1561  for (plane = 0; plane < s->bpp; plane++) {
1562  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1563  if (start >= buf_end)
1564  break;
1565  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1566  }
1567  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1568  }
1569  } else
1570  return unsupported(avctx);
1571  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1572  int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1573  int x;
1574  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1575  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1576  memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1577  buf += raw_width;
1578  if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1579  for (x = 0; x < avctx->width; x++)
1580  row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1581  }
1582  }
1583  } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1584  avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1585  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1586  memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1587  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1588  for (y = 0; y < avctx->height; y++) {
1589  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1590  memset(row, 0, avctx->width);
1591  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1592  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1593  buf += s->planesize;
1594  }
1595  }
1596  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1597  for (y = 0; y < avctx->height; y++) {
1598  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1599  memset(s->ham_buf, 0, s->planesize * 8);
1600  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1601  decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1602  buf += s->planesize;
1603  }
1604  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1605  }
1606  } else { // AV_PIX_FMT_BGR32
1607  for (y = 0; y < avctx->height; y++) {
1608  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1609  memset(row, 0, avctx->width << 2);
1610  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1611  decodeplane32((uint32_t *)row, buf,
1612  FFMIN(s->planesize, buf_end - buf), plane);
1613  buf += s->planesize;
1614  }
1615  }
1616  }
1617  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1618  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1619  for (y = 0; y < avctx->height && buf_end > buf; y++) {
1620  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1621  memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1622  buf += avctx->width + (avctx->width % 2); // padding if odd
1623  }
1624  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1625  for (y = 0; y < avctx->height && buf_end > buf; y++) {
1626  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1627  memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1628  buf += avctx->width + (avctx->width & 1); // padding if odd
1629  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1630  }
1631  } else
1632  return unsupported(avctx);
1633  } else {
1634  return unsupported(avctx);
1635  }
1636  break;
1637  case 0x1:
1638  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1639  avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1640  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1641  uint8_t *video = s->video[0];
1642 
1643  for (y = 0; y < avctx->height; y++) {
1644  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1645  memset(row, 0, avctx->width);
1646  for (plane = 0; plane < s->bpp; plane++) {
1647  buf += decode_byterun(s->planebuf, s->planesize, gb);
1648  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1649  memcpy(video, s->planebuf, s->planesize);
1650  video += s->planesize;
1651  }
1652  decodeplane8(row, s->planebuf, s->planesize, plane);
1653  }
1654  }
1655  } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1656  for (y = 0; y < avctx->height; y++) {
1657  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1658  memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1659  for (plane = 0; plane < s->bpp; plane++) {
1660  buf += decode_byterun(s->planebuf, s->planesize, gb);
1661  decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1662  }
1663  lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1664  }
1665  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1666  uint8_t *video = s->video[0];
1667  for (y = 0; y < avctx->height; y++) {
1668  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1669  memset(s->ham_buf, 0, s->planesize * 8);
1670  for (plane = 0; plane < s->bpp; plane++) {
1671  buf += decode_byterun(s->planebuf, s->planesize, gb);
1672  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1673  memcpy(video, s->planebuf, s->planesize);
1674  video += s->planesize;
1675  }
1676  decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1677  }
1678  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1679  }
1680  } else { // AV_PIX_FMT_BGR32
1681  for (y = 0; y < avctx->height; y++) {
1682  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1683  memset(row, 0, avctx->width << 2);
1684  for (plane = 0; plane < s->bpp; plane++) {
1685  buf += decode_byterun(s->planebuf, s->planesize, gb);
1686  decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1687  }
1688  }
1689  }
1690  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1691  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1692  for (y = 0; y < avctx->height; y++) {
1693  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1694  buf += decode_byterun(row, avctx->width, gb);
1695  }
1696  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1697  for (y = 0; y < avctx->height; y++) {
1698  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1699  buf += decode_byterun(s->ham_buf, avctx->width, gb);
1700  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1701  }
1702  } else
1703  return unsupported(avctx);
1704  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1705  if (av_get_bits_per_pixel(desc) == 32)
1706  decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1707  else
1708  return unsupported(avctx);
1709  } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1710  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1711  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1712  for (plane = 0; plane < s->bpp; plane++) {
1713  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1714  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1715  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1716  buf += s->planesize;
1717  }
1718  }
1719  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1720  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1721  for (y = 0; y < avctx->height; y++) {
1722  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1723  memset(s->ham_buf, 0, s->planesize * 8);
1724  for (plane = 0; plane < s->bpp; plane++) {
1725  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1726  if (start >= buf_end)
1727  break;
1728  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1729  }
1730  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1731  }
1732  } else {
1733  return unsupported(avctx);
1734  }
1735  } else {
1736  return unsupported(avctx);
1737  }
1738  break;
1739  case 0x2:
1740  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1741  for (plane = 0; plane < s->bpp; plane++) {
1742  decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1743  for (y = 0; y < avctx->height; y++) {
1744  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1745  decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1746  }
1747  }
1748  } else {
1749  return unsupported(avctx);
1750  }
1751  break;
1752  case 0x4:
1753  if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1754  decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1755  else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1756  decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1757  else
1758  return unsupported(avctx);
1759  break;
1760  case 0x5:
1761  if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1762  if (av_get_bits_per_pixel(desc) == 32)
1763  decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1764  else
1765  return unsupported(avctx);
1766  } else
1767  return unsupported(avctx);
1768  break;
1769  case 0x300:
1770  case 0x301:
1771  decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1772  break;
1773  case 0x500:
1774  case 0x501:
1775  decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1776  break;
1777  case 0x700:
1778  case 0x701:
1779  if (s->is_short)
1780  decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1781  else
1782  decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1783  break;
1784  case 0x800:
1785  case 0x801:
1786  if (s->is_short)
1787  decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1788  else
1789  decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1790  break;
1791  case 0x4a00:
1792  case 0x4a01:
1793  decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1794  break;
1795  case 0x6400:
1796  case 0x6401:
1797  if (s->is_interlaced)
1798  return unsupported(avctx);
1799  decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1800  break;
1801  case 0x6500:
1802  case 0x6501:
1803  if (s->is_interlaced)
1804  return unsupported(avctx);
1805  decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1806  break;
1807  case 0x6c00:
1808  case 0x6c01:
1809  decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1810  break;
1811  default:
1812  return unsupported(avctx);
1813  }
1814 
1815  if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1816  memcpy(s->video[1], s->video[0], s->video_size);
1817  }
1818 
1819  if (s->compression > 0xff) {
1820  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1821  buf = s->video[0];
1822  for (y = 0; y < avctx->height; y++) {
1823  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1824  memset(row, 0, avctx->width);
1825  for (plane = 0; plane < s->bpp; plane++) {
1826  decodeplane8(row, buf, s->planesize, plane);
1827  buf += s->planesize;
1828  }
1829  }
1830  memcpy(frame->data[1], s->pal, 256 * 4);
1831  } else if (s->ham) {
1832  int i, count = 1 << s->ham;
1833 
1834  buf = s->video[0];
1835  memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1836  for (i = 0; i < count; i++) {
1837  s->ham_palbuf[i*2+1] = s->pal[i];
1838  }
1839  for (i = 0; i < count; i++) {
1840  uint32_t tmp = i << (8 - s->ham);
1841  tmp |= tmp >> s->ham;
1842  s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1843  s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1844  s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1845  s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1846  s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1847  s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1848  }
1849  if (s->masking == MASK_HAS_MASK) {
1850  for (i = 0; i < 8 * (1 << s->ham); i++)
1851  s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1852  }
1853  for (y = 0; y < avctx->height; y++) {
1854  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1855  memset(s->ham_buf, 0, s->planesize * 8);
1856  for (plane = 0; plane < s->bpp; plane++) {
1857  decodeplane8(s->ham_buf, buf, s->planesize, plane);
1858  buf += s->planesize;
1859  }
1860  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1861  }
1862  } else {
1863  return unsupported(avctx);
1864  }
1865 
1866  if (!s->is_brush) {
1867  FFSWAP(uint8_t *, s->video[0], s->video[1]);
1868  }
1869  }
1870 
1871  if (avpkt->flags & AV_PKT_FLAG_KEY) {
1872  frame->key_frame = 1;
1873  frame->pict_type = AV_PICTURE_TYPE_I;
1874  } else {
1875  frame->key_frame = 0;
1876  frame->pict_type = AV_PICTURE_TYPE_P;
1877  }
1878 
1879  *got_frame = 1;
1880 
1881  return buf_size;
1882 }
1883 
1884 #if CONFIG_IFF_ILBM_DECODER
1886  .name = "iff",
1887  .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1888  .type = AVMEDIA_TYPE_VIDEO,
1889  .id = AV_CODEC_ID_IFF_ILBM,
1890  .priv_data_size = sizeof(IffContext),
1891  .init = decode_init,
1892  .close = decode_end,
1893  .decode = decode_frame,
1894  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1895  .capabilities = AV_CODEC_CAP_DR1,
1896 };
1897 #endif
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
int plane
Definition: avisynth_c.h:384
Definition: iff.c:43
#define NULL
Definition: coverity.c:32
unsigned is_brush
video is in ANBR format
Definition: iff.c:57
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
Decode interleaved plane buffer up to 24bpp.
Definition: iff.c:478
unsigned compression
delta compression method used
Definition: iff.c:54
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
uint32_t * mask_palbuf
masking palette table
Definition: iff.c:53
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
unsigned masking
TODO: masking method used.
Definition: iff.c:62
const char * g
Definition: vf_curves.c:115
const char * desc
Definition: nvenc.c:68
int av_get_bits_per_pixel(const AVPixFmtDescriptor *pixdesc)
Return the number of bits per pixel used by the pixel format described by pixdesc.
Definition: pixdesc.c:2474
#define avpriv_request_sample(...)
unsigned transparency
TODO: transparency color index in palette.
Definition: iff.c:61
static int cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
Convert CMAP buffer (stored in extradata) to lavc palette format.
Definition: iff.c:153
GetByteContext gb
Definition: iff.c:65
int size
Definition: avcodec.h:1481
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:143
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
GLint GLenum type
Definition: opengl_enc.c:104
#define av_le2ne32(x)
Definition: bswap.h:96
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:87
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:376
unsigned flags
1 for EHB, 0 is no extra half darkening
Definition: iff.c:60
#define src
Definition: vp8dsp.c:254
unsigned is_short
short compression method used
Definition: iff.c:55
AVCodec.
Definition: avcodec.h:3492
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static void decode_delta_e(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int flag, int bpp, int dst_size)
Definition: iff.c:1373
uint8_t * video[2]
Definition: iff.c:66
static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
Decode interleaved plane buffer up to 8bpp.
Definition: iff.c:457
uint32_t * mask_buf
temporary buffer for palette indices
Definition: iff.c:52
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
#define DECODE_HAM_PLANE32(x)
Definition: iff.c:496
static av_cold int decode_end(AVCodecContext *avctx)
Definition: iff.c:379
static const char *const cmds[]
Definition: jacosubdec.c:72
uint8_t * planebuf
Definition: iff.c:49
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
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)
Decode DEEP TVDC 32-bit buffer.
Definition: iff.c:757
float delta
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
uint8_t * ham_buf
temporary buffer for planar to chunky conversation
Definition: iff.c:50
static const OptionGroupDef groups[]
Definition: ffmpeg_opt.c:3252
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
uint32_t * pal
Definition: iff.c:68
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1669
Definition: iff.c:40
#define height
uint8_t * data
Definition: avcodec.h:1480
const uint8_t * buffer
Definition: bytestream.h:34
#define FFMIN3(a, b, c)
Definition: common.h:97
mask_type
Definition: iff.c:39
ptrdiff_t size
Definition: opengl_enc.c:100
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2792
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1512
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p)
Definition: bytestream.h:159
static const uint16_t mask[17]
Definition: lzw.c:38
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * r
Definition: vf_curves.c:114
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
GLsizei GLsizei * length
Definition: opengl_enc.c:114
#define AV_PIX_FMT_0BGR32
Definition: pixfmt.h:365
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_RL24
Definition: bytestream.h:87
GLsizei count
Definition: opengl_enc.c:108
#define FFMAX(a, b)
Definition: common.h:94
unsigned is_interlaced
video is interlaced
Definition: iff.c:56
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1486
#define GETNIBBLE
static av_always_inline void bytestream2_skip_p(PutByteContext *p, unsigned int size)
Definition: bytestream.h:176
#define LUT32(plane)
Definition: iff.c:114
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:282
#define b
Definition: input.c:41
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
#define FFMIN(a, b)
Definition: common.h:96
Definition: iff.c:46
#define width
static void decode_short_vertical_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)
Definition: iff.c:1028
int width
picture width / height.
Definition: avcodec.h:1741
uint8_t w
Definition: llviddspenc.c:38
int32_t
static void decode_short_horizontal_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)
Definition: iff.c:797
#define s(width, name)
Definition: cbs_vp9.c:257
static int decode_byterun(uint8_t *dst, int dst_size, GetByteContext *gb)
Decode one complete byterun1 encoded line.
Definition: iff.c:546
#define AV_WN64A(p, v)
Definition: intreadwrite.h:542
AVFrame * frame
Definition: iff.c:47
if(ret)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static av_always_inline int bytestream2_seek_p(PutByteContext *p, int offset, int whence)
Definition: bytestream.h:232
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
#define AV_PIX_FMT_BGR32
Definition: pixfmt.h:362
int init
Definition: iff.c:63
static void decode_long_vertical_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)
Definition: iff.c:1096
Libavcodec external API header.
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_RB24
Definition: bytestream.h:87
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
AVCodec ff_iff_ilbm_decoder
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
#define DECODE_RGBX_COMMON(type)
Definition: iff.c:643
main external API structure.
Definition: avcodec.h:1568
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:360
int planesize
Definition: iff.c:48
static void decode_short_vertical_delta2(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)
Definition: iff.c:1179
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
Definition: avcodec.h:1593
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1968
void * buf
Definition: avisynth_c.h:766
int extradata_size
Definition: avcodec.h:1670
static void decode_delta_j(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int h, int bpp, int dst_size)
Definition: iff.c:917
static av_always_inline uint32_t gray2rgb(const uint32_t x)
Definition: iff.c:146
static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
Decode RGBN buffer.
Definition: iff.c:687
#define AV_RN32(p)
Definition: intreadwrite.h:364
static void decode_long_vertical_delta2(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int bpp, int dst_size)
Definition: iff.c:1239
static void decode_delta_l(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int flag, int bpp, int dst_size)
Definition: iff.c:1428
uint8_t pixel
Definition: tiny_ssim.c:42
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
static void decode_byte_vertical_delta(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int xor, int bpp, int dst_size)
Definition: iff.c:850
Y , 8bpp.
Definition: pixfmt.h:74
common internal api header.
unsigned ham
0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise)
Definition: iff.c:59
static const uint32_t plane32_lut[32][16 *4]
Definition: iff.c:134
#define flag(name)
Definition: cbs_av1.c:553
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: iff.c:1502
static void decode_delta_d(uint8_t *dst, const uint8_t *buf, const uint8_t *buf_end, int w, int flag, int bpp, int dst_size)
Definition: iff.c:1318
static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
Decode RGB8 buffer.
Definition: iff.c:670
#define LUT8(plane)
Definition: iff.c:89
static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf, const uint32_t *const pal, unsigned buf_size)
Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
Definition: iff.c:514
#define MKBETAG(a, b, c, d)
Definition: common.h:367
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:793
static av_cold int decode_init(AVCodecContext *avctx)
Definition: iff.c:393
void * priv_data
Definition: avcodec.h:1595
static const uint64_t plane8_lut[8][256]
Definition: iff.c:109
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
static int decode_byterun2(uint8_t *dst, int height, int line_size, GetByteContext *gb)
Definition: iff.c:573
#define av_freep(p)
void INT64 start
Definition: avisynth_c.h:766
#define av_always_inline
Definition: attributes.h:39
unsigned video_size
Definition: iff.c:67
#define FFSWAP(type, a, b)
Definition: common.h:99
static int extract_header(AVCodecContext *const avctx, const AVPacket *const avpkt)
Extracts the IFF extra context and updates internal decoder structures.
Definition: iff.c:204
static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf, const uint32_t *const pal, unsigned width)
Definition: iff.c:529
int16_t tvdc[16]
TVDC lookup table.
Definition: iff.c:64
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
static int unsupported(AVCodecContext *avctx)
Definition: iff.c:1495
#define AV_RN64A(p)
Definition: intreadwrite.h:530
#define MKTAG(a, b, c, d)
Definition: common.h:366
This structure stores compressed data.
Definition: avcodec.h:1457
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:984
uint32_t * ham_palbuf
HAM decode table.
Definition: iff.c:51
Predicted.
Definition: avutil.h:275
unsigned bpp
bits per plane to decode (differs from bits_per_coded_sample if HAM)
Definition: iff.c:58
static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
Decode DEEP RLE 32-bit buffer.
Definition: iff.c:707
static uint8_t tmp[11]
Definition: aes_ctr.c:26