FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
flicvideo.c
Go to the documentation of this file.
1 /*
2  * FLI/FLC Animation Video Decoder
3  * Copyright (C) 2003, 2004 The FFmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Autodesk Animator FLI/FLC Video Decoder
25  * by Mike Melanson (melanson@pcisys.net)
26  * for more information on the .fli/.flc file format and all of its many
27  * variations, visit:
28  * http://www.compuphase.com/flic.htm
29  *
30  * This decoder outputs PAL8/RGB555/RGB565/BGR24. To use this decoder, be
31  * sure that your demuxer sends the FLI file header to the decoder via
32  * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
33  * large. The only exception is for FLI files from the game "Magic Carpet",
34  * in which the header is only 12 bytes.
35  */
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #include "libavutil/intreadwrite.h"
42 #include "avcodec.h"
43 #include "bytestream.h"
44 #include "internal.h"
45 #include "mathops.h"
46 
47 #define FLI_256_COLOR 4
48 #define FLI_DELTA 7
49 #define FLI_COLOR 11
50 #define FLI_LC 12
51 #define FLI_BLACK 13
52 #define FLI_BRUN 15
53 #define FLI_COPY 16
54 #define FLI_MINI 18
55 #define FLI_DTA_BRUN 25
56 #define FLI_DTA_COPY 26
57 #define FLI_DTA_LC 27
58 
59 #define FLI_TYPE_CODE (0xAF11)
60 #define FLC_FLX_TYPE_CODE (0xAF12)
61 #define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
62 #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
63 
64 #define CHECK_PIXEL_PTR(n) \
65  if (pixel_ptr + n > pixel_limit) { \
66  av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
67  pixel_ptr + n, pixel_limit); \
68  return AVERROR_INVALIDDATA; \
69  } \
70 
71 typedef struct FlicDecodeContext {
74 
75  unsigned int palette[256];
77  int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
79 
81 {
82  FlicDecodeContext *s = avctx->priv_data;
83  unsigned char *fli_header = (unsigned char *)avctx->extradata;
84  int depth;
85 
86  if (avctx->extradata_size != 0 &&
87  avctx->extradata_size != 12 &&
88  avctx->extradata_size != 128 &&
89  avctx->extradata_size != 256 &&
90  avctx->extradata_size != 904 &&
91  avctx->extradata_size != 1024) {
92  av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
93  return AVERROR_INVALIDDATA;
94  }
95 
96  s->avctx = avctx;
97 
98  if (s->avctx->extradata_size == 12) {
99  /* special case for magic carpet FLIs */
101  depth = 8;
102  } else if (avctx->extradata_size == 1024) {
103  uint8_t *ptr = avctx->extradata;
104  int i;
105 
106  for (i = 0; i < 256; i++) {
107  s->palette[i] = AV_RL32(ptr);
108  ptr += 4;
109  }
110  depth = 8;
111  /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
112  } else if (avctx->extradata_size == 0 ||
113  avctx->extradata_size == 256 ||
114  /* see FFmpeg ticket #1234 */
115  avctx->extradata_size == 904) {
116  s->fli_type = FLI_TYPE_CODE;
117  depth = 8;
118  } else {
119  s->fli_type = AV_RL16(&fli_header[4]);
120  depth = AV_RL16(&fli_header[12]);
121  }
122 
123  if (depth == 0) {
124  depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
125  }
126 
127  if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
128  depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
129  }
130 
131  switch (depth) {
132  case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
133  case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
134  case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
135  case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; break;
136  default :
137  av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
138  return AVERROR_INVALIDDATA;
139  }
140 
141  s->frame = av_frame_alloc();
142  if (!s->frame)
143  return AVERROR(ENOMEM);
144 
145  s->new_palette = 0;
146 
147  return 0;
148 }
149 
151  void *data, int *got_frame,
152  const uint8_t *buf, int buf_size)
153 {
154  FlicDecodeContext *s = avctx->priv_data;
155 
156  GetByteContext g2;
157  int pixel_ptr;
158  int palette_ptr;
159  unsigned char palette_idx1;
160  unsigned char palette_idx2;
161 
162  unsigned int frame_size;
163  int num_chunks;
164 
165  unsigned int chunk_size;
166  int chunk_type;
167 
168  int i, j, ret;
169 
170  int color_packets;
171  int color_changes;
172  int color_shift;
173  unsigned char r, g, b;
174 
175  int lines;
176  int compressed_lines;
177  int starting_line;
178  signed short line_packets;
179  int y_ptr;
180  int byte_run;
181  int pixel_skip;
182  int pixel_countdown;
183  unsigned char *pixels;
184  unsigned int pixel_limit;
185 
186  bytestream2_init(&g2, buf, buf_size);
187 
188  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
189  return ret;
190 
191  pixels = s->frame->data[0];
192  pixel_limit = s->avctx->height * s->frame->linesize[0];
193  if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + AV_INPUT_BUFFER_PADDING_SIZE))
194  return AVERROR_INVALIDDATA;
195  frame_size = bytestream2_get_le32(&g2);
196  if (frame_size > buf_size)
197  frame_size = buf_size;
198  bytestream2_skip(&g2, 2); /* skip the magic number */
199  num_chunks = bytestream2_get_le16(&g2);
200  bytestream2_skip(&g2, 8); /* skip padding */
201 
202  if (frame_size < 16)
203  return AVERROR_INVALIDDATA;
204 
205  frame_size -= 16;
206 
207  /* iterate through the chunks */
208  while ((frame_size >= 6) && (num_chunks > 0) &&
209  bytestream2_get_bytes_left(&g2) >= 4) {
210  int stream_ptr_after_chunk;
211  chunk_size = bytestream2_get_le32(&g2);
212  if (chunk_size > frame_size) {
213  av_log(avctx, AV_LOG_WARNING,
214  "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
215  chunk_size = frame_size;
216  }
217  stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
218 
219  chunk_type = bytestream2_get_le16(&g2);
220 
221  switch (chunk_type) {
222  case FLI_256_COLOR:
223  case FLI_COLOR:
224  /* check special case: If this file is from the Magic Carpet
225  * game and uses 6-bit colors even though it reports 256-color
226  * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
227  * initialization) */
228  if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
229  color_shift = 0;
230  else
231  color_shift = 2;
232  /* set up the palette */
233  color_packets = bytestream2_get_le16(&g2);
234  palette_ptr = 0;
235  for (i = 0; i < color_packets; i++) {
236  /* first byte is how many colors to skip */
237  palette_ptr += bytestream2_get_byte(&g2);
238 
239  /* next byte indicates how many entries to change */
240  color_changes = bytestream2_get_byte(&g2);
241 
242  /* if there are 0 color changes, there are actually 256 */
243  if (color_changes == 0)
244  color_changes = 256;
245 
246  if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
247  break;
248 
249  for (j = 0; j < color_changes; j++) {
250  unsigned int entry;
251 
252  /* wrap around, for good measure */
253  if ((unsigned)palette_ptr >= 256)
254  palette_ptr = 0;
255 
256  r = bytestream2_get_byte(&g2) << color_shift;
257  g = bytestream2_get_byte(&g2) << color_shift;
258  b = bytestream2_get_byte(&g2) << color_shift;
259  entry = 0xFFU << 24 | r << 16 | g << 8 | b;
260  if (color_shift == 2)
261  entry |= entry >> 6 & 0x30303;
262  if (s->palette[palette_ptr] != entry)
263  s->new_palette = 1;
264  s->palette[palette_ptr++] = entry;
265  }
266  }
267  break;
268 
269  case FLI_DELTA:
270  y_ptr = 0;
271  compressed_lines = bytestream2_get_le16(&g2);
272  while (compressed_lines > 0) {
273  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
274  break;
275  if (y_ptr > pixel_limit)
276  return AVERROR_INVALIDDATA;
277  line_packets = bytestream2_get_le16(&g2);
278  if ((line_packets & 0xC000) == 0xC000) {
279  // line skip opcode
280  line_packets = -line_packets;
281  if (line_packets > s->avctx->height)
282  return AVERROR_INVALIDDATA;
283  y_ptr += line_packets * s->frame->linesize[0];
284  } else if ((line_packets & 0xC000) == 0x4000) {
285  av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
286  } else if ((line_packets & 0xC000) == 0x8000) {
287  // "last byte" opcode
288  pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
289  CHECK_PIXEL_PTR(0);
290  pixels[pixel_ptr] = line_packets & 0xff;
291  } else {
292  compressed_lines--;
293  pixel_ptr = y_ptr;
294  CHECK_PIXEL_PTR(0);
295  pixel_countdown = s->avctx->width;
296  for (i = 0; i < line_packets; i++) {
297  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
298  break;
299  /* account for the skip bytes */
300  pixel_skip = bytestream2_get_byte(&g2);
301  pixel_ptr += pixel_skip;
302  pixel_countdown -= pixel_skip;
303  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
304  if (byte_run < 0) {
305  byte_run = -byte_run;
306  palette_idx1 = bytestream2_get_byte(&g2);
307  palette_idx2 = bytestream2_get_byte(&g2);
308  CHECK_PIXEL_PTR(byte_run * 2);
309  for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
310  pixels[pixel_ptr++] = palette_idx1;
311  pixels[pixel_ptr++] = palette_idx2;
312  }
313  } else {
314  CHECK_PIXEL_PTR(byte_run * 2);
315  if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
316  break;
317  for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
318  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
319  }
320  }
321  }
322 
323  y_ptr += s->frame->linesize[0];
324  }
325  }
326  break;
327 
328  case FLI_LC:
329  /* line compressed */
330  starting_line = bytestream2_get_le16(&g2);
331  if (starting_line >= s->avctx->height)
332  return AVERROR_INVALIDDATA;
333  y_ptr = 0;
334  y_ptr += starting_line * s->frame->linesize[0];
335 
336  compressed_lines = bytestream2_get_le16(&g2);
337  while (compressed_lines > 0) {
338  pixel_ptr = y_ptr;
339  CHECK_PIXEL_PTR(0);
340  pixel_countdown = s->avctx->width;
341  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
342  break;
343  line_packets = bytestream2_get_byte(&g2);
344  if (line_packets > 0) {
345  for (i = 0; i < line_packets; i++) {
346  /* account for the skip bytes */
347  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
348  break;
349  pixel_skip = bytestream2_get_byte(&g2);
350  pixel_ptr += pixel_skip;
351  pixel_countdown -= pixel_skip;
352  byte_run = sign_extend(bytestream2_get_byte(&g2),8);
353  if (byte_run > 0) {
354  CHECK_PIXEL_PTR(byte_run);
355  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
356  break;
357  for (j = 0; j < byte_run; j++, pixel_countdown--) {
358  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
359  }
360  } else if (byte_run < 0) {
361  byte_run = -byte_run;
362  palette_idx1 = bytestream2_get_byte(&g2);
363  CHECK_PIXEL_PTR(byte_run);
364  for (j = 0; j < byte_run; j++, pixel_countdown--) {
365  pixels[pixel_ptr++] = palette_idx1;
366  }
367  }
368  }
369  }
370 
371  y_ptr += s->frame->linesize[0];
372  compressed_lines--;
373  }
374  break;
375 
376  case FLI_BLACK:
377  /* set the whole frame to color 0 (which is usually black) */
378  memset(pixels, 0,
379  s->frame->linesize[0] * s->avctx->height);
380  break;
381 
382  case FLI_BRUN:
383  /* Byte run compression: This chunk type only occurs in the first
384  * FLI frame and it will update the entire frame. */
385  y_ptr = 0;
386  for (lines = 0; lines < s->avctx->height; lines++) {
387  pixel_ptr = y_ptr;
388  /* disregard the line packets; instead, iterate through all
389  * pixels on a row */
390  bytestream2_skip(&g2, 1);
391  pixel_countdown = s->avctx->width;
392  while (pixel_countdown > 0) {
393  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
394  break;
395  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
396  if (!byte_run) {
397  av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
398  return AVERROR_INVALIDDATA;
399  }
400 
401  if (byte_run > 0) {
402  palette_idx1 = bytestream2_get_byte(&g2);
403  CHECK_PIXEL_PTR(byte_run);
404  for (j = 0; j < byte_run; j++) {
405  pixels[pixel_ptr++] = palette_idx1;
406  pixel_countdown--;
407  if (pixel_countdown < 0)
408  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
409  pixel_countdown, lines);
410  }
411  } else { /* copy bytes if byte_run < 0 */
412  byte_run = -byte_run;
413  CHECK_PIXEL_PTR(byte_run);
414  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
415  break;
416  for (j = 0; j < byte_run; j++) {
417  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
418  pixel_countdown--;
419  if (pixel_countdown < 0)
420  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
421  pixel_countdown, lines);
422  }
423  }
424  }
425 
426  y_ptr += s->frame->linesize[0];
427  }
428  break;
429 
430  case FLI_COPY:
431  /* copy the chunk (uncompressed frame) */
432  if (chunk_size - 6 != FFALIGN(s->avctx->width, 4) * s->avctx->height) {
433  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
434  "has incorrect size, skipping chunk\n", chunk_size - 6);
435  bytestream2_skip(&g2, chunk_size - 6);
436  } else {
437  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
438  y_ptr += s->frame->linesize[0]) {
439  bytestream2_get_buffer(&g2, &pixels[y_ptr],
440  s->avctx->width);
441  if (s->avctx->width & 3)
442  bytestream2_skip(&g2, 4 - (s->avctx->width & 3));
443  }
444  }
445  break;
446 
447  case FLI_MINI:
448  /* some sort of a thumbnail? disregard this chunk... */
449  break;
450 
451  default:
452  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
453  break;
454  }
455 
456  if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0)
457  bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
458 
459  frame_size -= chunk_size;
460  num_chunks--;
461  }
462 
463  /* by the end of the chunk, the stream ptr should equal the frame
464  * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
465  if (bytestream2_get_bytes_left(&g2) > 2)
466  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
467  "and final chunk ptr = %d\n", buf_size,
468  buf_size - bytestream2_get_bytes_left(&g2));
469 
470  /* make the palette available on the way out */
471  memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
472  if (s->new_palette) {
473  s->frame->palette_has_changed = 1;
474  s->new_palette = 0;
475  }
476 
477  if ((ret = av_frame_ref(data, s->frame)) < 0)
478  return ret;
479 
480  *got_frame = 1;
481 
482  return buf_size;
483 }
484 
486  void *data, int *got_frame,
487  const uint8_t *buf, int buf_size)
488 {
489  /* Note, the only difference between the 15Bpp and 16Bpp */
490  /* Format is the pixel format, the packets are processed the same. */
491  FlicDecodeContext *s = avctx->priv_data;
492 
493  GetByteContext g2;
494  int pixel_ptr;
495  unsigned char palette_idx1;
496 
497  unsigned int frame_size;
498  int num_chunks;
499 
500  unsigned int chunk_size;
501  int chunk_type;
502 
503  int i, j, ret;
504 
505  int lines;
506  int compressed_lines;
507  signed short line_packets;
508  int y_ptr;
509  int byte_run;
510  int pixel_skip;
511  int pixel_countdown;
512  unsigned char *pixels;
513  int pixel;
514  unsigned int pixel_limit;
515 
516  bytestream2_init(&g2, buf, buf_size);
517 
518  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
519  return ret;
520 
521  pixels = s->frame->data[0];
522  pixel_limit = s->avctx->height * s->frame->linesize[0];
523 
524  frame_size = bytestream2_get_le32(&g2);
525  bytestream2_skip(&g2, 2); /* skip the magic number */
526  num_chunks = bytestream2_get_le16(&g2);
527  bytestream2_skip(&g2, 8); /* skip padding */
528  if (frame_size > buf_size)
529  frame_size = buf_size;
530 
531  if (frame_size < 16)
532  return AVERROR_INVALIDDATA;
533  frame_size -= 16;
534 
535  /* iterate through the chunks */
536  while ((frame_size > 0) && (num_chunks > 0) &&
537  bytestream2_get_bytes_left(&g2) >= 4) {
538  int stream_ptr_after_chunk;
539  chunk_size = bytestream2_get_le32(&g2);
540  if (chunk_size > frame_size) {
541  av_log(avctx, AV_LOG_WARNING,
542  "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
543  chunk_size = frame_size;
544  }
545  stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
546 
547  chunk_type = bytestream2_get_le16(&g2);
548 
549 
550  switch (chunk_type) {
551  case FLI_256_COLOR:
552  case FLI_COLOR:
553  /* For some reason, it seems that non-palettized flics do
554  * include one of these chunks in their first frame.
555  * Why I do not know, it seems rather extraneous. */
556  ff_dlog(avctx,
557  "Unexpected Palette chunk %d in non-palettized FLC\n",
558  chunk_type);
559  bytestream2_skip(&g2, chunk_size - 6);
560  break;
561 
562  case FLI_DELTA:
563  case FLI_DTA_LC:
564  y_ptr = 0;
565  compressed_lines = bytestream2_get_le16(&g2);
566  while (compressed_lines > 0) {
567  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
568  break;
569  if (y_ptr > pixel_limit)
570  return AVERROR_INVALIDDATA;
571  line_packets = bytestream2_get_le16(&g2);
572  if (line_packets < 0) {
573  line_packets = -line_packets;
574  if (line_packets > s->avctx->height)
575  return AVERROR_INVALIDDATA;
576  y_ptr += line_packets * s->frame->linesize[0];
577  } else {
578  compressed_lines--;
579  pixel_ptr = y_ptr;
580  CHECK_PIXEL_PTR(0);
581  pixel_countdown = s->avctx->width;
582  for (i = 0; i < line_packets; i++) {
583  /* account for the skip bytes */
584  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
585  break;
586  pixel_skip = bytestream2_get_byte(&g2);
587  pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
588  pixel_countdown -= pixel_skip;
589  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
590  if (byte_run < 0) {
591  byte_run = -byte_run;
592  pixel = bytestream2_get_le16(&g2);
593  CHECK_PIXEL_PTR(2 * byte_run);
594  for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
595  *((signed short*)(&pixels[pixel_ptr])) = pixel;
596  pixel_ptr += 2;
597  }
598  } else {
599  if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
600  break;
601  CHECK_PIXEL_PTR(2 * byte_run);
602  for (j = 0; j < byte_run; j++, pixel_countdown--) {
603  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
604  pixel_ptr += 2;
605  }
606  }
607  }
608 
609  y_ptr += s->frame->linesize[0];
610  }
611  }
612  break;
613 
614  case FLI_LC:
615  av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
616  bytestream2_skip(&g2, chunk_size - 6);
617  break;
618 
619  case FLI_BLACK:
620  /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
621  memset(pixels, 0x0000,
622  s->frame->linesize[0] * s->avctx->height);
623  break;
624 
625  case FLI_BRUN:
626  y_ptr = 0;
627  for (lines = 0; lines < s->avctx->height; lines++) {
628  pixel_ptr = y_ptr;
629  /* disregard the line packets; instead, iterate through all
630  * pixels on a row */
631  bytestream2_skip(&g2, 1);
632  pixel_countdown = (s->avctx->width * 2);
633 
634  while (pixel_countdown > 0) {
635  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
636  break;
637  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
638  if (byte_run > 0) {
639  palette_idx1 = bytestream2_get_byte(&g2);
640  CHECK_PIXEL_PTR(byte_run);
641  for (j = 0; j < byte_run; j++) {
642  pixels[pixel_ptr++] = palette_idx1;
643  pixel_countdown--;
644  if (pixel_countdown < 0)
645  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
646  pixel_countdown, lines);
647  }
648  } else { /* copy bytes if byte_run < 0 */
649  byte_run = -byte_run;
650  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
651  break;
652  CHECK_PIXEL_PTR(byte_run);
653  for (j = 0; j < byte_run; j++) {
654  palette_idx1 = bytestream2_get_byte(&g2);
655  pixels[pixel_ptr++] = palette_idx1;
656  pixel_countdown--;
657  if (pixel_countdown < 0)
658  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
659  pixel_countdown, lines);
660  }
661  }
662  }
663 
664  /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
665  * This does not give us any good opportunity to perform word endian conversion
666  * during decompression. So if it is required (i.e., this is not a LE target, we do
667  * a second pass over the line here, swapping the bytes.
668  */
669 #if HAVE_BIGENDIAN
670  pixel_ptr = y_ptr;
671  pixel_countdown = s->avctx->width;
672  while (pixel_countdown > 0) {
673  *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
674  pixel_ptr += 2;
675  }
676 #endif
677  y_ptr += s->frame->linesize[0];
678  }
679  break;
680 
681  case FLI_DTA_BRUN:
682  y_ptr = 0;
683  for (lines = 0; lines < s->avctx->height; lines++) {
684  pixel_ptr = y_ptr;
685  /* disregard the line packets; instead, iterate through all
686  * pixels on a row */
687  bytestream2_skip(&g2, 1);
688  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
689 
690  while (pixel_countdown > 0) {
691  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
692  break;
693  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
694  if (byte_run > 0) {
695  pixel = bytestream2_get_le16(&g2);
696  CHECK_PIXEL_PTR(2 * byte_run);
697  for (j = 0; j < byte_run; j++) {
698  *((signed short*)(&pixels[pixel_ptr])) = pixel;
699  pixel_ptr += 2;
700  pixel_countdown--;
701  if (pixel_countdown < 0)
702  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
703  pixel_countdown);
704  }
705  } else { /* copy pixels if byte_run < 0 */
706  byte_run = -byte_run;
707  if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
708  break;
709  CHECK_PIXEL_PTR(2 * byte_run);
710  for (j = 0; j < byte_run; j++) {
711  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
712  pixel_ptr += 2;
713  pixel_countdown--;
714  if (pixel_countdown < 0)
715  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
716  pixel_countdown);
717  }
718  }
719  }
720 
721  y_ptr += s->frame->linesize[0];
722  }
723  break;
724 
725  case FLI_COPY:
726  case FLI_DTA_COPY:
727  /* copy the chunk (uncompressed frame) */
728  if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*2) {
729  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
730  "bigger than image, skipping chunk\n", chunk_size - 6);
731  bytestream2_skip(&g2, chunk_size - 6);
732  } else {
733 
734  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
735  y_ptr += s->frame->linesize[0]) {
736 
737  pixel_countdown = s->avctx->width;
738  pixel_ptr = 0;
739  while (pixel_countdown > 0) {
740  *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
741  pixel_ptr += 2;
742  pixel_countdown--;
743  }
744  if (s->avctx->width & 1)
745  bytestream2_skip(&g2, 2);
746  }
747  }
748  break;
749 
750  case FLI_MINI:
751  /* some sort of a thumbnail? disregard this chunk... */
752  bytestream2_skip(&g2, chunk_size - 6);
753  break;
754 
755  default:
756  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
757  break;
758  }
759 
760  frame_size -= chunk_size;
761  num_chunks--;
762  }
763 
764  /* by the end of the chunk, the stream ptr should equal the frame
765  * size (minus 1, possibly); if it doesn't, issue a warning */
766  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
767  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
768  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
769 
770  if ((ret = av_frame_ref(data, s->frame)) < 0)
771  return ret;
772 
773  *got_frame = 1;
774 
775  return buf_size;
776 }
777 
779  void *data, int *got_frame,
780  const uint8_t *buf, int buf_size)
781 {
782  FlicDecodeContext *s = avctx->priv_data;
783 
784  GetByteContext g2;
785  int pixel_ptr;
786  unsigned char palette_idx1;
787 
788  unsigned int frame_size;
789  int num_chunks;
790 
791  unsigned int chunk_size;
792  int chunk_type;
793 
794  int i, j, ret;
795 
796  int lines;
797  int compressed_lines;
798  signed short line_packets;
799  int y_ptr;
800  int byte_run;
801  int pixel_skip;
802  int pixel_countdown;
803  unsigned char *pixels;
804  int pixel;
805  unsigned int pixel_limit;
806 
807  bytestream2_init(&g2, buf, buf_size);
808 
809  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
810  return ret;
811 
812  pixels = s->frame->data[0];
813  pixel_limit = s->avctx->height * s->frame->linesize[0];
814 
815  frame_size = bytestream2_get_le32(&g2);
816  bytestream2_skip(&g2, 2); /* skip the magic number */
817  num_chunks = bytestream2_get_le16(&g2);
818  bytestream2_skip(&g2, 8); /* skip padding */
819  if (frame_size > buf_size)
820  frame_size = buf_size;
821 
822  if (frame_size < 16)
823  return AVERROR_INVALIDDATA;
824  frame_size -= 16;
825 
826  /* iterate through the chunks */
827  while ((frame_size > 0) && (num_chunks > 0) &&
828  bytestream2_get_bytes_left(&g2) >= 4) {
829  int stream_ptr_after_chunk;
830  chunk_size = bytestream2_get_le32(&g2);
831  if (chunk_size > frame_size) {
832  av_log(avctx, AV_LOG_WARNING,
833  "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
834  chunk_size = frame_size;
835  }
836  stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
837 
838  chunk_type = bytestream2_get_le16(&g2);
839 
840 
841  switch (chunk_type) {
842  case FLI_256_COLOR:
843  case FLI_COLOR:
844  /* For some reason, it seems that non-palettized flics do
845  * include one of these chunks in their first frame.
846  * Why I do not know, it seems rather extraneous. */
847  ff_dlog(avctx,
848  "Unexpected Palette chunk %d in non-palettized FLC\n",
849  chunk_type);
850  bytestream2_skip(&g2, chunk_size - 6);
851  break;
852 
853  case FLI_DELTA:
854  case FLI_DTA_LC:
855  y_ptr = 0;
856  compressed_lines = bytestream2_get_le16(&g2);
857  while (compressed_lines > 0) {
858  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
859  break;
860  if (y_ptr > pixel_limit)
861  return AVERROR_INVALIDDATA;
862  line_packets = bytestream2_get_le16(&g2);
863  if (line_packets < 0) {
864  line_packets = -line_packets;
865  if (line_packets > s->avctx->height)
866  return AVERROR_INVALIDDATA;
867  y_ptr += line_packets * s->frame->linesize[0];
868  } else {
869  compressed_lines--;
870  pixel_ptr = y_ptr;
871  CHECK_PIXEL_PTR(0);
872  pixel_countdown = s->avctx->width;
873  for (i = 0; i < line_packets; i++) {
874  /* account for the skip bytes */
875  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
876  break;
877  pixel_skip = bytestream2_get_byte(&g2);
878  pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
879  pixel_countdown -= pixel_skip;
880  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
881  if (byte_run < 0) {
882  byte_run = -byte_run;
883  pixel = bytestream2_get_le24(&g2);
884  CHECK_PIXEL_PTR(3 * byte_run);
885  for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
886  AV_WL24(&pixels[pixel_ptr], pixel);
887  pixel_ptr += 3;
888  }
889  } else {
890  if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
891  break;
892  CHECK_PIXEL_PTR(2 * byte_run);
893  for (j = 0; j < byte_run; j++, pixel_countdown--) {
894  pixel = bytestream2_get_le24(&g2);
895  AV_WL24(&pixels[pixel_ptr], pixel);
896  pixel_ptr += 3;
897  }
898  }
899  }
900 
901  y_ptr += s->frame->linesize[0];
902  }
903  }
904  break;
905 
906  case FLI_LC:
907  av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
908  bytestream2_skip(&g2, chunk_size - 6);
909  break;
910 
911  case FLI_BLACK:
912  /* set the whole frame to 0x00 which is black for 24 bit mode. */
913  memset(pixels, 0x00,
914  s->frame->linesize[0] * s->avctx->height);
915  break;
916 
917  case FLI_BRUN:
918  y_ptr = 0;
919  for (lines = 0; lines < s->avctx->height; lines++) {
920  pixel_ptr = y_ptr;
921  /* disregard the line packets; instead, iterate through all
922  * pixels on a row */
923  bytestream2_skip(&g2, 1);
924  pixel_countdown = (s->avctx->width * 3);
925 
926  while (pixel_countdown > 0) {
927  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
928  break;
929  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
930  if (byte_run > 0) {
931  palette_idx1 = bytestream2_get_byte(&g2);
932  CHECK_PIXEL_PTR(byte_run);
933  for (j = 0; j < byte_run; j++) {
934  pixels[pixel_ptr++] = palette_idx1;
935  pixel_countdown--;
936  if (pixel_countdown < 0)
937  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
938  pixel_countdown, lines);
939  }
940  } else { /* copy bytes if byte_run < 0 */
941  byte_run = -byte_run;
942  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
943  break;
944  CHECK_PIXEL_PTR(byte_run);
945  for (j = 0; j < byte_run; j++) {
946  palette_idx1 = bytestream2_get_byte(&g2);
947  pixels[pixel_ptr++] = palette_idx1;
948  pixel_countdown--;
949  if (pixel_countdown < 0)
950  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
951  pixel_countdown, lines);
952  }
953  }
954  }
955 
956  y_ptr += s->frame->linesize[0];
957  }
958  break;
959 
960  case FLI_DTA_BRUN:
961  y_ptr = 0;
962  for (lines = 0; lines < s->avctx->height; lines++) {
963  pixel_ptr = y_ptr;
964  /* disregard the line packets; instead, iterate through all
965  * pixels on a row */
966  bytestream2_skip(&g2, 1);
967  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
968 
969  while (pixel_countdown > 0) {
970  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
971  break;
972  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
973  if (byte_run > 0) {
974  pixel = bytestream2_get_le24(&g2);
975  CHECK_PIXEL_PTR(3 * byte_run);
976  for (j = 0; j < byte_run; j++) {
977  AV_WL24(pixels + pixel_ptr, pixel);
978  pixel_ptr += 3;
979  pixel_countdown--;
980  if (pixel_countdown < 0)
981  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
982  pixel_countdown);
983  }
984  } else { /* copy pixels if byte_run < 0 */
985  byte_run = -byte_run;
986  if (bytestream2_tell(&g2) + 3 * byte_run > stream_ptr_after_chunk)
987  break;
988  CHECK_PIXEL_PTR(3 * byte_run);
989  for (j = 0; j < byte_run; j++) {
990  pixel = bytestream2_get_le24(&g2);
991  AV_WL24(pixels + pixel_ptr, pixel);
992  pixel_ptr += 3;
993  pixel_countdown--;
994  if (pixel_countdown < 0)
995  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
996  pixel_countdown);
997  }
998  }
999  }
1000 
1001  y_ptr += s->frame->linesize[0];
1002  }
1003  break;
1004 
1005  case FLI_COPY:
1006  case FLI_DTA_COPY:
1007  /* copy the chunk (uncompressed frame) */
1008  if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*3) {
1009  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
1010  "bigger than image, skipping chunk\n", chunk_size - 6);
1011  bytestream2_skip(&g2, chunk_size - 6);
1012  } else {
1013  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
1014  y_ptr += s->frame->linesize[0]) {
1015 
1016  pixel_countdown = s->avctx->width;
1017  pixel_ptr = 0;
1018  while (pixel_countdown > 0) {
1019  pixel = bytestream2_get_le24(&g2);
1020  AV_WL24(&pixels[y_ptr + pixel_ptr], pixel);
1021  pixel_ptr += 3;
1022  pixel_countdown--;
1023  }
1024  if (s->avctx->width & 1)
1025  bytestream2_skip(&g2, 3);
1026  }
1027  }
1028  break;
1029 
1030  case FLI_MINI:
1031  /* some sort of a thumbnail? disregard this chunk... */
1032  bytestream2_skip(&g2, chunk_size - 6);
1033  break;
1034 
1035  default:
1036  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1037  break;
1038  }
1039 
1040  frame_size -= chunk_size;
1041  num_chunks--;
1042  }
1043 
1044  /* by the end of the chunk, the stream ptr should equal the frame
1045  * size (minus 1, possibly); if it doesn't, issue a warning */
1046  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
1047  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
1048  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
1049 
1050  if ((ret = av_frame_ref(data, s->frame)) < 0)
1051  return ret;
1052 
1053  *got_frame = 1;
1054 
1055  return buf_size;
1056 }
1057 
1059  void *data, int *got_frame,
1060  AVPacket *avpkt)
1061 {
1062  const uint8_t *buf = avpkt->data;
1063  int buf_size = avpkt->size;
1064  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1065  return flic_decode_frame_8BPP(avctx, data, got_frame,
1066  buf, buf_size);
1067  } else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
1068  (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
1069  return flic_decode_frame_15_16BPP(avctx, data, got_frame,
1070  buf, buf_size);
1071  } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
1072  return flic_decode_frame_24BPP(avctx, data, got_frame,
1073  buf, buf_size);
1074  }
1075 
1076  /* Should not get here, ever as the pix_fmt is processed */
1077  /* in flic_decode_init and the above if should deal with */
1078  /* the finite set of possibilities allowable by here. */
1079  /* But in case we do, just error out. */
1080  av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
1081  return AVERROR_BUG;
1082 }
1083 
1084 
1086 {
1087  FlicDecodeContext *s = avctx->priv_data;
1088 
1089  av_frame_free(&s->frame);
1090 
1091  return 0;
1092 }
1093 
1095  .name = "flic",
1096  .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
1097  .type = AVMEDIA_TYPE_VIDEO,
1098  .id = AV_CODEC_ID_FLIC,
1099  .priv_data_size = sizeof(FlicDecodeContext),
1101  .close = flic_decode_end,
1103  .capabilities = AV_CODEC_CAP_DR1,
1104 };
#define FLI_DTA_COPY
Definition: flicvideo.c:56
AVCodecContext * avctx
Definition: flicvideo.c:72
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:187
#define FLI_TYPE_CODE
Definition: flicvideo.c:59
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
#define FLI_MINI
Definition: flicvideo.c:54
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define CHECK_PIXEL_PTR(n)
Definition: flicvideo.c:64
const char * g
Definition: vf_curves.c:112
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define FLI_COPY
Definition: flicvideo.c:53
int size
Definition: avcodec.h:1658
const char * b
Definition: vf_curves.c:113
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
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:485
AVCodec.
Definition: avcodec.h:3681
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:150
#define AV_WL24(p, d)
Definition: intreadwrite.h:469
uint8_t
#define av_cold
Definition: attributes.h:82
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:150
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:73
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
#define FLI_COLOR
Definition: flicvideo.c:49
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:388
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1847
uint8_t * data
Definition: avcodec.h:1657
#define ff_dlog(a,...)
#define FLI_LC
Definition: flicvideo.c:50
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
#define U(x)
Definition: vp56_arith.h:37
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define FLI_BRUN
Definition: flicvideo.c:52
AVFrame * frame
Definition: flicvideo.c:73
#define AVERROR(e)
Definition: error.h:43
static int flic_decode_frame_24BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:778
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:163
#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
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
Definition: flicvideo.c:62
const char * name
Name of the codec implementation.
Definition: avcodec.h:3688
int depth
Definition: v4l.c:62
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
Definition: utils.c:1002
#define FLI_DTA_BRUN
Definition: flicvideo.c:55
int width
picture width / height.
Definition: avcodec.h:1919
#define FLC_FLX_TYPE_CODE
Definition: flicvideo.c:60
#define FLI_256_COLOR
Definition: flicvideo.c:47
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:65
#define FLI_DELTA
Definition: flicvideo.c:48
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
int frame_size
Definition: mxfenc.c:1820
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:218
main external API structure.
Definition: avcodec.h:1732
void * buf
Definition: avisynth_c.h:690
#define FLI_DTA_LC
Definition: flicvideo.c:57
int extradata_size
Definition: avcodec.h:1848
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
static int flic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: flicvideo.c:1058
static av_cold int flic_decode_end(AVCodecContext *avctx)
Definition: flicvideo.c:1085
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:335
uint8_t pixel
Definition: tiny_ssim.c:42
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:130
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:201
#define FLI_BLACK
Definition: flicvideo.c:51
common internal api header.
if(ret< 0)
Definition: vf_mcdeint.c:282
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:339
#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
void * priv_data
Definition: avcodec.h:1774
int pixels
Definition: avisynth_c.h:429
unsigned int palette[256]
Definition: flicvideo.c:75
AVCodec ff_flic_decoder
Definition: flicvideo.c:1094
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:338
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame, AVPacket *pkt)
Definition: ffmpeg.c:2257
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1634
static av_cold int flic_decode_init(AVCodecContext *avctx)
Definition: flicvideo.c:80
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:994