Libav
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 Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 
42 #include "libavutil/intreadwrite.h"
43 #include "avcodec.h"
44 #include "bytestream.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_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %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 != 12 &&
88  avctx->extradata_size != 128) {
89  av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
90  return AVERROR_INVALIDDATA;
91  }
92 
93  s->avctx = avctx;
94 
95  s->fli_type = AV_RL16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
96 
97  depth = 0;
98  if (s->avctx->extradata_size == 12) {
99  /* special case for magic carpet FLIs */
101  depth = 8;
102  } else {
103  depth = AV_RL16(&fli_header[12]);
104  }
105 
106  if (depth == 0) {
107  depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
108  }
109 
110  if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
111  depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
112  }
113 
114  switch (depth) {
115  case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
116  case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
117  case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
118  case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
119  av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
120  return AVERROR_PATCHWELCOME;
121  default :
122  av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
123  return AVERROR_INVALIDDATA;
124  }
125 
126  s->frame = av_frame_alloc();
127  if (!s->frame)
128  return AVERROR(ENOMEM);
129 
130  s->new_palette = 0;
131 
132  return 0;
133 }
134 
136  void *data, int *got_frame,
137  const uint8_t *buf, int buf_size)
138 {
139  FlicDecodeContext *s = avctx->priv_data;
140 
141  GetByteContext g2;
142  int stream_ptr_after_color_chunk;
143  int pixel_ptr;
144  int palette_ptr;
145  unsigned char palette_idx1;
146  unsigned char palette_idx2;
147 
148  unsigned int frame_size;
149  int num_chunks;
150 
151  unsigned int chunk_size;
152  int chunk_type;
153 
154  int i, j, ret;
155 
156  int color_packets;
157  int color_changes;
158  int color_shift;
159  unsigned char r, g, b;
160 
161  int lines;
162  int compressed_lines;
163  int starting_line;
164  signed short line_packets;
165  int y_ptr;
166  int byte_run;
167  int pixel_skip;
168  int pixel_countdown;
169  unsigned char *pixels;
170  unsigned int pixel_limit;
171 
172  bytestream2_init(&g2, buf, buf_size);
173 
174  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
175  av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
176  return ret;
177  }
178 
179  pixels = s->frame->data[0];
180  pixel_limit = s->avctx->height * s->frame->linesize[0];
181  frame_size = bytestream2_get_le32(&g2);
182  bytestream2_skip(&g2, 2); /* skip the magic number */
183  num_chunks = bytestream2_get_le16(&g2);
184  bytestream2_skip(&g2, 8); /* skip padding */
185 
186  frame_size -= 16;
187 
188  /* iterate through the chunks */
189  while ((frame_size > 0) && (num_chunks > 0)) {
190  chunk_size = bytestream2_get_le32(&g2);
191  chunk_type = bytestream2_get_le16(&g2);
192 
193  switch (chunk_type) {
194  case FLI_256_COLOR:
195  case FLI_COLOR:
196  stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6;
197 
198  /* check special case: If this file is from the Magic Carpet
199  * game and uses 6-bit colors even though it reports 256-color
200  * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
201  * initialization) */
202  if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
203  color_shift = 0;
204  else
205  color_shift = 2;
206  /* set up the palette */
207  color_packets = bytestream2_get_le16(&g2);
208  palette_ptr = 0;
209  for (i = 0; i < color_packets; i++) {
210  /* first byte is how many colors to skip */
211  palette_ptr += bytestream2_get_byte(&g2);
212 
213  /* next byte indicates how many entries to change */
214  color_changes = bytestream2_get_byte(&g2);
215 
216  /* if there are 0 color changes, there are actually 256 */
217  if (color_changes == 0)
218  color_changes = 256;
219 
220  for (j = 0; j < color_changes; j++) {
221  unsigned int entry;
222 
223  /* wrap around, for good measure */
224  if ((unsigned)palette_ptr >= 256)
225  palette_ptr = 0;
226 
227  r = bytestream2_get_byte(&g2) << color_shift;
228  g = bytestream2_get_byte(&g2) << color_shift;
229  b = bytestream2_get_byte(&g2) << color_shift;
230  entry = (r << 16) | (g << 8) | b;
231  if (s->palette[palette_ptr] != entry)
232  s->new_palette = 1;
233  s->palette[palette_ptr++] = entry;
234  }
235  }
236 
237  /* color chunks sometimes have weird 16-bit alignment issues;
238  * therefore, take the hardline approach and skip
239  * to the value calculated w.r.t. the size specified by the color
240  * chunk header */
241  if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0)
242  bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2));
243 
244  break;
245 
246  case FLI_DELTA:
247  y_ptr = 0;
248  compressed_lines = bytestream2_get_le16(&g2);
249  while (compressed_lines > 0) {
250  line_packets = bytestream2_get_le16(&g2);
251  if ((line_packets & 0xC000) == 0xC000) {
252  // line skip opcode
253  line_packets = -line_packets;
254  y_ptr += line_packets * s->frame->linesize[0];
255  } else if ((line_packets & 0xC000) == 0x4000) {
256  av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
257  } else if ((line_packets & 0xC000) == 0x8000) {
258  // "last byte" opcode
259  pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
260  CHECK_PIXEL_PTR(0);
261  pixels[pixel_ptr] = line_packets & 0xff;
262  } else {
263  compressed_lines--;
264  pixel_ptr = y_ptr;
265  CHECK_PIXEL_PTR(0);
266  pixel_countdown = s->avctx->width;
267  for (i = 0; i < line_packets; i++) {
268  /* account for the skip bytes */
269  pixel_skip = bytestream2_get_byte(&g2);
270  pixel_ptr += pixel_skip;
271  pixel_countdown -= pixel_skip;
272  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
273  if (byte_run < 0) {
274  byte_run = -byte_run;
275  palette_idx1 = bytestream2_get_byte(&g2);
276  palette_idx2 = bytestream2_get_byte(&g2);
277  CHECK_PIXEL_PTR(byte_run * 2);
278  for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
279  pixels[pixel_ptr++] = palette_idx1;
280  pixels[pixel_ptr++] = palette_idx2;
281  }
282  } else {
283  CHECK_PIXEL_PTR(byte_run * 2);
284  for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
285  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
286  }
287  }
288  }
289 
290  y_ptr += s->frame->linesize[0];
291  }
292  }
293  break;
294 
295  case FLI_LC:
296  /* line compressed */
297  starting_line = bytestream2_get_le16(&g2);
298  y_ptr = 0;
299  y_ptr += starting_line * s->frame->linesize[0];
300 
301  compressed_lines = bytestream2_get_le16(&g2);
302  while (compressed_lines > 0) {
303  pixel_ptr = y_ptr;
304  CHECK_PIXEL_PTR(0);
305  pixel_countdown = s->avctx->width;
306  line_packets = bytestream2_get_byte(&g2);
307  if (line_packets > 0) {
308  for (i = 0; i < line_packets; i++) {
309  /* account for the skip bytes */
310  pixel_skip = bytestream2_get_byte(&g2);
311  pixel_ptr += pixel_skip;
312  pixel_countdown -= pixel_skip;
313  byte_run = sign_extend(bytestream2_get_byte(&g2),8);
314  if (byte_run > 0) {
315  CHECK_PIXEL_PTR(byte_run);
316  for (j = 0; j < byte_run; j++, pixel_countdown--) {
317  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
318  }
319  } else if (byte_run < 0) {
320  byte_run = -byte_run;
321  palette_idx1 = bytestream2_get_byte(&g2);
322  CHECK_PIXEL_PTR(byte_run);
323  for (j = 0; j < byte_run; j++, pixel_countdown--) {
324  pixels[pixel_ptr++] = palette_idx1;
325  }
326  }
327  }
328  }
329 
330  y_ptr += s->frame->linesize[0];
331  compressed_lines--;
332  }
333  break;
334 
335  case FLI_BLACK:
336  /* set the whole frame to color 0 (which is usually black) */
337  memset(pixels, 0,
338  s->frame->linesize[0] * s->avctx->height);
339  break;
340 
341  case FLI_BRUN:
342  /* Byte run compression: This chunk type only occurs in the first
343  * FLI frame and it will update the entire frame. */
344  y_ptr = 0;
345  for (lines = 0; lines < s->avctx->height; lines++) {
346  pixel_ptr = y_ptr;
347  /* disregard the line packets; instead, iterate through all
348  * pixels on a row */
349  bytestream2_skip(&g2, 1);
350  pixel_countdown = s->avctx->width;
351  while (pixel_countdown > 0) {
352  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
353  if (!byte_run) {
354  av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
355  return AVERROR_INVALIDDATA;
356  }
357 
358  if (byte_run > 0) {
359  palette_idx1 = bytestream2_get_byte(&g2);
360  CHECK_PIXEL_PTR(byte_run);
361  for (j = 0; j < byte_run; j++) {
362  pixels[pixel_ptr++] = palette_idx1;
363  pixel_countdown--;
364  if (pixel_countdown < 0)
365  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
366  pixel_countdown, lines);
367  }
368  } else { /* copy bytes if byte_run < 0 */
369  byte_run = -byte_run;
370  CHECK_PIXEL_PTR(byte_run);
371  for (j = 0; j < byte_run; j++) {
372  pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
373  pixel_countdown--;
374  if (pixel_countdown < 0)
375  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
376  pixel_countdown, lines);
377  }
378  }
379  }
380 
381  y_ptr += s->frame->linesize[0];
382  }
383  break;
384 
385  case FLI_COPY:
386  /* copy the chunk (uncompressed frame) */
387  if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
388  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
389  "bigger than image, skipping chunk\n", chunk_size - 6);
390  bytestream2_skip(&g2, chunk_size - 6);
391  } else {
392  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
393  y_ptr += s->frame->linesize[0]) {
394  bytestream2_get_buffer(&g2, &pixels[y_ptr],
395  s->avctx->width);
396  }
397  }
398  break;
399 
400  case FLI_MINI:
401  /* some sort of a thumbnail? disregard this chunk... */
402  bytestream2_skip(&g2, chunk_size - 6);
403  break;
404 
405  default:
406  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
407  break;
408  }
409 
410  frame_size -= chunk_size;
411  num_chunks--;
412  }
413 
414  /* by the end of the chunk, the stream ptr should equal the frame
415  * size (minus 1, possibly); if it doesn't, issue a warning */
416  if ((bytestream2_get_bytes_left(&g2) != 0) &&
417  (bytestream2_get_bytes_left(&g2) != 1))
418  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
419  "and final chunk ptr = %d\n", buf_size,
420  buf_size - bytestream2_get_bytes_left(&g2));
421 
422  /* make the palette available on the way out */
423  memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
424  if (s->new_palette) {
425  s->frame->palette_has_changed = 1;
426  s->new_palette = 0;
427  }
428 
429  if ((ret = av_frame_ref(data, s->frame)) < 0)
430  return ret;
431 
432  *got_frame = 1;
433 
434  return buf_size;
435 }
436 
438  void *data, int *got_frame,
439  const uint8_t *buf, int buf_size)
440 {
441  /* Note, the only difference between the 15Bpp and 16Bpp */
442  /* Format is the pixel format, the packets are processed the same. */
443  FlicDecodeContext *s = avctx->priv_data;
444 
445  GetByteContext g2;
446  int pixel_ptr;
447  unsigned char palette_idx1;
448 
449  unsigned int frame_size;
450  int num_chunks;
451 
452  unsigned int chunk_size;
453  int chunk_type;
454 
455  int i, j, ret;
456 
457  int lines;
458  int compressed_lines;
459  signed short line_packets;
460  int y_ptr;
461  int byte_run;
462  int pixel_skip;
463  int pixel_countdown;
464  unsigned char *pixels;
465  int pixel;
466  unsigned int pixel_limit;
467 
468  bytestream2_init(&g2, buf, buf_size);
469 
470  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
471  av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
472  return ret;
473  }
474 
475  pixels = s->frame->data[0];
476  pixel_limit = s->avctx->height * s->frame->linesize[0];
477 
478  frame_size = bytestream2_get_le32(&g2);
479  bytestream2_skip(&g2, 2); /* skip the magic number */
480  num_chunks = bytestream2_get_le16(&g2);
481  bytestream2_skip(&g2, 8); /* skip padding */
482 
483  frame_size -= 16;
484 
485  /* iterate through the chunks */
486  while ((frame_size > 0) && (num_chunks > 0)) {
487  chunk_size = bytestream2_get_le32(&g2);
488  chunk_type = bytestream2_get_le16(&g2);
489 
490  switch (chunk_type) {
491  case FLI_256_COLOR:
492  case FLI_COLOR:
493  /* For some reason, it seems that non-palettized flics do
494  * include one of these chunks in their first frame.
495  * Why I do not know, it seems rather extraneous. */
496  av_dlog(avctx,
497  "Unexpected Palette chunk %d in non-palettized FLC\n",
498  chunk_type);
499  bytestream2_skip(&g2, chunk_size - 6);
500  break;
501 
502  case FLI_DELTA:
503  case FLI_DTA_LC:
504  y_ptr = 0;
505  compressed_lines = bytestream2_get_le16(&g2);
506  while (compressed_lines > 0) {
507  line_packets = bytestream2_get_le16(&g2);
508  if (line_packets < 0) {
509  line_packets = -line_packets;
510  y_ptr += line_packets * s->frame->linesize[0];
511  } else {
512  compressed_lines--;
513  pixel_ptr = y_ptr;
514  CHECK_PIXEL_PTR(0);
515  pixel_countdown = s->avctx->width;
516  for (i = 0; i < line_packets; i++) {
517  /* account for the skip bytes */
518  pixel_skip = bytestream2_get_byte(&g2);
519  pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
520  pixel_countdown -= pixel_skip;
521  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
522  if (byte_run < 0) {
523  byte_run = -byte_run;
524  pixel = bytestream2_get_le16(&g2);
525  CHECK_PIXEL_PTR(2 * byte_run);
526  for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
527  *((signed short*)(&pixels[pixel_ptr])) = pixel;
528  pixel_ptr += 2;
529  }
530  } else {
531  CHECK_PIXEL_PTR(2 * byte_run);
532  for (j = 0; j < byte_run; j++, pixel_countdown--) {
533  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
534  pixel_ptr += 2;
535  }
536  }
537  }
538 
539  y_ptr += s->frame->linesize[0];
540  }
541  }
542  break;
543 
544  case FLI_LC:
545  av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
546  bytestream2_skip(&g2, chunk_size - 6);
547  break;
548 
549  case FLI_BLACK:
550  /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
551  memset(pixels, 0x0000,
552  s->frame->linesize[0] * s->avctx->height);
553  break;
554 
555  case FLI_BRUN:
556  y_ptr = 0;
557  for (lines = 0; lines < s->avctx->height; lines++) {
558  pixel_ptr = y_ptr;
559  /* disregard the line packets; instead, iterate through all
560  * pixels on a row */
561  bytestream2_skip(&g2, 1);
562  pixel_countdown = (s->avctx->width * 2);
563 
564  while (pixel_countdown > 0) {
565  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
566  if (byte_run > 0) {
567  palette_idx1 = bytestream2_get_byte(&g2);
568  CHECK_PIXEL_PTR(byte_run);
569  for (j = 0; j < byte_run; j++) {
570  pixels[pixel_ptr++] = palette_idx1;
571  pixel_countdown--;
572  if (pixel_countdown < 0)
573  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
574  pixel_countdown, lines);
575  }
576  } else { /* copy bytes if byte_run < 0 */
577  byte_run = -byte_run;
578  CHECK_PIXEL_PTR(byte_run);
579  for (j = 0; j < byte_run; j++) {
580  palette_idx1 = bytestream2_get_byte(&g2);
581  pixels[pixel_ptr++] = palette_idx1;
582  pixel_countdown--;
583  if (pixel_countdown < 0)
584  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
585  pixel_countdown, lines);
586  }
587  }
588  }
589 
590  /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
591  * This does not give us any good opportunity to perform word endian conversion
592  * during decompression. So if it is required (i.e., this is not a LE target, we do
593  * a second pass over the line here, swapping the bytes.
594  */
595 #if HAVE_BIGENDIAN
596  pixel_ptr = y_ptr;
597  pixel_countdown = s->avctx->width;
598  while (pixel_countdown > 0) {
599  *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
600  pixel_ptr += 2;
601  }
602 #endif
603  y_ptr += s->frame->linesize[0];
604  }
605  break;
606 
607  case FLI_DTA_BRUN:
608  y_ptr = 0;
609  for (lines = 0; lines < s->avctx->height; lines++) {
610  pixel_ptr = y_ptr;
611  /* disregard the line packets; instead, iterate through all
612  * pixels on a row */
613  bytestream2_skip(&g2, 1);
614  pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
615 
616  while (pixel_countdown > 0) {
617  byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
618  if (byte_run > 0) {
619  pixel = bytestream2_get_le16(&g2);
620  CHECK_PIXEL_PTR(2 * byte_run);
621  for (j = 0; j < byte_run; j++) {
622  *((signed short*)(&pixels[pixel_ptr])) = pixel;
623  pixel_ptr += 2;
624  pixel_countdown--;
625  if (pixel_countdown < 0)
626  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
627  pixel_countdown);
628  }
629  } else { /* copy pixels if byte_run < 0 */
630  byte_run = -byte_run;
631  CHECK_PIXEL_PTR(2 * byte_run);
632  for (j = 0; j < byte_run; j++) {
633  *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
634  pixel_ptr += 2;
635  pixel_countdown--;
636  if (pixel_countdown < 0)
637  av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
638  pixel_countdown);
639  }
640  }
641  }
642 
643  y_ptr += s->frame->linesize[0];
644  }
645  break;
646 
647  case FLI_COPY:
648  case FLI_DTA_COPY:
649  /* copy the chunk (uncompressed frame) */
650  if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
651  av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
652  "bigger than image, skipping chunk\n", chunk_size - 6);
653  bytestream2_skip(&g2, chunk_size - 6);
654  } else {
655 
656  for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
657  y_ptr += s->frame->linesize[0]) {
658 
659  pixel_countdown = s->avctx->width;
660  pixel_ptr = 0;
661  while (pixel_countdown > 0) {
662  *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
663  pixel_ptr += 2;
664  pixel_countdown--;
665  }
666  }
667  }
668  break;
669 
670  case FLI_MINI:
671  /* some sort of a thumbnail? disregard this chunk... */
672  bytestream2_skip(&g2, chunk_size - 6);
673  break;
674 
675  default:
676  av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
677  break;
678  }
679 
680  frame_size -= chunk_size;
681  num_chunks--;
682  }
683 
684  /* by the end of the chunk, the stream ptr should equal the frame
685  * size (minus 1, possibly); if it doesn't, issue a warning */
686  if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
687  av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
688  "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
689 
690  if ((ret = av_frame_ref(data, s->frame)) < 0)
691  return ret;
692 
693  *got_frame = 1;
694 
695  return buf_size;
696 }
697 
699  void *data, int *got_frame,
700  const uint8_t *buf, int buf_size)
701 {
702  av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
703  return AVERROR_PATCHWELCOME;
704 }
705 
707  void *data, int *got_frame,
708  AVPacket *avpkt)
709 {
710  const uint8_t *buf = avpkt->data;
711  int buf_size = avpkt->size;
712  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
713  return flic_decode_frame_8BPP(avctx, data, got_frame,
714  buf, buf_size);
715  }
716  else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
717  (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
718  return flic_decode_frame_15_16BPP(avctx, data, got_frame,
719  buf, buf_size);
720  }
721  else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
722  return flic_decode_frame_24BPP(avctx, data, got_frame,
723  buf, buf_size);
724  }
725 
726  /* Should not get here, ever as the pix_fmt is processed */
727  /* in flic_decode_init and the above if should deal with */
728  /* the finite set of possibilites allowable by here. */
729  /* But in case we do, just error out. */
730  av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
731  return AVERROR_BUG;
732 }
733 
734 
736 {
737  FlicDecodeContext *s = avctx->priv_data;
738 
739  av_frame_free(&s->frame);
740 
741  return 0;
742 }
743 
745  .name = "flic",
746  .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
747  .type = AVMEDIA_TYPE_VIDEO,
748  .id = AV_CODEC_ID_FLIC,
749  .priv_data_size = sizeof(FlicDecodeContext),
753  .capabilities = CODEC_CAP_DR1,
754 };
#define FLI_DTA_COPY
Definition: flicvideo.c:57
#define AVPALETTE_SIZE
Definition: avcodec.h:2959
AVCodecContext * avctx
Definition: flicvideo.c:73
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
This structure describes decoded (raw) audio or video data.
Definition: frame.h:107
#define FLI_MINI
Definition: flicvideo.c:55
#define CHECK_PIXEL_PTR(n)
Definition: flicvideo.c:65
#define FLI_COPY
Definition: flicvideo.c:54
int size
Definition: avcodec.h:974
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1247
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
#define AV_RL16
Definition: intreadwrite.h:42
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:437
AVCodec.
Definition: avcodec.h:2755
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:135
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
Definition: mimic.c:269
uint8_t
#define av_cold
Definition: attributes.h:66
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:43
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
#define b
Definition: input.c:52
#define FLI_COLOR
Definition: flicvideo.c:50
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:174
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1162
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:711
const char data[16]
Definition: mxf.c:66
uint8_t * data
Definition: avcodec.h:973
#define FLI_LC
Definition: flicvideo.c:51
#define r
Definition: input.c:51
static const uint8_t frame_size[4]
Definition: g723_1_data.h:47
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
#define FLI_BRUN
Definition: flicvideo.c:53
AVFrame * frame
Definition: flicvideo.c:74
#define AVERROR(e)
Definition: error.h:43
static int flic_decode_frame_24BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size)
Definition: flicvideo.c:698
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:159
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:55
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:142
g
Definition: yuv2rgb.c:535
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:248
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE
Definition: flicvideo.c:63
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:148
const char * name
Name of the codec implementation.
Definition: avcodec.h:2762
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
Definition: utils.c:755
#define FLI_DTA_BRUN
Definition: flicvideo.c:56
int width
picture width / height.
Definition: avcodec.h:1217
#define FLC_FLX_TYPE_CODE
Definition: flicvideo.c:61
#define FLI_256_COLOR
Definition: flicvideo.c:48
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:68
#define pixel
#define FLI_DELTA
Definition: flicvideo.c:49
if(ac->has_optimized_func)
#define AVERROR_PATCHWELCOME
Not yet implemented in Libav, patches welcome.
Definition: error.h:57
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:183
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:125
main external API structure.
Definition: avcodec.h:1054
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:489
#define FLI_DTA_LC
Definition: flicvideo.c:58
int extradata_size
Definition: avcodec.h:1163
#define AVERROR_BUG
Bug detected, please report the issue.
Definition: error.h:60
static int flic_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: flicvideo.c:706
static av_cold int flic_decode_end(AVCodecContext *avctx)
Definition: flicvideo.c:735
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:302
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:123
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:113
#define FLI_BLACK
Definition: flicvideo.c:52
common internal api header.
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:214
static av_cold int init(AVCodecParserContext *s)
Definition: h264_parser.c:498
void * priv_data
Definition: avcodec.h:1090
unsigned int palette[256]
Definition: flicvideo.c:76
AVCodec ff_flic_decoder
Definition: flicvideo.c:744
#define AV_PIX_FMT_RGB565
Definition: pixfmt.h:213
This structure stores compressed data.
Definition: avcodec.h:950
static av_cold int flic_decode_init(AVCodecContext *avctx)
Definition: flicvideo.c:81