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  if (bytestream2_get_bytes_left(&g2) < 2 * s->avctx->width * s->avctx->height )
739  return AVERROR_INVALIDDATA;
740  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
741  y_ptr += s->frame->linesize[0]) {
742 
743  pixel_countdown = s->avctx->width;
744  pixel_ptr = 0;
745  while (pixel_countdown > 0) {
746  *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
747  pixel_ptr += 2;
748  pixel_countdown--;
749  }
750  if (s->avctx->width & 1)
751  bytestream2_skip(&g2, 2);
752  }
753  }
754  break;
755 
756  case FLI_MINI:
757  /* some sort of a thumbnail? disregard this chunk... */
758  bytestream2_skip(&g2, chunk_size - 6);
759  break;
760 
761  default:
762  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
763  break;
764  }
765 
766  if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
767  bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
768  } else {
769  av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
770  break;
771  }
772 
773  frame_size -= chunk_size;
774  num_chunks--;
775  }
776 
777  /* by the end of the chunk, the stream ptr should equal the frame
778  * size (minus 1, possibly); if it doesn't, issue a warning */
779  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
780  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
781  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
782 
783  if ((ret = av_frame_ref(data, s->frame)) < 0)
784  return ret;
785 
786  *got_frame = 1;
787 
788  return buf_size;
789 }
790 
792  void *data, int *got_frame,
793  const uint8_t *buf, int buf_size)
794 {
795  FlicDecodeContext *s = avctx->priv_data;
796 
797  GetByteContext g2;
798  int pixel_ptr;
799  unsigned char palette_idx1;
800 
801  unsigned int frame_size;
802  int num_chunks;
803 
804  unsigned int chunk_size;
805  int chunk_type;
806 
807  int i, j, ret;
808 
809  int lines;
810  int compressed_lines;
811  int line_packets;
812  int y_ptr;
813  int byte_run;
814  int pixel_skip;
815  int pixel_countdown;
816  unsigned char *pixels;
817  int pixel;
818  unsigned int pixel_limit;
819 
820  bytestream2_init(&g2, buf, buf_size);
821 
822  if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
823  return ret;
824 
825  pixels = s->frame->data[0];
826  pixel_limit = s->avctx->height * s->frame->linesize[0];
827 
828  frame_size = bytestream2_get_le32(&g2);
829  bytestream2_skip(&g2, 2); /* skip the magic number */
830  num_chunks = bytestream2_get_le16(&g2);
831  bytestream2_skip(&g2, 8); /* skip padding */
832  if (frame_size > buf_size)
833  frame_size = buf_size;
834 
835  if (frame_size < 16)
836  return AVERROR_INVALIDDATA;
837  frame_size -= 16;
838 
839  /* iterate through the chunks */
840  while ((frame_size > 0) && (num_chunks > 0) &&
841  bytestream2_get_bytes_left(&g2) >= 4) {
842  int stream_ptr_after_chunk;
843  chunk_size = bytestream2_get_le32(&g2);
844  if (chunk_size > frame_size) {
845  av_log(avctx, AV_LOG_WARNING,
846  "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
847  chunk_size = frame_size;
848  }
849  stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
850 
851  chunk_type = bytestream2_get_le16(&g2);
852 
853 
854  switch (chunk_type) {
855  case FLI_256_COLOR:
856  case FLI_COLOR:
857  /* For some reason, it seems that non-palettized flics do
858  * include one of these chunks in their first frame.
859  * Why I do not know, it seems rather extraneous. */
860  ff_dlog(avctx,
861  "Unexpected Palette chunk %d in non-palettized FLC\n",
862  chunk_type);
863  bytestream2_skip(&g2, chunk_size - 6);
864  break;
865 
866  case FLI_DELTA:
867  case FLI_DTA_LC:
868  y_ptr = 0;
869  compressed_lines = bytestream2_get_le16(&g2);
870  while (compressed_lines > 0) {
871  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
872  break;
873  if (y_ptr > pixel_limit)
874  return AVERROR_INVALIDDATA;
875  line_packets = sign_extend(bytestream2_get_le16(&g2), 16);
876  if (line_packets < 0) {
877  line_packets = -line_packets;
878  if (line_packets > s->avctx->height)
879  return AVERROR_INVALIDDATA;
880  y_ptr += line_packets * s->frame->linesize[0];
881  } else {
882  compressed_lines--;
883  pixel_ptr = y_ptr;
884  CHECK_PIXEL_PTR(0);
885  pixel_countdown = s->avctx->width;
886  for (i = 0; i < line_packets; i++) {
887  /* account for the skip bytes */
888  if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
889  break;
890  pixel_skip = bytestream2_get_byte(&g2);
891  pixel_ptr += (pixel_skip*3); /* Pixel is 3 bytes wide */
892  pixel_countdown -= pixel_skip;
893  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
894  if (byte_run < 0) {
895  byte_run = -byte_run;
896  pixel = bytestream2_get_le24(&g2);
897  CHECK_PIXEL_PTR(3 * byte_run);
898  for (j = 0; j < byte_run; j++, pixel_countdown -= 1) {
899  AV_WL24(&pixels[pixel_ptr], pixel);
900  pixel_ptr += 3;
901  }
902  } else {
903  if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
904  break;
905  CHECK_PIXEL_PTR(3 * byte_run);
906  for (j = 0; j < byte_run; j++, pixel_countdown--) {
907  pixel = bytestream2_get_le24(&g2);
908  AV_WL24(&pixels[pixel_ptr], pixel);
909  pixel_ptr += 3;
910  }
911  }
912  }
913 
914  y_ptr += s->frame->linesize[0];
915  }
916  }
917  break;
918 
919  case FLI_LC:
920  av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
921  bytestream2_skip(&g2, chunk_size - 6);
922  break;
923 
924  case FLI_BLACK:
925  /* set the whole frame to 0x00 which is black for 24 bit mode. */
926  memset(pixels, 0x00,
927  s->frame->linesize[0] * s->avctx->height);
928  break;
929 
930  case FLI_BRUN:
931  y_ptr = 0;
932  for (lines = 0; lines < s->avctx->height; lines++) {
933  pixel_ptr = y_ptr;
934  /* disregard the line packets; instead, iterate through all
935  * pixels on a row */
936  bytestream2_skip(&g2, 1);
937  pixel_countdown = (s->avctx->width * 3);
938 
939  while (pixel_countdown > 0) {
940  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
941  break;
942  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
943  if (byte_run > 0) {
944  palette_idx1 = bytestream2_get_byte(&g2);
945  CHECK_PIXEL_PTR(byte_run);
946  for (j = 0; j < byte_run; j++) {
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) (linea%d)\n",
951  pixel_countdown, lines);
952  }
953  } else { /* copy bytes if byte_run < 0 */
954  byte_run = -byte_run;
955  if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
956  break;
957  CHECK_PIXEL_PTR(byte_run);
958  for (j = 0; j < byte_run; j++) {
959  palette_idx1 = bytestream2_get_byte(&g2);
960  pixels[pixel_ptr++] = palette_idx1;
961  pixel_countdown--;
962  if (pixel_countdown < 0)
963  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
964  pixel_countdown, lines);
965  }
966  }
967  }
968 
969  y_ptr += s->frame->linesize[0];
970  }
971  break;
972 
973  case FLI_DTA_BRUN:
974  y_ptr = 0;
975  for (lines = 0; lines < s->avctx->height; lines++) {
976  pixel_ptr = y_ptr;
977  /* disregard the line packets; instead, iterate through all
978  * pixels on a row */
979  bytestream2_skip(&g2, 1);
980  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
981 
982  while (pixel_countdown > 0) {
983  if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
984  break;
985  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
986  if (byte_run > 0) {
987  pixel = bytestream2_get_le24(&g2);
988  CHECK_PIXEL_PTR(3 * byte_run);
989  for (j = 0; j < byte_run; j++) {
990  AV_WL24(pixels + pixel_ptr, pixel);
991  pixel_ptr += 3;
992  pixel_countdown--;
993  if (pixel_countdown < 0)
994  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
995  pixel_countdown);
996  }
997  } else { /* copy pixels if byte_run < 0 */
998  byte_run = -byte_run;
999  if (bytestream2_tell(&g2) + 3 * byte_run > stream_ptr_after_chunk)
1000  break;
1001  CHECK_PIXEL_PTR(3 * byte_run);
1002  for (j = 0; j < byte_run; j++) {
1003  pixel = bytestream2_get_le24(&g2);
1004  AV_WL24(pixels + pixel_ptr, pixel);
1005  pixel_ptr += 3;
1006  pixel_countdown--;
1007  if (pixel_countdown < 0)
1008  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
1009  pixel_countdown);
1010  }
1011  }
1012  }
1013 
1014  y_ptr += s->frame->linesize[0];
1015  }
1016  break;
1017 
1018  case FLI_COPY:
1019  case FLI_DTA_COPY:
1020  /* copy the chunk (uncompressed frame) */
1021  if (chunk_size - 6 > (unsigned int)(FFALIGN(s->avctx->width, 2) * s->avctx->height)*3) {
1022  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
1023  "bigger than image, skipping chunk\n", chunk_size - 6);
1024  bytestream2_skip(&g2, chunk_size - 6);
1025  } else {
1026  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
1027  y_ptr += s->frame->linesize[0]) {
1028 
1029  bytestream2_get_buffer(&g2, pixels + y_ptr, 3*s->avctx->width);
1030  if (s->avctx->width & 1)
1031  bytestream2_skip(&g2, 3);
1032  }
1033  }
1034  break;
1035 
1036  case FLI_MINI:
1037  /* some sort of a thumbnail? disregard this chunk... */
1038  bytestream2_skip(&g2, chunk_size - 6);
1039  break;
1040 
1041  default:
1042  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
1043  break;
1044  }
1045 
1046  if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
1047  bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
1048  } else {
1049  av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
1050  break;
1051  }
1052 
1053  frame_size -= chunk_size;
1054  num_chunks--;
1055  }
1056 
1057  /* by the end of the chunk, the stream ptr should equal the frame
1058  * size (minus 1, possibly); if it doesn't, issue a warning */
1059  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
1060  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
1061  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
1062 
1063  if ((ret = av_frame_ref(data, s->frame)) < 0)
1064  return ret;
1065 
1066  *got_frame = 1;
1067 
1068  return buf_size;
1069 }
1070 
1072  void *data, int *got_frame,
1073  AVPacket *avpkt)
1074 {
1075  const uint8_t *buf = avpkt->data;
1076  int buf_size = avpkt->size;
1077  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
1078  return flic_decode_frame_8BPP(avctx, data, got_frame,
1079  buf, buf_size);
1080  } else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
1081  (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
1082  return flic_decode_frame_15_16BPP(avctx, data, got_frame,
1083  buf, buf_size);
1084  } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
1085  return flic_decode_frame_24BPP(avctx, data, got_frame,
1086  buf, buf_size);
1087  }
1088 
1089  /* Should not get here, ever as the pix_fmt is processed */
1090  /* in flic_decode_init and the above if should deal with */
1091  /* the finite set of possibilities allowable by here. */
1092  /* But in case we do, just error out. */
1093  av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
1094  return AVERROR_BUG;
1095 }
1096 
1097 
1099 {
1100  FlicDecodeContext *s = avctx->priv_data;
1101 
1102  av_frame_free(&s->frame);
1103 
1104  return 0;
1105 }
1106 
1108  .name = "flic",
1109  .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
1110  .type = AVMEDIA_TYPE_VIDEO,
1111  .id = AV_CODEC_ID_FLIC,
1112  .priv_data_size = sizeof(FlicDecodeContext),
1114  .close = flic_decode_end,
1116  .capabilities = AV_CODEC_CAP_DR1,
1117  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
1118 };
AVCodec
AVCodec.
Definition: codec.h:202
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:42
flic_decode_end
static av_cold int flic_decode_end(AVCodecContext *avctx)
Definition: flicvideo.c:1098
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
FLC_FLX_TYPE_CODE
#define FLC_FLX_TYPE_CODE
Definition: flicvideo.c:60
r
const char * r
Definition: vf_curves.c:116
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
GetByteContext
Definition: bytestream.h:33
FLI_BRUN
#define FLI_BRUN
Definition: flicvideo.c:52
FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
Definition: flicvideo.c:62
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:112
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:310
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
b
#define b
Definition: input.c:40
AV_CODEC_ID_FLIC
@ AV_CODEC_ID_FLIC
Definition: codec_id.h:100
data
const char data[16]
Definition: mxf.c:143
FLI_COLOR
#define FLI_COLOR
Definition: flicvideo.c:49
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:69
ff_flic_decoder
const AVCodec ff_flic_decoder
Definition: flicvideo.c:1107
flic_decode_frame
static int flic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: flicvideo.c:1071
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
FlicDecodeContext::fli_type
int fli_type
Definition: flicvideo.c:77
U
#define U(x)
Definition: vp56_arith.h:37
FLI_BLACK
#define FLI_BLACK
Definition: flicvideo.c:51
flic_decode_init
static av_cold int flic_decode_init(AVCodecContext *avctx)
Definition: flicvideo.c:80
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:99
FlicDecodeContext::frame
AVFrame * frame
Definition: flicvideo.c:73
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:485
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
g
const char * g
Definition: vf_curves.c:117
frame_size
int frame_size
Definition: mxfenc.c:2198
FLI_TYPE_CODE
#define FLI_TYPE_CODE
Definition: flicvideo.c:59
FLI_DTA_BRUN
#define FLI_DTA_BRUN
Definition: flicvideo.c:55
CHECK_PIXEL_PTR
#define CHECK_PIXEL_PTR(n)
Definition: flicvideo.c:64
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
if
if(ret)
Definition: filter_design.txt:179
FLI_DELTA
#define FLI_DELTA
Definition: flicvideo.c:48
pixel
uint8_t pixel
Definition: tiny_ssim.c:42
AVPALETTE_SIZE
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
AV_WL24
#define AV_WL24(p, d)
Definition: intreadwrite.h:464
mathops.h
bytestream2_get_buffer
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
bytestream2_tell
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:192
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:29
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
av_frame_ref
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:327
FLI_MINI
#define FLI_MINI
Definition: flicvideo.c:54
FLI_COPY
#define FLI_COPY
Definition: flicvideo.c:53
FLI_LC
#define FLI_LC
Definition: flicvideo.c:50
FlicDecodeContext
Definition: flicvideo.c:71
flic_decode_frame_15_16BPP
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
FLI_DTA_COPY
#define FLI_DTA_COPY
Definition: flicvideo.c:56
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:484
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:392
flic_decode_frame_24BPP
static int flic_decode_frame_24BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:791
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
AV_PIX_FMT_RGB565
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:391
avcodec.h
AV_PIX_FMT_PAL8
@ AV_PIX_FMT_PAL8
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
ff_reget_buffer
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:1758
ret
ret
Definition: filter_design.txt:187
FlicDecodeContext::avctx
AVCodecContext * avctx
Definition: flicvideo.c:72
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:92
AVCodecContext
main external API structure.
Definition: avcodec.h:383
FLI_DTA_LC
#define FLI_DTA_LC
Definition: flicvideo.c:57
sign_extend
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:130
FLI_256_COLOR
#define FLI_256_COLOR
Definition: flicvideo.c:47
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
flic_decode_frame_8BPP
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:150
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
bytestream.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
FlicDecodeContext::palette
unsigned int palette[256]
Definition: flicvideo.c:75
FlicDecodeContext::new_palette
int new_palette
Definition: flicvideo.c:76