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.

888 lines
25KB

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