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.

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