You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

745 lines
28KB

  1. /*
  2. * FLI/FLC Animation Video Decoder
  3. * Copyright (C) 2003, 2004 the ffmpeg project
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. /**
  21. * @file flic.c
  22. * Autodesk Animator FLI/FLC Video Decoder
  23. * by Mike Melanson (melanson@pcisys.net)
  24. * for more information on the .fli/.flc file format and all of its many
  25. * variations, visit:
  26. * http://www.compuphase.com/flic.htm
  27. *
  28. * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24
  29. * colorspace data, depending on the FLC. To use this decoder, be
  30. * sure that your demuxer sends the FLI file header to the decoder via
  31. * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
  32. * large. The only exception is for FLI files from the game "Magic Carpet",
  33. * in which the header is only 12 bytes.
  34. */
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #include <unistd.h>
  39. #include "common.h"
  40. #include "avcodec.h"
  41. #include "bswap.h"
  42. #define FLI_256_COLOR 4
  43. #define FLI_DELTA 7
  44. #define FLI_COLOR 11
  45. #define FLI_LC 12
  46. #define FLI_BLACK 13
  47. #define FLI_BRUN 15
  48. #define FLI_COPY 16
  49. #define FLI_MINI 18
  50. #define FLI_DTA_BRUN 25
  51. #define FLI_DTA_COPY 26
  52. #define FLI_DTA_LC 27
  53. #define FLI_TYPE_CODE (0xAF11)
  54. #define FLC_FLX_TYPE_CODE (0xAF12)
  55. #define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
  56. #define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
  57. #define CHECK_PIXEL_PTR(n) \
  58. if (pixel_ptr + n > pixel_limit) { \
  59. av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
  60. pixel_ptr + n, pixel_limit); \
  61. return -1; \
  62. } \
  63. typedef struct FlicDecodeContext {
  64. AVCodecContext *avctx;
  65. AVFrame frame;
  66. unsigned int palette[256];
  67. int new_palette;
  68. int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
  69. } FlicDecodeContext;
  70. static int flic_decode_init(AVCodecContext *avctx)
  71. {
  72. FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
  73. unsigned char *fli_header = (unsigned char *)avctx->extradata;
  74. int depth;
  75. s->avctx = avctx;
  76. avctx->has_b_frames = 0;
  77. s->fli_type = LE_16(&fli_header[4]); /* Might be overridden if a Magic Carpet FLC */
  78. depth = LE_16(&fli_header[12]);
  79. if (depth == 0) {
  80. depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
  81. }
  82. if (s->avctx->extradata_size == 12) {
  83. /* special case for magic carpet FLIs */
  84. s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
  85. } else if (s->avctx->extradata_size != 128) {
  86. av_log(avctx, AV_LOG_ERROR, "Expected extradata of 12 or 128 bytes\n");
  87. return -1;
  88. }
  89. if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
  90. depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
  91. }
  92. switch (depth) {
  93. case 8 : avctx->pix_fmt = PIX_FMT_PAL8; break;
  94. case 15 : avctx->pix_fmt = PIX_FMT_RGB555; break;
  95. case 16 : avctx->pix_fmt = PIX_FMT_RGB565; break;
  96. case 24 : avctx->pix_fmt = PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
  97. av_log(avctx, AV_LOG_ERROR, "24Bpp FLC/FLX is unsupported due to no test files.\n");
  98. return -1;
  99. break;
  100. default :
  101. av_log(avctx, AV_LOG_ERROR, "Unkown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
  102. return -1;
  103. }
  104. s->frame.data[0] = NULL;
  105. s->new_palette = 0;
  106. return 0;
  107. }
  108. static int flic_decode_frame_8BPP(AVCodecContext *avctx,
  109. void *data, int *data_size,
  110. uint8_t *buf, int buf_size)
  111. {
  112. FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
  113. int stream_ptr = 0;
  114. int stream_ptr_after_color_chunk;
  115. int pixel_ptr;
  116. int palette_ptr;
  117. unsigned char palette_idx1;
  118. unsigned char palette_idx2;
  119. unsigned int frame_size;
  120. int num_chunks;
  121. unsigned int chunk_size;
  122. int chunk_type;
  123. int i, j;
  124. int color_packets;
  125. int color_changes;
  126. int color_shift;
  127. unsigned char r, g, b;
  128. int lines;
  129. int compressed_lines;
  130. int starting_line;
  131. signed short line_packets;
  132. int y_ptr;
  133. signed char byte_run;
  134. int pixel_skip;
  135. int pixel_countdown;
  136. unsigned char *pixels;
  137. int pixel_limit;
  138. s->frame.reference = 1;
  139. s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
  140. if (avctx->reget_buffer(avctx, &s->frame) < 0) {
  141. av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
  142. return -1;
  143. }
  144. pixels = s->frame.data[0];
  145. pixel_limit = s->avctx->height * s->frame.linesize[0];
  146. frame_size = LE_32(&buf[stream_ptr]);
  147. stream_ptr += 6; /* skip the magic number */
  148. num_chunks = LE_16(&buf[stream_ptr]);
  149. stream_ptr += 10; /* skip padding */
  150. frame_size -= 16;
  151. /* iterate through the chunks */
  152. while ((frame_size > 0) && (num_chunks > 0)) {
  153. chunk_size = LE_32(&buf[stream_ptr]);
  154. stream_ptr += 4;
  155. chunk_type = LE_16(&buf[stream_ptr]);
  156. stream_ptr += 2;
  157. switch (chunk_type) {
  158. case FLI_256_COLOR:
  159. case FLI_COLOR:
  160. stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6;
  161. s->new_palette = 1;
  162. /* check special case: If this file is from the Magic Carpet
  163. * game and uses 6-bit colors even though it reports 256-color
  164. * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
  165. * initialization) */
  166. if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
  167. color_shift = 0;
  168. else
  169. color_shift = 2;
  170. /* set up the palette */
  171. color_packets = LE_16(&buf[stream_ptr]);
  172. stream_ptr += 2;
  173. palette_ptr = 0;
  174. for (i = 0; i < color_packets; i++) {
  175. /* first byte is how many colors to skip */
  176. palette_ptr += buf[stream_ptr++];
  177. /* next byte indicates how many entries to change */
  178. color_changes = buf[stream_ptr++];
  179. /* if there are 0 color changes, there are actually 256 */
  180. if (color_changes == 0)
  181. color_changes = 256;
  182. for (j = 0; j < color_changes; j++) {
  183. /* wrap around, for good measure */
  184. if ((unsigned)palette_ptr >= 256)
  185. palette_ptr = 0;
  186. r = buf[stream_ptr++] << color_shift;
  187. g = buf[stream_ptr++] << color_shift;
  188. b = buf[stream_ptr++] << color_shift;
  189. s->palette[palette_ptr++] = (r << 16) | (g << 8) | b;
  190. }
  191. }
  192. /* color chunks sometimes have weird 16-bit alignment issues;
  193. * therefore, take the hardline approach and set the stream_ptr
  194. * to the value calculated w.r.t. the size specified by the color
  195. * chunk header */
  196. stream_ptr = stream_ptr_after_color_chunk;
  197. break;
  198. case FLI_DELTA:
  199. y_ptr = 0;
  200. compressed_lines = LE_16(&buf[stream_ptr]);
  201. stream_ptr += 2;
  202. while (compressed_lines > 0) {
  203. line_packets = LE_16(&buf[stream_ptr]);
  204. stream_ptr += 2;
  205. if (line_packets < 0) {
  206. line_packets = -line_packets;
  207. y_ptr += line_packets * s->frame.linesize[0];
  208. } else {
  209. compressed_lines--;
  210. pixel_ptr = y_ptr;
  211. pixel_countdown = s->avctx->width;
  212. for (i = 0; i < line_packets; i++) {
  213. /* account for the skip bytes */
  214. pixel_skip = buf[stream_ptr++];
  215. pixel_ptr += pixel_skip;
  216. pixel_countdown -= pixel_skip;
  217. byte_run = buf[stream_ptr++];
  218. if (byte_run < 0) {
  219. byte_run = -byte_run;
  220. palette_idx1 = buf[stream_ptr++];
  221. palette_idx2 = buf[stream_ptr++];
  222. CHECK_PIXEL_PTR(byte_run);
  223. for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
  224. pixels[pixel_ptr++] = palette_idx1;
  225. pixels[pixel_ptr++] = palette_idx2;
  226. }
  227. } else {
  228. CHECK_PIXEL_PTR(byte_run * 2);
  229. for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
  230. palette_idx1 = buf[stream_ptr++];
  231. pixels[pixel_ptr++] = palette_idx1;
  232. }
  233. }
  234. }
  235. y_ptr += s->frame.linesize[0];
  236. }
  237. }
  238. break;
  239. case FLI_LC:
  240. /* line compressed */
  241. starting_line = LE_16(&buf[stream_ptr]);
  242. stream_ptr += 2;
  243. y_ptr = 0;
  244. y_ptr += starting_line * s->frame.linesize[0];
  245. compressed_lines = LE_16(&buf[stream_ptr]);
  246. stream_ptr += 2;
  247. while (compressed_lines > 0) {
  248. pixel_ptr = y_ptr;
  249. pixel_countdown = s->avctx->width;
  250. line_packets = buf[stream_ptr++];
  251. if (line_packets > 0) {
  252. for (i = 0; i < line_packets; i++) {
  253. /* account for the skip bytes */
  254. pixel_skip = buf[stream_ptr++];
  255. pixel_ptr += pixel_skip;
  256. pixel_countdown -= pixel_skip;
  257. byte_run = buf[stream_ptr++];
  258. if (byte_run > 0) {
  259. CHECK_PIXEL_PTR(byte_run);
  260. for (j = 0; j < byte_run; j++, pixel_countdown--) {
  261. palette_idx1 = buf[stream_ptr++];
  262. pixels[pixel_ptr++] = palette_idx1;
  263. }
  264. } else {
  265. byte_run = -byte_run;
  266. palette_idx1 = buf[stream_ptr++];
  267. CHECK_PIXEL_PTR(byte_run);
  268. for (j = 0; j < byte_run; j++, pixel_countdown--) {
  269. pixels[pixel_ptr++] = palette_idx1;
  270. }
  271. }
  272. }
  273. }
  274. y_ptr += s->frame.linesize[0];
  275. compressed_lines--;
  276. }
  277. break;
  278. case FLI_BLACK:
  279. /* set the whole frame to color 0 (which is usually black) */
  280. memset(pixels, 0,
  281. s->frame.linesize[0] * s->avctx->height);
  282. break;
  283. case FLI_BRUN:
  284. /* Byte run compression: This chunk type only occurs in the first
  285. * FLI frame and it will update the entire frame. */
  286. y_ptr = 0;
  287. for (lines = 0; lines < s->avctx->height; lines++) {
  288. pixel_ptr = y_ptr;
  289. /* disregard the line packets; instead, iterate through all
  290. * pixels on a row */
  291. stream_ptr++;
  292. pixel_countdown = s->avctx->width;
  293. while (pixel_countdown > 0) {
  294. byte_run = buf[stream_ptr++];
  295. if (byte_run > 0) {
  296. palette_idx1 = buf[stream_ptr++];
  297. CHECK_PIXEL_PTR(byte_run);
  298. for (j = 0; j < byte_run; j++) {
  299. pixels[pixel_ptr++] = palette_idx1;
  300. pixel_countdown--;
  301. if (pixel_countdown < 0)
  302. av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
  303. pixel_countdown);
  304. }
  305. } else { /* copy bytes if byte_run < 0 */
  306. byte_run = -byte_run;
  307. CHECK_PIXEL_PTR(byte_run);
  308. for (j = 0; j < byte_run; j++) {
  309. palette_idx1 = buf[stream_ptr++];
  310. pixels[pixel_ptr++] = palette_idx1;
  311. pixel_countdown--;
  312. if (pixel_countdown < 0)
  313. av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
  314. pixel_countdown);
  315. }
  316. }
  317. }
  318. y_ptr += s->frame.linesize[0];
  319. }
  320. break;
  321. case FLI_COPY:
  322. /* copy the chunk (uncompressed frame) */
  323. if (chunk_size - 6 > s->avctx->width * s->avctx->height) {
  324. av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
  325. "bigger than image, skipping chunk\n", chunk_size - 6);
  326. stream_ptr += chunk_size - 6;
  327. } else {
  328. for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
  329. y_ptr += s->frame.linesize[0]) {
  330. memcpy(&pixels[y_ptr], &buf[stream_ptr],
  331. s->avctx->width);
  332. stream_ptr += s->avctx->width;
  333. }
  334. }
  335. break;
  336. case FLI_MINI:
  337. /* some sort of a thumbnail? disregard this chunk... */
  338. stream_ptr += chunk_size - 6;
  339. break;
  340. default:
  341. av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
  342. break;
  343. }
  344. frame_size -= chunk_size;
  345. num_chunks--;
  346. }
  347. /* by the end of the chunk, the stream ptr should equal the frame
  348. * size (minus 1, possibly); if it doesn't, issue a warning */
  349. if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
  350. av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
  351. "and final chunk ptr = %d\n", buf_size, stream_ptr);
  352. /* make the palette available on the way out */
  353. // if (s->new_palette) {
  354. if (1) {
  355. memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE);
  356. s->frame.palette_has_changed = 1;
  357. s->new_palette = 0;
  358. }
  359. *data_size=sizeof(AVFrame);
  360. *(AVFrame*)data = s->frame;
  361. return buf_size;
  362. }
  363. int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
  364. void *data, int *data_size,
  365. uint8_t *buf, int buf_size)
  366. {
  367. /* Note, the only difference between the 15Bpp and 16Bpp */
  368. /* Format is the pixel format, the packets are processed the same. */
  369. FlicDecodeContext *s = (FlicDecodeContext *)avctx->priv_data;
  370. int stream_ptr = 0;
  371. int pixel_ptr;
  372. unsigned char palette_idx1;
  373. unsigned int frame_size;
  374. int num_chunks;
  375. unsigned int chunk_size;
  376. int chunk_type;
  377. int i, j;
  378. int lines;
  379. int compressed_lines;
  380. signed short line_packets;
  381. int y_ptr;
  382. signed char byte_run;
  383. int pixel_skip;
  384. int pixel_countdown;
  385. unsigned char *pixels;
  386. int pixel;
  387. int pixel_limit;
  388. s->frame.reference = 1;
  389. s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
  390. if (avctx->reget_buffer(avctx, &s->frame) < 0) {
  391. av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
  392. return -1;
  393. }
  394. pixels = s->frame.data[0];
  395. pixel_limit = s->avctx->height * s->frame.linesize[0];
  396. frame_size = LE_32(&buf[stream_ptr]);
  397. stream_ptr += 6; /* skip the magic number */
  398. num_chunks = LE_16(&buf[stream_ptr]);
  399. stream_ptr += 10; /* skip padding */
  400. frame_size -= 16;
  401. /* iterate through the chunks */
  402. while ((frame_size > 0) && (num_chunks > 0)) {
  403. chunk_size = LE_32(&buf[stream_ptr]);
  404. stream_ptr += 4;
  405. chunk_type = LE_16(&buf[stream_ptr]);
  406. stream_ptr += 2;
  407. switch (chunk_type) {
  408. case FLI_256_COLOR:
  409. case FLI_COLOR:
  410. /* For some reason, it seems that non-paletised flics do include one of these */
  411. /* chunks in their first frame. Why i do not know, it seems rather extraneous */
  412. /* av_log(avctx, AV_LOG_ERROR, "Unexpected Palette chunk %d in non-paletised FLC\n",chunk_type);*/
  413. stream_ptr = stream_ptr + chunk_size - 6;
  414. break;
  415. case FLI_DELTA:
  416. case FLI_DTA_LC:
  417. y_ptr = 0;
  418. compressed_lines = LE_16(&buf[stream_ptr]);
  419. stream_ptr += 2;
  420. while (compressed_lines > 0) {
  421. line_packets = LE_16(&buf[stream_ptr]);
  422. stream_ptr += 2;
  423. if (line_packets < 0) {
  424. line_packets = -line_packets;
  425. y_ptr += line_packets * s->frame.linesize[0];
  426. } else {
  427. compressed_lines--;
  428. pixel_ptr = y_ptr;
  429. pixel_countdown = s->avctx->width;
  430. for (i = 0; i < line_packets; i++) {
  431. /* account for the skip bytes */
  432. pixel_skip = buf[stream_ptr++];
  433. pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
  434. pixel_countdown -= pixel_skip;
  435. byte_run = buf[stream_ptr++];
  436. if (byte_run < 0) {
  437. byte_run = -byte_run;
  438. pixel = LE_16(&buf[stream_ptr]);
  439. stream_ptr += 2;
  440. CHECK_PIXEL_PTR(byte_run);
  441. for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
  442. *((signed short*)(&pixels[pixel_ptr])) = pixel;
  443. pixel_ptr += 2;
  444. }
  445. } else {
  446. CHECK_PIXEL_PTR(byte_run);
  447. for (j = 0; j < byte_run; j++, pixel_countdown--) {
  448. *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]);
  449. stream_ptr += 2;
  450. pixel_ptr += 2;
  451. }
  452. }
  453. }
  454. y_ptr += s->frame.linesize[0];
  455. }
  456. }
  457. break;
  458. case FLI_LC:
  459. av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-paletised FLC\n");
  460. stream_ptr = stream_ptr + chunk_size - 6;
  461. break;
  462. case FLI_BLACK:
  463. /* set the whole frame to 0x0000 which is balck in both 15Bpp and 16Bpp modes. */
  464. memset(pixels, 0x0000,
  465. s->frame.linesize[0] * s->avctx->height * 2);
  466. break;
  467. case FLI_BRUN:
  468. y_ptr = 0;
  469. for (lines = 0; lines < s->avctx->height; lines++) {
  470. pixel_ptr = y_ptr;
  471. /* disregard the line packets; instead, iterate through all
  472. * pixels on a row */
  473. stream_ptr++;
  474. pixel_countdown = (s->avctx->width * 2);
  475. while (pixel_countdown > 0) {
  476. byte_run = buf[stream_ptr++];
  477. if (byte_run > 0) {
  478. palette_idx1 = buf[stream_ptr++];
  479. CHECK_PIXEL_PTR(byte_run);
  480. for (j = 0; j < byte_run; j++) {
  481. pixels[pixel_ptr++] = palette_idx1;
  482. pixel_countdown--;
  483. if (pixel_countdown < 0)
  484. av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
  485. pixel_countdown);
  486. }
  487. } else { /* copy bytes if byte_run < 0 */
  488. byte_run = -byte_run;
  489. CHECK_PIXEL_PTR(byte_run);
  490. for (j = 0; j < byte_run; j++) {
  491. palette_idx1 = buf[stream_ptr++];
  492. pixels[pixel_ptr++] = palette_idx1;
  493. pixel_countdown--;
  494. if (pixel_countdown < 0)
  495. av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
  496. pixel_countdown);
  497. }
  498. }
  499. }
  500. /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
  501. * This doesnt give us any good oportunity to perform word endian conversion
  502. * during decompression. So if its requried (ie, this isnt a LE target, we do
  503. * a second pass over the line here, swapping the bytes.
  504. */
  505. pixel = 0xFF00;
  506. if (0xFF00 != LE_16(&pixel)) /* Check if its not an LE Target */
  507. {
  508. pixel_ptr = y_ptr;
  509. pixel_countdown = s->avctx->width;
  510. while (pixel_countdown > 0) {
  511. *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[pixel_ptr]);
  512. pixel_ptr += 2;
  513. }
  514. }
  515. y_ptr += s->frame.linesize[0];
  516. }
  517. break;
  518. case FLI_DTA_BRUN:
  519. y_ptr = 0;
  520. for (lines = 0; lines < s->avctx->height; lines++) {
  521. pixel_ptr = y_ptr;
  522. /* disregard the line packets; instead, iterate through all
  523. * pixels on a row */
  524. stream_ptr++;
  525. pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
  526. while (pixel_countdown > 0) {
  527. byte_run = buf[stream_ptr++];
  528. if (byte_run > 0) {
  529. pixel = LE_16(&buf[stream_ptr]);
  530. stream_ptr += 2;
  531. CHECK_PIXEL_PTR(byte_run);
  532. for (j = 0; j < byte_run; j++) {
  533. *((signed short*)(&pixels[pixel_ptr])) = pixel;
  534. pixel_ptr += 2;
  535. pixel_countdown--;
  536. if (pixel_countdown < 0)
  537. av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
  538. pixel_countdown);
  539. }
  540. } else { /* copy pixels if byte_run < 0 */
  541. byte_run = -byte_run;
  542. CHECK_PIXEL_PTR(byte_run);
  543. for (j = 0; j < byte_run; j++) {
  544. *((signed short*)(&pixels[pixel_ptr])) = LE_16(&buf[stream_ptr]);
  545. stream_ptr += 2;
  546. pixel_ptr += 2;
  547. pixel_countdown--;
  548. if (pixel_countdown < 0)
  549. av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
  550. pixel_countdown);
  551. }
  552. }
  553. }
  554. y_ptr += s->frame.linesize[0];
  555. }
  556. break;
  557. case FLI_COPY:
  558. case FLI_DTA_COPY:
  559. /* copy the chunk (uncompressed frame) */
  560. if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
  561. av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
  562. "bigger than image, skipping chunk\n", chunk_size - 6);
  563. stream_ptr += chunk_size - 6;
  564. } else {
  565. for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height;
  566. y_ptr += s->frame.linesize[0]) {
  567. pixel_countdown = s->avctx->width;
  568. pixel_ptr = 0;
  569. while (pixel_countdown > 0) {
  570. *((signed short*)(&pixels[y_ptr + pixel_ptr])) = LE_16(&buf[stream_ptr+pixel_ptr]);
  571. pixel_ptr += 2;
  572. pixel_countdown--;
  573. }
  574. stream_ptr += s->avctx->width*2;
  575. }
  576. }
  577. break;
  578. case FLI_MINI:
  579. /* some sort of a thumbnail? disregard this chunk... */
  580. stream_ptr += chunk_size - 6;
  581. break;
  582. default:
  583. av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
  584. break;
  585. }
  586. frame_size -= chunk_size;
  587. num_chunks--;
  588. }
  589. /* by the end of the chunk, the stream ptr should equal the frame
  590. * size (minus 1, possibly); if it doesn't, issue a warning */
  591. if ((stream_ptr != buf_size) && (stream_ptr != buf_size - 1))
  592. av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
  593. "and final chunk ptr = %d\n", buf_size, stream_ptr);
  594. *data_size=sizeof(AVFrame);
  595. *(AVFrame*)data = s->frame;
  596. return buf_size;
  597. }
  598. static int flic_decode_frame_24BPP(AVCodecContext *avctx,
  599. void *data, int *data_size,
  600. uint8_t *buf, int buf_size)
  601. {
  602. av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
  603. return -1;
  604. }
  605. static int flic_decode_frame(AVCodecContext *avctx,
  606. void *data, int *data_size,
  607. uint8_t *buf, int buf_size)
  608. {
  609. if (avctx->pix_fmt == PIX_FMT_PAL8) {
  610. return flic_decode_frame_8BPP(avctx, data, data_size,
  611. buf, buf_size);
  612. }
  613. else if ((avctx->pix_fmt == PIX_FMT_RGB555) ||
  614. (avctx->pix_fmt == PIX_FMT_RGB565)) {
  615. return flic_decode_frame_15_16BPP(avctx, data, data_size,
  616. buf, buf_size);
  617. }
  618. else if (avctx->pix_fmt == PIX_FMT_BGR24) {
  619. return flic_decode_frame_24BPP(avctx, data, data_size,
  620. buf, buf_size);
  621. }
  622. /* Shouldnt get here, ever as the pix_fmt is processed */
  623. /* in flic_decode_init and the above if should deal with */
  624. /* the finite set of possibilites allowable by here. */
  625. /* but in case we do, just error out. */
  626. av_log(avctx, AV_LOG_ERROR, "Unknown Format of FLC. My Science cant explain how this happened\n");
  627. return -1;
  628. }
  629. static int flic_decode_end(AVCodecContext *avctx)
  630. {
  631. FlicDecodeContext *s = avctx->priv_data;
  632. if (s->frame.data[0])
  633. avctx->release_buffer(avctx, &s->frame);
  634. return 0;
  635. }
  636. AVCodec flic_decoder = {
  637. "flic",
  638. CODEC_TYPE_VIDEO,
  639. CODEC_ID_FLIC,
  640. sizeof(FlicDecodeContext),
  641. flic_decode_init,
  642. NULL,
  643. flic_decode_end,
  644. flic_decode_frame,
  645. CODEC_CAP_DR1,
  646. NULL,
  647. NULL,
  648. NULL,
  649. NULL
  650. };