FFmpeg
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  int 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)) < 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 = sign_extend(bytestream2_get_le16(&g2), 16);
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  } else {
459  av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
460  break;
461  }
462 
463  frame_size -= chunk_size;
464  num_chunks--;
465  }
466 
467  /* by the end of the chunk, the stream ptr should equal the frame
468  * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
469  if (bytestream2_get_bytes_left(&g2) > 2)
470  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
471  "and final chunk ptr = %d\n", buf_size,
472  buf_size - bytestream2_get_bytes_left(&g2));
473 
474  /* make the palette available on the way out */
475  memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
476  if (s->new_palette) {
477  s->frame->palette_has_changed = 1;
478  s->new_palette = 0;
479  }
480 
481  if ((ret = av_frame_ref(data, s->frame)) < 0)
482  return ret;
483 
484  *got_frame = 1;
485 
486  return buf_size;
487 }
488 
490  void *data, int *got_frame,
491  const uint8_t *buf, int buf_size)
492 {
493  /* Note, the only difference between the 15Bpp and 16Bpp */
494  /* Format is the pixel format, the packets are processed the same. */
495  FlicDecodeContext *s = avctx->priv_data;
496 
497  GetByteContext g2;
498  int pixel_ptr;
499  unsigned char palette_idx1;
500 
501  unsigned int frame_size;
502  int num_chunks;
503 
504  unsigned int chunk_size;
505  int chunk_type;
506 
507  int i, j, ret;
508 
509  int lines;
510  int compressed_lines;
511  int line_packets;
512  int y_ptr;
513  int byte_run;
514  int pixel_skip;
515  int pixel_countdown;
516  unsigned char *pixels;
517  int pixel;
518  unsigned int pixel_limit;
519 
520  bytestream2_init(&g2, buf, buf_size);
521 
522  if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
523  return ret;
524 
525  pixels = s->frame->data[0];
526  pixel_limit = s->avctx->height * s->frame->linesize[0];
527 
528  frame_size = bytestream2_get_le32(&g2);
529  bytestream2_skip(&g2, 2); /* skip the magic number */
530  num_chunks = bytestream2_get_le16(&g2);
531  bytestream2_skip(&g2, 8); /* skip padding */
532  if (frame_size > buf_size)
533  frame_size = buf_size;
534 
535  if (frame_size < 16)
536  return AVERROR_INVALIDDATA;
537  frame_size -= 16;
538 
539  /* iterate through the chunks */
540  while ((frame_size > 0) && (num_chunks > 0) &&
541  bytestream2_get_bytes_left(&g2) >= 4) {
542  int stream_ptr_after_chunk;
543  chunk_size = bytestream2_get_le32(&g2);
544  if (chunk_size > frame_size) {
545  av_log(avctx, AV_LOG_WARNING,
546  "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
547  chunk_size = frame_size;
548  }
549  stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
550 
551  chunk_type = bytestream2_get_le16(&g2);
552 
553 
554  switch (chunk_type) {
555  case FLI_256_COLOR:
556  case FLI_COLOR:
557  /* For some reason, it seems that non-palettized flics do
558  * include one of these chunks in their first frame.
559  * Why I do not know, it seems rather extraneous. */
560  ff_dlog(avctx,
561  "Unexpected Palette chunk %d in non-palettized FLC\n",
562  chunk_type);
563  bytestream2_skip(&g2, chunk_size - 6);
564  break;
565 
566  case FLI_DELTA:
567  case FLI_DTA_LC:
568  y_ptr = 0;
569  compressed_lines = bytestream2_get_le16(&g2);
570  while (compressed_lines > 0) {
571  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
572  break;
573  if (y_ptr > pixel_limit)
574  return AVERROR_INVALIDDATA;
575  line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
576  if (line_packets < 0) {
577  line_packets = -line_packets;
578  if (line_packets > s->avctx->height)
579  return AVERROR_INVALIDDATA;
580  y_ptr += line_packets * s->frame->linesize[0];
581  } else {
582  compressed_lines--;
583  pixel_ptr = y_ptr;
584  CHECK_PIXEL_PTR(0);
585  pixel_countdown = s->avctx->width;
586  for (i = 0; i < line_packets; i++) {
587  /* account for the skip bytes */
588  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
589  break;
590  pixel_skip = bytestream2_get_byte(&g2);
591  pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
592  pixel_countdown -= pixel_skip;
593  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
594  if (byte_run < 0) {
595  byte_run = -byte_run;
596  pixel = bytestream2_get_le16(&g2);
597  CHECK_PIXEL_PTR(2 * byte_run);
598  for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
599  *((signed short*)(&pixels[pixel_ptr])) = pixel;
600  pixel_ptr += 2;
601  }
602  } else {
603  if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
604  break;
605  CHECK_PIXEL_PTR(2 * byte_run);
606  for (j = 0; j < byte_run; j++, pixel_countdown--) {
607  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
608  pixel_ptr += 2;
609  }
610  }
611  }
612 
613  y_ptr += s->frame->linesize[0];
614  }
615  }
616  break;
617 
618  case FLI_LC:
619  av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
620  bytestream2_skip(&g2, chunk_size - 6);
621  break;
622 
623  case FLI_BLACK:
624  /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
625  memset(pixels, 0x0000,
626  s->frame->linesize[0] * s->avctx->height);
627  break;
628 
629  case FLI_BRUN:
630  y_ptr = 0;
631  for (lines = 0; lines < s->avctx->height; lines++) {
632  pixel_ptr = y_ptr;
633  /* disregard the line packets; instead, iterate through all
634  * pixels on a row */
635  bytestream2_skip(&g2, 1);
636  pixel_countdown = (s->avctx->width * 2);
637 
638  while (pixel_countdown > 0) {
639  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
640  break;
641  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
642  if (byte_run > 0) {
643  palette_idx1 = bytestream2_get_byte(&g2);
644  CHECK_PIXEL_PTR(byte_run);
645  for (j = 0; j < byte_run; j++) {
646  pixels[pixel_ptr++] = palette_idx1;
647  pixel_countdown--;
648  if (pixel_countdown < 0)
649  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
650  pixel_countdown, lines);
651  }
652  } else { /* copy bytes if byte_run < 0 */
653  byte_run = -byte_run;
654  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
655  break;
656  CHECK_PIXEL_PTR(byte_run);
657  for (j = 0; j < byte_run; j++) {
658  palette_idx1 = bytestream2_get_byte(&g2);
659  pixels[pixel_ptr++] = palette_idx1;
660  pixel_countdown--;
661  if (pixel_countdown < 0)
662  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
663  pixel_countdown, lines);
664  }
665  }
666  }
667 
668  /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
669  * This does not give us any good opportunity to perform word endian conversion
670  * during decompression. So if it is required (i.e., this is not a LE target, we do
671  * a second pass over the line here, swapping the bytes.
672  */
673 #if HAVE_BIGENDIAN
674  pixel_ptr = y_ptr;
675  pixel_countdown = s->avctx->width;
676  while (pixel_countdown > 0) {
677  *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
678  pixel_ptr += 2;
679  }
680 #endif
681  y_ptr += s->frame->linesize[0];
682  }
683  break;
684 
685  case FLI_DTA_BRUN:
686  y_ptr = 0;
687  for (lines = 0; lines < s->avctx->height; lines++) {
688  pixel_ptr = y_ptr;
689  /* disregard the line packets; instead, iterate through all
690  * pixels on a row */
691  bytestream2_skip(&g2, 1);
692  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
693 
694  while (pixel_countdown > 0) {
695  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
696  break;
697  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
698  if (byte_run > 0) {
699  pixel = bytestream2_get_le16(&g2);
700  CHECK_PIXEL_PTR(2 * byte_run);
701  for (j = 0; j < byte_run; j++) {
702  *((signed short*)(&pixels[pixel_ptr])) = pixel;
703  pixel_ptr += 2;
704  pixel_countdown--;
705  if (pixel_countdown < 0)
706  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
707  pixel_countdown);
708  }
709  } else { /* copy pixels if byte_run < 0 */
710  byte_run = -byte_run;
711  if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
712  break;
713  CHECK_PIXEL_PTR(2 * byte_run);
714  for (j = 0; j < byte_run; j++) {
715  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
716  pixel_ptr += 2;
717  pixel_countdown--;
718  if (pixel_countdown < 0)
719  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
720  pixel_countdown);
721  }
722  }
723  }
724 
725  y_ptr += s->frame->linesize[0];
726  }
727  break;
728 
729  case FLI_COPY:
730  case FLI_DTA_COPY:
731  /* copy the chunk (uncompressed frame) */
732  if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*2) {
733  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
734  "bigger than image, skipping chunk\n", chunk_size - 6);
735  bytestream2_skip(&g2, chunk_size - 6);
736  } else {
737 
738  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
739  y_ptr += s->frame->linesize[0]) {
740 
741  pixel_countdown = s->avctx->width;
742  pixel_ptr = 0;
743  while (pixel_countdown > 0) {
744  *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
745  pixel_ptr += 2;
746  pixel_countdown--;
747  }
748  if (s->avctx->width & 1)
749  bytestream2_skip(&g2, 2);
750  }
751  }
752  break;
753 
754  case FLI_MINI:
755  /* some sort of a thumbnail? disregard this chunk... */
756  bytestream2_skip(&g2, chunk_size - 6);
757  break;
758 
759  default:
760  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
761  break;
762  }
763 
764  if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
765  bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
766  } else {
767  av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
768  break;
769  }
770 
771  frame_size -= chunk_size;
772  num_chunks--;
773  }
774 
775  /* by the end of the chunk, the stream ptr should equal the frame
776  * size (minus 1, possibly); if it doesn't, issue a warning */
777  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
778  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
779  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
780 
781  if ((ret = av_frame_ref(data, s->frame)) < 0)
782  return ret;
783 
784  *got_frame = 1;
785 
786  return buf_size;
787 }
788 
790  void *data, int *got_frame,
791  const uint8_t *buf, int buf_size)
792 {
793  FlicDecodeContext *s = avctx->priv_data;
794 
795  GetByteContext g2;
796  int pixel_ptr;
797  unsigned char palette_idx1;
798 
799  unsigned int frame_size;
800  int num_chunks;
801 
802  unsigned int chunk_size;
803  int chunk_type;
804 
805  int i, j, ret;
806 
807  int lines;
808  int compressed_lines;
809  int line_packets;
810  int y_ptr;
811  int byte_run;
812  int pixel_skip;
813  int pixel_countdown;
814  unsigned char *pixels;
815  int pixel;
816  unsigned int pixel_limit;
817 
818  bytestream2_init(&g2, buf, buf_size);
819 
820  if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
821  return ret;
822 
823  pixels = s->frame->data[0];
824  pixel_limit = s->avctx->height * s->frame->linesize[0];
825 
826  frame_size = bytestream2_get_le32(&g2);
827  bytestream2_skip(&g2, 2); /* skip the magic number */
828  num_chunks = bytestream2_get_le16(&g2);
829  bytestream2_skip(&g2, 8); /* skip padding */
830  if (frame_size > buf_size)
831  frame_size = buf_size;
832 
833  if (frame_size < 16)
834  return AVERROR_INVALIDDATA;
835  frame_size -= 16;
836 
837  /* iterate through the chunks */
838  while ((frame_size > 0) && (num_chunks > 0) &&
839  bytestream2_get_bytes_left(&g2) >= 4) {
840  int stream_ptr_after_chunk;
841  chunk_size = bytestream2_get_le32(&g2);
842  if (chunk_size > frame_size) {
843  av_log(avctx, AV_LOG_WARNING,
844  "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
845  chunk_size = frame_size;
846  }
847  stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
848 
849  chunk_type = bytestream2_get_le16(&g2);
850 
851 
852  switch (chunk_type) {
853  case FLI_256_COLOR:
854  case FLI_COLOR:
855  /* For some reason, it seems that non-palettized flics do
856  * include one of these chunks in their first frame.
857  * Why I do not know, it seems rather extraneous. */
858  ff_dlog(avctx,
859  "Unexpected Palette chunk %d in non-palettized FLC\n",
860  chunk_type);
861  bytestream2_skip(&g2, chunk_size - 6);
862  break;
863 
864  case FLI_DELTA:
865  case FLI_DTA_LC:
866  y_ptr = 0;
867  compressed_lines = bytestream2_get_le16(&g2);
868  while (compressed_lines > 0) {
869  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
870  break;
871  if (y_ptr > pixel_limit)
872  return AVERROR_INVALIDDATA;
873  line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
874  if (line_packets < 0) {
875  line_packets = -line_packets;
876  if (line_packets > s->avctx->height)
877  return AVERROR_INVALIDDATA;
878  y_ptr += line_packets * s->frame->linesize[0];
879  } else {
880  compressed_lines--;
881  pixel_ptr = y_ptr;
882  CHECK_PIXEL_PTR(0);
883  pixel_countdown = s->avctx->width;
884  for (i = 0; i < line_packets; i++) {
885  /* account for the skip bytes */
886  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
887  break;
888  pixel_skip = bytestream2_get_byte(&g2);
889  pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
890  pixel_countdown -= pixel_skip;
891  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
892  if (byte_run < 0) {
893  byte_run = -byte_run;
894  pixel = bytestream2_get_le24(&g2);
895  CHECK_PIXEL_PTR(3 * byte_run);
896  for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
897  AV_WL24(&pixels[pixel_ptr], pixel);
898  pixel_ptr += 3;
899  }
900  } else {
901  if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
902  break;
903  CHECK_PIXEL_PTR(3 * byte_run);
904  for (j = 0; j < byte_run; j++, pixel_countdown--) {
905  pixel = bytestream2_get_le24(&g2);
906  AV_WL24(&pixels[pixel_ptr], pixel);
907  pixel_ptr += 3;
908  }
909  }
910  }
911 
912  y_ptr += s->frame->linesize[0];
913  }
914  }
915  break;
916 
917  case FLI_LC:
918  av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
919  bytestream2_skip(&g2, chunk_size - 6);
920  break;
921 
922  case FLI_BLACK:
923  /* set the whole frame to 0x00 which is black for 24 bit mode. */
924  memset(pixels, 0x00,
925  s->frame->linesize[0] * s->avctx->height);
926  break;
927 
928  case FLI_BRUN:
929  y_ptr = 0;
930  for (lines = 0; lines < s->avctx->height; lines++) {
931  pixel_ptr = y_ptr;
932  /* disregard the line packets; instead, iterate through all
933  * pixels on a row */
934  bytestream2_skip(&g2, 1);
935  pixel_countdown = (s->avctx->width * 3);
936 
937  while (pixel_countdown > 0) {
938  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
939  break;
940  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
941  if (byte_run > 0) {
942  palette_idx1 = bytestream2_get_byte(&g2);
943  CHECK_PIXEL_PTR(byte_run);
944  for (j = 0; j < byte_run; j++) {
945  pixels[pixel_ptr++] = palette_idx1;
946  pixel_countdown--;
947  if (pixel_countdown < 0)
948  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
949  pixel_countdown, lines);
950  }
951  } else { /* copy bytes if byte_run < 0 */
952  byte_run = -byte_run;
953  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
954  break;
955  CHECK_PIXEL_PTR(byte_run);
956  for (j = 0; j < byte_run; j++) {
957  palette_idx1 = bytestream2_get_byte(&g2);
958  pixels[pixel_ptr++] = palette_idx1;
959  pixel_countdown--;
960  if (pixel_countdown < 0)
961  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
962  pixel_countdown, lines);
963  }
964  }
965  }
966 
967  y_ptr += s->frame->linesize[0];
968  }
969  break;
970 
971  case FLI_DTA_BRUN:
972  y_ptr = 0;
973  for (lines = 0; lines < s->avctx->height; lines++) {
974  pixel_ptr = y_ptr;
975  /* disregard the line packets; instead, iterate through all
976  * pixels on a row */
977  bytestream2_skip(&g2, 1);
978  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
979 
980  while (pixel_countdown > 0) {
981  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
982  break;
983  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
984  if (byte_run > 0) {
985  pixel = bytestream2_get_le24(&g2);
986  CHECK_PIXEL_PTR(3 * byte_run);
987  for (j = 0; j < byte_run; j++) {
988  AV_WL24(pixels + pixel_ptr, pixel);
989  pixel_ptr += 3;
990  pixel_countdown--;
991  if (pixel_countdown < 0)
992  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
993  pixel_countdown);
994  }
995  } else { /* copy pixels if byte_run < 0 */
996  byte_run = -byte_run;
997  if (bytestream2_tell(&g2) + 3 * byte_run > stream_ptr_after_chunk)
998  break;
999  CHECK_PIXEL_PTR(3 * byte_run);
1000  for (j = 0; j < byte_run; j++) {
1001  pixel = bytestream2_get_le24(&g2);
1002  AV_WL24(pixels + pixel_ptr, pixel);
1003  pixel_ptr += 3;
1004  pixel_countdown--;
1005  if (pixel_countdown < 0)
1006  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1007  pixel_countdown);
1008  }
1009  }
1010  }
1011 
1012  y_ptr += s->frame->linesize[0];
1013  }
1014  break;
1015 
1016  case FLI_COPY:
1017  case FLI_DTA_COPY:
1018  /* copy the chunk (uncompressed frame) */
1019  if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*3) {
1020  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
1021  "bigger than image, skipping chunk\n", chunk_size - 6);
1022  bytestream2_skip(&g2, chunk_size - 6);
1023  } else {
1024  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
1025  y_ptr += s->frame->linesize[0]) {
1026 
1027  bytestream2_get_buffer(&g2, pixels + y_ptr, 3*s->avctx->width);
1028  if (s->avctx->width & 1)
1029  bytestream2_skip(&g2, 3);
1030  }
1031  }
1032  break;
1033 
1034  case FLI_MINI:
1035  /* some sort of a thumbnail? disregard this chunk... */
1036  bytestream2_skip(&g2, chunk_size - 6);
1037  break;
1038 
1039  default:
1040  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1041  break;
1042  }
1043 
1044  if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
1045  bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
1046  } else {
1047  av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
1048  break;
1049  }
1050 
1051  frame_size -= chunk_size;
1052  num_chunks--;
1053  }
1054 
1055  /* by the end of the chunk, the stream ptr should equal the frame
1056  * size (minus 1, possibly); if it doesn't, issue a warning */
1057  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
1058  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
1059  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
1060 
1061  if ((ret = av_frame_ref(data, s->frame)) < 0)
1062  return ret;
1063 
1064  *got_frame = 1;
1065 
1066  return buf_size;
1067 }
1068 
1070  void *data, int *got_frame,
1071  AVPacket *avpkt)
1072 {
1073  const uint8_t *buf = avpkt->data;
1074  int buf_size = avpkt->size;
1075  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1076  return flic_decode_frame_8BPP(avctx, data, got_frame,
1077  buf, buf_size);
1078  } else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
1079  (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
1080  return flic_decode_frame_15_16BPP(avctx, data, got_frame,
1081  buf, buf_size);
1082  } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
1083  return flic_decode_frame_24BPP(avctx, data, got_frame,
1084  buf, buf_size);
1085  }
1086 
1087  /* Should not get here, ever as the pix_fmt is processed */
1088  /* in flic_decode_init and the above if should deal with */
1089  /* the finite set of possibilities allowable by here. */
1090  /* But in case we do, just error out. */
1091  av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
1092  return AVERROR_BUG;
1093 }
1094 
1095 
1097 {
1098  FlicDecodeContext *s = avctx->priv_data;
1099 
1100  av_frame_free(&s->frame);
1101 
1102  return 0;
1103 }
1104 
1106  .name = "flic",
1107  .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
1108  .type = AVMEDIA_TYPE_VIDEO,
1109  .id = AV_CODEC_ID_FLIC,
1110  .priv_data_size = sizeof(FlicDecodeContext),
1112  .close = flic_decode_end,
1114  .capabilities = AV_CODEC_CAP_DR1,
1115 };
#define FLI_DTA_COPY
Definition: flicvideo.c:56
AVCodecContext * avctx
Definition: flicvideo.c:72
#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:295
#define FLI_TYPE_CODE
Definition: flicvideo.c:59
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
#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:115
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define FLI_COPY
Definition: flicvideo.c:53
int size
Definition: avcodec.h:1481
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
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:489
AVCodec.
Definition: avcodec.h:3492
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 void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
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:464
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:189
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
#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:443
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1669
uint8_t * data
Definition: avcodec.h:1480
#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 i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
#define FLI_BRUN
Definition: flicvideo.c:52
AVFrame * frame
Definition: flicvideo.c:73
static int flic_decode_frame_24BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:789
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:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available...
Definition: decode.c:2015
const char * r
Definition: vf_curves.c:114
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
Definition: flicvideo.c:62
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
#define b
Definition: input.c:41
#define FLI_DTA_BRUN
Definition: flicvideo.c:55
int width
picture width / height.
Definition: avcodec.h:1741
#define FLC_FLX_TYPE_CODE
Definition: flicvideo.c:60
#define FLI_256_COLOR
Definition: flicvideo.c:47
#define s(width, name)
Definition: cbs_vp9.c:257
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
#define FLI_DELTA
Definition: flicvideo.c:48
if(ret)
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
int frame_size
Definition: mxfenc.c:2223
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
main external API structure.
Definition: avcodec.h:1568
void * buf
Definition: avisynth_c.h:766
#define FLI_DTA_LC
Definition: flicvideo.c:57
int extradata_size
Definition: avcodec.h:1670
#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:1069
static av_cold int flic_decode_end(AVCodecContext *avctx)
Definition: flicvideo.c:1096
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:452
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:309
#define FLI_BLACK
Definition: flicvideo.c:51
common internal api header.
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:793
void * priv_data
Definition: avcodec.h:1595
int pixels
Definition: avisynth_c.h:390
unsigned int palette[256]
Definition: flicvideo.c:75
AVCodec ff_flic_decoder
Definition: flicvideo.c:1105
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:374
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
This structure stores compressed data.
Definition: avcodec.h:1457
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:984