X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fh.263%2Fvideo.c;h=31391dbd56a39d76ad83cbdf156b3daf3eb18e58;hb=879d0eec420fe0fd5ddcd56c8fe62b82a6744edd;hp=2376017530a1b9f28439f45a1cf5fbccce8f768d;hpb=c66d70eb818cbc80ddae1dd5f35352d048ce5a5c;p=swftools.git diff --git a/lib/h.263/video.c b/lib/h.263/video.c index 2376017..31391db 100644 --- a/lib/h.263/video.c +++ b/lib/h.263/video.c @@ -3,16 +3,31 @@ Part of the swftools package. - Copyright (c) 2003 Matthias Kramm */ - -#include "../config.h" + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "../../config.h" #include #include #include #include -#include "../lib/rfxswf.h" -#include "../lib/args.h" -#include "h263tables.c" +#include +#include "../rfxswf.h" +#include "../args.h" +#include "h263tables.h" static char * filename = 0; static char * indent = " "; @@ -129,6 +144,62 @@ int checkhufftable(struct huffcode*code, char*name) } } + +struct hufftree +{ + struct hufftree*left;//0 + struct hufftree*right;//1 + int index; +}; + +struct hufftree * rle_tree; +struct hufftree * mcbpc_intra_tree; +struct hufftree * mcbpc_inter_tree; +struct hufftree * cbpy_tree; +struct hufftree * mvd_tree; + +static void insert(struct hufftree*tree, char*code, int index) +{ + if(!*code) { + assert(!tree->left); //shannon conditional + assert(!tree->right); + tree->left = 0; + tree->right = 0; + tree->index = index; + return; + } + if(code[0] == '0') { + if(!tree->left) { + tree->left = (struct hufftree*)malloc(sizeof(struct hufftree)); + memset(tree->left, 0, sizeof(struct hufftree)); + tree->left->index = -1; + } + insert(tree->left, code+1, index); + return; + } else { + assert(code[0] == '1'); + if(!tree->right) { + tree->right = (struct hufftree*)malloc(sizeof(struct hufftree)); + memset(tree->right, 0, sizeof(struct hufftree)); + tree->right->index = -1; + } + insert(tree->right, code+1, index); + return; + } +} + +struct hufftree* huffcode2tree(struct huffcode*code) +{ + struct hufftree* t = malloc(sizeof(struct hufftree)); + memset(t, 0, sizeof(struct hufftree)); + t->index = -1; + while(code->code) { + insert(t, code->code, code->index); + code++; + } + return t; +} + int gethuffvalue(TAG*tag, struct huffcode*code) { int len = 0; @@ -177,12 +248,32 @@ int gethuffvalue(TAG*tag, struct huffcode*code) }*/ } +int gethuffvalue2(TAG*tag, struct huffcode*code, struct hufftree*tree) +{ + while(1) { + if(tree->index>=0) { + return tree->index; + } + if(!swf_GetBits(tag, 1)) { + assert(tree->left); + tree=tree->left; + } else { + assert(tree->right); + tree=tree->right; + } + } +} + void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) { int dc; int ac;// = swf_GetBits(); int index; int pos = 0; + int line[64]; + int show_rle_code=0; + memset(line, 0, sizeof(line)); + //printf("DC:%d\n", dc); if(has_dc) { dc = swf_GetBits(tag, 8); @@ -190,17 +281,18 @@ void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) printf("error: dc=%d\n", dc); exit(1); } - DEBUG printf(" %d ", dc); + DEBUG if(show_rle_code) printf(" %d ", dc); + line[pos] = dc; pos++; } if(has_tcoef) { - DEBUG printf("["); + DEBUG if(show_rle_code) printf("["); while(1) { int last; int run; int level; - index = gethuffvalue(tag, rle); + index = gethuffvalue2(tag, rle, rle_tree); last = rle_params[index].last; run = rle_params[index].run; level = rle_params[index].level; @@ -209,10 +301,11 @@ void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) last = swf_GetBits(tag, 1); run = swf_GetBits(tag, 6); level = swf_GetBits(tag, 8); - if(run) - DEBUG printf("(%d) E%d", run, level); - else - DEBUG printf("E"); + if(run) { + DEBUG if(show_rle_code) printf(" (%d) E%d", run, level); + } else { + DEBUG if(show_rle_code) printf("E"); + } if(level == 0 || level == 128) { printf("error: level=%d\n", level); exit(1); @@ -220,31 +313,47 @@ void get_DC_TCOEF(TAG*tag, int t, int has_dc, int has_tcoef) level = (int)((signed char)level); } else { int sign = swf_GetBits(tag, 1); - if(sign) + if(sign) { level = -level; - if(run) - DEBUG printf("(%d) %s%d", run, level>0?"+":"",level); - else - DEBUG printf("%s%d", level>0?"+":"",level); + } + if(run) { + DEBUG if(show_rle_code) printf(" (%d) %s%d", run, level>0?"+":"",level); + } else { + DEBUG if(show_rle_code) printf(" %s%d", level>0?"+":"",level); + } } - pos += run+1; + pos += run; + if(pos>=64) { + printf("\nerror:bad pos: %d\n", pos); + exit(1); + } + line[pos++] = level; //DEBUG printf("run:%d level:%d\n", run, level); if(last) { - DEBUG printf("] pos: %d", pos); + DEBUG if(show_rle_code) printf("] pos: %d", pos); if(pos>64) { printf("\nerror:bad pos (%d)\n", pos); exit(1); } - return; + break; } } } + DEBUG if(show_rle_code) printf("\n"); + + DEBUG printf("["); + for(t=0;t>t); DEBUG printf("luminance%d ", t); get_DC_TCOEF(tag, t, has_intradc, has_tcoef); /*luminance - affected by cbpy*/ - DEBUG printf("\n"); } for(t=0;t<2;t++) { int has_intradc = intrablock; int has_tcoef = cbpc & (2>>t); DEBUG printf("chrominance%d ", t); get_DC_TCOEF(tag, t, has_intradc, has_tcoef); /*chrominance - affected by mcbc*/ - DEBUG printf("\n"); } } @@ -397,7 +511,7 @@ void handleVideoFrame(TAG*tag, char*prefix) sizeflags = swf_GetBits(tag, 3); switch(sizeflags) { - case 0: width = swf_GetU8(tag); height = swf_GetU8(tag); break; + case 0: width = swf_GetBits(tag,8); height = swf_GetBits(tag,8); break; case 1: width = swf_GetBits(tag, 16); height = swf_GetBits(tag, 16); break; case 2: width = 352; height = 288; break; case 3: width = 176; height = 144; break; @@ -441,8 +555,8 @@ void handleVideoFrame(TAG*tag, char*prefix) /*if(pictype == TYPE_INTER) return;*/ - if(pictype == TYPE_INTRA) - return; + /*if(pictype == TYPE_INTRA) + return;*/ /*tagnr++; if(tagnr!=2) @@ -490,6 +604,12 @@ int main (int argc,char ** argv) checkhufftable(cbpy, "cbpy"); checkhufftable(mvd, "mvd"); + rle_tree = huffcode2tree(rle); + mcbpc_intra_tree = huffcode2tree(mcbpc_intra); + mcbpc_inter_tree = huffcode2tree(mcbpc_inter); + cbpy_tree = huffcode2tree(cbpy); + mvd_tree = huffcode2tree(mvd); + processargs(argc, argv); if(!filename) { fprintf(stderr, "You must supply a filename.\n");