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  if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1147  return;
1148 
1149  while (opcode) {
1150  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1151  if (h && (j == (ncolumns - 1))) {
1152  bytestream2_put_be16(&pb, x);
1153  } else {
1154  bytestream2_put_be32(&pb, x);
1155  }
1156  ofsdst += dstpitch;
1157  opcode--;
1158  }
1159  } else if (opcode < 0x80) {
1160  ofsdst += opcode * dstpitch;
1161  } else {
1162  opcode &= 0x7f;
1163 
1164  while (opcode) {
1165  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1166  if (h && (j == (ncolumns - 1))) {
1167  bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1168  bytestream2_skip(&dgb, 2);
1169  } else {
1170  bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1171  }
1172  ofsdst += dstpitch;
1173  opcode--;
1174  }
1175  }
1176  i--;
1177  }
1178  }
1179  }
1180 }
1181 
1183  const uint8_t *buf, const uint8_t *buf_end,
1184  int w, int bpp, int dst_size)
1185 {
1186  int ncolumns = (w + 15) >> 4;
1187  int dstpitch = ncolumns * bpp * 2;
1188  unsigned ofsdst, ofssrc, opcode, x;
1189  GetByteContext ptrs, gb;
1190  PutByteContext pb;
1191  int i, j, k;
1192 
1193  bytestream2_init(&ptrs, buf, buf_end - buf);
1194  bytestream2_init_writer(&pb, dst, dst_size);
1195 
1196  for (k = 0; k < bpp; k++) {
1197  ofssrc = bytestream2_get_be32(&ptrs);
1198 
1199  if (!ofssrc)
1200  continue;
1201 
1202  if (ofssrc >= buf_end - buf)
1203  continue;
1204 
1205  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1206  for (j = 0; j < ncolumns; j++) {
1207  ofsdst = (j + k * ncolumns) * 2;
1208 
1209  i = bytestream2_get_be16(&gb);
1210  while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1211  opcode = bytestream2_get_be16(&gb);
1212 
1213  if (opcode == 0) {
1214  opcode = bytestream2_get_be16(&gb);
1215  x = bytestream2_get_be16(&gb);
1216 
1217  while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1218  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1219  bytestream2_put_be16(&pb, x);
1220  ofsdst += dstpitch;
1221  opcode--;
1222  }
1223  } else if (opcode < 0x8000) {
1224  ofsdst += opcode * dstpitch;
1225  } else {
1226  opcode &= 0x7fff;
1227 
1228  while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1229  bytestream2_get_bytes_left_p(&pb) > 1) {
1230  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1231  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1232  ofsdst += dstpitch;
1233  opcode--;
1234  }
1235  }
1236  i--;
1237  }
1238  }
1239  }
1240 }
1241 
1243  const uint8_t *buf, const uint8_t *buf_end,
1244  int w, int bpp, int dst_size)
1245 {
1246  int ncolumns = (w + 31) >> 5;
1247  int dstpitch = ((w + 15) / 16 * 2) * bpp;
1248  unsigned ofsdst, ofssrc, opcode, x;
1249  unsigned skip = 0x80000000, mask = skip - 1;
1250  GetByteContext ptrs, gb;
1251  PutByteContext pb;
1252  int i, j, k, h;
1253 
1254  h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1255  bytestream2_init(&ptrs, buf, buf_end - buf);
1256  bytestream2_init_writer(&pb, dst, dst_size);
1257 
1258  for (k = 0; k < bpp; k++) {
1259  ofssrc = bytestream2_get_be32(&ptrs);
1260 
1261  if (!ofssrc)
1262  continue;
1263 
1264  if (ofssrc >= buf_end - buf)
1265  continue;
1266 
1267  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1268  for (j = 0; j < ncolumns; j++) {
1269  ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1270 
1271  if (h && (j == (ncolumns - 1))) {
1272  skip = 0x8000;
1273  mask = skip - 1;
1274  }
1275 
1276  i = bytestream2_get_be32(&gb);
1277  while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1278  opcode = bytestream2_get_be32(&gb);
1279 
1280  if (opcode == 0) {
1281  if (h && (j == ncolumns - 1)) {
1282  opcode = bytestream2_get_be16(&gb);
1283  x = bytestream2_get_be16(&gb);
1284  } else {
1285  opcode = bytestream2_get_be32(&gb);
1286  x = bytestream2_get_be32(&gb);
1287  }
1288 
1289  if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1290  return;
1291 
1292  while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1293  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1294  if (h && (j == ncolumns - 1))
1295  bytestream2_put_be16(&pb, x);
1296  else
1297  bytestream2_put_be32(&pb, x);
1298  ofsdst += dstpitch;
1299  opcode--;
1300  }
1301  } else if (opcode < skip) {
1302  ofsdst += opcode * dstpitch;
1303  } else {
1304  opcode &= mask;
1305 
1306  while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1307  bytestream2_get_bytes_left_p(&pb) > 1) {
1308  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1309  if (h && (j == ncolumns - 1)) {
1310  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1311  } else {
1312  bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1313  }
1314  ofsdst += dstpitch;
1315  opcode--;
1316  }
1317  }
1318  i--;
1319  }
1320  }
1321  }
1322 }
1323 
1324 static void decode_delta_d(uint8_t *dst,
1325  const uint8_t *buf, const uint8_t *buf_end,
1326  int w, int flag, int bpp, int dst_size)
1327 {
1328  int planepitch = FFALIGN(w, 16) >> 3;
1329  int pitch = planepitch * bpp;
1330  int planepitch_byte = (w + 7) / 8;
1331  unsigned entries, ofssrc;
1332  GetByteContext gb, ptrs;
1333  PutByteContext pb;
1334  int k;
1335 
1336  if (buf_end - buf <= 4 * bpp)
1337  return;
1338 
1339  bytestream2_init_writer(&pb, dst, dst_size);
1340  bytestream2_init(&ptrs, buf, bpp * 4);
1341 
1342  for (k = 0; k < bpp; k++) {
1343  ofssrc = bytestream2_get_be32(&ptrs);
1344 
1345  if (!ofssrc)
1346  continue;
1347 
1348  if (ofssrc >= buf_end - buf)
1349  continue;
1350 
1351  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1352 
1353  entries = bytestream2_get_be32(&gb);
1354  while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1355  int32_t opcode = bytestream2_get_be32(&gb);
1356  unsigned offset = bytestream2_get_be32(&gb);
1357 
1358  bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1359  if (opcode >= 0) {
1360  uint32_t x = bytestream2_get_be32(&gb);
1361  while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1362  bytestream2_put_be32(&pb, x);
1363  bytestream2_skip_p(&pb, pitch - 4);
1364  opcode--;
1365  }
1366  } else {
1367  opcode = -opcode;
1368  while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1369  bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1370  bytestream2_skip_p(&pb, pitch - 4);
1371  opcode--;
1372  }
1373  }
1374  entries--;
1375  }
1376  }
1377 }
1378 
1379 static void decode_delta_e(uint8_t *dst,
1380  const uint8_t *buf, const uint8_t *buf_end,
1381  int w, int flag, int bpp, int dst_size)
1382 {
1383  int planepitch = FFALIGN(w, 16) >> 3;
1384  int pitch = planepitch * bpp;
1385  int planepitch_byte = (w + 7) / 8;
1386  unsigned entries, ofssrc;
1387  GetByteContext gb, ptrs;
1388  PutByteContext pb;
1389  int k;
1390 
1391  if (buf_end - buf <= 4 * bpp)
1392  return;
1393 
1394  bytestream2_init_writer(&pb, dst, dst_size);
1395  bytestream2_init(&ptrs, buf, bpp * 4);
1396 
1397  for (k = 0; k < bpp; k++) {
1398  ofssrc = bytestream2_get_be32(&ptrs);
1399 
1400  if (!ofssrc)
1401  continue;
1402 
1403  if (ofssrc >= buf_end - buf)
1404  continue;
1405 
1406  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1407 
1408  entries = bytestream2_get_be16(&gb);
1409  while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1410  int16_t opcode = bytestream2_get_be16(&gb);
1411  unsigned offset = bytestream2_get_be32(&gb);
1412 
1413  bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1414  if (opcode >= 0) {
1415  uint16_t x = bytestream2_get_be16(&gb);
1416  while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1417  bytestream2_put_be16(&pb, x);
1418  bytestream2_skip_p(&pb, pitch - 2);
1419  opcode--;
1420  }
1421  } else {
1422  opcode = -opcode;
1423  while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1424  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1425  bytestream2_skip_p(&pb, pitch - 2);
1426  opcode--;
1427  }
1428  }
1429  entries--;
1430  }
1431  }
1432 }
1433 
1434 static void decode_delta_l(uint8_t *dst,
1435  const uint8_t *buf, const uint8_t *buf_end,
1436  int w, int flag, int bpp, int dst_size)
1437 {
1438  GetByteContext off0, off1, dgb, ogb;
1439  PutByteContext pb;
1440  unsigned poff0, poff1;
1441  int i, k, dstpitch;
1442  int planepitch_byte = (w + 7) / 8;
1443  int planepitch = ((w + 15) / 16) * 2;
1444  int pitch = planepitch * bpp;
1445 
1446  if (buf_end - buf <= 64)
1447  return;
1448 
1449  bytestream2_init(&off0, buf, buf_end - buf);
1450  bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1451  bytestream2_init_writer(&pb, dst, dst_size);
1452 
1453  dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1454 
1455  for (k = 0; k < bpp; k++) {
1456  poff0 = bytestream2_get_be32(&off0);
1457  poff1 = bytestream2_get_be32(&off1);
1458 
1459  if (!poff0)
1460  continue;
1461 
1462  if (2LL * poff0 >= buf_end - buf)
1463  return;
1464 
1465  if (2LL * poff1 >= buf_end - buf)
1466  return;
1467 
1468  bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1469  bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1470 
1471  while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1472  uint32_t offset = bytestream2_get_be16(&ogb);
1473  int16_t cnt = bytestream2_get_be16(&ogb);
1474  uint16_t data;
1475 
1476  offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1477  if (cnt < 0) {
1478  if (bytestream2_get_bytes_left(&dgb) < 2)
1479  break;
1480  bytestream2_seek_p(&pb, offset, SEEK_SET);
1481  cnt = -cnt;
1482  data = bytestream2_get_be16(&dgb);
1483  for (i = 0; i < cnt; i++) {
1484  bytestream2_put_be16(&pb, data);
1485  bytestream2_skip_p(&pb, dstpitch - 2);
1486  }
1487  } else {
1488  if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1489  break;
1490  bytestream2_seek_p(&pb, offset, SEEK_SET);
1491  for (i = 0; i < cnt; i++) {
1492  data = bytestream2_get_be16(&dgb);
1493  bytestream2_put_be16(&pb, data);
1494  bytestream2_skip_p(&pb, dstpitch - 2);
1495  }
1496  }
1497  }
1498  }
1499 }
1500 
1501 static int unsupported(AVCodecContext *avctx)
1502 {
1503  IffContext *s = avctx->priv_data;
1504  avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1505  return AVERROR_INVALIDDATA;
1506 }
1507 
1508 static int decode_frame(AVCodecContext *avctx,
1509  void *data, int *got_frame,
1510  AVPacket *avpkt)
1511 {
1512  IffContext *s = avctx->priv_data;
1513  AVFrame *frame = data;
1514  const uint8_t *buf = avpkt->data;
1515  int buf_size = avpkt->size;
1516  const uint8_t *buf_end = buf + buf_size;
1517  int y, plane, res;
1518  GetByteContext *gb = &s->gb;
1519  const AVPixFmtDescriptor *desc;
1520 
1521  bytestream2_init(gb, avpkt->data, avpkt->size);
1522 
1523  if ((res = extract_header(avctx, avpkt)) < 0)
1524  return res;
1525 
1526  if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1527  return res;
1528  s->frame = frame;
1529 
1530  buf += bytestream2_tell(gb);
1531  buf_size -= bytestream2_tell(gb);
1532  desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1533 
1534  if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1535  avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1536  if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1537  return res;
1538  } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1539  avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1540  if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1541  return res;
1542  }
1543  s->init = 1;
1544 
1545  if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1546  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1547  memcpy(s->pal, s->frame->data[1], 256 * 4);
1548  }
1549 
1550  switch (s->compression) {
1551  case 0x0:
1552  if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1553  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1554  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1555  for (plane = 0; plane < s->bpp; plane++) {
1556  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1557  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1558  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1559  buf += s->planesize;
1560  }
1561  }
1562  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1563  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1564  for (y = 0; y < avctx->height; y++) {
1565  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1566  memset(s->ham_buf, 0, s->planesize * 8);
1567  for (plane = 0; plane < s->bpp; plane++) {
1568  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1569  if (start >= buf_end)
1570  break;
1571  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1572  }
1573  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1574  }
1575  } else
1576  return unsupported(avctx);
1577  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1578  int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1579  int x;
1580  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1581  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1582  memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1583  buf += raw_width;
1584  if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1585  for (x = 0; x < avctx->width; x++)
1586  row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1587  }
1588  }
1589  } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1590  avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1591  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1592  memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1593  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1594  for (y = 0; y < avctx->height; y++) {
1595  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1596  memset(row, 0, avctx->width);
1597  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1598  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1599  buf += s->planesize;
1600  }
1601  }
1602  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1603  for (y = 0; y < avctx->height; y++) {
1604  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1605  memset(s->ham_buf, 0, s->planesize * 8);
1606  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1607  decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1608  buf += s->planesize;
1609  }
1610  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1611  }
1612  } else { // AV_PIX_FMT_BGR32
1613  for (y = 0; y < avctx->height; y++) {
1614  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1615  memset(row, 0, avctx->width << 2);
1616  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1617  decodeplane32((uint32_t *)row, buf,
1618  FFMIN(s->planesize, buf_end - buf), plane);
1619  buf += s->planesize;
1620  }
1621  }
1622  }
1623  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1624  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1625  for (y = 0; y < avctx->height && buf_end > buf; y++) {
1626  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1627  memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1628  buf += avctx->width + (avctx->width % 2); // padding if odd
1629  }
1630  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1631  for (y = 0; y < avctx->height && buf_end > buf; y++) {
1632  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1633  memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1634  buf += avctx->width + (avctx->width & 1); // padding if odd
1635  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1636  }
1637  } else
1638  return unsupported(avctx);
1639  } else {
1640  return unsupported(avctx);
1641  }
1642  break;
1643  case 0x1:
1644  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1645  avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1646  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1647  uint8_t *video = s->video[0];
1648 
1649  for (y = 0; y < avctx->height; y++) {
1650  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1651  memset(row, 0, avctx->width);
1652  for (plane = 0; plane < s->bpp; plane++) {
1653  buf += decode_byterun(s->planebuf, s->planesize, gb);
1654  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1655  memcpy(video, s->planebuf, s->planesize);
1656  video += s->planesize;
1657  }
1658  decodeplane8(row, s->planebuf, s->planesize, plane);
1659  }
1660  }
1661  } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1662  for (y = 0; y < avctx->height; y++) {
1663  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1664  memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1665  for (plane = 0; plane < s->bpp; plane++) {
1666  buf += decode_byterun(s->planebuf, s->planesize, gb);
1667  decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1668  }
1669  lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1670  }
1671  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1672  uint8_t *video = s->video[0];
1673  for (y = 0; y < avctx->height; y++) {
1674  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1675  memset(s->ham_buf, 0, s->planesize * 8);
1676  for (plane = 0; plane < s->bpp; plane++) {
1677  buf += decode_byterun(s->planebuf, s->planesize, gb);
1678  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1679  memcpy(video, s->planebuf, s->planesize);
1680  video += s->planesize;
1681  }
1682  decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1683  }
1684  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1685  }
1686  } else { // AV_PIX_FMT_BGR32
1687  for (y = 0; y < avctx->height; y++) {
1688  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1689  memset(row, 0, avctx->width << 2);
1690  for (plane = 0; plane < s->bpp; plane++) {
1691  buf += decode_byterun(s->planebuf, s->planesize, gb);
1692  decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1693  }
1694  }
1695  }
1696  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1697  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1698  for (y = 0; y < avctx->height; y++) {
1699  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1700  buf += decode_byterun(row, avctx->width, gb);
1701  }
1702  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1703  for (y = 0; y < avctx->height; y++) {
1704  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1705  buf += decode_byterun(s->ham_buf, avctx->width, gb);
1706  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1707  }
1708  } else
1709  return unsupported(avctx);
1710  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1711  if (av_get_bits_per_pixel(desc) == 32)
1712  decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1713  else
1714  return unsupported(avctx);
1715  } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1716  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1717  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1718  for (plane = 0; plane < s->bpp; plane++) {
1719  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1720  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1721  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1722  buf += s->planesize;
1723  }
1724  }
1725  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1726  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1727  for (y = 0; y < avctx->height; y++) {
1728  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1729  memset(s->ham_buf, 0, s->planesize * 8);
1730  for (plane = 0; plane < s->bpp; plane++) {
1731  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1732  if (start >= buf_end)
1733  break;
1734  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1735  }
1736  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1737  }
1738  } else {
1739  return unsupported(avctx);
1740  }
1741  } else {
1742  return unsupported(avctx);
1743  }
1744  break;
1745  case 0x2:
1746  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1747  for (plane = 0; plane < s->bpp; plane++) {
1748  decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1749  for (y = 0; y < avctx->height; y++) {
1750  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1751  decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1752  }
1753  }
1754  } else {
1755  return unsupported(avctx);
1756  }
1757  break;
1758  case 0x4:
1759  if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1760  decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1761  else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1762  decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1763  else
1764  return unsupported(avctx);
1765  break;
1766  case 0x5:
1767  if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1768  if (av_get_bits_per_pixel(desc) == 32)
1769  decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1770  else
1771  return unsupported(avctx);
1772  } else
1773  return unsupported(avctx);
1774  break;
1775  case 0x300:
1776  case 0x301:
1777  decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1778  break;
1779  case 0x500:
1780  case 0x501:
1781  decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1782  break;
1783  case 0x700:
1784  case 0x701:
1785  if (s->is_short)
1786  decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1787  else
1788  decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1789  break;
1790  case 0x800:
1791  case 0x801:
1792  if (s->is_short)
1793  decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1794  else
1795  decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1796  break;
1797  case 0x4a00:
1798  case 0x4a01:
1799  decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1800  break;
1801  case 0x6400:
1802  case 0x6401:
1803  if (s->is_interlaced)
1804  return unsupported(avctx);
1805  decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1806  break;
1807  case 0x6500:
1808  case 0x6501:
1809  if (s->is_interlaced)
1810  return unsupported(avctx);
1811  decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1812  break;
1813  case 0x6c00:
1814  case 0x6c01:
1815  decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1816  break;
1817  default:
1818  return unsupported(avctx);
1819  }
1820 
1821  if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1822  memcpy(s->video[1], s->video[0], s->video_size);
1823  }
1824 
1825  if (s->compression > 0xff) {
1826  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1827  buf = s->video[0];
1828  for (y = 0; y < avctx->height; y++) {
1829  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1830  memset(row, 0, avctx->width);
1831  for (plane = 0; plane < s->bpp; plane++) {
1832  decodeplane8(row, buf, s->planesize, plane);
1833  buf += s->planesize;
1834  }
1835  }
1836  memcpy(frame->data[1], s->pal, 256 * 4);
1837  } else if (s->ham) {
1838  int i, count = 1 << s->ham;
1839 
1840  buf = s->video[0];
1841  memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1842  for (i = 0; i < count; i++) {
1843  s->ham_palbuf[i*2+1] = s->pal[i];
1844  }
1845  for (i = 0; i < count; i++) {
1846  uint32_t tmp = i << (8 - s->ham);
1847  tmp |= tmp >> s->ham;
1848  s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1849  s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1850  s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1851  s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1852  s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1853  s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1854  }
1855  if (s->masking == MASK_HAS_MASK) {
1856  for (i = 0; i < 8 * (1 << s->ham); i++)
1857  s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1858  }
1859  for (y = 0; y < avctx->height; y++) {
1860  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1861  memset(s->ham_buf, 0, s->planesize * 8);
1862  for (plane = 0; plane < s->bpp; plane++) {
1863  decodeplane8(s->ham_buf, buf, s->planesize, plane);
1864  buf += s->planesize;
1865  }
1866  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1867  }
1868  } else {
1869  return unsupported(avctx);
1870  }
1871 
1872  if (!s->is_brush) {
1873  FFSWAP(uint8_t *, s->video[0], s->video[1]);
1874  }
1875  }
1876 
1877  if (avpkt->flags & AV_PKT_FLAG_KEY) {
1878  frame->key_frame = 1;
1879  frame->pict_type = AV_PICTURE_TYPE_I;
1880  } else {
1881  frame->key_frame = 0;
1882  frame->pict_type = AV_PICTURE_TYPE_P;
1883  }
1884 
1885  *got_frame = 1;
1886 
1887  return buf_size;
1888 }
1889 
1890 #if CONFIG_IFF_ILBM_DECODER
1892  .name = "iff",
1893  .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1894  .type = AVMEDIA_TYPE_VIDEO,
1895  .id = AV_CODEC_ID_IFF_ILBM,
1896  .priv_data_size = sizeof(IffContext),
1897  .init = decode_init,
1898  .close = decode_end,
1899  .decode = decode_frame,
1900  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1901  .capabilities = AV_CODEC_CAP_DR1,
1902 };
1903 #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:1379
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:3260
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:1182
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:1242
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:1434
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:1508
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:1324
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:1501
#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
static av_always_inline int bytestream2_size_p(PutByteContext *p)
Definition: bytestream.h:203
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