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