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