X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fswfcombine.c;h=13ff22429263883826011e5c49c54e9eca7801a3;hb=f72efb3e0b08321fe70a478bf939c312ed7564ce;hp=cc3bffca661bf6b9ef671eecf4b15becfdc759ec;hpb=aee9de2c6eb23628e54b6896f5b441d9b39317c1;p=swftools.git diff --git a/src/swfcombine.c b/src/swfcombine.c index cc3bffc..13ff224 100644 --- a/src/swfcombine.c +++ b/src/swfcombine.c @@ -103,12 +103,14 @@ int args_callback_option(char*name,char*val) { } else if (!strcmp(name, "x")) { - config.movex = atoi(val); + float x = atof(val); + config.movex = (int)(x*20+0.5); return 1; } else if (!strcmp(name, "y")) { - config.movey = atoi(val); + float y = atof(val); + config.movey = (int)(y*20+0.5); return 1; } else if (!strcmp(name, "m")) @@ -133,7 +135,13 @@ int args_callback_option(char*name,char*val) { } else if (!strcmp(name, "r")) { - config.framerate = atoi(val)*256/100; + + float rate = atof(val); + if ((rate < 0) ||(rate >= 256.0)) { + fprintf(stderr, "Error: You must specify a valid framerate between 1/256 and 255.\n"); + exit(1); + } + config.framerate = (int)(rate*256); return 1; } else if (!strcmp(name, "X")) @@ -177,26 +185,25 @@ int args_callback_option(char*name,char*val) { } } -struct options_t options[] = -{{"o","output"}, - {"s","scale"}, - {"d","dummy"}, - {"x","xpos"}, - {"y","ypos"}, - {"X","width"}, - {"Y","height"}, - {"r","rate"}, - {"f","frame"}, - {"l","overlay"}, - {"m","merge"}, - {"t","stack"}, - {"T","stack1"}, - {"v","verbose"}, - {"V","version"}, - {"c","clip"}, - {"a","cat"}, - {"z","zlib"}, - {0,0} +static struct options_t options[] = { +{"o", "output"}, +{"t", "stack"}, +{"T", "stack1"}, +{"m", "merge"}, +{"a", "cat"}, +{"l", "overlay"}, +{"c", "clip"}, +{"v", "verbose"}, +{"d", "dummy"}, +{"f", "frame"}, +{"x", "movex"}, +{"y", "movey"}, +{"s", "scale"}, +{"r", "rate"}, +{"X", "width"}, +{"Y", "height"}, +{"z", "zlib"}, +{0,0} }; int args_callback_longoption(char*name,char*val) { @@ -248,30 +255,32 @@ int args_callback_command(char*name, char*val) { return 0; } -void args_callback_usage(char*name) +void args_callback_usage(char *name) { + printf("\n"); printf("Usage: %s [-rXYomlcv] [-f] masterfile [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); printf("OR: %s [-rXYomv] --stack[1] [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); printf("OR: %s [-rXYov] --cat [-xysf] [(name1|#id1)=]slavefile1 .. [-xysf] [(nameN|#idN)=]slavefileN\n", name); printf("OR: %s [-rXYomlcv] --dummy [-xys] [file]\n", name); printf("\n"); - printf("-o outputfile --output explicitly specify output file. (otherwise, output.swf will be used)\n"); - printf("-t --stack place each slave in a seperate frame (no master movie)\n"); - printf("-T --stack1 place each slave in the first frame (no master movie)\n"); - printf("-m --merge Don't store the slaves in Sprites/MovieClips\n"); - printf("-a --cat concatenate all slave files (no master movie)\n"); - printf("-l --overlay Don't remove any master objects, only overlay new objects\n"); - printf("-c --clip Clip the slave objects by the corresponding master objects\n"); - printf("-v --verbose Use more than one -v for greater effect \n"); - printf("-d --dummy Don't require slave objects \n"); - printf("-f --frame The following identifier is a frame or framelabel, not an id or objectname\n"); - printf("-x xpos --movex x Adjust position of slave by xpos twips (1/20 pixel)\n"); - printf("-y ypos --movey y Adjust position of slave by ypos twips (1/20 pixel)\n"); - printf("-s scale --scale Adjust size of slave by scale%\n"); - printf("-r framerate --rate Set movie framerate (100 frames/sec)\n"); - printf("-X width --width Force movie width to scale (default: use master width (not with -t))\n"); - printf("-Y height --height Force movie height to scale (default: use master height (not with -t))\n"); - printf("-z zlib --zlib Enable Flash 6 (MX) Zlib Compression\n"); + printf("-o , --output explicitly specify output file. (otherwise, output.swf will be used)\n"); + printf("-t , --stack place each slave in a seperate frame (no master movie)\n"); + printf("-T , --stack1 place each slave in the first frame (no master movie)\n"); + printf("-m , --merge Don't store the slaves in Sprites/MovieClips\n"); + printf("-a , --cat concatenate all slave files (no master movie)\n"); + printf("-l , --overlay Don't remove any master objects, only overlay new objects\n"); + printf("-c , --clip Clip the slave objects by the corresponding master objects\n"); + printf("-v , --verbose Be verbose. Use more than one -v for greater effect \n"); + printf("-d , --dummy Don't require slave objects (for changing movie attributes)\n"); + printf("-f , --frame The following identifier is a frame or framelabel, not an id or objectname\n"); + printf("-x , --movex x Adjust position of slave by pixels\n"); + printf("-y , --movey y Adjust position of slave by pixels\n"); + printf("-s , --scale Adjust size of slave by percent (e.g. 100% = original size)\n"); + printf("-r , --rate Set movie framerate to (frames/sec)\n"); + printf("-X , --width Force movie bbox width to (default: use master width (not with -t))\n"); + printf("-Y , --height Force movie bbox height to (default: use master height (not with -t))\n"); + printf("-z , --zlib Enable Flash 6 (MX) Zlib Compression\n"); + printf("\n"); } static void makestackmaster(SWF*swf) @@ -279,7 +288,7 @@ static void makestackmaster(SWF*swf) TAG*tag; int t; SRECT box; - int fileversion = 1; + int fileversion = config.zlib?6:3; int frameRate = 256; RGBA rgb; rgb.r=rgb.b=rgb.g=0; @@ -297,6 +306,7 @@ static void makestackmaster(SWF*swf) exit(1); } close(fi); + swf_RemoveJPEGTables(&head); msg(" File %s has bounding box %d:%d:%d:%d\n", slave_filename[t], head.movieSize.xmin, head.movieSize.ymin, @@ -372,6 +382,7 @@ static char* slavename = 0; static int slaveid = -1; static int slaveframe = -1; static char masterbitmap[65536]; +static char depthbitmap[65536]; #define FLAGS_WRITEDEFINES 1 #define FLAGS_WRITENONDEFINES 2 @@ -470,13 +481,19 @@ TAG* write_sprite_defines(TAG*tag, SWF*sprite) case ST_SETBACKGROUNDCOLOR: msg(" deliberately ignoring BACKGROUNDCOLOR tag"); break; + case ST_SHOWFRAME: + msg(" deliberately ignoring SHOWFRAME tag"); + break; + case ST_REFLEX: + msg(" deliberately ignoring REFLEX tag"); + break; case 40: case 49: case 51: - msg(" found tag %d. This is a Generator template, isn't it?", tag->id); + msg(" found tag %d. This is a Generator template, isn't it?", rtag->id); break; default: - msg(" funny tag: %d is neither defining nor sprite", tag->id); + msg(" funny tag: %d is neither defining nor sprite", rtag->id); } } } @@ -487,7 +504,6 @@ TAG* write_sprite_defines(TAG*tag, SWF*sprite) void changedepth(TAG*tag, int add) { - /* fucking byteorders */ if(tag->id == ST_PLACEOBJECT) PUT16(&tag->data[2],GET16(&tag->data[2])+add); if(tag->id == ST_PLACEOBJECT2) @@ -496,6 +512,23 @@ void changedepth(TAG*tag, int add) PUT16(&tag->data[2],GET16(&tag->data[2])+add); if(tag->id == ST_REMOVEOBJECT2) PUT16(&tag->data[0],GET16(&tag->data[0])+add); + if(tag->id == ST_PLACEOBJECT2) { + SWFPLACEOBJECT obj; + U8 flags; + swf_SetTagPos(tag, 0); + flags = swf_GetU8(tag); + if(flags&2) swf_GetU16(tag); //id + if(flags&4) swf_GetMatrix(tag, 0); + if(flags&8) swf_GetCXForm(tag, 0,1); + if(flags&16) swf_GetU16(tag); //ratio + if(flags&64) { + swf_ResetReadBits(tag); + printf("%d->%d\n", GET16(&tag->data[tag->pos]), + GET16(&tag->data[tag->pos])+add); + PUT16(&tag->data[tag->pos],GET16(&tag->data[tag->pos])+add); + } + msg(" Depth relocation not fully working yet with clipdepths", tag->id); + } } void matrix_adjust(MATRIX*m, int movex, int movey, float scalex, float scaley, int scalepos) @@ -514,7 +547,7 @@ void matrix_adjust(MATRIX*m, int movex, int movey, float scalex, float scaley, i void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, float scaley, int scalepos) { - if(movex || movey || scalex != 1 || scaley != 1) + if(movex || movey || scalex != 1.0 || scaley != 1.0) { switch(tag->id) { @@ -541,7 +574,8 @@ void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, fl matrix_adjust(&m, movex, movey, scalex, scaley, scalepos); swf_SetMatrix(output, &m); - //swf_ResetReadBits(tag); + if (tag->readBit) { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag); + swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos); break; } @@ -554,7 +588,8 @@ void write_changepos(TAG*output, TAG*tag, int movex, int movey, float scalex, fl matrix_adjust(&m, movex, movey, scalex, scaley, scalepos); swf_SetMatrix(output, &m); - //swf_ResetReadBits(tag); + if (tag->readBit) { tag->pos++; tag->readBit = 0; } //swf_ResetReadBits(tag); + swf_SetBlock(output, &tag->data[tag->pos], tag->len - tag->pos); break; } @@ -606,8 +641,9 @@ TAG* write_sprite(TAG*tag, SWF*sprite, int spriteid, int replaceddefine) rtag->id, rtag->len); tag = swf_InsertTag(tag, rtag->id); write_changepos(tag, rtag, config.movex, config.movey, config.scalex, config.scaley, 0); - - changedepth(tag, +2); + + if(config.clip || (config.overlay && !config.isframe)) + changedepth(tag, +2); if(tag->id == ST_SHOWFRAME) { @@ -631,9 +667,10 @@ static char tag_ok_for_slave(int id) TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefine, int flags) { int outputslave = 0; - int frame = 0; + int frame = 1; int sframe = 0; int slavewritten = 0; + int deletedepth = -1; TAG* rtag = master->firstTag; TAG* stag = slave->firstTag; @@ -658,6 +695,14 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi if(rtag->id == ST_SHOWFRAME) { frame ++; + tag = swf_InsertTag(tag, ST_SHOWFRAME); + if(deletedepth>=0) { + tag = swf_InsertTag(tag, ST_REMOVEOBJECT2); + swf_SetU16(tag, deletedepth); + deletedepth=-1; + } + rtag = rtag->next; + continue; } if(swf_isDefiningTag(rtag) && (flags&FLAGS_WRITEDEFINES)) @@ -691,7 +736,7 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi swf_SetBlock(tag, rtag->data, rtag->len); } } - if(frame == slaveframe) + if(frame == slaveframe) /* only happens with config.isframe: put slave at specific frame */ { if(flags&FLAGS_WRITESLAVE) { outputslave = 1; @@ -700,7 +745,8 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi if((flags&FLAGS_WRITESPRITE) && !slavewritten) { int id = get_free_id(masterbitmap); - int depth = 0; + int depth = 65535; + deletedepth = 65535; if(config.clip) { msg(" Can't combine --clip and --frame"); } @@ -741,6 +787,7 @@ TAG* write_master(TAG*tag, SWF*master, SWF*slave, int spriteid, int replaceddefi rtag->id, rtag->len); tag = swf_InsertTag(tag, rtag->id); write_changepos(tag, rtag, config.mastermovex, config.mastermovey, config.masterscalex, config.masterscaley, 1); + } } rtag = rtag->next; @@ -883,14 +930,21 @@ void normalcombine(SWF*master, char*slave_name, SWF*slave, SWF*newswf) int frame = 0; char*framelabel; TAG * tag = master->firstTag; + + memset(depthbitmap, 0, sizeof(depthbitmap)); // set the idtab while(tag) { + int depth = swf_GetDepth(tag); + if(depth>=0) { + depthbitmap[depth] = 1; + } if(swf_isDefiningTag(tag)) { int defineid = swf_GetDefineID(tag); msg(" tagid %02x defines object %d", tag->id, defineid); masterbitmap[defineid] = 1; + if (!slavename && defineid==slaveid) { if(defineid>=0) { spriteid = defineid; @@ -938,6 +992,8 @@ void normalcombine(SWF*master, char*slave_name, SWF*slave, SWF*newswf) } swf_Relocate (slave, masterbitmap); + if(config.merge) + swf_RelocateDepth (slave, depthbitmap); jpeg_assert(slave, master); if (config.overlay) @@ -1096,6 +1152,7 @@ int main(int argn, char *argv[]) msg(" Failed to read from %s\n", master_filename); exit(1); } + swf_RemoveJPEGTables(&master); msg(" Read %d bytes from masterfile\n", ret); close(fi); } @@ -1163,6 +1220,7 @@ int main(int argn, char *argv[]) } msg(" Read %d bytes from slavefile\n", ret); close(fi); + swf_RemoveJPEGTables(&slave); } else { @@ -1176,13 +1234,21 @@ int main(int argn, char *argv[]) combine(&master, slave_name[t], &slave, &newswf); master = newswf; } + if(config.dummy && !config.hassizex && !config.hassizey && !config.mastermovex && !config.mastermovey) { + newswf.movieSize.xmin = newswf.movieSize.xmin*config.masterscalex; + newswf.movieSize.ymin = newswf.movieSize.ymin*config.masterscaley; + newswf.movieSize.xmax = newswf.movieSize.xmax*config.masterscalex; + newswf.movieSize.ymax = newswf.movieSize.ymax*config.masterscaley; + } } fi = open(outputname, O_BINARY|O_RDWR|O_TRUNC|O_CREAT, 0777); - if(config.zlib) + if(config.zlib) { + if(newswf.fileVersion < 6) + newswf.fileVersion = 6; swf_WriteSWC(fi, &newswf); - else { + } else { newswf.compressed = 0; swf_WriteSWF(fi, &newswf); }