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