Part of the swftools package.
- Copyright (c) 2003 Matthias Kramm <kramm@quiss.org> */
+ Copyright (c) 2003 Matthias Kramm <kramm@quiss.org>
+
+ 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 <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
+#include <assert.h>
#include "../rfxswf.h"
#include "../args.h"
-#include "h263tables.c"
+#include "h263tables.h"
static char * filename = 0;
static char * indent = " ";
}
}
+
+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;
}*/
}
+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);
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;
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);
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<pos;t++) {
+ DEBUG printf("%d", line[t]);
+ DEBUG if(t<pos-1) printf(" ");
+ }
+ DEBUG printf("]\n");
}
int readMVD(TAG*tag)
{
- int index = gethuffvalue(tag, mvd);
+ int index = gethuffvalue2(tag, mvd, mvd_tree);
DEBUG printf("mvd index:%d\n", index);
return index;
}
/* read mcbpc */
if(pictype == TYPE_INTRA) { /* I-frame */
- type = gethuffvalue(tag, mcbpc_intra);
+ type = gethuffvalue2(tag, mcbpc_intra, mcbpc_intra_tree);
DEBUG printf("mcbpc=%d\n",type);
mb_type = mcbpc_intra_params[type].mb_type;
cbpc = mcbpc_intra_params[type].cbpc;
}
}
else if(pictype == 1) { /* P-frame */
- type = gethuffvalue(tag, mcbpc_inter);
+ type = gethuffvalue2(tag, mcbpc_inter, mcbpc_inter_tree);
DEBUG printf("mcbpc=%d\n",type);
mb_type = mcbpc_inter_params[type].mb_type;
cbpc = mcbpc_inter_params[type].cbpc;
/* read cbpy */
- cbpy_index = gethuffvalue(tag, cbpy);
+ cbpy_index = gethuffvalue2(tag, cbpy, cbpy_tree);
cbpy_value = cbpy_index;
if(!intrablock)
cbpy_value ^= 15;
int x,y;
x = readMVD(tag); //horizontal
y = readMVD(tag); //vertical
- if(x==32 && y==32)
- printf("\b0");
+ /*if(x==32 && y==32)
+ printf("\b0"); // prediction was 100% match
+ */
}
if(has_mvd[mb_type]&2) {
/* only in advanced prediction mode */
int has_tcoef = cbpy_value & (8>>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");
}
}
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");