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