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