⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zmbv.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -