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  if (s->video_size && s->planesize * s->bpp * avctx->height > s->video_size)
326  return AVERROR_INVALIDDATA;
327 
328  av_freep(&s->ham_buf);
329  av_freep(&s->ham_palbuf);
330 
331  if (s->ham) {
332  int i, count = FFMIN(palette_size / 3, 1 << s->ham);
333  int ham_count;
334  const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
335 
337  if (!s->ham_buf)
338  return AVERROR(ENOMEM);
339 
340  ham_count = 8 * (1 << s->ham);
341  s->ham_palbuf = av_malloc((ham_count << !!(s->masking == MASK_HAS_MASK)) * sizeof (uint32_t) + AV_INPUT_BUFFER_PADDING_SIZE);
342  if (!s->ham_palbuf) {
343  av_freep(&s->ham_buf);
344  return AVERROR(ENOMEM);
345  }
346 
347  if (count) { // HAM with color palette attached
348  // prefill with black and palette and set HAM take direct value mask to zero
349  memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof (uint32_t));
350  for (i=0; i < count; i++) {
351  s->ham_palbuf[i*2+1] = 0xFF000000 | AV_RL24(palette + i*3);
352  }
353  count = 1 << s->ham;
354  } else { // HAM with grayscale color palette
355  count = 1 << s->ham;
356  for (i=0; i < count; i++) {
357  s->ham_palbuf[i*2] = 0xFF000000; // take direct color value from palette
358  s->ham_palbuf[i*2+1] = 0xFF000000 | av_le2ne32(gray2rgb((i * 255) >> s->ham));
359  }
360  }
361  for (i=0; i < count; i++) {
362  uint32_t tmp = i << (8 - s->ham);
363  tmp |= tmp >> s->ham;
364  s->ham_palbuf[(i+count)*2] = 0xFF00FFFF; // just modify blue color component
365  s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00; // just modify red color component
366  s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF; // just modify green color component
367  s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
368  s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
369  s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
370  }
371  if (s->masking == MASK_HAS_MASK) {
372  for (i = 0; i < ham_count; i++)
373  s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
374  }
375  }
376  }
377 
378  return 0;
379 }
380 
382 {
383  IffContext *s = avctx->priv_data;
384  av_freep(&s->planebuf);
385  av_freep(&s->ham_buf);
386  av_freep(&s->ham_palbuf);
387  av_freep(&s->mask_buf);
388  av_freep(&s->mask_palbuf);
389  av_freep(&s->video[0]);
390  av_freep(&s->video[1]);
391  av_freep(&s->pal);
392  return 0;
393 }
394 
396 {
397  IffContext *s = avctx->priv_data;
398  int err;
399 
400  if (avctx->bits_per_coded_sample <= 8) {
401  int palette_size;
402 
403  if (avctx->extradata_size >= 2)
404  palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
405  else
406  palette_size = 0;
407  avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) ||
408  (avctx->extradata_size >= 2 && palette_size) ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
409  } else if (avctx->bits_per_coded_sample <= 32) {
410  if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) {
411  avctx->pix_fmt = AV_PIX_FMT_RGB32;
412  } else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) {
413  avctx->pix_fmt = AV_PIX_FMT_RGB444;
414  } else if (avctx->codec_tag != MKTAG('D', 'E', 'E', 'P')) {
415  if (avctx->bits_per_coded_sample == 24) {
416  avctx->pix_fmt = AV_PIX_FMT_0BGR32;
417  } else if (avctx->bits_per_coded_sample == 32) {
418  avctx->pix_fmt = AV_PIX_FMT_BGR32;
419  } else {
420  avpriv_request_sample(avctx, "unknown bits_per_coded_sample");
421  return AVERROR_PATCHWELCOME;
422  }
423  }
424  } else {
425  return AVERROR_INVALIDDATA;
426  }
427 
428  if ((err = av_image_check_size(avctx->width, avctx->height, 0, avctx)))
429  return err;
430  s->planesize = FFALIGN(avctx->width, 16) >> 3; // Align plane size in bits to word-boundary
432  if (!s->planebuf)
433  return AVERROR(ENOMEM);
434 
435  s->bpp = avctx->bits_per_coded_sample;
436 
437  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
438  s->video_size = FFALIGN(avctx->width, 2) * avctx->height * s->bpp;
439  s->video[0] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
440  s->video[1] = av_calloc(FFALIGN(avctx->width, 2) * avctx->height, s->bpp);
441  s->pal = av_calloc(256, sizeof(*s->pal));
442  if (!s->video[0] || !s->video[1] || !s->pal)
443  return AVERROR(ENOMEM);
444  }
445 
446  if ((err = extract_header(avctx, NULL)) < 0)
447  return err;
448 
449  return 0;
450 }
451 
452 /**
453  * Decode interleaved plane buffer up to 8bpp
454  * @param dst Destination buffer
455  * @param buf Source buffer
456  * @param buf_size
457  * @param plane plane number to decode as
458  */
459 static void decodeplane8(uint8_t *dst, const uint8_t *buf, int buf_size, int plane)
460 {
461  const uint64_t *lut;
462  if (plane >= 8) {
463  av_log(NULL, AV_LOG_WARNING, "Ignoring extra planes beyond 8\n");
464  return;
465  }
466  lut = plane8_lut[plane];
467  do {
468  uint64_t v = AV_RN64A(dst) | lut[*buf++];
469  AV_WN64A(dst, v);
470  dst += 8;
471  } while (--buf_size);
472 }
473 
474 /**
475  * Decode interleaved plane buffer up to 24bpp
476  * @param dst Destination buffer
477  * @param buf Source buffer
478  * @param buf_size
479  * @param plane plane number to decode as
480  */
481 static void decodeplane32(uint32_t *dst, const uint8_t *buf, int buf_size, int plane)
482 {
483  const uint32_t *lut = plane32_lut[plane];
484  do {
485  unsigned mask = (*buf >> 2) & ~3;
486  dst[0] |= lut[mask++];
487  dst[1] |= lut[mask++];
488  dst[2] |= lut[mask++];
489  dst[3] |= lut[mask];
490  mask = (*buf++ << 2) & 0x3F;
491  dst[4] |= lut[mask++];
492  dst[5] |= lut[mask++];
493  dst[6] |= lut[mask++];
494  dst[7] |= lut[mask];
495  dst += 8;
496  } while (--buf_size);
497 }
498 
499 #define DECODE_HAM_PLANE32(x) \
500  first = buf[x] << 1; \
501  second = buf[(x)+1] << 1; \
502  delta &= pal[first++]; \
503  delta |= pal[first]; \
504  dst[x] = delta; \
505  delta &= pal[second++]; \
506  delta |= pal[second]; \
507  dst[(x)+1] = delta
508 
509 /**
510  * Converts one line of HAM6/8-encoded chunky buffer to 24bpp.
511  *
512  * @param dst the destination 24bpp buffer
513  * @param buf the source 8bpp chunky buffer
514  * @param pal the HAM decode table
515  * @param buf_size the plane size in bytes
516  */
517 static void decode_ham_plane32(uint32_t *dst, const uint8_t *buf,
518  const uint32_t *const pal, unsigned buf_size)
519 {
520  uint32_t delta = pal[1]; /* first palette entry */
521  do {
522  uint32_t first, second;
527  buf += 8;
528  dst += 8;
529  } while (--buf_size);
530 }
531 
532 static void lookup_pal_indicies(uint32_t *dst, const uint32_t *buf,
533  const uint32_t *const pal, unsigned width)
534 {
535  do {
536  *dst++ = pal[*buf++];
537  } while (--width);
538 }
539 
540 /**
541  * Decode one complete byterun1 encoded line.
542  *
543  * @param dst the destination buffer where to store decompressed bitstream
544  * @param dst_size the destination plane size in bytes
545  * @param buf the source byterun1 compressed bitstream
546  * @param buf_end the EOF of source byterun1 compressed bitstream
547  * @return number of consumed bytes in byterun1 compressed bitstream
548  */
549 static int decode_byterun(uint8_t *dst, int dst_size,
551 {
552  unsigned x;
553  for (x = 0; x < dst_size && bytestream2_get_bytes_left(gb) > 0;) {
554  unsigned length;
555  const int8_t value = bytestream2_get_byte(gb);
556  if (value >= 0) {
557  length = FFMIN3(value + 1, dst_size - x, bytestream2_get_bytes_left(gb));
558  bytestream2_get_buffer(gb, dst + x, length);
559  if (length < value + 1)
560  bytestream2_skip(gb, value + 1 - length);
561  } else if (value > -128) {
562  length = FFMIN(-value + 1, dst_size - x);
563  memset(dst + x, bytestream2_get_byte(gb), length);
564  } else { // noop
565  continue;
566  }
567  x += length;
568  }
569  if (x < dst_size) {
570  av_log(NULL, AV_LOG_WARNING, "decode_byterun ended before plane size\n");
571  memset(dst+x, 0, dst_size - x);
572  }
573  return bytestream2_tell(gb);
574 }
575 
576 static int decode_byterun2(uint8_t *dst, int height, int line_size,
578 {
580  unsigned count;
581  int i, y_pos = 0, x_pos = 0;
582 
583  if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T'))
584  return 0;
585 
586  bytestream2_skip(gb, 4);
587  count = bytestream2_get_be16(gb) - 2;
588  if (bytestream2_get_bytes_left(gb) < count)
589  return 0;
590 
591  bytestream2_init(&cmds, gb->buffer, count);
592  bytestream2_skip(gb, count);
593 
594  for (i = 0; i < count && x_pos < line_size; i++) {
595  int8_t cmd = bytestream2_get_byte(&cmds);
596  int l, r;
597 
598  if (cmd == 0) {
599  l = bytestream2_get_be16(gb);
600  while (l-- > 0 && x_pos < line_size) {
601  dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
602  dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
603  if (y_pos >= height) {
604  y_pos = 0;
605  x_pos += 2;
606  }
607  }
608  } else if (cmd < 0) {
609  l = -cmd;
610  while (l-- > 0 && x_pos < line_size) {
611  dst[x_pos + y_pos * line_size ] = bytestream2_get_byte(gb);
612  dst[x_pos + y_pos++ * line_size + 1] = bytestream2_get_byte(gb);
613  if (y_pos >= height) {
614  y_pos = 0;
615  x_pos += 2;
616  }
617  }
618  } else if (cmd == 1) {
619  l = bytestream2_get_be16(gb);
620  r = bytestream2_get_be16(gb);
621  while (l-- > 0 && x_pos < line_size) {
622  dst[x_pos + y_pos * line_size ] = r >> 8;
623  dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
624  if (y_pos >= height) {
625  y_pos = 0;
626  x_pos += 2;
627  }
628  }
629  } else {
630  l = cmd;
631  r = bytestream2_get_be16(gb);
632  while (l-- > 0 && x_pos < line_size) {
633  dst[x_pos + y_pos * line_size ] = r >> 8;
634  dst[x_pos + y_pos++ * line_size + 1] = r & 0xFF;
635  if (y_pos >= height) {
636  y_pos = 0;
637  x_pos += 2;
638  }
639  }
640  }
641  }
642 
643  return bytestream2_tell(gb);
644 }
645 
646 #define DECODE_RGBX_COMMON(type) \
647  if (!length) { \
648  length = bytestream2_get_byte(gb); \
649  if (!length) { \
650  length = bytestream2_get_be16(gb); \
651  if (!length) \
652  return; \
653  } \
654  } \
655  for (i = 0; i < length; i++) { \
656  *(type *)(dst + y*linesize + x * sizeof(type)) = pixel; \
657  x += 1; \
658  if (x >= width) { \
659  y += 1; \
660  if (y >= height) \
661  return; \
662  x = 0; \
663  } \
664  }
665 
666 /**
667  * Decode RGB8 buffer
668  * @param[out] dst Destination buffer
669  * @param width Width of destination buffer (pixels)
670  * @param height Height of destination buffer (pixels)
671  * @param linesize Line size of destination buffer (bytes)
672  */
673 static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
674 {
675  int x = 0, y = 0, i, length;
676  while (bytestream2_get_bytes_left(gb) >= 4) {
677  uint32_t pixel = 0xFF000000 | bytestream2_get_be24(gb);
678  length = bytestream2_get_byte(gb) & 0x7F;
679  DECODE_RGBX_COMMON(uint32_t)
680  }
681 }
682 
683 /**
684  * Decode RGBN buffer
685  * @param[out] dst Destination buffer
686  * @param width Width of destination buffer (pixels)
687  * @param height Height of destination buffer (pixels)
688  * @param linesize Line size of destination buffer (bytes)
689  */
690 static void decode_rgbn(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
691 {
692  int x = 0, y = 0, i, length;
693  while (bytestream2_get_bytes_left(gb) >= 2) {
694  uint32_t pixel = bytestream2_get_be16u(gb);
695  length = pixel & 0x7;
696  pixel >>= 4;
697  DECODE_RGBX_COMMON(uint16_t)
698  }
699 }
700 
701 /**
702  * Decode DEEP RLE 32-bit buffer
703  * @param[out] dst Destination buffer
704  * @param[in] src Source buffer
705  * @param src_size Source buffer size (bytes)
706  * @param width Width of destination buffer (pixels)
707  * @param height Height of destination buffer (pixels)
708  * @param linesize Line size of destination buffer (bytes)
709  */
710 static void decode_deep_rle32(uint8_t *dst, const uint8_t *src, int src_size, int width, int height, int linesize)
711 {
712  const uint8_t *src_end = src + src_size;
713  int x = 0, y = 0, i;
714  while (src + 5 <= src_end) {
715  int opcode;
716  opcode = *(int8_t *)src++;
717  if (opcode >= 0) {
718  int size = opcode + 1;
719  for (i = 0; i < size; i++) {
720  int length = FFMIN(size - i, width);
721  memcpy(dst + y*linesize + x * 4, src, length * 4);
722  src += length * 4;
723  x += length;
724  i += length;
725  if (x >= width) {
726  x = 0;
727  y += 1;
728  if (y >= height)
729  return;
730  }
731  }
732  } else {
733  int size = -opcode + 1;
734  uint32_t pixel = AV_RN32(src);
735  for (i = 0; i < size; i++) {
736  *(uint32_t *)(dst + y*linesize + x * 4) = pixel;
737  x += 1;
738  if (x >= width) {
739  x = 0;
740  y += 1;
741  if (y >= height)
742  return;
743  }
744  }
745  src += 4;
746  }
747  }
748 }
749 
750 /**
751  * Decode DEEP TVDC 32-bit buffer
752  * @param[out] dst Destination buffer
753  * @param[in] src Source buffer
754  * @param src_size Source buffer size (bytes)
755  * @param width Width of destination buffer (pixels)
756  * @param height Height of destination buffer (pixels)
757  * @param linesize Line size of destination buffer (bytes)
758  * @param[int] tvdc TVDC lookup table
759  */
760 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)
761 {
762  int x = 0, y = 0, plane = 0;
763  int8_t pixel = 0;
764  int i, j;
765 
766  for (i = 0; i < src_size * 2;) {
767 #define GETNIBBLE ((i & 1) ? (src[i>>1] & 0xF) : (src[i>>1] >> 4))
768  int d = tvdc[GETNIBBLE];
769  i++;
770  if (d) {
771  pixel += d;
772  dst[y * linesize + x*4 + plane] = pixel;
773  x++;
774  } else {
775  if (i >= src_size * 2)
776  return;
777  d = GETNIBBLE + 1;
778  i++;
779  d = FFMIN(d, width - x);
780  for (j = 0; j < d; j++) {
781  dst[y * linesize + x*4 + plane] = pixel;
782  x++;
783  }
784  }
785  if (x >= width) {
786  plane++;
787  if (plane >= 4) {
788  y++;
789  if (y >= height)
790  return;
791  plane = 0;
792  }
793  x = 0;
794  pixel = 0;
795  i = (i + 1) & ~1;
796  }
797  }
798 }
799 
801  const uint8_t *buf, const uint8_t *buf_end,
802  int w, int bpp, int dst_size)
803 {
804  int planepitch = FFALIGN(w, 16) >> 3;
805  int pitch = planepitch * bpp;
806  GetByteContext ptrs, gb;
807  PutByteContext pb;
808  unsigned ofssrc, pos;
809  int i, k;
810 
811  bytestream2_init(&ptrs, buf, buf_end - buf);
812  bytestream2_init_writer(&pb, dst, dst_size);
813 
814  for (k = 0; k < bpp; k++) {
815  ofssrc = bytestream2_get_be32(&ptrs);
816  pos = 0;
817 
818  if (!ofssrc)
819  continue;
820 
821  if (ofssrc >= buf_end - buf)
822  continue;
823 
824  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
825  while (bytestream2_peek_be16(&gb) != 0xFFFF && bytestream2_get_bytes_left(&gb) > 3) {
826  int16_t offset = bytestream2_get_be16(&gb);
827  unsigned noffset;
828 
829  if (offset >= 0) {
830  unsigned data = bytestream2_get_be16(&gb);
831 
832  pos += offset * 2;
833  noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
834  bytestream2_seek_p(&pb, noffset, SEEK_SET);
835  bytestream2_put_be16(&pb, data);
836  } else {
837  uint16_t count = bytestream2_get_be16(&gb);
838 
839  pos += 2 * -(offset + 2);
840  for (i = 0; i < count; i++) {
841  uint16_t data = bytestream2_get_be16(&gb);
842 
843  pos += 2;
844  noffset = (pos / planepitch) * pitch + (pos % planepitch) + k * planepitch;
845  bytestream2_seek_p(&pb, noffset, SEEK_SET);
846  bytestream2_put_be16(&pb, data);
847  }
848  }
849  }
850  }
851 }
852 
854  const uint8_t *buf, const uint8_t *buf_end,
855  int w, int xor, int bpp, int dst_size)
856 {
857  int ncolumns = ((w + 15) / 16) * 2;
858  int dstpitch = ncolumns * bpp;
859  unsigned ofsdst, ofssrc, opcode, x;
860  GetByteContext ptrs, gb;
861  PutByteContext pb;
862  int i, j, k;
863 
864  bytestream2_init(&ptrs, buf, buf_end - buf);
865  bytestream2_init_writer(&pb, dst, dst_size);
866 
867  for (k = 0; k < bpp; k++) {
868  ofssrc = bytestream2_get_be32(&ptrs);
869 
870  if (!ofssrc)
871  continue;
872 
873  if (ofssrc >= buf_end - buf)
874  continue;
875 
876  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
877  for (j = 0; j < ncolumns; j++) {
878  ofsdst = j + k * ncolumns;
879 
880  i = bytestream2_get_byte(&gb);
881  while (i > 0) {
882  opcode = bytestream2_get_byte(&gb);
883 
884  if (opcode == 0) {
885  opcode = bytestream2_get_byte(&gb);
886  x = bytestream2_get_byte(&gb);
887 
888  while (opcode) {
889  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
890  if (xor && ofsdst < dst_size) {
891  bytestream2_put_byte(&pb, dst[ofsdst] ^ x);
892  } else {
893  bytestream2_put_byte(&pb, x);
894  }
895  ofsdst += dstpitch;
896  opcode--;
897  }
898  } else if (opcode < 0x80) {
899  ofsdst += opcode * dstpitch;
900  } else {
901  opcode &= 0x7f;
902 
903  while (opcode) {
904  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
905  if (xor && ofsdst < dst_size) {
906  bytestream2_put_byte(&pb, dst[ofsdst] ^ bytestream2_get_byte(&gb));
907  } else {
908  bytestream2_put_byte(&pb, bytestream2_get_byte(&gb));
909  }
910  ofsdst += dstpitch;
911  opcode--;
912  }
913  }
914  i--;
915  }
916  }
917  }
918 }
919 
920 static void decode_delta_j(uint8_t *dst,
921  const uint8_t *buf, const uint8_t *buf_end,
922  int w, int h, int bpp, int dst_size)
923 {
924  int32_t pitch;
925  uint8_t *ptr;
926  uint32_t type, flag, cols, groups, rows, bytes;
927  uint32_t offset;
928  int planepitch_byte = (w + 7) / 8;
929  int planepitch = ((w + 15) / 16) * 2;
930  int kludge_j, b, g, r, d;
932 
933  pitch = planepitch * bpp;
934  kludge_j = w < 320 ? (320 - w) / 8 / 2 : 0;
935 
936  bytestream2_init(&gb, buf, buf_end - buf);
937 
938  while (bytestream2_get_bytes_left(&gb) >= 2) {
939  type = bytestream2_get_be16(&gb);
940 
941  switch (type) {
942  case 0:
943  return;
944  case 1:
945  flag = bytestream2_get_be16(&gb);
946  cols = bytestream2_get_be16(&gb);
947  groups = bytestream2_get_be16(&gb);
948 
949  for (g = 0; g < groups; g++) {
950  offset = bytestream2_get_be16(&gb);
951 
952  if (cols * bpp == 0 || bytestream2_get_bytes_left(&gb) < cols * bpp) {
953  av_log(NULL, AV_LOG_ERROR, "cols*bpp is invalid (%"PRId32"*%d)", cols, bpp);
954  return;
955  }
956 
957  if (kludge_j)
958  offset = ((offset / (320 / 8)) * pitch) + (offset % (320 / 8)) - kludge_j;
959  else
960  offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
961 
962  for (b = 0; b < cols; b++) {
963  for (d = 0; d < bpp; d++) {
964  uint8_t value = bytestream2_get_byte(&gb);
965 
966  if (offset >= dst_size)
967  return;
968  ptr = dst + offset;
969 
970  if (flag)
971  ptr[0] ^= value;
972  else
973  ptr[0] = value;
974 
975  offset += planepitch;
976  }
977  }
978  if ((cols * bpp) & 1)
979  bytestream2_skip(&gb, 1);
980  }
981  break;
982  case 2:
983  flag = bytestream2_get_be16(&gb);
984  rows = bytestream2_get_be16(&gb);
985  bytes = bytestream2_get_be16(&gb);
986  groups = bytestream2_get_be16(&gb);
987 
988  for (g = 0; g < groups; g++) {
989  offset = bytestream2_get_be16(&gb);
990 
991  if (kludge_j)
992  offset = ((offset / (320 / 8)) * pitch) + (offset % (320/ 8)) - kludge_j;
993  else
994  offset = ((offset / planepitch_byte) * pitch) + (offset % planepitch_byte);
995 
996  for (r = 0; r < rows; r++) {
997  for (d = 0; d < bpp; d++) {
998  unsigned noffset = offset + (r * pitch) + d * planepitch;
999 
1000  if (!bytes || bytestream2_get_bytes_left(&gb) < bytes) {
1001  av_log(NULL, AV_LOG_ERROR, "bytes %"PRId32" is invalid", bytes);
1002  return;
1003  }
1004 
1005  for (b = 0; b < bytes; b++) {
1006  uint8_t value = bytestream2_get_byte(&gb);
1007 
1008  if (noffset >= dst_size)
1009  return;
1010  ptr = dst + noffset;
1011 
1012  if (flag)
1013  ptr[0] ^= value;
1014  else
1015  ptr[0] = value;
1016 
1017  noffset++;
1018  }
1019  }
1020  }
1021  if ((rows * bytes * bpp) & 1)
1022  bytestream2_skip(&gb, 1);
1023  }
1024  break;
1025  default:
1026  return;
1027  }
1028  }
1029 }
1030 
1032  const uint8_t *buf, const uint8_t *buf_end,
1033  int w, int bpp, int dst_size)
1034 {
1035  int ncolumns = (w + 15) >> 4;
1036  int dstpitch = ncolumns * bpp * 2;
1037  unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1038  GetByteContext ptrs, gb, dptrs, dgb;
1039  PutByteContext pb;
1040  int i, j, k;
1041 
1042  if (buf_end - buf <= 64)
1043  return;
1044 
1045  bytestream2_init(&ptrs, buf, buf_end - buf);
1046  bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1047  bytestream2_init_writer(&pb, dst, dst_size);
1048 
1049  for (k = 0; k < bpp; k++) {
1050  ofssrc = bytestream2_get_be32(&ptrs);
1051  ofsdata = bytestream2_get_be32(&dptrs);
1052 
1053  if (!ofssrc)
1054  continue;
1055 
1056  if (ofssrc >= buf_end - buf)
1057  return;
1058 
1059  if (ofsdata >= buf_end - buf)
1060  return;
1061 
1062  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1063  bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1064  for (j = 0; j < ncolumns; j++) {
1065  ofsdst = (j + k * ncolumns) * 2;
1066 
1067  i = bytestream2_get_byte(&gb);
1068  while (i > 0) {
1069  opcode = bytestream2_get_byte(&gb);
1070 
1071  if (opcode == 0) {
1072  opcode = bytestream2_get_byte(&gb);
1073  x = bytestream2_get_be16(&dgb);
1074 
1075  while (opcode) {
1076  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1077  bytestream2_put_be16(&pb, x);
1078  ofsdst += dstpitch;
1079  opcode--;
1080  }
1081  } else if (opcode < 0x80) {
1082  ofsdst += opcode * dstpitch;
1083  } else {
1084  opcode &= 0x7f;
1085 
1086  while (opcode) {
1087  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1088  bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1089  ofsdst += dstpitch;
1090  opcode--;
1091  }
1092  }
1093  i--;
1094  }
1095  }
1096  }
1097 }
1098 
1100  const uint8_t *buf, const uint8_t *buf_end,
1101  int w, int bpp, int dst_size)
1102 {
1103  int ncolumns = (w + 31) >> 5;
1104  int dstpitch = ((w + 15) / 16 * 2) * bpp;
1105  unsigned ofsdst, ofssrc, ofsdata, opcode, x;
1106  GetByteContext ptrs, gb, dptrs, dgb;
1107  PutByteContext pb;
1108  int i, j, k, h;
1109 
1110  if (buf_end - buf <= 64)
1111  return;
1112 
1113  h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1114  bytestream2_init(&ptrs, buf, buf_end - buf);
1115  bytestream2_init(&dptrs, buf + 32, (buf_end - buf) - 32);
1116  bytestream2_init_writer(&pb, dst, dst_size);
1117 
1118  for (k = 0; k < bpp; k++) {
1119  ofssrc = bytestream2_get_be32(&ptrs);
1120  ofsdata = bytestream2_get_be32(&dptrs);
1121 
1122  if (!ofssrc)
1123  continue;
1124 
1125  if (ofssrc >= buf_end - buf)
1126  return;
1127 
1128  if (ofsdata >= buf_end - buf)
1129  return;
1130 
1131  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1132  bytestream2_init(&dgb, buf + ofsdata, buf_end - (buf + ofsdata));
1133  for (j = 0; j < ncolumns; j++) {
1134  ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1135 
1136  i = bytestream2_get_byte(&gb);
1137  while (i > 0) {
1138  opcode = bytestream2_get_byte(&gb);
1139 
1140  if (opcode == 0) {
1141  opcode = bytestream2_get_byte(&gb);
1142  if (h && (j == (ncolumns - 1))) {
1143  x = bytestream2_get_be16(&dgb);
1144  bytestream2_skip(&dgb, 2);
1145  } else {
1146  x = bytestream2_get_be32(&dgb);
1147  }
1148 
1149  if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1150  return;
1151 
1152  while (opcode) {
1153  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1154  if (h && (j == (ncolumns - 1))) {
1155  bytestream2_put_be16(&pb, x);
1156  } else {
1157  bytestream2_put_be32(&pb, x);
1158  }
1159  ofsdst += dstpitch;
1160  opcode--;
1161  }
1162  } else if (opcode < 0x80) {
1163  ofsdst += opcode * dstpitch;
1164  } else {
1165  opcode &= 0x7f;
1166 
1167  while (opcode) {
1168  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1169  if (h && (j == (ncolumns - 1))) {
1170  bytestream2_put_be16(&pb, bytestream2_get_be16(&dgb));
1171  bytestream2_skip(&dgb, 2);
1172  } else {
1173  bytestream2_put_be32(&pb, bytestream2_get_be32(&dgb));
1174  }
1175  ofsdst += dstpitch;
1176  opcode--;
1177  }
1178  }
1179  i--;
1180  }
1181  }
1182  }
1183 }
1184 
1186  const uint8_t *buf, const uint8_t *buf_end,
1187  int w, int bpp, int dst_size)
1188 {
1189  int ncolumns = (w + 15) >> 4;
1190  int dstpitch = ncolumns * bpp * 2;
1191  unsigned ofsdst, ofssrc, opcode, x;
1192  GetByteContext ptrs, gb;
1193  PutByteContext pb;
1194  int i, j, k;
1195 
1196  bytestream2_init(&ptrs, buf, buf_end - buf);
1197  bytestream2_init_writer(&pb, dst, dst_size);
1198 
1199  for (k = 0; k < bpp; k++) {
1200  ofssrc = bytestream2_get_be32(&ptrs);
1201 
1202  if (!ofssrc)
1203  continue;
1204 
1205  if (ofssrc >= buf_end - buf)
1206  continue;
1207 
1208  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1209  for (j = 0; j < ncolumns; j++) {
1210  ofsdst = (j + k * ncolumns) * 2;
1211 
1212  i = bytestream2_get_be16(&gb);
1213  while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1214  opcode = bytestream2_get_be16(&gb);
1215 
1216  if (opcode == 0) {
1217  opcode = bytestream2_get_be16(&gb);
1218  x = bytestream2_get_be16(&gb);
1219 
1220  while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1221  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1222  bytestream2_put_be16(&pb, x);
1223  ofsdst += dstpitch;
1224  opcode--;
1225  }
1226  } else if (opcode < 0x8000) {
1227  ofsdst += opcode * dstpitch;
1228  } else {
1229  opcode &= 0x7fff;
1230 
1231  while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1232  bytestream2_get_bytes_left_p(&pb) > 1) {
1233  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1234  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1235  ofsdst += dstpitch;
1236  opcode--;
1237  }
1238  }
1239  i--;
1240  }
1241  }
1242  }
1243 }
1244 
1246  const uint8_t *buf, const uint8_t *buf_end,
1247  int w, int bpp, int dst_size)
1248 {
1249  int ncolumns = (w + 31) >> 5;
1250  int dstpitch = ((w + 15) / 16 * 2) * bpp;
1251  unsigned ofsdst, ofssrc, opcode, x;
1252  unsigned skip = 0x80000000, mask = skip - 1;
1253  GetByteContext ptrs, gb;
1254  PutByteContext pb;
1255  int i, j, k, h;
1256 
1257  h = (((w + 15) / 16 * 2) != ((w + 31) / 32 * 4)) ? 1 : 0;
1258  bytestream2_init(&ptrs, buf, buf_end - buf);
1259  bytestream2_init_writer(&pb, dst, dst_size);
1260 
1261  for (k = 0; k < bpp; k++) {
1262  ofssrc = bytestream2_get_be32(&ptrs);
1263 
1264  if (!ofssrc)
1265  continue;
1266 
1267  if (ofssrc >= buf_end - buf)
1268  continue;
1269 
1270  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1271  for (j = 0; j < ncolumns; j++) {
1272  ofsdst = (j + k * ncolumns) * 4 - h * (2 * k);
1273 
1274  if (h && (j == (ncolumns - 1))) {
1275  skip = 0x8000;
1276  mask = skip - 1;
1277  }
1278 
1279  i = bytestream2_get_be32(&gb);
1280  while (i > 0 && bytestream2_get_bytes_left(&gb) > 4) {
1281  opcode = bytestream2_get_be32(&gb);
1282 
1283  if (opcode == 0) {
1284  if (h && (j == ncolumns - 1)) {
1285  opcode = bytestream2_get_be16(&gb);
1286  x = bytestream2_get_be16(&gb);
1287  } else {
1288  opcode = bytestream2_get_be32(&gb);
1289  x = bytestream2_get_be32(&gb);
1290  }
1291 
1292  if (ofsdst + (opcode - 1LL) * dstpitch > bytestream2_size_p(&pb))
1293  return;
1294 
1295  while (opcode && bytestream2_get_bytes_left_p(&pb) > 1) {
1296  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1297  if (h && (j == ncolumns - 1))
1298  bytestream2_put_be16(&pb, x);
1299  else
1300  bytestream2_put_be32(&pb, x);
1301  ofsdst += dstpitch;
1302  opcode--;
1303  }
1304  } else if (opcode < skip) {
1305  ofsdst += opcode * dstpitch;
1306  } else {
1307  opcode &= mask;
1308 
1309  while (opcode && bytestream2_get_bytes_left(&gb) > 1 &&
1310  bytestream2_get_bytes_left_p(&pb) > 1) {
1311  bytestream2_seek_p(&pb, ofsdst, SEEK_SET);
1312  if (h && (j == ncolumns - 1)) {
1313  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1314  } else {
1315  bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1316  }
1317  ofsdst += dstpitch;
1318  opcode--;
1319  }
1320  }
1321  i--;
1322  }
1323  }
1324  }
1325 }
1326 
1327 static void decode_delta_d(uint8_t *dst,
1328  const uint8_t *buf, const uint8_t *buf_end,
1329  int w, int flag, int bpp, int dst_size)
1330 {
1331  int planepitch = FFALIGN(w, 16) >> 3;
1332  int pitch = planepitch * bpp;
1333  int planepitch_byte = (w + 7) / 8;
1334  unsigned entries, ofssrc;
1335  GetByteContext gb, ptrs;
1336  PutByteContext pb;
1337  int k;
1338 
1339  if (buf_end - buf <= 4 * bpp)
1340  return;
1341 
1342  bytestream2_init_writer(&pb, dst, dst_size);
1343  bytestream2_init(&ptrs, buf, bpp * 4);
1344 
1345  for (k = 0; k < bpp; k++) {
1346  ofssrc = bytestream2_get_be32(&ptrs);
1347 
1348  if (!ofssrc)
1349  continue;
1350 
1351  if (ofssrc >= buf_end - buf)
1352  continue;
1353 
1354  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1355 
1356  entries = bytestream2_get_be32(&gb);
1357  if (entries * 8LL > bytestream2_get_bytes_left(&gb))
1358  return;
1359 
1360  while (entries && bytestream2_get_bytes_left(&gb) >= 8) {
1361  int32_t opcode = bytestream2_get_be32(&gb);
1362  unsigned offset = bytestream2_get_be32(&gb);
1363 
1364  bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1365  if (opcode >= 0) {
1366  uint32_t x = bytestream2_get_be32(&gb);
1367  if (opcode && 4 + (opcode - 1LL) * pitch > bytestream2_get_bytes_left_p(&pb))
1368  continue;
1369  while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1370  bytestream2_put_be32(&pb, x);
1371  bytestream2_skip_p(&pb, pitch - 4);
1372  opcode--;
1373  }
1374  } else {
1375  opcode = -opcode;
1376  while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1377  bytestream2_put_be32(&pb, bytestream2_get_be32(&gb));
1378  bytestream2_skip_p(&pb, pitch - 4);
1379  opcode--;
1380  }
1381  }
1382  entries--;
1383  }
1384  }
1385 }
1386 
1387 static void decode_delta_e(uint8_t *dst,
1388  const uint8_t *buf, const uint8_t *buf_end,
1389  int w, int flag, int bpp, int dst_size)
1390 {
1391  int planepitch = FFALIGN(w, 16) >> 3;
1392  int pitch = planepitch * bpp;
1393  int planepitch_byte = (w + 7) / 8;
1394  unsigned entries, ofssrc;
1395  GetByteContext gb, ptrs;
1396  PutByteContext pb;
1397  int k;
1398 
1399  if (buf_end - buf <= 4 * bpp)
1400  return;
1401 
1402  bytestream2_init_writer(&pb, dst, dst_size);
1403  bytestream2_init(&ptrs, buf, bpp * 4);
1404 
1405  for (k = 0; k < bpp; k++) {
1406  ofssrc = bytestream2_get_be32(&ptrs);
1407 
1408  if (!ofssrc)
1409  continue;
1410 
1411  if (ofssrc >= buf_end - buf)
1412  continue;
1413 
1414  bytestream2_init(&gb, buf + ofssrc, buf_end - (buf + ofssrc));
1415 
1416  entries = bytestream2_get_be16(&gb);
1417  while (entries && bytestream2_get_bytes_left(&gb) >= 6) {
1418  int16_t opcode = bytestream2_get_be16(&gb);
1419  unsigned offset = bytestream2_get_be32(&gb);
1420 
1421  bytestream2_seek_p(&pb, (offset / planepitch_byte) * pitch + (offset % planepitch_byte) + k * planepitch, SEEK_SET);
1422  if (opcode >= 0) {
1423  uint16_t x = bytestream2_get_be16(&gb);
1424  while (opcode && bytestream2_get_bytes_left_p(&pb) > 0) {
1425  bytestream2_put_be16(&pb, x);
1426  bytestream2_skip_p(&pb, pitch - 2);
1427  opcode--;
1428  }
1429  } else {
1430  opcode = -opcode;
1431  while (opcode && bytestream2_get_bytes_left(&gb) > 0) {
1432  bytestream2_put_be16(&pb, bytestream2_get_be16(&gb));
1433  bytestream2_skip_p(&pb, pitch - 2);
1434  opcode--;
1435  }
1436  }
1437  entries--;
1438  }
1439  }
1440 }
1441 
1442 static void decode_delta_l(uint8_t *dst,
1443  const uint8_t *buf, const uint8_t *buf_end,
1444  int w, int flag, int bpp, int dst_size)
1445 {
1446  GetByteContext off0, off1, dgb, ogb;
1447  PutByteContext pb;
1448  unsigned poff0, poff1;
1449  int i, k, dstpitch;
1450  int planepitch_byte = (w + 7) / 8;
1451  int planepitch = ((w + 15) / 16) * 2;
1452  int pitch = planepitch * bpp;
1453 
1454  if (buf_end - buf <= 64)
1455  return;
1456 
1457  bytestream2_init(&off0, buf, buf_end - buf);
1458  bytestream2_init(&off1, buf + 32, buf_end - (buf + 32));
1459  bytestream2_init_writer(&pb, dst, dst_size);
1460 
1461  dstpitch = flag ? (((w + 7) / 8) * bpp): 2;
1462 
1463  for (k = 0; k < bpp; k++) {
1464  poff0 = bytestream2_get_be32(&off0);
1465  poff1 = bytestream2_get_be32(&off1);
1466 
1467  if (!poff0)
1468  continue;
1469 
1470  if (2LL * poff0 >= buf_end - buf)
1471  return;
1472 
1473  if (2LL * poff1 >= buf_end - buf)
1474  return;
1475 
1476  bytestream2_init(&dgb, buf + 2 * poff0, buf_end - (buf + 2 * poff0));
1477  bytestream2_init(&ogb, buf + 2 * poff1, buf_end - (buf + 2 * poff1));
1478 
1479  while (bytestream2_peek_be16(&ogb) != 0xFFFF && bytestream2_get_bytes_left(&ogb) >= 4) {
1480  uint32_t offset = bytestream2_get_be16(&ogb);
1481  int16_t cnt = bytestream2_get_be16(&ogb);
1482  uint16_t data;
1483 
1484  offset = ((2 * offset) / planepitch_byte) * pitch + ((2 * offset) % planepitch_byte) + k * planepitch;
1485  if (cnt < 0) {
1486  if (bytestream2_get_bytes_left(&dgb) < 2)
1487  break;
1488  bytestream2_seek_p(&pb, offset, SEEK_SET);
1489  cnt = -cnt;
1490  data = bytestream2_get_be16(&dgb);
1491  for (i = 0; i < cnt; i++) {
1492  bytestream2_put_be16(&pb, data);
1493  bytestream2_skip_p(&pb, dstpitch - 2);
1494  }
1495  } else {
1496  if (bytestream2_get_bytes_left(&dgb) < 2*cnt)
1497  break;
1498  bytestream2_seek_p(&pb, offset, SEEK_SET);
1499  for (i = 0; i < cnt; i++) {
1500  data = bytestream2_get_be16(&dgb);
1501  bytestream2_put_be16(&pb, data);
1502  bytestream2_skip_p(&pb, dstpitch - 2);
1503  }
1504  }
1505  }
1506  }
1507 }
1508 
1509 static int unsupported(AVCodecContext *avctx)
1510 {
1511  IffContext *s = avctx->priv_data;
1512  avpriv_request_sample(avctx, "bitmap (compression 0x%0x, bpp %i, ham %i, interlaced %i)", s->compression, s->bpp, s->ham, s->is_interlaced);
1513  return AVERROR_INVALIDDATA;
1514 }
1515 
1516 static int decode_frame(AVCodecContext *avctx,
1517  void *data, int *got_frame,
1518  AVPacket *avpkt)
1519 {
1520  IffContext *s = avctx->priv_data;
1521  AVFrame *frame = data;
1522  const uint8_t *buf = avpkt->data;
1523  int buf_size = avpkt->size;
1524  const uint8_t *buf_end = buf + buf_size;
1525  int y, plane, res;
1526  GetByteContext *gb = &s->gb;
1527  const AVPixFmtDescriptor *desc;
1528 
1529  bytestream2_init(gb, avpkt->data, avpkt->size);
1530 
1531  if ((res = extract_header(avctx, avpkt)) < 0)
1532  return res;
1533 
1534  if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1535  return res;
1536  s->frame = frame;
1537 
1538  buf += bytestream2_tell(gb);
1539  buf_size -= bytestream2_tell(gb);
1540  desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1541 
1542  if (!s->init && avctx->bits_per_coded_sample <= 8 - (s->masking == MASK_HAS_MASK) &&
1543  avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1544  if ((res = cmap_read_palette(avctx, (uint32_t *)frame->data[1])) < 0)
1545  return res;
1546  } else if (!s->init && avctx->bits_per_coded_sample <= 8 &&
1547  avctx->pix_fmt == AV_PIX_FMT_RGB32) {
1548  if ((res = cmap_read_palette(avctx, s->mask_palbuf)) < 0)
1549  return res;
1550  }
1551  s->init = 1;
1552 
1553  if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1554  if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
1555  memcpy(s->pal, s->frame->data[1], 256 * 4);
1556  }
1557 
1558  switch (s->compression) {
1559  case 0x0:
1560  if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1561  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1562  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1563  for (plane = 0; plane < s->bpp; plane++) {
1564  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1565  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1566  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1567  buf += s->planesize;
1568  }
1569  }
1570  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1571  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1572  for (y = 0; y < avctx->height; y++) {
1573  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1574  memset(s->ham_buf, 0, s->planesize * 8);
1575  for (plane = 0; plane < s->bpp; plane++) {
1576  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1577  if (start >= buf_end)
1578  break;
1579  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1580  }
1581  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1582  }
1583  } else
1584  return unsupported(avctx);
1585  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1586  int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3);
1587  int x;
1588  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1589  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1590  memcpy(row, buf, FFMIN(raw_width, buf_end - buf));
1591  buf += raw_width;
1592  if (avctx->pix_fmt == AV_PIX_FMT_BGR32) {
1593  for (x = 0; x < avctx->width; x++)
1594  row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);
1595  }
1596  }
1597  } else if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1598  avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1599  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))
1600  memcpy(s->video[0], buf, FFMIN(buf_end - buf, s->video_size));
1601  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1602  for (y = 0; y < avctx->height; y++) {
1603  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1604  memset(row, 0, avctx->width);
1605  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1606  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1607  buf += s->planesize;
1608  }
1609  }
1610  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1611  for (y = 0; y < avctx->height; y++) {
1612  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1613  memset(s->ham_buf, 0, s->planesize * 8);
1614  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1615  decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
1616  buf += s->planesize;
1617  }
1618  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1619  }
1620  } else { // AV_PIX_FMT_BGR32
1621  for (y = 0; y < avctx->height; y++) {
1622  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1623  memset(row, 0, avctx->width << 2);
1624  for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
1625  decodeplane32((uint32_t *)row, buf,
1626  FFMIN(s->planesize, buf_end - buf), plane);
1627  buf += s->planesize;
1628  }
1629  }
1630  }
1631  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1632  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1633  for (y = 0; y < avctx->height && buf_end > buf; y++) {
1634  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1635  memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));
1636  buf += avctx->width + (avctx->width % 2); // padding if odd
1637  }
1638  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1639  for (y = 0; y < avctx->height && buf_end > buf; y++) {
1640  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1641  memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));
1642  buf += avctx->width + (avctx->width & 1); // padding if odd
1643  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1644  }
1645  } else
1646  return unsupported(avctx);
1647  } else {
1648  return unsupported(avctx);
1649  }
1650  break;
1651  case 0x1:
1652  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') || // interleaved
1653  avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1654  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1655  uint8_t *video = s->video[0];
1656 
1657  for (y = 0; y < avctx->height; y++) {
1658  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1659  memset(row, 0, avctx->width);
1660  for (plane = 0; plane < s->bpp; plane++) {
1661  buf += decode_byterun(s->planebuf, s->planesize, gb);
1662  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1663  memcpy(video, s->planebuf, s->planesize);
1664  video += s->planesize;
1665  }
1666  decodeplane8(row, s->planebuf, s->planesize, plane);
1667  }
1668  }
1669  } else if (avctx->bits_per_coded_sample <= 8) { //8-bit (+ mask) to AV_PIX_FMT_BGR32
1670  for (y = 0; y < avctx->height; y++) {
1671  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1672  memset(s->mask_buf, 0, avctx->width * sizeof(uint32_t));
1673  for (plane = 0; plane < s->bpp; plane++) {
1674  buf += decode_byterun(s->planebuf, s->planesize, gb);
1675  decodeplane32(s->mask_buf, s->planebuf, s->planesize, plane);
1676  }
1677  lookup_pal_indicies((uint32_t *)row, s->mask_buf, s->mask_palbuf, avctx->width);
1678  }
1679  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1680  uint8_t *video = s->video[0];
1681  for (y = 0; y < avctx->height; y++) {
1682  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1683  memset(s->ham_buf, 0, s->planesize * 8);
1684  for (plane = 0; plane < s->bpp; plane++) {
1685  buf += decode_byterun(s->planebuf, s->planesize, gb);
1686  if (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M')) {
1687  memcpy(video, s->planebuf, s->planesize);
1688  video += s->planesize;
1689  }
1690  decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);
1691  }
1692  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1693  }
1694  } else { // AV_PIX_FMT_BGR32
1695  for (y = 0; y < avctx->height; y++) {
1696  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1697  memset(row, 0, avctx->width << 2);
1698  for (plane = 0; plane < s->bpp; plane++) {
1699  buf += decode_byterun(s->planebuf, s->planesize, gb);
1700  decodeplane32((uint32_t *)row, s->planebuf, s->planesize, plane);
1701  }
1702  }
1703  }
1704  } else if (avctx->codec_tag == MKTAG('P', 'B', 'M', ' ')) { // IFF-PBM
1705  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1706  for (y = 0; y < avctx->height; y++) {
1707  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1708  buf += decode_byterun(row, avctx->width, gb);
1709  }
1710  } else if (s->ham) { // IFF-PBM: HAM to AV_PIX_FMT_BGR32
1711  for (y = 0; y < avctx->height; y++) {
1712  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1713  buf += decode_byterun(s->ham_buf, avctx->width, gb);
1714  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1715  }
1716  } else
1717  return unsupported(avctx);
1718  } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP
1719  if (av_get_bits_per_pixel(desc) == 32)
1720  decode_deep_rle32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0]);
1721  else
1722  return unsupported(avctx);
1723  } else if (avctx->codec_tag == MKTAG('A', 'C', 'B', 'M')) {
1724  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1725  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1726  for (plane = 0; plane < s->bpp; plane++) {
1727  for (y = 0; y < avctx->height && buf < buf_end; y++) {
1728  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1729  decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
1730  buf += s->planesize;
1731  }
1732  }
1733  } else if (s->ham) { // HAM to AV_PIX_FMT_BGR32
1734  memset(frame->data[0], 0, avctx->height * frame->linesize[0]);
1735  for (y = 0; y < avctx->height; y++) {
1736  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1737  memset(s->ham_buf, 0, s->planesize * 8);
1738  for (plane = 0; plane < s->bpp; plane++) {
1739  const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
1740  if (start >= buf_end)
1741  break;
1742  decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
1743  }
1744  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1745  }
1746  } else {
1747  return unsupported(avctx);
1748  }
1749  } else {
1750  return unsupported(avctx);
1751  }
1752  break;
1753  case 0x2:
1754  if (avctx->codec_tag == MKTAG('I', 'L', 'B', 'M') && avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1755  for (plane = 0; plane < s->bpp; plane++) {
1756  decode_byterun2(s->planebuf, avctx->height, s->planesize, gb);
1757  for (y = 0; y < avctx->height; y++) {
1758  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1759  decodeplane8(row, s->planebuf + s->planesize * y, s->planesize, plane);
1760  }
1761  }
1762  } else {
1763  return unsupported(avctx);
1764  }
1765  break;
1766  case 0x4:
1767  if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32)
1768  decode_rgb8(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1769  else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444)
1770  decode_rgbn(gb, frame->data[0], avctx->width, avctx->height, frame->linesize[0]);
1771  else
1772  return unsupported(avctx);
1773  break;
1774  case 0x5:
1775  if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) {
1776  if (av_get_bits_per_pixel(desc) == 32)
1777  decode_deep_tvdc32(frame->data[0], buf, buf_size, avctx->width, avctx->height, frame->linesize[0], s->tvdc);
1778  else
1779  return unsupported(avctx);
1780  } else
1781  return unsupported(avctx);
1782  break;
1783  case 0x300:
1784  case 0x301:
1785  decode_short_horizontal_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1786  break;
1787  case 0x500:
1788  case 0x501:
1789  decode_byte_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->is_brush, s->bpp, s->video_size);
1790  break;
1791  case 0x700:
1792  case 0x701:
1793  if (s->is_short)
1794  decode_short_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1795  else
1796  decode_long_vertical_delta(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1797  break;
1798  case 0x800:
1799  case 0x801:
1800  if (s->is_short)
1801  decode_short_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1802  else
1803  decode_long_vertical_delta2(s->video[0], buf, buf_end, avctx->width, s->bpp, s->video_size);
1804  break;
1805  case 0x4a00:
1806  case 0x4a01:
1807  decode_delta_j(s->video[0], buf, buf_end, avctx->width, avctx->height, s->bpp, s->video_size);
1808  break;
1809  case 0x6400:
1810  case 0x6401:
1811  if (s->is_interlaced)
1812  return unsupported(avctx);
1813  decode_delta_d(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1814  break;
1815  case 0x6500:
1816  case 0x6501:
1817  if (s->is_interlaced)
1818  return unsupported(avctx);
1819  decode_delta_e(s->video[0], buf, buf_end, avctx->width, s->is_interlaced, s->bpp, s->video_size);
1820  break;
1821  case 0x6c00:
1822  case 0x6c01:
1823  decode_delta_l(s->video[0], buf, buf_end, avctx->width, s->is_short, s->bpp, s->video_size);
1824  break;
1825  default:
1826  return unsupported(avctx);
1827  }
1828 
1829  if (s->compression <= 0xff && (avctx->codec_tag == MKTAG('A', 'N', 'I', 'M'))) {
1830  memcpy(s->video[1], s->video[0], s->video_size);
1831  }
1832 
1833  if (s->compression > 0xff) {
1834  if (avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
1835  buf = s->video[0];
1836  for (y = 0; y < avctx->height; y++) {
1837  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1838  memset(row, 0, avctx->width);
1839  for (plane = 0; plane < s->bpp; plane++) {
1840  decodeplane8(row, buf, s->planesize, plane);
1841  buf += s->planesize;
1842  }
1843  }
1844  memcpy(frame->data[1], s->pal, 256 * 4);
1845  } else if (s->ham) {
1846  int i, count = 1 << s->ham;
1847 
1848  buf = s->video[0];
1849  memset(s->ham_palbuf, 0, (1 << s->ham) * 2 * sizeof(uint32_t));
1850  for (i = 0; i < count; i++) {
1851  s->ham_palbuf[i*2+1] = s->pal[i];
1852  }
1853  for (i = 0; i < count; i++) {
1854  uint32_t tmp = i << (8 - s->ham);
1855  tmp |= tmp >> s->ham;
1856  s->ham_palbuf[(i+count)*2] = 0xFF00FFFF;
1857  s->ham_palbuf[(i+count*2)*2] = 0xFFFFFF00;
1858  s->ham_palbuf[(i+count*3)*2] = 0xFFFF00FF;
1859  s->ham_palbuf[(i+count)*2+1] = 0xFF000000 | tmp << 16;
1860  s->ham_palbuf[(i+count*2)*2+1] = 0xFF000000 | tmp;
1861  s->ham_palbuf[(i+count*3)*2+1] = 0xFF000000 | tmp << 8;
1862  }
1863  if (s->masking == MASK_HAS_MASK) {
1864  for (i = 0; i < 8 * (1 << s->ham); i++)
1865  s->ham_palbuf[(1 << s->bpp) + i] = s->ham_palbuf[i] | 0xFF000000;
1866  }
1867  for (y = 0; y < avctx->height; y++) {
1868  uint8_t *row = &frame->data[0][y * frame->linesize[0]];
1869  memset(s->ham_buf, 0, s->planesize * 8);
1870  for (plane = 0; plane < s->bpp; plane++) {
1871  decodeplane8(s->ham_buf, buf, s->planesize, plane);
1872  buf += s->planesize;
1873  }
1874  decode_ham_plane32((uint32_t *)row, s->ham_buf, s->ham_palbuf, s->planesize);
1875  }
1876  } else {
1877  return unsupported(avctx);
1878  }
1879 
1880  if (!s->is_brush) {
1881  FFSWAP(uint8_t *, s->video[0], s->video[1]);
1882  }
1883  }
1884 
1885  if (avpkt->flags & AV_PKT_FLAG_KEY) {
1886  frame->key_frame = 1;
1887  frame->pict_type = AV_PICTURE_TYPE_I;
1888  } else {
1889  frame->key_frame = 0;
1890  frame->pict_type = AV_PICTURE_TYPE_P;
1891  }
1892 
1893  *got_frame = 1;
1894 
1895  return buf_size;
1896 }
1897 
1898 #if CONFIG_IFF_ILBM_DECODER
1900  .name = "iff",
1901  .long_name = NULL_IF_CONFIG_SMALL("IFF ACBM/ANIM/DEEP/ILBM/PBM/RGB8/RGBN"),
1902  .type = AVMEDIA_TYPE_VIDEO,
1903  .id = AV_CODEC_ID_IFF_ILBM,
1904  .priv_data_size = sizeof(IffContext),
1905  .init = decode_init,
1906  .close = decode_end,
1907  .decode = decode_frame,
1908  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1909  .capabilities = AV_CODEC_CAP_DR1,
1910 };
1911 #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:481
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:1495
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:1792
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:3506
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:1387
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:459
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:499
static av_cold int decode_end(AVCodecContext *avctx)
Definition: iff.c:381
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:760
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:1683
Definition: iff.c:40
#define height
uint8_t * data
Definition: avcodec.h:1494
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:2806
#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:1526
#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:3513
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:1500
#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:1031
int width
picture width / height.
Definition: avcodec.h:1755
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:800
#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:549
#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:1099
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:646
main external API structure.
Definition: avcodec.h:1582
#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:1185
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:1607
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:1684
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:920
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:690
#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:1245
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:1442
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:853
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:556
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: iff.c:1516
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:1327
static void decode_rgb8(GetByteContext *gb, uint8_t *dst, int width, int height, int linesize)
Decode RGB8 buffer.
Definition: iff.c:673
#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:517
#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:797
static av_cold int decode_init(AVCodecContext *avctx)
Definition: iff.c:395
void * priv_data
Definition: avcodec.h:1609
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:576
#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:532
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:1509
#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:1471
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:988
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:710
static uint8_t tmp[11]
Definition: aes_ctr.c:26