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