X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fswfdump.c;h=051b8a20a12ff8c866b38e8a598f1ea0fa4a89b9;hb=458c53f3b2fe6e6ae3f106084f536701a94dccbf;hp=9b58e2daf71410ff64bc6eb7c98677d5ba2decfd;hpb=8cd6b7f4e60afa919134a2a2ce9af12809d01bbc;p=swftools.git diff --git a/src/swfdump.c b/src/swfdump.c index 9b58e2d..051b8a2 100644 --- a/src/swfdump.c +++ b/src/swfdump.c @@ -53,27 +53,30 @@ static int action = 0; static int html = 0; static int xy = 0; static int showtext = 0; +static int showshapes = 0; static int hex = 0; static int used = 0; - -struct options_t options[] = -{ - {"D","full"}, - {"a","action"}, - {"t","text"}, - {"X","width"}, - {"Y","height"}, - {"f","frames"}, - {"r","rate"}, - {"e","html"}, - {"p","placements"}, - {"u","used"}, - {"V","version"}, - {"d","hex"}, - {0,0} +static int bbox = 0; + +static struct options_t options[] = { +{"h", "help"}, +{"D", "full"}, +{"V", "version"}, +{"e", "html"}, +{"a", "action"}, +{"t", "text"}, +{"s", "shapes"}, +{"p", "placements"}, +{"b", "bbox"}, +{"X", "width"}, +{"Y", "height"}, +{"r", "rate"}, +{"f", "frames"}, +{"d", "hex"}, +{"u", "used"}, +{0,0} }; - int args_callback_option(char*name,char*val) { if(!strcmp(name, "V")) { @@ -92,6 +95,10 @@ int args_callback_option(char*name,char*val) showtext = 1; return 0; } + else if(name[0]=='s') { + showshapes = 1; + return 0; + } else if(name[0]=='e') { html = 1; return 0; @@ -120,8 +127,12 @@ int args_callback_option(char*name,char*val) used = 1; return 0; } + else if(name[0]=='b') { + bbox = 1; + return 0; + } else if(name[0]=='D') { - action = placements = showtext = 1; + action = placements = showtext = showshapes = 1; return 0; } else { @@ -135,22 +146,27 @@ int args_callback_longoption(char*name,char*val) { return args_long2shortoption(options, name, val); } -void args_callback_usage(char*name) -{ - printf("Usage: %s [-at] file.swf\n", name); - printf("\t-h , --help\t\t Print help and exit\n"); - printf("\t-D , --full\t\t Show everything. The same as -atMp\n"); - printf("\t-e , --html\t\t Create html output embedding the file (simple, but useful)\n"); - printf("\t-X , --width\t\t Prints out a string of the form \"-X width\"\n"); - printf("\t-Y , --height\t\t Prints out a string of the form \"-Y height\"\n"); - printf("\t-r , --rate\t\t Prints out a string of the form \"-r rate\"\n"); - printf("\t-f , --frames\t\t Prints out a string of the form \"-f framenum\"\n"); - printf("\t-a , --action\t\t Disassemble action tags\n"); - printf("\t-p , --placements\t Show extra placement information\n"); - printf("\t-t , --text\t\t Show text data\n"); - printf("\t-d , --hex\t\t Print hex output of tag data, too\n"); - printf("\t-u , --used\t\t Show referred IDs for each Tag\n"); - printf("\t-V , --version\t\t Print program version and exit\n"); +void args_callback_usage(char *name) +{ + printf("\n"); + printf("Usage: %s [-atpdu] file.swf\n", name); + printf("\n"); + printf("-h , --help Print short help message and exit\n"); + printf("-D , --full Show everything. Same as -atp\n"); + printf("-V , --version Print version info and exit\n"); + printf("-e , --html Print out html code for embedding the file\n"); + printf("-a , --action Disassemble action tags\n"); + printf("-t , --text Show text fields (like swfstrings).\n"); + printf("-s , --shapes Show shape coordinates/styles\n"); + printf("-p , --placements Show placement information\n"); + printf("-b , --bbox Print tag's bounding boxes\n"); + printf("-X , --width Prints out a string of the form \"-X width\".\n"); + printf("-Y , --height Prints out a string of the form \"-Y height\".\n"); + printf("-r , --rate Prints out a string of the form \"-r rate\".\n"); + printf("-f , --frames Prints out a string of the form \"-f framenum\".\n"); + printf("-d , --hex Print hex output of tag data, too.\n"); + printf("-u , --used Show referred IDs for each Tag.\n"); + printf("\n"); } int args_callback_command(char*name,char*val) { @@ -224,31 +240,14 @@ void dumpButtonActions(TAG*tag, char*prefix) swf_DumpActions(actions, prefix); } -#define ET_HASTEXT 32768 -#define ET_WORDWRAP 16384 -#define ET_MULTILINE 8192 -#define ET_PASSWORD 4096 -#define ET_READONLY 2048 -#define ET_HASTEXTCOLOR 1024 -#define ET_HASMAXLENGTH 512 -#define ET_HASFONT 256 -#define ET_X3 128 -#define ET_X2 64 -#define ET_HASLAYOUT 32 -#define ET_NOSELECT 16 -#define ET_BORDER 8 -#define ET_X1 4 -#define ET_X0 2 -#define ET_USEOUTLINES 1 - SWF swf; int fontnum = 0; SWFFONT**fonts; -void textcallback(int*glyphs, int nr, int fontid) +void textcallback(void*self, int*glyphs, int*ypos, int nr, int fontid, int fontsize, int startx, int starty, RGBA*color) { int font=-1,t; - printf(" <%2d glyphs in font %2d> ",nr, fontid); + printf(" <%2d glyphs in font %2d, color #%02x%02x%02x%02x> ",nr, fontid, color->r, color->g, color->b, color->a); for(t=0;tid == fontid) { @@ -263,9 +262,9 @@ void textcallback(int*glyphs, int nr, int fontid) if(font>=0) { if(glyphs[t] >= fonts[font]->numchars /*glyph is in range*/ || !fonts[font]->glyph2ascii /* font has ascii<->glyph mapping */ - ) - continue; - a = fonts[font]->glyph2ascii[glyphs[t]]; + ) a = glyphs[t]; + else + a = fonts[font]->glyph2ascii[glyphs[t]]; } else { a = glyphs[t]; } @@ -280,7 +279,7 @@ void textcallback(int*glyphs, int nr, int fontid) void handleText(TAG*tag) { printf("\n"); - swf_FontExtract_DefineTextCallback(-1,0,tag,4, textcallback); + swf_ParseDefineText(tag,textcallback, 0); } void handleDefineSound(TAG*tag) @@ -330,7 +329,9 @@ void handleEditText(TAG*tag) int t; id = swf_GetU16(tag); swf_GetRect(tag,0); + //swf_ResetReadBits(tag); + if (tag->readBit) { tag->pos++; tag->readBit = 0; @@ -356,20 +357,20 @@ void handleEditText(TAG*tag) swf_GetU16(tag); //indent swf_GetU16(tag); //leading } - printf(" variable \"%s\"", &tag->data[tag->pos]); + printf(" variable \"%s\" ", &tag->data[tag->pos]); + if(flags & ET_HTML) printf("(html)"); + if(flags & ET_NOSELECT) printf("(noselect)"); + if(flags & ET_PASSWORD) printf("(password)"); + if(flags & ET_READONLY) printf("(readonly)"); - if(flags & (ET_X1 | ET_X2 | ET_X3 | ET_X0)) + if(flags & (ET_X1 | ET_X3 )) { - printf(" undefined flags: %d%d%d%d", - (flags&ET_X0?1:0), - (flags&ET_X1?1:0), - (flags&ET_X2?1:0), - (flags&ET_X3?1:0)); + printf(" undefined flags: %08x (%08x)", (flags&(ET_X1|ET_X3)), flags); } while(tag->data[tag->pos++]); if(flags & ET_HASTEXT) - // printf(" text \"%s\"\n", &tag->data[tag->pos]) + // printf(" text \"%s\"\n", &tag->data[tag->pos]) //TODO ; } void printhandlerflags(U32 handlerflags) @@ -461,6 +462,7 @@ void handlePlaceObject2(TAG*tag, char*prefix) char pstr[3][160]; int ppos[3] = {0,0,0}; swf_GetU16(tag); //depth + //flags&1: move if(flags&2) swf_GetU16(tag); //id if(flags&4) { @@ -548,14 +550,108 @@ void handlePlaceObject2(TAG*tag, char*prefix) void handlePlaceObject(TAG*tag, char*prefix) { - /*TODO*/ + TAG*tag2 = swf_InsertTag(0, ST_PLACEOBJECT2); + + U16 id = swf_GetU16(tag); + U16 depth = swf_GetU16(tag); + MATRIX matrix; + CXFORM cxform; + swf_GetMatrix(tag, &matrix); + swf_GetCXForm(tag, &cxform, 0); + + swf_SetU8(tag2, 14); + swf_SetU16(tag2, depth); + swf_SetMatrix(tag2, &matrix); + swf_SetCXForm(tag2, &cxform, 1); + + handlePlaceObject2(tag2, prefix); +} +char stylebuf[256]; +char* fillstyle2str(FILLSTYLE*style) +{ + switch(style->type) { + case 0x00: + sprintf(stylebuf, "SOLID %02x%02x%02x%02x", style->color.r, style->color.g, style->color.b, style->color.a); + break; + case 0x10: case 0x12: + sprintf(stylebuf, "GRADIENT (%d steps)", style->gradient.num); + break; + case 0x40: case 0x41: + /* TODO: display information about that bitmap */ + sprintf(stylebuf, "BITMAP %d", style->id_bitmap); + break; + default: + sprintf(stylebuf, "UNKNOWN[%02x]",style->type); + } + return stylebuf; +} +char* linestyle2str(LINESTYLE*style) +{ + sprintf(stylebuf, "%.2f %02x%02x%02x%02x", style->width/20.0, style->color.r, style->color.g, style->color.b, style->color.a); + return stylebuf; +} + +void handleShape(TAG*tag, char*prefix) +{ + SHAPE2 shape; + SHAPELINE*line; + int t,max; + + tag->pos = 0; + tag->readBit = 0; + swf_ParseDefineShape(tag, &shape); + + max = shape.numlinestyles > shape.numfillstyles?shape.numlinestyles:shape.numfillstyles; + + if(max) printf("%s | fillstyles(%02d) linestyles(%02d)\n", + prefix, + shape.numfillstyles, + shape.numlinestyles + ); + else printf("%s | (Neither line nor fill styles)\n", prefix); + + for(t=0;tfillstyle0, + line->fillstyle1, + line->linestyle); + if(line->type == moveTo) { + printf("moveTo %.2f %.2f\n", line->x/20.0, line->y/20.0); + } else if(line->type == lineTo) { + printf("lineTo %.2f %.2f\n", line->x/20.0, line->y/20.0); + } else if(line->type == splineTo) { + printf("splineTo (%.2f %.2f) %.2f %.2f\n", + line->sx/20.0, line->sy/20.0, + line->x/20.0, line->y/20.0 + ); + } + line = line->next; + } + printf("%s |\n", prefix); } -void fontcallback1(U16 id,U8 * name) +void fontcallback1(void*self, U16 id,U8 * name) { fontnum++; } -void fontcallback2(U16 id,U8 * name) +void fontcallback2(void*self, U16 id,U8 * name) { swf_FontExtract(&swf,id,&fonts[fontnum]); fontnum++; @@ -576,9 +672,9 @@ void hexdumpTag(TAG*tag, char* prefix) ascii[t&15] = printable(tag->data[t]); if((t && ((t&15)==15)) || (t==tag->len-1)) { - int s,p=((t-1)&15)+1; + int s,p=((t)&15)+1; ascii[p] = 0; - for(s=p;s<16;s++) { + for(s=p-1;s<16;s++) { printf(" "); } if(t==tag->len-1) @@ -701,7 +797,7 @@ int main (int argc,char ** argv) printf(" "); if(xy&4) - printf("-r %d", swf.frameRate*100/256); + printf("-r %.2f", swf.frameRate/256.0); if((xy&7) && (xy&8)) printf(" "); @@ -715,9 +811,9 @@ int main (int argc,char ** argv) if(html) { char*fileversions[] = {"","1,0,0,0", "2,0,0,0","3,0,0,0","4,0,0,0", - "5,0,0,0","6,0,23,0","7,0,0,0","8,0,0,0"}; - if(swf.fileVersion>8) { - fprintf(stderr, "Fileversion>8\n"); + "5,0,0,0","6,0,23,0","7,0,0,0","8,0,0,0","9,0,0,0"}; + if(swf.fileVersion>9) { + fprintf(stderr, "Fileversion>9\n"); exit(1); } printf("id == ST_PLACEOBJECT2) { if(tag->data[0]&1) @@ -821,8 +916,16 @@ int main (int argc,char ** argv) printf(" object"); printf(" at depth %04d", swf_GetDepth(tag)); + + if(tag->data[0]&64) { + SWFPLACEOBJECT po; + swf_GetPlaceObject(tag, &po); + printf(" (clip to %04d)", po.clipdepth); + swf_PlaceObjectFree(&po); + } if(swf_GetName(tag)) printf(" name \"%s\"",swf_GetName(tag)); + } else if(tag->id == ST_REMOVEOBJECT) { printf(" removes id %04d from depth %04d", swf_GetPlaceID(tag), swf_GetDepth(tag)); @@ -881,9 +984,9 @@ int main (int argc,char ** argv) } } if(nframe == frame) - printf(" %d (%s)", frame, timestring(frame*(256.0/(swf.frameRate+0.1)))); + printf(" %d (%s)", frame+1, timestring(frame*(256.0/(swf.frameRate+0.1)))); else - printf(" %d-%d (%s-%s)", frame, nframe, + printf(" %d-%d (%s-%s)", frame+1, nframe+1, timestring(frame*(256.0/(swf.frameRate+0.1))), timestring(nframe*(256.0/(swf.frameRate+0.1))) ); @@ -902,6 +1005,8 @@ int main (int argc,char ** argv) else if(tag->id == ST_PROTECT) { if(tag->len>0) { printf(" %s\n", swf_GetString(tag)); + } else { + printf("\n"); } } else if(tag->id == ST_DEFINEBITSLOSSLESS || @@ -945,6 +1050,15 @@ int main (int argc,char ** argv) else { printf("\n"); } + + if(bbox && swf_isDefiningTag(tag) && tag->id != ST_DEFINESPRITE) { + SRECT r = swf_GetDefineBBox(tag); + printf(" %s bbox [%.2f, %.2f, %.2f, %.2f]\n", prefix, + r.xmin/20.0, + r.ymin/20.0, + r.xmax/20.0, + r.ymax/20.0); + } sprintf(myprefix, " %s", prefix); @@ -972,15 +1086,30 @@ int main (int argc,char ** argv) actions = swf_ActionGet(tag); swf_DumpActions(actions, myprefix); } + else if(tag->id == ST_DOINITACTION && action) { + ActionTAG*actions; + swf_GetU16(tag); // id + actions = swf_ActionGet(tag); + swf_DumpActions(actions, myprefix); + } else if(tag->id == ST_DEFINEBUTTON && action) { dumpButtonActions(tag, myprefix); } else if(tag->id == ST_DEFINEBUTTON2 && action) { dumpButton2Actions(tag, myprefix); } + else if(tag->id == ST_PLACEOBJECT) { + handlePlaceObject(tag, myprefix); + } else if(tag->id == ST_PLACEOBJECT2) { handlePlaceObject2(tag, myprefix); } + else if(tag->id == ST_DEFINESHAPE || + tag->id == ST_DEFINESHAPE2 || + tag->id == ST_DEFINESHAPE3) { + if(showshapes) + handleShape(tag, myprefix); + } if(tag->len && used) { int num = swf_GetNumUsedIDs(tag); @@ -991,8 +1120,13 @@ int main (int argc,char ** argv) swf_GetUsedIDs(tag, used); printf("%s%suses IDs: ", indent, prefix); for(t=0;t