Part of the swftools package.
- Copyright (c) 2003 Matthias Kramm <kramm@quiss.org> */
-
-#include "../config.h"
+ 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 "../lib/rfxswf.h"
-#include "../lib/args.h"
-#include "h263tables.c"
+#include <assert.h>
+#include "../rfxswf.h"
+#include "../args.h"
+#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 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;
run = swf_GetBits(tag, 6);
level = swf_GetBits(tag, 8);
if(run)
- DEBUG printf("(%d) E%d", run, level);
+ DEBUG printf(" (%d) E%d", run, level);
else
DEBUG printf("E");
if(level == 0 || level == 128) {
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 printf(" (%d) %s%d", run, level>0?"+":"",level);
+ } else {
+ DEBUG printf(" %s%d", level>0?"+":"",level);
+ }
}
pos += run+1;
//DEBUG printf("run:%d level:%d\n", run, level);
}
}
-void readMVD(TAG*tag)
+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;
}
char has_quant[] = {0,1,0,0,1};
{
int t;
int mb_type = -1, cbpc = -1;
- int dbquant;
+ int dquant;
int cbpy_index, cbpy_value;
int intrablock = 0;
int type;
if(pictype == TYPE_INTER) /* non-intra pictures have a cod flag */
- /* TODO: according to the flash spec, this field is always present */
{
int cod = swf_GetBits(tag, 1);
DEBUG printf("cod=%d\n",cod);
/* 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;
{
intrablock = 1;
}
-
- printf("%d", intrablock);
+
+ printf("%c", "vqVii"[mb_type]);
DEBUG printf("mcbpc type: %d mb_type:%d cbpc:%d\n", type, mb_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;
/* quantizer */
if(has_quant[mb_type]) {
- dbquant = swf_GetBits(tag, 2);
- DEBUG printf("quantizer: %d\n", dbquant);
+ dquant = swf_GetBits(tag, 2);
+ if(dquant == 0) dquant = -1;
+ else if(dquant == 1) dquant = -2;
+ else if(dquant == 2) dquant = +1;
+ else if(dquant == 3) dquant = +2;
+ DEBUG printf("dquant: %d\n", dquant);
}
if(has_mvd[mb_type]&1) {
- readMVD(tag); //horizontal
- readMVD(tag); //vertical
+ int x,y;
+ x = readMVD(tag); //horizontal
+ y = readMVD(tag); //vertical
+ /*if(x==32 && y==32)
+ printf("\b0"); // prediction was 100% match
+ */
}
if(has_mvd[mb_type]&2) {
/* only in advanced prediction mode */
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;
/*if(pictype == TYPE_INTER)
return;*/
- if(pictype == TYPE_INTRA)
- return;
+ /*if(pictype == TYPE_INTRA)
+ return;*/
/*tagnr++;
if(tagnr!=2)
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");