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