📄 zmbv.c
字号:
/* * Zip Motion Blocks Video (ZMBV) decoder * Copyright (c) 2006 Konstantin Shishkov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * *//** * @file zmbv.c * Zip Motion Blocks Video decoder */#include <stdio.h>#include <stdlib.h>#include "common.h"#include "avcodec.h"#ifdef CONFIG_ZLIB#include <zlib.h>#endif#define ZMBV_KEYFRAME 1#define ZMBV_DELTAPAL 2enum ZmbvFormat { ZMBV_FMT_NONE = 0, ZMBV_FMT_1BPP = 1, ZMBV_FMT_2BPP = 2, ZMBV_FMT_4BPP = 3, ZMBV_FMT_8BPP = 4, ZMBV_FMT_15BPP = 5, ZMBV_FMT_16BPP = 6, ZMBV_FMT_24BPP = 7, ZMBV_FMT_32BPP = 8};/* * Decoder context */typedef struct ZmbvContext { AVCodecContext *avctx; AVFrame pic; int bpp; unsigned int decomp_size; uint8_t* decomp_buf; uint8_t pal[768]; uint8_t *prev, *cur; int width, height; int fmt; int comp; int flags; int bw, bh, bx, by; int decomp_len;#ifdef CONFIG_ZLIB z_stream zstream;#endif int (*decode_intra)(struct ZmbvContext *c); int (*decode_xor)(struct ZmbvContext *c);} ZmbvContext;/** * Decode XOR'ed frame - 8bpp version */static int zmbv_decode_xor_8(ZmbvContext *c){ uint8_t *src = c->decomp_buf; uint8_t *output, *prev; int8_t *mvec; int x, y; int d, dx, dy, bw2, bh2; int block; int i, j; int mx, my; output = c->cur; prev = c->prev; if(c->flags & ZMBV_DELTAPAL){ for(i = 0; i < 768; i++) c->pal[i] ^= *src++; } mvec = (int8_t*)src; src += ((c->bx * c->by * 2 + 3) & ~3); block = 0; for(y = 0; y < c->height; y += c->bh) { bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); for(x = 0; x < c->width; x += c->bw) { uint8_t *out, *tprev; d = mvec[block] & 1; dx = mvec[block] >> 1; dy = mvec[block + 1] >> 1; block += 2; bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); /* copy block - motion vectors out of bounds are used to zero blocks */ out = output + x; tprev = prev + x + dx + dy * c->width; mx = x + dx; my = y + dy; for(j = 0; j < bh2; j++){ if((my + j < 0) || (my + j >= c->height)) { memset(out, 0, bw2); } else { for(i = 0; i < bw2; i++){ if((mx + i < 0) || (mx + i >= c->width)) out[i] = 0; else out[i] = tprev[i]; } } out += c->width; tprev += c->width; } if(d) { /* apply XOR'ed difference */ out = output + x; for(j = 0; j < bh2; j++){ for(i = 0; i < bw2; i++) out[i] ^= *src++; out += c->width; } } } output += c->width * c->bh; prev += c->width * c->bh; } if(src - c->decomp_buf != c->decomp_len) av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0;}/** * Decode XOR'ed frame - 15bpp and 16bpp version */static int zmbv_decode_xor_16(ZmbvContext *c){ uint8_t *src = c->decomp_buf; uint16_t *output, *prev; int8_t *mvec; int x, y; int d, dx, dy, bw2, bh2; int block; int i, j; int mx, my; output = (uint16_t*)c->cur; prev = (uint16_t*)c->prev; mvec = (int8_t*)src; src += ((c->bx * c->by * 2 + 3) & ~3); block = 0; for(y = 0; y < c->height; y += c->bh) { bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); for(x = 0; x < c->width; x += c->bw) { uint16_t *out, *tprev; d = mvec[block] & 1; dx = mvec[block] >> 1; dy = mvec[block + 1] >> 1; block += 2; bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); /* copy block - motion vectors out of bounds are used to zero blocks */ out = output + x; tprev = prev + x + dx + dy * c->width; mx = x + dx; my = y + dy; for(j = 0; j < bh2; j++){ if((my + j < 0) || (my + j >= c->height)) { memset(out, 0, bw2 * 2); } else { for(i = 0; i < bw2; i++){ if((mx + i < 0) || (mx + i >= c->width)) out[i] = 0; else out[i] = tprev[i]; } } out += c->width; tprev += c->width; } if(d) { /* apply XOR'ed difference */ out = output + x; for(j = 0; j < bh2; j++){ for(i = 0; i < bw2; i++) { out[i] ^= *((uint16_t*)src); src += 2; } out += c->width; } } } output += c->width * c->bh; prev += c->width * c->bh; } if(src - c->decomp_buf != c->decomp_len) av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0;}#ifdef ZMBV_ENABLE_24BPP/** * Decode XOR'ed frame - 24bpp version */static int zmbv_decode_xor_24(ZmbvContext *c){ uint8_t *src = c->decomp_buf; uint8_t *output, *prev; int8_t *mvec; int x, y; int d, dx, dy, bw2, bh2; int block; int i, j; int mx, my; int stride; output = c->cur; prev = c->prev; stride = c->width * 3; mvec = (int8_t*)src; src += ((c->bx * c->by * 2 + 3) & ~3); block = 0; for(y = 0; y < c->height; y += c->bh) { bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); for(x = 0; x < c->width; x += c->bw) { uint8_t *out, *tprev; d = mvec[block] & 1; dx = mvec[block] >> 1; dy = mvec[block + 1] >> 1; block += 2; bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); /* copy block - motion vectors out of bounds are used to zero blocks */ out = output + x * 3; tprev = prev + (x + dx) * 3 + dy * stride; mx = x + dx; my = y + dy; for(j = 0; j < bh2; j++){ if((my + j < 0) || (my + j >= c->height)) { memset(out, 0, bw2 * 3); } else { for(i = 0; i < bw2; i++){ if((mx + i < 0) || (mx + i >= c->width)) { out[i * 3 + 0] = 0; out[i * 3 + 1] = 0; out[i * 3 + 2] = 0; } else { out[i * 3 + 0] = tprev[i * 3 + 0]; out[i * 3 + 1] = tprev[i * 3 + 1]; out[i * 3 + 2] = tprev[i * 3 + 2]; } } } out += stride; tprev += stride; } if(d) { /* apply XOR'ed difference */ out = output + x * 3; for(j = 0; j < bh2; j++){ for(i = 0; i < bw2; i++) { out[i * 3 + 0] ^= *src++; out[i * 3 + 1] ^= *src++; out[i * 3 + 2] ^= *src++; } out += stride; } } } output += stride * c->bh; prev += stride * c->bh; } if(src - c->decomp_buf != c->decomp_len) av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); return 0;}#endif //ZMBV_ENABLE_24BPP/** * Decode XOR'ed frame - 32bpp version */static int zmbv_decode_xor_32(ZmbvContext *c){ uint8_t *src = c->decomp_buf; uint32_t *output, *prev; int8_t *mvec; int x, y; int d, dx, dy, bw2, bh2; int block; int i, j; int mx, my; output = (uint32_t*)c->cur; prev = (uint32_t*)c->prev; mvec = (int8_t*)src; src += ((c->bx * c->by * 2 + 3) & ~3); block = 0; for(y = 0; y < c->height; y += c->bh) { bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); for(x = 0; x < c->width; x += c->bw) { uint32_t *out, *tprev; d = mvec[block] & 1; dx = mvec[block] >> 1; dy = mvec[block + 1] >> 1; block += 2; bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); /* copy block - motion vectors out of bounds are used to zero blocks */ out = output + x; tprev = prev + x + dx + dy * c->width; mx = x + dx; my = y + dy; for(j = 0; j < bh2; j++){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -