00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <unistd.h>
00035
00036 #include "avcodec.h"
00037
00038 typedef struct XanContext {
00039
00040 AVCodecContext *avctx;
00041 AVFrame last_frame;
00042 AVFrame current_frame;
00043
00044 const unsigned char *buf;
00045 int size;
00046
00047
00048 unsigned char *buffer1;
00049 int buffer1_size;
00050 unsigned char *buffer2;
00051 int buffer2_size;
00052
00053 int frame_size;
00054
00055 } XanContext;
00056
00057 static int xan_decode_init(AVCodecContext *avctx)
00058 {
00059 XanContext *s = avctx->priv_data;
00060
00061 s->avctx = avctx;
00062 s->frame_size = 0;
00063
00064 if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
00065 (s->avctx->palctrl == NULL)) {
00066 av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n");
00067 return -1;
00068 }
00069
00070 avctx->pix_fmt = PIX_FMT_PAL8;
00071
00072 if(avcodec_check_dimensions(avctx, avctx->width, avctx->height))
00073 return -1;
00074
00075 s->buffer1_size = avctx->width * avctx->height;
00076 s->buffer1 = av_malloc(s->buffer1_size);
00077 s->buffer2_size = avctx->width * avctx->height;
00078 s->buffer2 = av_malloc(s->buffer2_size);
00079 if (!s->buffer1 || !s->buffer2)
00080 return -1;
00081
00082 return 0;
00083 }
00084
00085
00086
00087
00088
00089
00090 static inline void bytecopy(unsigned char *dest, const unsigned char *src, int count)
00091 {
00092 int i;
00093
00094 for (i = 0; i < count; i++)
00095 dest[i] = src[i];
00096 }
00097
00098 static int xan_huffman_decode(unsigned char *dest, const unsigned char *src,
00099 int dest_len)
00100 {
00101 unsigned char byte = *src++;
00102 unsigned char ival = byte + 0x16;
00103 const unsigned char * ptr = src + byte*2;
00104 unsigned char val = ival;
00105 int counter = 0;
00106 unsigned char *dest_end = dest + dest_len;
00107
00108 unsigned char bits = *ptr++;
00109
00110 while ( val != 0x16 ) {
00111 if ( (1 << counter) & bits )
00112 val = src[byte + val - 0x17];
00113 else
00114 val = src[val - 0x17];
00115
00116 if ( val < 0x16 ) {
00117 if (dest + 1 > dest_end)
00118 return 0;
00119 *dest++ = val;
00120 val = ival;
00121 }
00122
00123 if (counter++ == 7) {
00124 counter = 0;
00125 bits = *ptr++;
00126 }
00127 }
00128
00129 return 0;
00130 }
00131
00132 static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len)
00133 {
00134 unsigned char opcode;
00135 int size;
00136 int offset;
00137 int byte1, byte2, byte3;
00138 unsigned char *dest_end = dest + dest_len;
00139
00140 for (;;) {
00141 opcode = *src++;
00142
00143 if ( (opcode & 0x80) == 0 ) {
00144
00145 offset = *src++;
00146
00147 size = opcode & 3;
00148 if (dest + size > dest_end)
00149 return;
00150 bytecopy(dest, src, size); dest += size; src += size;
00151
00152 size = ((opcode & 0x1c) >> 2) + 3;
00153 if (dest + size > dest_end)
00154 return;
00155 bytecopy (dest, dest - (((opcode & 0x60) << 3) + offset + 1), size);
00156 dest += size;
00157
00158 } else if ( (opcode & 0x40) == 0 ) {
00159
00160 byte1 = *src++;
00161 byte2 = *src++;
00162
00163 size = byte1 >> 6;
00164 if (dest + size > dest_end)
00165 return;
00166 bytecopy (dest, src, size); dest += size; src += size;
00167
00168 size = (opcode & 0x3f) + 4;
00169 if (dest + size > dest_end)
00170 return;
00171 bytecopy (dest, dest - (((byte1 & 0x3f) << 8) + byte2 + 1), size);
00172 dest += size;
00173
00174 } else if ( (opcode & 0x20) == 0 ) {
00175
00176 byte1 = *src++;
00177 byte2 = *src++;
00178 byte3 = *src++;
00179
00180 size = opcode & 3;
00181 if (dest + size > dest_end)
00182 return;
00183 bytecopy (dest, src, size); dest += size; src += size;
00184
00185 size = byte3 + 5 + ((opcode & 0xc) << 6);
00186 if (dest + size > dest_end)
00187 return;
00188 bytecopy (dest,
00189 dest - ((((opcode & 0x10) >> 4) << 0x10) + 1 + (byte1 << 8) + byte2),
00190 size);
00191 dest += size;
00192 } else {
00193 size = ((opcode & 0x1f) << 2) + 4;
00194
00195 if (size > 0x70)
00196 break;
00197
00198 if (dest + size > dest_end)
00199 return;
00200 bytecopy (dest, src, size); dest += size; src += size;
00201 }
00202 }
00203
00204 size = opcode & 3;
00205 bytecopy(dest, src, size); dest += size; src += size;
00206 }
00207
00208 static inline void xan_wc3_output_pixel_run(XanContext *s,
00209 const unsigned char *pixel_buffer, int x, int y, int pixel_count)
00210 {
00211 int stride;
00212 int line_inc;
00213 int index;
00214 int current_x;
00215 int width = s->avctx->width;
00216 unsigned char *palette_plane;
00217
00218 palette_plane = s->current_frame.data[0];
00219 stride = s->current_frame.linesize[0];
00220 line_inc = stride - width;
00221 index = y * stride + x;
00222 current_x = x;
00223 while((pixel_count--) && (index < s->frame_size)) {
00224
00225
00226
00227 palette_plane[index++] = *pixel_buffer++;
00228
00229 current_x++;
00230 if (current_x >= width) {
00231 index += line_inc;
00232 current_x = 0;
00233 }
00234 }
00235 }
00236
00237 static inline void xan_wc3_copy_pixel_run(XanContext *s,
00238 int x, int y, int pixel_count, int motion_x, int motion_y)
00239 {
00240 int stride;
00241 int line_inc;
00242 int curframe_index, prevframe_index;
00243 int curframe_x, prevframe_x;
00244 int width = s->avctx->width;
00245 unsigned char *palette_plane, *prev_palette_plane;
00246
00247 palette_plane = s->current_frame.data[0];
00248 prev_palette_plane = s->last_frame.data[0];
00249 stride = s->current_frame.linesize[0];
00250 line_inc = stride - width;
00251 curframe_index = y * stride + x;
00252 curframe_x = x;
00253 prevframe_index = (y + motion_y) * stride + x + motion_x;
00254 prevframe_x = x + motion_x;
00255 while((pixel_count--) && (curframe_index < s->frame_size)) {
00256
00257 palette_plane[curframe_index++] =
00258 prev_palette_plane[prevframe_index++];
00259
00260 curframe_x++;
00261 if (curframe_x >= width) {
00262 curframe_index += line_inc;
00263 curframe_x = 0;
00264 }
00265
00266 prevframe_x++;
00267 if (prevframe_x >= width) {
00268 prevframe_index += line_inc;
00269 prevframe_x = 0;
00270 }
00271 }
00272 }
00273
00274 static void xan_wc3_decode_frame(XanContext *s) {
00275
00276 int width = s->avctx->width;
00277 int height = s->avctx->height;
00278 int total_pixels = width * height;
00279 unsigned char opcode;
00280 unsigned char flag = 0;
00281 int size = 0;
00282 int motion_x, motion_y;
00283 int x, y;
00284
00285 unsigned char *opcode_buffer = s->buffer1;
00286 int opcode_buffer_size = s->buffer1_size;
00287 const unsigned char *imagedata_buffer = s->buffer2;
00288
00289
00290 const unsigned char *huffman_segment;
00291 const unsigned char *size_segment;
00292 const unsigned char *vector_segment;
00293 const unsigned char *imagedata_segment;
00294
00295 huffman_segment = s->buf + AV_RL16(&s->buf[0]);
00296 size_segment = s->buf + AV_RL16(&s->buf[2]);
00297 vector_segment = s->buf + AV_RL16(&s->buf[4]);
00298 imagedata_segment = s->buf + AV_RL16(&s->buf[6]);
00299
00300 xan_huffman_decode(opcode_buffer, huffman_segment, opcode_buffer_size);
00301
00302 if (imagedata_segment[0] == 2)
00303 xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size);
00304 else
00305 imagedata_buffer = &imagedata_segment[1];
00306
00307
00308 x = y = 0;
00309 while (total_pixels) {
00310
00311 opcode = *opcode_buffer++;
00312 size = 0;
00313
00314 switch (opcode) {
00315
00316 case 0:
00317 flag ^= 1;
00318 continue;
00319
00320 case 1:
00321 case 2:
00322 case 3:
00323 case 4:
00324 case 5:
00325 case 6:
00326 case 7:
00327 case 8:
00328 size = opcode;
00329 break;
00330
00331 case 12:
00332 case 13:
00333 case 14:
00334 case 15:
00335 case 16:
00336 case 17:
00337 case 18:
00338 size += (opcode - 10);
00339 break;
00340
00341 case 9:
00342 case 19:
00343 size = *size_segment++;
00344 break;
00345
00346 case 10:
00347 case 20:
00348 size = AV_RB16(&size_segment[0]);
00349 size_segment += 2;
00350 break;
00351
00352 case 11:
00353 case 21:
00354 size = AV_RB24(size_segment);
00355 size_segment += 3;
00356 break;
00357 }
00358
00359 if (opcode < 12) {
00360 flag ^= 1;
00361 if (flag) {
00362
00363 xan_wc3_copy_pixel_run(s, x, y, size, 0, 0);
00364 } else {
00365
00366 xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size);
00367 imagedata_buffer += size;
00368 }
00369 } else {
00370
00371 motion_x = (*vector_segment >> 4) & 0xF;
00372 motion_y = *vector_segment & 0xF;
00373 vector_segment++;
00374
00375
00376 if (motion_x & 0x8)
00377 motion_x |= 0xFFFFFFF0;
00378 if (motion_y & 0x8)
00379 motion_y |= 0xFFFFFFF0;
00380
00381
00382 xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
00383
00384 flag = 0;
00385 }
00386
00387
00388 total_pixels -= size;
00389 while (size) {
00390 if (x + size >= width) {
00391 y++;
00392 size -= (width - x);
00393 x = 0;
00394 } else {
00395 x += size;
00396 size = 0;
00397 }
00398 }
00399 }
00400 }
00401
00402 static void xan_wc4_decode_frame(XanContext *s) {
00403 }
00404
00405 static int xan_decode_frame(AVCodecContext *avctx,
00406 void *data, int *data_size,
00407 const uint8_t *buf, int buf_size)
00408 {
00409 XanContext *s = avctx->priv_data;
00410 AVPaletteControl *palette_control = avctx->palctrl;
00411
00412 if (avctx->get_buffer(avctx, &s->current_frame)) {
00413 av_log(s->avctx, AV_LOG_ERROR, " Xan Video: get_buffer() failed\n");
00414 return -1;
00415 }
00416 s->current_frame.reference = 3;
00417
00418 if (!s->frame_size)
00419 s->frame_size = s->current_frame.linesize[0] * s->avctx->height;
00420
00421 palette_control->palette_changed = 0;
00422 memcpy(s->current_frame.data[1], palette_control->palette,
00423 AVPALETTE_SIZE);
00424 s->current_frame.palette_has_changed = 1;
00425
00426 s->buf = buf;
00427 s->size = buf_size;
00428
00429 if (avctx->codec->id == CODEC_ID_XAN_WC3)
00430 xan_wc3_decode_frame(s);
00431 else if (avctx->codec->id == CODEC_ID_XAN_WC4)
00432 xan_wc4_decode_frame(s);
00433
00434
00435 if (s->last_frame.data[0])
00436 avctx->release_buffer(avctx, &s->last_frame);
00437
00438
00439 s->last_frame = s->current_frame;
00440
00441 *data_size = sizeof(AVFrame);
00442 *(AVFrame*)data = s->current_frame;
00443
00444
00445 return buf_size;
00446 }
00447
00448 static int xan_decode_end(AVCodecContext *avctx)
00449 {
00450 XanContext *s = avctx->priv_data;
00451
00452
00453 if (s->last_frame.data[0])
00454 avctx->release_buffer(avctx, &s->last_frame);
00455
00456 av_free(s->buffer1);
00457 av_free(s->buffer2);
00458
00459 return 0;
00460 }
00461
00462 AVCodec xan_wc3_decoder = {
00463 "xan_wc3",
00464 CODEC_TYPE_VIDEO,
00465 CODEC_ID_XAN_WC3,
00466 sizeof(XanContext),
00467 xan_decode_init,
00468 NULL,
00469 xan_decode_end,
00470 xan_decode_frame,
00471 CODEC_CAP_DR1,
00472 };
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486