00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029
00030 #include "avcodec.h"
00031
00032 #include <zlib.h>
00033
00034 #define ZMBV_KEYFRAME 1
00035 #define ZMBV_DELTAPAL 2
00036
00037 enum ZmbvFormat {
00038 ZMBV_FMT_NONE = 0,
00039 ZMBV_FMT_1BPP = 1,
00040 ZMBV_FMT_2BPP = 2,
00041 ZMBV_FMT_4BPP = 3,
00042 ZMBV_FMT_8BPP = 4,
00043 ZMBV_FMT_15BPP = 5,
00044 ZMBV_FMT_16BPP = 6,
00045 ZMBV_FMT_24BPP = 7,
00046 ZMBV_FMT_32BPP = 8
00047 };
00048
00049
00050
00051
00052 typedef struct ZmbvContext {
00053 AVCodecContext *avctx;
00054 AVFrame pic;
00055
00056 int bpp;
00057 unsigned int decomp_size;
00058 uint8_t* decomp_buf;
00059 uint8_t pal[768];
00060 uint8_t *prev, *cur;
00061 int width, height;
00062 int fmt;
00063 int comp;
00064 int flags;
00065 int bw, bh, bx, by;
00066 int decomp_len;
00067 z_stream zstream;
00068 int (*decode_intra)(struct ZmbvContext *c);
00069 int (*decode_xor)(struct ZmbvContext *c);
00070 } ZmbvContext;
00071
00076 static int zmbv_decode_xor_8(ZmbvContext *c)
00077 {
00078 uint8_t *src = c->decomp_buf;
00079 uint8_t *output, *prev;
00080 int8_t *mvec;
00081 int x, y;
00082 int d, dx, dy, bw2, bh2;
00083 int block;
00084 int i, j;
00085 int mx, my;
00086
00087 output = c->cur;
00088 prev = c->prev;
00089
00090 if(c->flags & ZMBV_DELTAPAL){
00091 for(i = 0; i < 768; i++)
00092 c->pal[i] ^= *src++;
00093 }
00094
00095 mvec = (int8_t*)src;
00096 src += ((c->bx * c->by * 2 + 3) & ~3);
00097
00098 block = 0;
00099 for(y = 0; y < c->height; y += c->bh) {
00100 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
00101 for(x = 0; x < c->width; x += c->bw) {
00102 uint8_t *out, *tprev;
00103
00104 d = mvec[block] & 1;
00105 dx = mvec[block] >> 1;
00106 dy = mvec[block + 1] >> 1;
00107 block += 2;
00108
00109 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
00110
00111
00112 out = output + x;
00113 tprev = prev + x + dx + dy * c->width;
00114 mx = x + dx;
00115 my = y + dy;
00116 for(j = 0; j < bh2; j++){
00117 if((my + j < 0) || (my + j >= c->height)) {
00118 memset(out, 0, bw2);
00119 } else {
00120 for(i = 0; i < bw2; i++){
00121 if((mx + i < 0) || (mx + i >= c->width))
00122 out[i] = 0;
00123 else
00124 out[i] = tprev[i];
00125 }
00126 }
00127 out += c->width;
00128 tprev += c->width;
00129 }
00130
00131 if(d) {
00132 out = output + x;
00133 for(j = 0; j < bh2; j++){
00134 for(i = 0; i < bw2; i++)
00135 out[i] ^= *src++;
00136 out += c->width;
00137 }
00138 }
00139 }
00140 output += c->width * c->bh;
00141 prev += c->width * c->bh;
00142 }
00143 if(src - c->decomp_buf != c->decomp_len)
00144 av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len);
00145 return 0;
00146 }
00147
00152 static int zmbv_decode_xor_16(ZmbvContext *c)
00153 {
00154 uint8_t *src = c->decomp_buf;
00155 uint16_t *output, *prev;
00156 int8_t *mvec;
00157 int x, y;
00158 int d, dx, dy, bw2, bh2;
00159 int block;
00160 int i, j;
00161 int mx, my;
00162
00163 output = (uint16_t*)c->cur;
00164 prev = (uint16_t*)c->prev;
00165
00166 mvec = (int8_t*)src;
00167 src += ((c->bx * c->by * 2 + 3) & ~3);
00168
00169 block = 0;
00170 for(y = 0; y < c->height; y += c->bh) {
00171 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
00172 for(x = 0; x < c->width; x += c->bw) {
00173 uint16_t *out, *tprev;
00174
00175 d = mvec[block] & 1;
00176 dx = mvec[block] >> 1;
00177 dy = mvec[block + 1] >> 1;
00178 block += 2;
00179
00180 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
00181
00182
00183 out = output + x;
00184 tprev = prev + x + dx + dy * c->width;
00185 mx = x + dx;
00186 my = y + dy;
00187 for(j = 0; j < bh2; j++){
00188 if((my + j < 0) || (my + j >= c->height)) {
00189 memset(out, 0, bw2 * 2);
00190 } else {
00191 for(i = 0; i < bw2; i++){
00192 if((mx + i < 0) || (mx + i >= c->width))
00193 out[i] = 0;
00194 else
00195 out[i] = tprev[i];
00196 }
00197 }
00198 out += c->width;
00199 tprev += c->width;
00200 }
00201
00202 if(d) {
00203 out = output + x;
00204 for(j = 0; j < bh2; j++){
00205 for(i = 0; i < bw2; i++) {
00206 out[i] ^= *((uint16_t*)src);
00207 src += 2;
00208 }
00209 out += c->width;
00210 }
00211 }
00212 }
00213 output += c->width * c->bh;
00214 prev += c->width * c->bh;
00215 }
00216 if(src - c->decomp_buf != c->decomp_len)
00217 av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len);
00218 return 0;
00219 }
00220
00221 #ifdef ZMBV_ENABLE_24BPP
00222
00226 static int zmbv_decode_xor_24(ZmbvContext *c)
00227 {
00228 uint8_t *src = c->decomp_buf;
00229 uint8_t *output, *prev;
00230 int8_t *mvec;
00231 int x, y;
00232 int d, dx, dy, bw2, bh2;
00233 int block;
00234 int i, j;
00235 int mx, my;
00236 int stride;
00237
00238 output = c->cur;
00239 prev = c->prev;
00240
00241 stride = c->width * 3;
00242 mvec = (int8_t*)src;
00243 src += ((c->bx * c->by * 2 + 3) & ~3);
00244
00245 block = 0;
00246 for(y = 0; y < c->height; y += c->bh) {
00247 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
00248 for(x = 0; x < c->width; x += c->bw) {
00249 uint8_t *out, *tprev;
00250
00251 d = mvec[block] & 1;
00252 dx = mvec[block] >> 1;
00253 dy = mvec[block + 1] >> 1;
00254 block += 2;
00255
00256 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
00257
00258
00259 out = output + x * 3;
00260 tprev = prev + (x + dx) * 3 + dy * stride;
00261 mx = x + dx;
00262 my = y + dy;
00263 for(j = 0; j < bh2; j++){
00264 if((my + j < 0) || (my + j >= c->height)) {
00265 memset(out, 0, bw2 * 3);
00266 } else {
00267 for(i = 0; i < bw2; i++){
00268 if((mx + i < 0) || (mx + i >= c->width)) {
00269 out[i * 3 + 0] = 0;
00270 out[i * 3 + 1] = 0;
00271 out[i * 3 + 2] = 0;
00272 } else {
00273 out[i * 3 + 0] = tprev[i * 3 + 0];
00274 out[i * 3 + 1] = tprev[i * 3 + 1];
00275 out[i * 3 + 2] = tprev[i * 3 + 2];
00276 }
00277 }
00278 }
00279 out += stride;
00280 tprev += stride;
00281 }
00282
00283 if(d) {
00284 out = output + x * 3;
00285 for(j = 0; j < bh2; j++){
00286 for(i = 0; i < bw2; i++) {
00287 out[i * 3 + 0] ^= *src++;
00288 out[i * 3 + 1] ^= *src++;
00289 out[i * 3 + 2] ^= *src++;
00290 }
00291 out += stride;
00292 }
00293 }
00294 }
00295 output += stride * c->bh;
00296 prev += stride * c->bh;
00297 }
00298 if(src - c->decomp_buf != c->decomp_len)
00299 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
00300 return 0;
00301 }
00302 #endif //ZMBV_ENABLE_24BPP
00303
00308 static int zmbv_decode_xor_32(ZmbvContext *c)
00309 {
00310 uint8_t *src = c->decomp_buf;
00311 uint32_t *output, *prev;
00312 int8_t *mvec;
00313 int x, y;
00314 int d, dx, dy, bw2, bh2;
00315 int block;
00316 int i, j;
00317 int mx, my;
00318
00319 output = (uint32_t*)c->cur;
00320 prev = (uint32_t*)c->prev;
00321
00322 mvec = (int8_t*)src;
00323 src += ((c->bx * c->by * 2 + 3) & ~3);
00324
00325 block = 0;
00326 for(y = 0; y < c->height; y += c->bh) {
00327 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
00328 for(x = 0; x < c->width; x += c->bw) {
00329 uint32_t *out, *tprev;
00330
00331 d = mvec[block] & 1;
00332 dx = mvec[block] >> 1;
00333 dy = mvec[block + 1] >> 1;
00334 block += 2;
00335
00336 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
00337
00338
00339 out = output + x;
00340 tprev = prev + x + dx + dy * c->width;
00341 mx = x + dx;
00342 my = y + dy;
00343 for(j = 0; j < bh2; j++){
00344 if((my + j < 0) || (my + j >= c->height)) {
00345 memset(out, 0, bw2 * 4);
00346 } else {
00347 for(i = 0; i < bw2; i++){
00348 if((mx + i < 0) || (mx + i >= c->width))
00349 out[i] = 0;
00350 else
00351 out[i] = tprev[i];
00352 }
00353 }
00354 out += c->width;
00355 tprev += c->width;
00356 }
00357
00358 if(d) {
00359 out = output + x;
00360 for(j = 0; j < bh2; j++){
00361 for(i = 0; i < bw2; i++) {
00362 out[i] ^= *((uint32_t*)src);
00363 src += 4;
00364 }
00365 out += c->width;
00366 }
00367 }
00368 }
00369 output += c->width * c->bh;
00370 prev += c->width * c->bh;
00371 }
00372 if(src - c->decomp_buf != c->decomp_len)
00373 av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n", src-c->decomp_buf, c->decomp_len);
00374 return 0;
00375 }
00376
00380 static int zmbv_decode_intra(ZmbvContext *c)
00381 {
00382 uint8_t *src = c->decomp_buf;
00383
00384
00385 if (c->fmt == ZMBV_FMT_8BPP) {
00386 memcpy(c->pal, src, 768);
00387 src += 768;
00388 }
00389
00390 memcpy(c->cur, src, c->width * c->height * (c->bpp / 8));
00391 return 0;
00392 }
00393
00394 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, const uint8_t *buf, int buf_size)
00395 {
00396 ZmbvContext * const c = avctx->priv_data;
00397 uint8_t *outptr;
00398 int zret = Z_OK;
00399 int len = buf_size;
00400 int hi_ver, lo_ver;
00401
00402 if(c->pic.data[0])
00403 avctx->release_buffer(avctx, &c->pic);
00404
00405 c->pic.reference = 1;
00406 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00407 if(avctx->get_buffer(avctx, &c->pic) < 0){
00408 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00409 return -1;
00410 }
00411
00412 outptr = c->pic.data[0];
00413
00414
00415 c->flags = buf[0];
00416 buf++; len--;
00417 if(c->flags & ZMBV_KEYFRAME) {
00418 hi_ver = buf[0];
00419 lo_ver = buf[1];
00420 c->comp = buf[2];
00421 c->fmt = buf[3];
00422 c->bw = buf[4];
00423 c->bh = buf[5];
00424
00425 buf += 6;
00426 len -= 6;
00427 av_log(avctx, AV_LOG_DEBUG, "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
00428 if(hi_ver != 0 || lo_ver != 1) {
00429 av_log(avctx, AV_LOG_ERROR, "Unsupported version %i.%i\n", hi_ver, lo_ver);
00430 return -1;
00431 }
00432 if(c->bw == 0 || c->bh == 0) {
00433 av_log(avctx, AV_LOG_ERROR, "Unsupported block size %ix%i\n", c->bw, c->bh);
00434 }
00435 if(c->comp != 0 && c->comp != 1) {
00436 av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp);
00437 return -1;
00438 }
00439
00440 switch(c->fmt) {
00441 case ZMBV_FMT_8BPP:
00442 c->bpp = 8;
00443 c->decode_intra = zmbv_decode_intra;
00444 c->decode_xor = zmbv_decode_xor_8;
00445 break;
00446 case ZMBV_FMT_15BPP:
00447 case ZMBV_FMT_16BPP:
00448 c->bpp = 16;
00449 c->decode_intra = zmbv_decode_intra;
00450 c->decode_xor = zmbv_decode_xor_16;
00451 break;
00452 #ifdef ZMBV_ENABLE_24BPP
00453 case ZMBV_FMT_24BPP:
00454 c->bpp = 24;
00455 c->decode_intra = zmbv_decode_intra;
00456 c->decode_xor = zmbv_decode_xor_24;
00457 break;
00458 #endif //ZMBV_ENABLE_24BPP
00459 case ZMBV_FMT_32BPP:
00460 c->bpp = 32;
00461 c->decode_intra = zmbv_decode_intra;
00462 c->decode_xor = zmbv_decode_xor_32;
00463 break;
00464 default:
00465 c->decode_intra = NULL;
00466 c->decode_xor = NULL;
00467 av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt);
00468 return -1;
00469 }
00470
00471 zret = inflateReset(&c->zstream);
00472 if (zret != Z_OK) {
00473 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
00474 return -1;
00475 }
00476
00477 c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8));
00478 c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8));
00479 c->bx = (c->width + c->bw - 1) / c->bw;
00480 c->by = (c->height+ c->bh - 1) / c->bh;
00481 }
00482
00483 if(c->decode_intra == NULL) {
00484 av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
00485 return -1;
00486 }
00487
00488 if(c->comp == 0) {
00489 memcpy(c->decomp_buf, buf, len);
00490 c->decomp_size = 1;
00491 } else {
00492 c->zstream.total_in = c->zstream.total_out = 0;
00493 c->zstream.next_in = buf;
00494 c->zstream.avail_in = len;
00495 c->zstream.next_out = c->decomp_buf;
00496 c->zstream.avail_out = c->decomp_size;
00497 inflate(&c->zstream, Z_FINISH);
00498 c->decomp_len = c->zstream.total_out;
00499 }
00500 if(c->flags & ZMBV_KEYFRAME) {
00501 c->pic.key_frame = 1;
00502 c->pic.pict_type = FF_I_TYPE;
00503 c->decode_intra(c);
00504 } else {
00505 c->pic.key_frame = 0;
00506 c->pic.pict_type = FF_P_TYPE;
00507 c->decode_xor(c);
00508 }
00509
00510
00511 {
00512 uint8_t *out, *src;
00513 int i, j;
00514
00515 out = c->pic.data[0];
00516 src = c->cur;
00517 switch(c->fmt) {
00518 case ZMBV_FMT_8BPP:
00519 for(j = 0; j < c->height; j++) {
00520 for(i = 0; i < c->width; i++) {
00521 out[i * 3 + 0] = c->pal[(*src) * 3 + 0];
00522 out[i * 3 + 1] = c->pal[(*src) * 3 + 1];
00523 out[i * 3 + 2] = c->pal[(*src) * 3 + 2];
00524 src++;
00525 }
00526 out += c->pic.linesize[0];
00527 }
00528 break;
00529 case ZMBV_FMT_15BPP:
00530 for(j = 0; j < c->height; j++) {
00531 for(i = 0; i < c->width; i++) {
00532 uint16_t tmp = AV_RL16(src);
00533 src += 2;
00534 out[i * 3 + 0] = (tmp & 0x7C00) >> 7;
00535 out[i * 3 + 1] = (tmp & 0x03E0) >> 2;
00536 out[i * 3 + 2] = (tmp & 0x001F) << 3;
00537 }
00538 out += c->pic.linesize[0];
00539 }
00540 break;
00541 case ZMBV_FMT_16BPP:
00542 for(j = 0; j < c->height; j++) {
00543 for(i = 0; i < c->width; i++) {
00544 uint16_t tmp = AV_RL16(src);
00545 src += 2;
00546 out[i * 3 + 0] = (tmp & 0xF800) >> 8;
00547 out[i * 3 + 1] = (tmp & 0x07E0) >> 3;
00548 out[i * 3 + 2] = (tmp & 0x001F) << 3;
00549 }
00550 out += c->pic.linesize[0];
00551 }
00552 break;
00553 #ifdef ZMBV_ENABLE_24BPP
00554 case ZMBV_FMT_24BPP:
00555 for(j = 0; j < c->height; j++) {
00556 memcpy(out, src, c->width * 3);
00557 src += c->width * 3;
00558 out += c->pic.linesize[0];
00559 }
00560 break;
00561 #endif //ZMBV_ENABLE_24BPP
00562 case ZMBV_FMT_32BPP:
00563 for(j = 0; j < c->height; j++) {
00564 for(i = 0; i < c->width; i++) {
00565 uint32_t tmp = AV_RL32(src);
00566 src += 4;
00567 AV_WB24(out+(i*3), tmp);
00568 }
00569 out += c->pic.linesize[0];
00570 }
00571 break;
00572 default:
00573 av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
00574 }
00575 memcpy(c->prev, c->cur, c->width * c->height * (c->bpp / 8));
00576 }
00577 *data_size = sizeof(AVFrame);
00578 *(AVFrame*)data = c->pic;
00579
00580
00581 return buf_size;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591 static int decode_init(AVCodecContext *avctx)
00592 {
00593 ZmbvContext * const c = avctx->priv_data;
00594 int zret;
00595
00596 c->avctx = avctx;
00597
00598 c->pic.data[0] = NULL;
00599 c->width = avctx->width;
00600 c->height = avctx->height;
00601
00602 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
00603 return 1;
00604 }
00605 c->bpp = avctx->bits_per_sample;
00606
00607
00608 memset(&(c->zstream), 0, sizeof(z_stream));
00609
00610 avctx->pix_fmt = PIX_FMT_RGB24;
00611 c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64);
00612
00613
00614 if (c->decomp_size) {
00615 if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
00616 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00617 return 1;
00618 }
00619 }
00620
00621 c->zstream.zalloc = Z_NULL;
00622 c->zstream.zfree = Z_NULL;
00623 c->zstream.opaque = Z_NULL;
00624 zret = inflateInit(&(c->zstream));
00625 if (zret != Z_OK) {
00626 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00627 return 1;
00628 }
00629
00630 return 0;
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640 static int decode_end(AVCodecContext *avctx)
00641 {
00642 ZmbvContext * const c = avctx->priv_data;
00643
00644 av_freep(&c->decomp_buf);
00645
00646 if (c->pic.data[0])
00647 avctx->release_buffer(avctx, &c->pic);
00648 inflateEnd(&(c->zstream));
00649 av_freep(&c->cur);
00650 av_freep(&c->prev);
00651
00652 return 0;
00653 }
00654
00655 AVCodec zmbv_decoder = {
00656 "zmbv",
00657 CODEC_TYPE_VIDEO,
00658 CODEC_ID_ZMBV,
00659 sizeof(ZmbvContext),
00660 decode_init,
00661 NULL,
00662 decode_end,
00663 decode_frame
00664 };
00665