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.

821 lines
22KB

  1. /*
  2. * Wing Commander/Xan Video Decoder
  3. * Copyright (C) 2003 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 xan.c
  22. * Xan video decoder for Wing Commander III & IV computer games
  23. * by Mario Brito (mbrito@student.dei.uc.pt)
  24. * and Mike Melanson (melanson@pcisys.net)
  25. *
  26. * The xan_wc3 decoder outputs the following colorspaces natively:
  27. * PAL8 (default), RGB555, RGB565, RGB24, BGR24, RGBA32, YUV444P
  28. */
  29. #include <stdio.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #include "common.h"
  34. #include "avcodec.h"
  35. #include "dsputil.h"
  36. #define PALETTE_COUNT 256
  37. #define PALETTE_CONTROL_SIZE ((256 * 3) + 1)
  38. typedef struct XanContext {
  39. AVCodecContext *avctx;
  40. DSPContext dsp;
  41. AVFrame last_frame;
  42. AVFrame current_frame;
  43. unsigned char *buf;
  44. int size;
  45. unsigned char palette[PALETTE_COUNT * 4];
  46. /* scratch space */
  47. unsigned char *buffer1;
  48. unsigned char *buffer2;
  49. } XanContext;
  50. #define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
  51. #define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
  52. #define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \
  53. (((uint8_t*)(x))[2] << 16) | \
  54. (((uint8_t*)(x))[1] << 8) | \
  55. ((uint8_t*)(x))[0])
  56. /* RGB -> YUV conversion stuff */
  57. #define SCALEFACTOR 65536
  58. #define CENTERSAMPLE 128
  59. #define COMPUTE_Y(r, g, b) \
  60. (unsigned char) \
  61. ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR)
  62. #define COMPUTE_U(r, g, b) \
  63. (unsigned char) \
  64. ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
  65. #define COMPUTE_V(r, g, b) \
  66. (unsigned char) \
  67. ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE)
  68. #define Y_R (SCALEFACTOR * 0.29900)
  69. #define Y_G (SCALEFACTOR * 0.58700)
  70. #define Y_B (SCALEFACTOR * 0.11400)
  71. #define U_R (SCALEFACTOR * -0.16874)
  72. #define U_G (SCALEFACTOR * -0.33126)
  73. #define U_B (SCALEFACTOR * 0.50000)
  74. #define V_R (SCALEFACTOR * 0.50000)
  75. #define V_G (SCALEFACTOR * -0.41869)
  76. #define V_B (SCALEFACTOR * -0.08131)
  77. /*
  78. * Precalculate all of the YUV tables since it requires fewer than
  79. * 10 kilobytes to store them.
  80. */
  81. static int y_r_table[256];
  82. static int y_g_table[256];
  83. static int y_b_table[256];
  84. static int u_r_table[256];
  85. static int u_g_table[256];
  86. static int u_b_table[256];
  87. static int v_r_table[256];
  88. static int v_g_table[256];
  89. static int v_b_table[256];
  90. static int xan_decode_init(AVCodecContext *avctx)
  91. {
  92. XanContext *s = avctx->priv_data;
  93. int i;
  94. s->avctx = avctx;
  95. if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
  96. (s->avctx->extradata_size != sizeof(AVPaletteControl))) {
  97. printf (" WC3 Xan video: expected extradata_size of %d\n",
  98. sizeof(AVPaletteControl));
  99. return -1;
  100. }
  101. avctx->pix_fmt = PIX_FMT_PAL8;
  102. avctx->has_b_frames = 0;
  103. dsputil_init(&s->dsp, avctx);
  104. /* initialize the RGB -> YUV tables */
  105. for (i = 0; i < 256; i++) {
  106. y_r_table[i] = Y_R * i;
  107. y_g_table[i] = Y_G * i;
  108. y_b_table[i] = Y_B * i;
  109. u_r_table[i] = U_R * i;
  110. u_g_table[i] = U_G * i;
  111. u_b_table[i] = U_B * i;
  112. v_r_table[i] = V_R * i;
  113. v_g_table[i] = V_G * i;
  114. v_b_table[i] = V_B * i;
  115. }
  116. s->buffer1 = av_malloc(avctx->width * avctx->height);
  117. s->buffer2 = av_malloc(avctx->width * avctx->height);
  118. if (!s->buffer1 || !s->buffer2)
  119. return -1;
  120. return 0;
  121. }
  122. /* This function is used in lieu of memcpy(). This decoder can not use
  123. * memcpy because the memory locations often overlap and
  124. * memcpy doesn't like that; it's not uncommon, for example, for
  125. * dest = src+1, to turn byte A into pattern AAAAAAAA.
  126. * This was originally repz movsb in Intel x86 ASM. */
  127. static inline void bytecopy(unsigned char *dest, unsigned char *src, int count)
  128. {
  129. int i;
  130. for (i = 0; i < count; i++)
  131. dest[i] = src[i];
  132. }
  133. static int xan_huffman_decode(unsigned char *dest, unsigned char *src)
  134. {
  135. unsigned char byte = *src++;
  136. unsigned char ival = byte + 0x16;
  137. unsigned char * ptr = src + byte*2;
  138. unsigned char val = ival;
  139. int counter = 0;
  140. unsigned char bits = *ptr++;
  141. while ( val != 0x16 ) {
  142. if ( (1 << counter) & bits )
  143. val = src[byte + val - 0x17];
  144. else
  145. val = src[val - 0x17];
  146. if ( val < 0x16 ) {
  147. *dest++ = val;
  148. val = ival;
  149. }
  150. if (counter++ == 7) {
  151. counter = 0;
  152. bits = *ptr++;
  153. }
  154. }
  155. return 0;
  156. }
  157. static void xan_unpack(unsigned char *dest, unsigned char *src)
  158. {
  159. unsigned char opcode;
  160. int size;
  161. int offset;
  162. int byte1, byte2, byte3;
  163. for (;;) {
  164. opcode = *src++;
  165. if ( (opcode & 0x80) == 0 ) {
  166. offset = *src++;
  167. size = opcode & 3;
  168. bytecopy(dest, src, size); dest += size; src += size;
  169. size = ((opcode & 0x1c) >> 2) + 3;
  170. bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size);
  171. dest += size;
  172. } else if ( (opcode & 0x40) == 0 ) {
  173. byte1 = *src++;
  174. byte2 = *src++;
  175. size = byte1 >> 6;
  176. bytecopy (dest, src, size); dest += size; src += size;
  177. size = (opcode & 0x3f) + 4;
  178. bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size);
  179. dest += size;
  180. } else if ( (opcode & 0x20) == 0 ) {
  181. byte1 = *src++;
  182. byte2 = *src++;
  183. byte3 = *src++;
  184. size = opcode & 3;
  185. bytecopy (dest, src, size); dest += size; src += size;
  186. size = byte3 + 5 + ((opcode & 0xc) << 6);
  187. bytecopy (dest,
  188. dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2),
  189. size);
  190. dest += size;
  191. } else {
  192. size = ((opcode & 0x1f) << 2) + 4;
  193. if (size > 0x70)
  194. break;
  195. bytecopy (dest, src, size); dest += size; src += size;
  196. }
  197. }
  198. size = opcode & 3;
  199. bytecopy(dest, src, size); dest += size; src += size;
  200. }
  201. static void inline xan_wc3_build_palette(XanContext *s,
  202. unsigned char *palette_data)
  203. {
  204. int i;
  205. unsigned char r, g, b;
  206. unsigned short *palette16;
  207. unsigned int *palette32;
  208. /* transform the palette passed through the palette control structure
  209. * into the necessary internal format depending on colorspace */
  210. switch (s->avctx->pix_fmt) {
  211. case PIX_FMT_RGB555:
  212. palette16 = (unsigned short *)s->palette;
  213. for (i = 0; i < PALETTE_COUNT; i++) {
  214. r = *palette_data++;
  215. g = *palette_data++;
  216. b = *palette_data++;
  217. palette16[i] =
  218. ((r >> 3) << 10) |
  219. ((g >> 3) << 5) |
  220. ((b >> 3) << 0);
  221. }
  222. break;
  223. case PIX_FMT_RGB565:
  224. palette16 = (unsigned short *)s->palette;
  225. for (i = 0; i < PALETTE_COUNT; i++) {
  226. r = *palette_data++;
  227. g = *palette_data++;
  228. b = *palette_data++;
  229. palette16[i] =
  230. ((r >> 3) << 11) |
  231. ((g >> 2) << 5) |
  232. ((b >> 3) << 0);
  233. }
  234. break;
  235. case PIX_FMT_RGB24:
  236. for (i = 0; i < PALETTE_COUNT; i++) {
  237. s->palette[i * 4 + 0] = *palette_data++;
  238. s->palette[i * 4 + 1] = *palette_data++;
  239. s->palette[i * 4 + 2] = *palette_data++;
  240. }
  241. break;
  242. case PIX_FMT_BGR24:
  243. for (i = 0; i < PALETTE_COUNT; i++) {
  244. r = *palette_data++;
  245. g = *palette_data++;
  246. b = *palette_data++;
  247. s->palette[i * 4 + 0] = b;
  248. s->palette[i * 4 + 1] = g;
  249. s->palette[i * 4 + 2] = r;
  250. }
  251. break;
  252. case PIX_FMT_PAL8:
  253. case PIX_FMT_RGBA32:
  254. palette32 = (unsigned int *)s->palette;
  255. for (i = 0; i < PALETTE_COUNT; i++) {
  256. r = *palette_data++;
  257. g = *palette_data++;
  258. b = *palette_data++;
  259. palette32[i] = (r << 16) | (g << 8) | (b);
  260. }
  261. break;
  262. case PIX_FMT_YUV444P:
  263. for (i = 0; i < PALETTE_COUNT; i++) {
  264. r = *palette_data++;
  265. g = *palette_data++;
  266. b = *palette_data++;
  267. s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b);
  268. s->palette[i * 4 + 1] = COMPUTE_U(r, g, b);
  269. s->palette[i * 4 + 2] = COMPUTE_V(r, g, b);
  270. }
  271. break;
  272. default:
  273. printf (" Xan WC3: Unhandled colorspace\n");
  274. break;
  275. }
  276. }
  277. /* advance current_x variable; reset accounting variables if current_x
  278. * moves beyond width */
  279. #define ADVANCE_CURRENT_X() \
  280. current_x++; \
  281. if (current_x >= width) { \
  282. index += line_inc; \
  283. current_x = 0; \
  284. }
  285. static void inline xan_wc3_output_pixel_run(XanContext *s,
  286. unsigned char *pixel_buffer, int x, int y, int pixel_count)
  287. {
  288. int stride;
  289. int line_inc;
  290. int index;
  291. int current_x;
  292. int width = s->avctx->width;
  293. unsigned char pix;
  294. unsigned char *palette_plane;
  295. unsigned char *y_plane;
  296. unsigned char *u_plane;
  297. unsigned char *v_plane;
  298. unsigned char *rgb_plane;
  299. unsigned short *rgb16_plane;
  300. unsigned short *palette16;
  301. unsigned int *rgb32_plane;
  302. unsigned int *palette32;
  303. switch (s->avctx->pix_fmt) {
  304. case PIX_FMT_PAL8:
  305. palette_plane = s->current_frame.data[0];
  306. stride = s->current_frame.linesize[0];
  307. line_inc = stride - width;
  308. index = y * stride + x;
  309. current_x = x;
  310. while(pixel_count--) {
  311. /* don't do a memcpy() here; keyframes generally copy an entire
  312. * frame of data and the stride needs to be accounted for */
  313. palette_plane[index++] = *pixel_buffer++;
  314. ADVANCE_CURRENT_X();
  315. }
  316. break;
  317. case PIX_FMT_RGB555:
  318. case PIX_FMT_RGB565:
  319. rgb16_plane = (unsigned short *)s->current_frame.data[0];
  320. palette16 = (unsigned short *)s->palette;
  321. stride = s->current_frame.linesize[0] / 2;
  322. line_inc = stride - width;
  323. index = y * stride + x;
  324. current_x = x;
  325. while(pixel_count--) {
  326. rgb16_plane[index++] = palette16[*pixel_buffer++];
  327. ADVANCE_CURRENT_X();
  328. }
  329. break;
  330. case PIX_FMT_RGB24:
  331. case PIX_FMT_BGR24:
  332. rgb_plane = s->current_frame.data[0];
  333. stride = s->current_frame.linesize[0];
  334. line_inc = stride - width * 3;
  335. index = y * stride + x * 3;
  336. current_x = x;
  337. while(pixel_count--) {
  338. pix = *pixel_buffer++;
  339. rgb_plane[index++] = s->palette[pix * 4 + 0];
  340. rgb_plane[index++] = s->palette[pix * 4 + 1];
  341. rgb_plane[index++] = s->palette[pix * 4 + 2];
  342. ADVANCE_CURRENT_X();
  343. }
  344. break;
  345. case PIX_FMT_RGBA32:
  346. rgb32_plane = (unsigned int *)s->current_frame.data[0];
  347. palette32 = (unsigned int *)s->palette;
  348. stride = s->current_frame.linesize[0] / 4;
  349. line_inc = stride - width;
  350. index = y * stride + x;
  351. current_x = x;
  352. while(pixel_count--) {
  353. rgb32_plane[index++] = palette32[*pixel_buffer++];
  354. ADVANCE_CURRENT_X();
  355. }
  356. break;
  357. case PIX_FMT_YUV444P:
  358. y_plane = s->current_frame.data[0];
  359. u_plane = s->current_frame.data[1];
  360. v_plane = s->current_frame.data[2];
  361. stride = s->current_frame.linesize[0];
  362. line_inc = stride - width;
  363. index = y * stride + x;
  364. current_x = x;
  365. while(pixel_count--) {
  366. pix = *pixel_buffer++;
  367. y_plane[index] = s->palette[pix * 4 + 0];
  368. u_plane[index] = s->palette[pix * 4 + 1];
  369. v_plane[index] = s->palette[pix * 4 + 2];
  370. index++;
  371. ADVANCE_CURRENT_X();
  372. }
  373. break;
  374. default:
  375. printf (" Xan WC3: Unhandled colorspace\n");
  376. break;
  377. }
  378. }
  379. #define ADVANCE_CURFRAME_X() \
  380. curframe_x++; \
  381. if (curframe_x >= width) { \
  382. curframe_index += line_inc; \
  383. curframe_x = 0; \
  384. }
  385. #define ADVANCE_PREVFRAME_X() \
  386. prevframe_x++; \
  387. if (prevframe_x >= width) { \
  388. prevframe_index += line_inc; \
  389. prevframe_x = 0; \
  390. }
  391. static void inline xan_wc3_copy_pixel_run(XanContext *s,
  392. int x, int y, int pixel_count, int motion_x, int motion_y)
  393. {
  394. int stride;
  395. int line_inc;
  396. int curframe_index, prevframe_index;
  397. int curframe_x, prevframe_x;
  398. int width = s->avctx->width;
  399. unsigned char *palette_plane, *prev_palette_plane;
  400. unsigned char *y_plane, *u_plane, *v_plane;
  401. unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane;
  402. unsigned char *rgb_plane, *prev_rgb_plane;
  403. unsigned short *rgb16_plane, *prev_rgb16_plane;
  404. unsigned int *rgb32_plane, *prev_rgb32_plane;
  405. switch (s->avctx->pix_fmt) {
  406. case PIX_FMT_PAL8:
  407. palette_plane = s->current_frame.data[0];
  408. prev_palette_plane = s->last_frame.data[0];
  409. stride = s->current_frame.linesize[0];
  410. line_inc = stride - width;
  411. curframe_index = y * stride + x;
  412. curframe_x = x;
  413. prevframe_index = (y + motion_y) * stride + x + motion_x;
  414. prevframe_x = x + motion_x;
  415. while(pixel_count--) {
  416. palette_plane[curframe_index++] =
  417. prev_palette_plane[prevframe_index++];
  418. ADVANCE_CURFRAME_X();
  419. ADVANCE_PREVFRAME_X();
  420. }
  421. break;
  422. case PIX_FMT_RGB555:
  423. case PIX_FMT_RGB565:
  424. rgb16_plane = (unsigned short *)s->current_frame.data[0];
  425. prev_rgb16_plane = (unsigned short *)s->last_frame.data[0];
  426. stride = s->current_frame.linesize[0] / 2;
  427. line_inc = stride - width;
  428. curframe_index = y * stride + x;
  429. curframe_x = x;
  430. prevframe_index = (y + motion_y) * stride + x + motion_x;
  431. prevframe_x = x + motion_x;
  432. while(pixel_count--) {
  433. rgb16_plane[curframe_index++] =
  434. prev_rgb16_plane[prevframe_index++];
  435. ADVANCE_CURFRAME_X();
  436. ADVANCE_PREVFRAME_X();
  437. }
  438. break;
  439. case PIX_FMT_RGB24:
  440. case PIX_FMT_BGR24:
  441. rgb_plane = s->current_frame.data[0];
  442. prev_rgb_plane = s->last_frame.data[0];
  443. stride = s->current_frame.linesize[0];
  444. line_inc = stride - width * 3;
  445. curframe_index = y * stride + x * 3;
  446. curframe_x = x;
  447. prevframe_index = (y + motion_y) * stride +
  448. (3 * (x + motion_x));
  449. prevframe_x = x + motion_x;
  450. while(pixel_count--) {
  451. rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
  452. rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
  453. rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
  454. ADVANCE_CURFRAME_X();
  455. ADVANCE_PREVFRAME_X();
  456. }
  457. break;
  458. case PIX_FMT_RGBA32:
  459. rgb32_plane = (unsigned int *)s->current_frame.data[0];
  460. prev_rgb32_plane = (unsigned int *)s->last_frame.data[0];
  461. stride = s->current_frame.linesize[0] / 4;
  462. line_inc = stride - width;
  463. curframe_index = y * stride + x;
  464. curframe_x = x;
  465. prevframe_index = (y + motion_y) * stride + x + motion_x;
  466. prevframe_x = x + motion_x;
  467. while(pixel_count--) {
  468. rgb32_plane[curframe_index++] =
  469. prev_rgb32_plane[prevframe_index++];
  470. ADVANCE_CURFRAME_X();
  471. ADVANCE_PREVFRAME_X();
  472. }
  473. break;
  474. case PIX_FMT_YUV444P:
  475. y_plane = s->current_frame.data[0];
  476. u_plane = s->current_frame.data[1];
  477. v_plane = s->current_frame.data[2];
  478. prev_y_plane = s->last_frame.data[0];
  479. prev_u_plane = s->last_frame.data[1];
  480. prev_v_plane = s->last_frame.data[2];
  481. stride = s->current_frame.linesize[0];
  482. line_inc = stride - width;
  483. curframe_index = y * stride + x;
  484. curframe_x = x;
  485. prevframe_index = (y + motion_y) * stride + x + motion_x;
  486. prevframe_x = x + motion_x;
  487. while(pixel_count--) {
  488. y_plane[curframe_index] = prev_y_plane[prevframe_index];
  489. u_plane[curframe_index] = prev_u_plane[prevframe_index];
  490. v_plane[curframe_index] = prev_v_plane[prevframe_index];
  491. curframe_index++;
  492. ADVANCE_CURFRAME_X();
  493. prevframe_index++;
  494. ADVANCE_PREVFRAME_X();
  495. }
  496. break;
  497. default:
  498. printf (" Xan WC3: Unhandled colorspace\n");
  499. break;
  500. }
  501. }
  502. static void xan_wc3_decode_frame(XanContext *s) {
  503. int width = s->avctx->width;
  504. int height = s->avctx->height;
  505. int total_pixels = width * height;
  506. unsigned char opcode;
  507. unsigned char flag = 0;
  508. int size = 0;
  509. int motion_x, motion_y;
  510. int x, y;
  511. unsigned char *opcode_buffer = s->buffer1;
  512. unsigned char *imagedata_buffer = s->buffer2;
  513. /* pointers to segments inside the compressed chunk */
  514. unsigned char *huffman_segment;
  515. unsigned char *size_segment;
  516. unsigned char *vector_segment;
  517. unsigned char *imagedata_segment;
  518. huffman_segment = s->buf + LE_16(&s->buf[0]);
  519. size_segment = s->buf + LE_16(&s->buf[2]);
  520. vector_segment = s->buf + LE_16(&s->buf[4]);
  521. imagedata_segment = s->buf + LE_16(&s->buf[6]);
  522. xan_huffman_decode(opcode_buffer, huffman_segment);
  523. if (imagedata_segment[0] == 2)
  524. xan_unpack(imagedata_buffer, &imagedata_segment[1]);
  525. else
  526. imagedata_buffer = &imagedata_segment[1];
  527. /* use the decoded data segments to build the frame */
  528. x = y = 0;
  529. while (total_pixels) {
  530. opcode = *opcode_buffer++;
  531. size = 0;
  532. switch (opcode) {
  533. case 0:
  534. flag ^= 1;
  535. continue;
  536. case 1:
  537. case 2:
  538. case 3:
  539. case 4:
  540. case 5:
  541. case 6:
  542. case 7:
  543. case 8:
  544. size = opcode;
  545. break;
  546. case 12:
  547. case 13:
  548. case 14:
  549. case 15:
  550. case 16:
  551. case 17:
  552. case 18:
  553. size += (opcode - 10);
  554. break;
  555. case 9:
  556. case 19:
  557. size = *size_segment++;
  558. break;
  559. case 10:
  560. case 20:
  561. size = BE_16(&size_segment[0]);
  562. size_segment += 2;
  563. break;
  564. case 11:
  565. case 21:
  566. size = (size_segment[0] << 16) | (size_segment[1] << 8) |
  567. size_segment[2];
  568. size_segment += 3;
  569. break;
  570. }
  571. if (opcode < 12) {
  572. flag ^= 1;
  573. if (flag) {
  574. /* run of (size) pixels is unchanged from last frame */
  575. xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
  576. } else {
  577. /* output a run of pixels from imagedata_buffer */
  578. xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
  579. imagedata_buffer += size;
  580. }
  581. } else {
  582. /* run-based motion compensation from last frame */
  583. motion_x = (*vector_segment >> 4) & 0xF;
  584. motion_y = *vector_segment & 0xF;
  585. vector_segment++;
  586. /* sign extension */
  587. if (motion_x & 0x8)
  588. motion_x |= 0xFFFFFFF0;
  589. if (motion_y & 0x8)
  590. motion_y |= 0xFFFFFFF0;
  591. /* copy a run of pixels from the previous frame */
  592. xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
  593. flag = 0;
  594. }
  595. /* coordinate accounting */
  596. total_pixels -= size;
  597. while (size) {
  598. if (x + size >= width) {
  599. y++;
  600. size -= (width - x);
  601. x = 0;
  602. } else {
  603. x += size;
  604. size = 0;
  605. }
  606. }
  607. }
  608. /* for PAL8, make the palette available on the way out */
  609. if (s->avctx->pix_fmt == PIX_FMT_PAL8)
  610. memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
  611. }
  612. static void xan_wc4_decode_frame(XanContext *s) {
  613. }
  614. static int xan_decode_frame(AVCodecContext *avctx,
  615. void *data, int *data_size,
  616. uint8_t *buf, int buf_size)
  617. {
  618. XanContext *s = avctx->priv_data;
  619. AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata;
  620. int keyframe = 0;
  621. if (palette_control->palette_changed) {
  622. /* load the new palette and reset the palette control */
  623. xan_wc3_build_palette(s, palette_control->palette);
  624. palette_control->palette_changed = 0;
  625. keyframe = 1;
  626. }
  627. if (avctx->get_buffer(avctx, &s->current_frame)) {
  628. printf (" Xan Video: get_buffer() failed\n");
  629. return -1;
  630. }
  631. s->current_frame.reference = 3;
  632. s->buf = buf;
  633. s->size = buf_size;
  634. if (avctx->codec->id == CODEC_ID_XAN_WC3)
  635. xan_wc3_decode_frame(s);
  636. else if (avctx->codec->id == CODEC_ID_XAN_WC4)
  637. xan_wc4_decode_frame(s);
  638. /* release the last frame if it is allocated */
  639. if (s->last_frame.data[0])
  640. avctx->release_buffer(avctx, &s->last_frame);
  641. /* shuffle frames */
  642. s->last_frame = s->current_frame;
  643. *data_size = sizeof(AVFrame);
  644. *(AVFrame*)data = s->current_frame;
  645. /* always report that the buffer was completely consumed */
  646. return buf_size;
  647. }
  648. static int xan_decode_end(AVCodecContext *avctx)
  649. {
  650. XanContext *s = avctx->priv_data;
  651. /* release the last frame */
  652. avctx->release_buffer(avctx, &s->last_frame);
  653. av_free(s->buffer1);
  654. av_free(s->buffer2);
  655. return 0;
  656. }
  657. AVCodec xan_wc3_decoder = {
  658. "xan_wc3",
  659. CODEC_TYPE_VIDEO,
  660. CODEC_ID_XAN_WC3,
  661. sizeof(XanContext),
  662. xan_decode_init,
  663. NULL,
  664. xan_decode_end,
  665. xan_decode_frame,
  666. CODEC_CAP_DR1,
  667. };
  668. /*
  669. AVCodec xan_wc4_decoder = {
  670. "xan_wc4",
  671. CODEC_TYPE_VIDEO,
  672. CODEC_ID_XAN_WC4,
  673. sizeof(XanContext),
  674. xan_decode_init,
  675. NULL,
  676. xan_decode_end,
  677. xan_decode_frame,
  678. CODEC_CAP_DR1,
  679. };
  680. */