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.

878 lines
24KB

  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. ((g >> 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. ((g >> 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. static void inline xan_wc3_output_pixel_run(XanContext *s,
  278. unsigned char *pixel_buffer, int x, int y, int pixel_count)
  279. {
  280. int stride;
  281. int line_inc;
  282. int index;
  283. int current_x;
  284. int width = s->avctx->width;
  285. unsigned char pix;
  286. unsigned char *palette_plane;
  287. unsigned char *y_plane;
  288. unsigned char *u_plane;
  289. unsigned char *v_plane;
  290. unsigned char *rgb_plane;
  291. unsigned short *rgb16_plane;
  292. unsigned short *palette16;
  293. unsigned int *rgb32_plane;
  294. unsigned int *palette32;
  295. switch (s->avctx->pix_fmt) {
  296. case PIX_FMT_PAL8:
  297. palette_plane = s->current_frame.data[0];
  298. stride = s->current_frame.linesize[0];
  299. line_inc = stride - width;
  300. index = y * stride + x;
  301. current_x = x;
  302. while(pixel_count--) {
  303. /* don't do a memcpy() here; keyframes generally copy an entire
  304. * frame of data and the stride needs to be accounted for */
  305. palette_plane[index++] = *pixel_buffer++;
  306. current_x++;
  307. if (current_x >= width) {
  308. /* reset accounting variables */
  309. index += line_inc;
  310. current_x = 0;
  311. }
  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. current_x++;
  325. if (current_x >= width) {
  326. /* reset accounting variables */
  327. index += line_inc;
  328. current_x = 0;
  329. }
  330. }
  331. break;
  332. case PIX_FMT_RGB24:
  333. case PIX_FMT_BGR24:
  334. rgb_plane = s->current_frame.data[0];
  335. stride = s->current_frame.linesize[0];
  336. line_inc = stride - width * 3;
  337. index = y * stride + x * 3;
  338. current_x = x;
  339. while(pixel_count--) {
  340. pix = *pixel_buffer++;
  341. rgb_plane[index++] = s->palette[pix * 4 + 0];
  342. rgb_plane[index++] = s->palette[pix * 4 + 1];
  343. rgb_plane[index++] = s->palette[pix * 4 + 2];
  344. current_x++;
  345. if (current_x >= width) {
  346. /* reset accounting variables */
  347. index += line_inc;
  348. current_x = 0;
  349. }
  350. }
  351. break;
  352. case PIX_FMT_RGBA32:
  353. rgb32_plane = (unsigned int *)s->current_frame.data[0];
  354. palette32 = (unsigned int *)s->palette;
  355. stride = s->current_frame.linesize[0] / 4;
  356. line_inc = stride - width;
  357. index = y * stride + x;
  358. current_x = x;
  359. while(pixel_count--) {
  360. rgb32_plane[index++] = palette32[*pixel_buffer++];
  361. current_x++;
  362. if (current_x >= width) {
  363. /* reset accounting variables */
  364. index += line_inc;
  365. current_x = 0;
  366. }
  367. }
  368. break;
  369. case PIX_FMT_YUV444P:
  370. y_plane = s->current_frame.data[0];
  371. u_plane = s->current_frame.data[1];
  372. v_plane = s->current_frame.data[2];
  373. stride = s->current_frame.linesize[0];
  374. line_inc = stride - width;
  375. index = y * stride + x;
  376. current_x = x;
  377. while(pixel_count--) {
  378. pix = *pixel_buffer++;
  379. y_plane[index] = s->palette[pix * 4 + 0];
  380. u_plane[index] = s->palette[pix * 4 + 1];
  381. v_plane[index] = s->palette[pix * 4 + 2];
  382. index++;
  383. current_x++;
  384. if (current_x >= width) {
  385. /* reset accounting variables */
  386. index += line_inc;
  387. current_x = 0;
  388. }
  389. }
  390. break;
  391. default:
  392. printf (" Xan WC3: Unhandled colorspace\n");
  393. break;
  394. }
  395. }
  396. static void inline xan_wc3_copy_pixel_run(XanContext *s,
  397. int x, int y, int pixel_count, int motion_x, int motion_y)
  398. {
  399. int stride;
  400. int line_inc;
  401. int curframe_index, prevframe_index;
  402. int curframe_x, prevframe_x;
  403. int width = s->avctx->width;
  404. unsigned char *palette_plane, *prev_palette_plane;
  405. unsigned char *y_plane, *u_plane, *v_plane;
  406. unsigned char *prev_y_plane, *prev_u_plane, *prev_v_plane;
  407. unsigned char *rgb_plane, *prev_rgb_plane;
  408. unsigned short *rgb16_plane, *prev_rgb16_plane;
  409. unsigned int *rgb32_plane, *prev_rgb32_plane;
  410. switch (s->avctx->pix_fmt) {
  411. case PIX_FMT_PAL8:
  412. palette_plane = s->current_frame.data[0];
  413. prev_palette_plane = s->last_frame.data[0];
  414. stride = s->current_frame.linesize[0];
  415. line_inc = stride - width;
  416. curframe_index = y * stride + x;
  417. curframe_x = x;
  418. prevframe_index = (y + motion_y) * stride + x + motion_x;
  419. prevframe_x = x + motion_x;
  420. while(pixel_count--) {
  421. palette_plane[curframe_index++] =
  422. prev_palette_plane[prevframe_index++];
  423. curframe_x++;
  424. if (curframe_x >= width) {
  425. /* reset accounting variables */
  426. curframe_index += line_inc;
  427. curframe_x = 0;
  428. }
  429. prevframe_x++;
  430. if (prevframe_x >= width) {
  431. /* reset accounting variables */
  432. prevframe_index += line_inc;
  433. prevframe_x = 0;
  434. }
  435. }
  436. break;
  437. case PIX_FMT_RGB555:
  438. case PIX_FMT_RGB565:
  439. rgb16_plane = (unsigned short *)s->current_frame.data[0];
  440. prev_rgb16_plane = (unsigned short *)s->last_frame.data[0];
  441. stride = s->current_frame.linesize[0] / 2;
  442. line_inc = stride - width;
  443. curframe_index = y * stride + x;
  444. curframe_x = x;
  445. prevframe_index = (y + motion_y) * stride + x + motion_x;
  446. prevframe_x = x + motion_x;
  447. while(pixel_count--) {
  448. rgb16_plane[curframe_index++] =
  449. prev_rgb16_plane[prevframe_index++];
  450. curframe_x++;
  451. if (curframe_x >= width) {
  452. /* reset accounting variables */
  453. curframe_index += line_inc;
  454. curframe_x = 0;
  455. }
  456. prevframe_x++;
  457. if (prevframe_x >= width) {
  458. /* reset accounting variables */
  459. prevframe_index += line_inc;
  460. prevframe_x = 0;
  461. }
  462. }
  463. break;
  464. case PIX_FMT_RGB24:
  465. case PIX_FMT_BGR24:
  466. rgb_plane = s->current_frame.data[0];
  467. prev_rgb_plane = s->last_frame.data[0];
  468. stride = s->current_frame.linesize[0];
  469. line_inc = stride - width * 3;
  470. curframe_index = y * stride + x * 3;
  471. curframe_x = x;
  472. prevframe_index = (y + motion_y) * stride +
  473. (3 * (x + motion_x));
  474. prevframe_x = x + motion_x;
  475. while(pixel_count--) {
  476. rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
  477. rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
  478. rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
  479. curframe_x++;
  480. if (curframe_x >= width) {
  481. /* reset accounting variables */
  482. curframe_index += line_inc;
  483. curframe_x = 0;
  484. }
  485. prevframe_x++;
  486. if (prevframe_x >= width) {
  487. /* reset accounting variables */
  488. prevframe_index += line_inc;
  489. prevframe_x = 0;
  490. }
  491. }
  492. break;
  493. case PIX_FMT_RGBA32:
  494. rgb32_plane = (unsigned int *)s->current_frame.data[0];
  495. prev_rgb32_plane = (unsigned int *)s->last_frame.data[0];
  496. stride = s->current_frame.linesize[0] / 4;
  497. line_inc = stride - width;
  498. curframe_index = y * stride + x;
  499. curframe_x = x;
  500. prevframe_index = (y + motion_y) * stride + x + motion_x;
  501. prevframe_x = x + motion_x;
  502. while(pixel_count--) {
  503. rgb32_plane[curframe_index++] =
  504. prev_rgb32_plane[prevframe_index++];
  505. curframe_x++;
  506. if (curframe_x >= width) {
  507. /* reset accounting variables */
  508. curframe_index += line_inc;
  509. curframe_x = 0;
  510. }
  511. prevframe_x++;
  512. if (prevframe_x >= width) {
  513. /* reset accounting variables */
  514. prevframe_index += line_inc;
  515. prevframe_x = 0;
  516. }
  517. }
  518. break;
  519. case PIX_FMT_YUV444P:
  520. y_plane = s->current_frame.data[0];
  521. u_plane = s->current_frame.data[1];
  522. v_plane = s->current_frame.data[2];
  523. prev_y_plane = s->last_frame.data[0];
  524. prev_u_plane = s->last_frame.data[1];
  525. prev_v_plane = s->last_frame.data[2];
  526. stride = s->current_frame.linesize[0];
  527. line_inc = stride - width;
  528. curframe_index = y * stride + x;
  529. curframe_x = x;
  530. prevframe_index = (y + motion_y) * stride + x + motion_x;
  531. prevframe_x = x + motion_x;
  532. while(pixel_count--) {
  533. y_plane[curframe_index] = prev_y_plane[prevframe_index];
  534. u_plane[curframe_index] = prev_u_plane[prevframe_index];
  535. v_plane[curframe_index] = prev_v_plane[prevframe_index];
  536. curframe_index++;
  537. curframe_x++;
  538. if (curframe_x >= width) {
  539. /* reset accounting variables */
  540. curframe_index += line_inc;
  541. curframe_x = 0;
  542. }
  543. prevframe_index++;
  544. prevframe_x++;
  545. if (prevframe_x >= width) {
  546. /* reset accounting variables */
  547. prevframe_index += line_inc;
  548. prevframe_x = 0;
  549. }
  550. }
  551. break;
  552. default:
  553. printf (" Xan WC3: Unhandled colorspace\n");
  554. break;
  555. }
  556. }
  557. static void xan_wc3_decode_frame(XanContext *s) {
  558. int width = s->avctx->width;
  559. int height = s->avctx->height;
  560. int total_pixels = width * height;
  561. unsigned char opcode;
  562. unsigned char flag = 0;
  563. int size = 0;
  564. int motion_x, motion_y;
  565. int x, y;
  566. unsigned char *opcode_buffer = s->buffer1;
  567. unsigned char *imagedata_buffer = s->buffer2;
  568. /* pointers to segments inside the compressed chunk */
  569. unsigned char *huffman_segment;
  570. unsigned char *size_segment;
  571. unsigned char *vector_segment;
  572. unsigned char *imagedata_segment;
  573. huffman_segment = s->buf + LE_16(&s->buf[0]);
  574. size_segment = s->buf + LE_16(&s->buf[2]);
  575. vector_segment = s->buf + LE_16(&s->buf[4]);
  576. imagedata_segment = s->buf + LE_16(&s->buf[6]);
  577. xan_huffman_decode(opcode_buffer, huffman_segment);
  578. if (imagedata_segment[0] == 2)
  579. xan_unpack(imagedata_buffer, &imagedata_segment[1]);
  580. else
  581. imagedata_buffer = &imagedata_segment[1];
  582. /* use the decoded data segments to build the frame */
  583. x = y = 0;
  584. while (total_pixels) {
  585. opcode = *opcode_buffer++;
  586. size = 0;
  587. switch (opcode) {
  588. case 0:
  589. flag ^= 1;
  590. continue;
  591. case 1:
  592. case 2:
  593. case 3:
  594. case 4:
  595. case 5:
  596. case 6:
  597. case 7:
  598. case 8:
  599. size = opcode;
  600. break;
  601. case 12:
  602. case 13:
  603. case 14:
  604. case 15:
  605. case 16:
  606. case 17:
  607. case 18:
  608. size += (opcode - 10);
  609. break;
  610. case 9:
  611. case 19:
  612. size = *size_segment++;
  613. break;
  614. case 10:
  615. case 20:
  616. size = BE_16(&size_segment[0]);
  617. size_segment += 2;
  618. break;
  619. case 11:
  620. case 21:
  621. size = (size_segment[0] << 16) | (size_segment[1] << 8) |
  622. size_segment[2];
  623. size_segment += 3;
  624. break;
  625. }
  626. if (opcode < 12) {
  627. flag ^= 1;
  628. if (flag) {
  629. /* run of (size) pixels is unchanged from last frame */
  630. xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
  631. } else {
  632. /* output a run of pixels from imagedata_buffer */
  633. xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
  634. imagedata_buffer += size;
  635. }
  636. } else {
  637. /* run-based motion compensation from last frame */
  638. motion_x = (*vector_segment >> 4) & 0xF;
  639. motion_y = *vector_segment & 0xF;
  640. vector_segment++;
  641. /* sign extension */
  642. if (motion_x & 0x8)
  643. motion_x |= 0xFFFFFFF0;
  644. if (motion_y & 0x8)
  645. motion_y |= 0xFFFFFFF0;
  646. /* copy a run of pixels from the previous frame */
  647. xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
  648. flag = 0;
  649. }
  650. /* coordinate accounting */
  651. total_pixels -= size;
  652. while (size) {
  653. if (x + size >= width) {
  654. y++;
  655. size -= (width - x);
  656. x = 0;
  657. } else {
  658. x += size;
  659. size = 0;
  660. }
  661. }
  662. }
  663. /* for PAL8, make the palette available on the way out */
  664. if (s->avctx->pix_fmt == PIX_FMT_PAL8)
  665. memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
  666. }
  667. static void xan_wc4_decode_frame(XanContext *s) {
  668. }
  669. static int xan_decode_frame(AVCodecContext *avctx,
  670. void *data, int *data_size,
  671. uint8_t *buf, int buf_size)
  672. {
  673. XanContext *s = avctx->priv_data;
  674. AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata;
  675. int keyframe = 0;
  676. if (palette_control->palette_changed) {
  677. /* load the new palette and reset the palette control */
  678. xan_wc3_build_palette(s, palette_control->palette);
  679. palette_control->palette_changed = 0;
  680. keyframe = 1;
  681. }
  682. if (avctx->get_buffer(avctx, &s->current_frame)) {
  683. printf (" Xan Video: get_buffer() failed\n");
  684. return -1;
  685. }
  686. s->current_frame.reference = 3;
  687. s->buf = buf;
  688. s->size = buf_size;
  689. if (avctx->codec->id == CODEC_ID_XAN_WC3)
  690. xan_wc3_decode_frame(s);
  691. else if (avctx->codec->id == CODEC_ID_XAN_WC4)
  692. xan_wc4_decode_frame(s);
  693. /* release the last frame if it is allocated */
  694. if (s->last_frame.data[0])
  695. avctx->release_buffer(avctx, &s->last_frame);
  696. /* shuffle frames */
  697. s->last_frame = s->current_frame;
  698. *data_size = sizeof(AVFrame);
  699. *(AVFrame*)data = s->current_frame;
  700. /* always report that the buffer was completely consumed */
  701. return buf_size;
  702. }
  703. static int xan_decode_end(AVCodecContext *avctx)
  704. {
  705. XanContext *s = avctx->priv_data;
  706. /* release the last frame */
  707. avctx->release_buffer(avctx, &s->last_frame);
  708. av_free(s->buffer1);
  709. av_free(s->buffer2);
  710. return 0;
  711. }
  712. AVCodec xan_wc3_decoder = {
  713. "xan_wc3",
  714. CODEC_TYPE_VIDEO,
  715. CODEC_ID_XAN_WC3,
  716. sizeof(XanContext),
  717. xan_decode_init,
  718. NULL,
  719. xan_decode_end,
  720. xan_decode_frame,
  721. CODEC_CAP_DR1,
  722. };
  723. /*
  724. AVCodec xan_wc4_decoder = {
  725. "xan_wc4",
  726. CODEC_TYPE_VIDEO,
  727. CODEC_ID_XAN_WC4,
  728. sizeof(XanContext),
  729. xan_decode_init,
  730. NULL,
  731. xan_decode_end,
  732. xan_decode_frame,
  733. CODEC_CAP_DR1,
  734. };
  735. */