X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=src%2Fswfbbox.c;h=9eafc24a655668d6abf168a404af837b99820e34;hp=de0d96c554bbb49a19c3c5782fd2b110ac7473b6;hb=c63b2bf21dc1df9a736f0b4c08f6cba828cdab92;hpb=13f358624c58a5379ef681bf695423901cf34174 diff --git a/src/swfbbox.c b/src/swfbbox.c index de0d96c..9eafc24 100644 --- a/src/swfbbox.c +++ b/src/swfbbox.c @@ -34,15 +34,24 @@ static char * outfilename = "output.swf"; static int optimize = 0; static int swifty = 0; static int verbose = 0; - -struct options_t options[] = -{ - {"V","version"}, - {"O","optimize"}, - {"o","output"}, - {"S","swifty"}, - {"v","verbose"}, - {0,0} +static int showbbox = 0; +static int showorigbbox = 1; +static int expand = 0; +static int clip = 0; +static int checkclippings = 0; + +static struct options_t options[] = { +{"h", "help"}, +{"b", "bbox"}, +{"B", "newbbox"}, +{"e", "expand"}, +{"O", "optimize"}, +{"S", "swifty"}, +{"c", "clip"}, +{"o", "output"}, +{"v", "verbose"}, +{"V", "version"}, +{0,0} }; int args_callback_option(char*name,char*val) @@ -51,16 +60,48 @@ int args_callback_option(char*name,char*val) printf("swfbbox - part of %s %s\n", PACKAGE, VERSION); exit(0); } + else if(!strcmp(name, "b")) { + showorigbbox = 2; + if(showbbox == 1) showbbox = 0; + return 0; + } + else if(!strcmp(name, "B")) { + showbbox = 2; + return 0; + } else if(!strcmp(name, "O")) { optimize = 1; + if(showorigbbox == 1) showorigbbox = 0; return 0; } else if(!strcmp(name, "S")) { swifty = 1; + if(showorigbbox == 1) showorigbbox = 0; + return 0; + } + else if(!strcmp(name, "c")) { + if(showorigbbox == 1) showorigbbox = 0; + clip = 1; return 0; } else if(!strcmp(name, "v")) { - verbose = 1; + verbose ++; + return 0; + } + else if(!strcmp(name, "q")) { + if(verbose) + verbose --; + return 0; + } + else if(!strcmp(name, "Q")) { + /* DEPRECATED- was used for testing the bbox-clip feature + of pdf2swf */ + if(showorigbbox == 1) showorigbbox = 0; + checkclippings = 1; + return 0; + } + else if(!strcmp(name, "e")) { + expand = 1; return 0; } else if(!strcmp(name, "o")) { @@ -78,15 +119,22 @@ int args_callback_longoption(char*name,char*val) { return args_long2shortoption(options, name, val); } -void args_callback_usage(char*name) -{ +void args_callback_usage(char *name) +{ + printf("\n"); printf("Usage: %s [-OS] file.swf\n", name); - printf("\t-h , --help\t\t Print help and exit\n"); - printf("\t-O , --optimize\t\t Recalculate bounding boxes\n"); - printf("\t-S , --swifty\t\t Print out transformed bounding boxes\n"); - printf("\t-o , --output\t\t Set output filename (for -O)\n"); - printf("\t-v , --verbose\t\t Be more verbose\n"); - printf("\t-V , --version\t\t Print program version and exit\n"); + printf("\n"); + printf("-h , --help Print help and exit\n"); + printf("-b , --bbox Show movie bounding box (default)\n"); + printf("-B , --newbbox Show recalculated (optimized/expanded) bounding box\n"); + printf("-e , --expand Write out a new file using the recalculated header bounding box\n"); + printf("-O , --optimize Recalculate all object bounding boxes (except for the header)\n"); + printf("-S , --swifty Print out transformed bounding boxes\n"); + printf("-c , --clip Clip bounding boxes to movie size\n"); + printf("-o , --output Set output filename to (for -O)\n"); + printf("-v , --verbose Be more verbose\n"); + printf("-V , --version Print program version and exit\n"); + printf("\n"); } int args_callback_command(char*name,char*val) { @@ -100,117 +148,6 @@ int args_callback_command(char*name,char*val) #define swf_ResetReadBits(tag) if (tag->readBit) { tag->pos++; tag->readBit = 0; } -void parseFillStyleArray(TAG*tag, SHAPE2*shape) -{ - U16 count; - int t; - int num=0; - if(tag->id == ST_DEFINESHAPE) - num = 1; - else if(tag->id == ST_DEFINESHAPE2) - num = 2; - else if(tag->id == ST_DEFINESHAPE3) - num = 3; - - count = swf_GetU8(tag); - if(count == 0xff && num>1) // defineshape2,3 only - count = swf_GetU16(tag); - - if(verbose) printf("num: %d\n", count); - shape->numfillstyles = count; - shape->fillstyles = malloc(sizeof(FILLSTYLE)*count); - - for(t=0;tfillstyles[t]; - swf_ResetReadBits(tag); - type = swf_GetU8(tag); //type - shape->fillstyles[t].type = type; - if(type == 0) { - /* plain color */ - if(num == 3) - swf_GetRGBA(tag, &dest->color); - else - swf_GetRGB(tag, &dest->color); - } - else if(type == 0x10 || type == 0x12) - { - /* linear/radial gradient fill */ - swf_ResetReadBits(tag); - swf_GetMatrix(tag, &dest->m); - swf_ResetReadBits(tag); - swf_GetGradient(tag, &dest->gradient, num>=3?1:0); - } - else if(type == 0x40 || type == 0x41) - { - /* bitmap fill */ - swf_ResetReadBits(tag); - dest->id_bitmap = swf_GetU16(tag); //id - swf_ResetReadBits(tag); //? - swf_GetMatrix(tag, &dest->m); - } - else { - fprintf(stderr, "rfxswf:swftools.c Unknown fillstyle:0x%02x\n",type); - } - } - swf_ResetReadBits(tag); - count = swf_GetU8(tag); // line style array - if(count == 0xff) - count = swf_GetU16(tag); - - if(verbose) printf("lnum: %d\n", count); - - shape->numlinestyles = count; - shape->linestyles = malloc(sizeof(LINESTYLE)*count); - /* TODO: should we start with 1 and insert a correct definition of the - "built in" linestyle 0? */ - for(t=0;tlinestyles[t].width = swf_GetU16(tag); - if(num == 3) - swf_GetRGBA(tag, &shape->linestyles[t].color); - else - swf_GetRGB(tag, &shape->linestyles[t].color); - } - return; -} - -void swf_ParseDefineShape(TAG*tag, SHAPE2*shape) -{ - int num = 0, id; - U16 fill,line; - SRECT r; - SRECT r2; - SHAPELINE*l; - if(tag->id == ST_DEFINESHAPE) - num = 1; - else if(tag->id == ST_DEFINESHAPE2) - num = 2; - else if(tag->id == ST_DEFINESHAPE3) - num = 3; - else { - fprintf(stderr, "parseDefineShape must be called with a shape tag"); - } - - id = swf_GetU16(tag); //id - memset(shape, 0, sizeof(SHAPE2)); - shape->bbox = malloc(sizeof(SRECT)); - swf_GetRect(tag, &r); - - memcpy(shape->bbox, &r, sizeof(SRECT)); - parseFillStyleArray(tag, shape); - - swf_ResetReadBits(tag); - fill = (U16)swf_GetBits(tag,4); - line = (U16)swf_GetBits(tag,4); - - shape->lines = swf_ParseShapeData(&tag->data[tag->pos], (tag->len - tag->pos)*8, fill, line); - - l = shape->lines; -} - void swf_Shape2Optimize(SHAPE2*shape) { if(!shape->bbox) @@ -218,73 +155,6 @@ void swf_Shape2Optimize(SHAPE2*shape) *(shape->bbox) = swf_GetShapeBoundingBox(shape); } -void swf_Shape2ToShape(SHAPE2*shape2, SHAPE*shape) -{ - TAG*tag = swf_InsertTag(0,0); - SHAPELINE*l,*next; - int newx=0,newy=0,lastx=0,lasty=0,oldls=0,oldfs0=0,oldfs1=0; - - memset(shape, 0, sizeof(SHAPE)); - - shape->linestyle.n = shape2->numlinestyles; - shape->linestyle.data = (LINESTYLE*)malloc(sizeof(LINESTYLE)*shape->linestyle.n); - memcpy(shape->linestyle.data, shape2->linestyles, sizeof(LINESTYLE)*shape->linestyle.n); - - shape->fillstyle.n = shape2->numfillstyles; - shape->fillstyle.data = (FILLSTYLE*)malloc(sizeof(FILLSTYLE)*shape->fillstyle.n); - memcpy(shape->fillstyle.data, shape2->fillstyles, sizeof(FILLSTYLE)*shape->fillstyle.n); - - swf_ShapeCountBits(shape,NULL,NULL); - - l = shape2->lines; - - while(l) { - int ls=0,fs0=0,fs1=0; - - if(l->type != moveTo) { - if(oldls != l->linestyle) {oldls = ls = l->linestyle;if(!ls) ls=0x8000;} - if(oldfs0 != l->fillstyle0) {oldfs0 = fs0 = l->fillstyle0;if(!fs0) fs0=0x8000;} - if(oldfs1 != l->fillstyle1) {oldfs1 = fs1 = l->fillstyle1;if(!fs1) fs1=0x8000;} - - if(ls || fs0 || fs1 || newx!=0x7fffffff || newy!=0x7fffffff) { - swf_ShapeSetAll(tag,shape,newx,newy,ls,fs0,fs1); - newx = 0x7fffffff; - newy = 0x7fffffff; - } - } - - if(l->type == lineTo) { - swf_ShapeSetLine(tag,shape,l->x-lastx,l->y-lasty); - } else if(l->type == splineTo) { - swf_ShapeSetCurve(tag,shape, l->sx-lastx,l->sy-lasty, l->x-l->sx,l->y-l->sy); - } - if(l->type == moveTo) { - newx = l->x; - newy = l->y; - } - - lastx = l->x; - lasty = l->y; - l = l->next; - } - swf_ShapeSetEnd(tag); - shape->data = tag->data; - shape->bitlen = tag->len*8; -} - -void swf_SetShape2(TAG*tag, SHAPE2*shape2) -{ - SHAPE shape; - swf_Shape2ToShape(shape2, &shape); - - swf_SetRect(tag,shape2->bbox); - swf_SetShapeStyles(tag, &shape); - swf_ShapeCountBits(&shape,NULL,NULL); - swf_SetShapeBits(tag,&shape); - - swf_SetBlock(tag, shape.data, (shape.bitlen+7)/8); -} - /* {char {x1 y1 x2 y2 x3 y3 x4 y4]] */ @@ -299,6 +169,8 @@ int hasid(TAG*tag) return 1; if(tag->id == ST_PLACEOBJECT2 && (tag->data[0] & 2)) return 1; + if(tag->id == ST_PLACEOBJECT3 && (tag->data[0] & 2)) + return 1; return 0; } @@ -308,6 +180,8 @@ int hasname(TAG*tag) return 0; if(tag->id == ST_PLACEOBJECT2 && (tag->data[0] & 0x20)) return 1; + if(tag->id == ST_PLACEOBJECT3 && (tag->data[0] & 0x20)) + return 1; return 0; } @@ -321,6 +195,12 @@ char* getname(TAG*tag) swf_GetPlaceObject(tag, &o); return o.name; } + if(tag->id == ST_PLACEOBJECT3 && (tag->data[0] & 0x20)) { + SWFPLACEOBJECT o; + tag->pos = 0;tag->readBit = 0; + swf_GetPlaceObject(tag, &o); + return o.name; + } return 0; } @@ -332,21 +212,293 @@ MATRIX getmatrix(TAG*tag) return o.matrix; } + +static int fontnum = -1; +static SWFFONT**fonts; +static SWF*c_swf; +static void fontcallback1(void*self, U16 id,U8 * name) +{ fontnum++; +} +static void fontcallback2(void*self, U16 id,U8 * name) +{ + fonts[fontnum] = 0; + swf_FontExtract(c_swf,id,&fonts[fontnum]); + if(verbose) { + if(fonts[fontnum]) printf("Extracting font %d (%s)\n", id, name); + else printf("Extracting font %d (%s) failed\n", id, name); + fflush(stdout); + } + fontnum++; +} +typedef struct _textbounds +{ + SRECT r; + MATRIX m; // character transform matrix +} textbounds_t; + +typedef struct _placement +{ + SWFPLACEOBJECT* po; + int num; +} placement_t; + +static placement_t* placements; + +static placement_t* readPlacements(SWF*swf) +{ + placement_t* p = (placement_t*)rfx_calloc(sizeof(placement_t)*65536); + TAG*tag = swf->firstTag; + while(tag) { + if(swf_isPlaceTag(tag)) { + SWFPLACEOBJECT*po = rfx_alloc(sizeof(SWFPLACEOBJECT)); + int id; + swf_GetPlaceObject(tag, po); + id = po->id; + if(po->move) { + fprintf(stderr, "MOVE tags not supported with -c"); + } + p[id].po = po; + p[id].num++; + } + tag = tag->next; + } + + return p; +} + +static void freePlacements(placement_t*p) +{ + int t; + for(t=0;t<65536;t++) { + if(p[t].po) { + swf_PlaceObjectFree(p[t].po); p[t].po = 0; + } + } + rfx_free(p); +} + +static SRECT clipBBox(TAG*tag, SRECT mbbox, SRECT r) +{ + int id = swf_GetDefineID(tag); + MATRIX m; + if(!placements[id].po) { + if(verbose) + printf("Id %d is never set\n", id); + return r; + } + if(placements[id].num>1) { + if(verbose) + printf("Id %d is set more than once\n", id); + return r; + } + m = placements[id].po->matrix; + if(m.r0 || m.r1) { + fprintf(stderr, "Rotating PLACEOBJECTS are not supported with -c\n"); + return r; + } + + if(verbose) { + printf("ID %d\n", id); + swf_DumpMatrix(stdout, &m); + } + mbbox.xmin -= m.tx; + mbbox.ymin -= m.ty; + mbbox.xmax -= m.tx; + mbbox.ymax -= m.ty; + mbbox.xmin *= 65536.0/m.sx; + mbbox.xmax *= 65536.0/m.sx; + mbbox.ymin *= 65536.0/m.sy; + mbbox.ymax *= 65536.0/m.sy; + + if(verbose) { + printf("border: %f/%f/%f/%f - rect: %f/%f/%f/%f\n", + mbbox.xmin /20.0, + mbbox.ymin /20.0, + mbbox.xmax /20.0, + mbbox.ymax /20.0, + r.xmin /20.0, + r.ymin /20.0, + r.xmax /20.0, + r.ymax /20.0); + } + + if(checkclippings) { + int clip = 0; + if(r.xmax > mbbox.xmax) clip += r.xmax - mbbox.xmax; + if(r.ymax > mbbox.ymax) clip += r.ymax - mbbox.ymax; + if(r.xmax < mbbox.xmin) clip += -(r.xmax - mbbox.xmin); + if(r.ymax < mbbox.ymin) clip += -(r.ymax - mbbox.ymin); + + if(r.xmin > mbbox.xmax) clip += r.xmin = mbbox.xmax; + if(r.ymin > mbbox.ymax) clip += r.ymin = mbbox.ymax; + if(r.xmin < mbbox.xmin) clip += -(r.xmin = mbbox.xmin); + if(r.ymin < mbbox.ymin) clip += -(r.ymin = mbbox.ymin); + if(clip > 3*20) { + printf("needs clipping: [%.2f %.2f %2.f %2.f] is outside [%.2f %2.f %2.f %2.f]\n", + r.xmin / 20.0, r.ymin / 20.0, r.xmax / 20.0, r.ymax / 20.0, + mbbox.xmin / 20.0, mbbox.ymin / 20.0, mbbox.xmax / 20.0, mbbox.ymax / 20.0 + ); + } + } + + r = swf_ClipRect(mbbox, r); + + if(verbose) { + printf("new rect: %f/%f/%f/%f\n", + r.xmin /20.0, + r.ymin /20.0, + r.xmax /20.0, + r.ymax /20.0); + } + + return r; +} + + +static void textcallback(void*self, int*chars, int*xpos, int nr, int fontid, int fontsize, + int xstart, int ystart, RGBA* color) +{ + textbounds_t * bounds = (textbounds_t*)self; + SWFFONT*font = 0; + int t; + for(t=0;tid == fontid) { + font = fonts[t]; + break; + } + } + if(!font) { + fprintf(stderr, "Font %d unknown\n", fontid); + exit(1); + } + if(!font->layout) { + /* This is an expensive operation- but what should we do, we + need the glyph's bounding boxes */ + swf_FontCreateLayout(font); + } + + if(verbose) + printf("%d chars, font %d, size %d, at (%d,%d)\n", nr, fontid, fontsize, xstart, ystart); + + for(t=0;tlayout->bounds[chars[t]]; + MATRIX m = bounds->m; + SPOINT p; + + if(chars[t] < font->numchars && font->glyph2ascii) { + ch = font->glyph2ascii[chars[t]]; + } + + p.x = x; p.y = y; + p = swf_TurnPoint(p, &m); + + m.sx = (m.sx * fontsize) / 1024; + m.sy = (m.sy * fontsize) / 1024; + m.r0 = (m.r0 * fontsize) / 1024; + m.r1 = (m.r1 * fontsize) / 1024; + + m.tx += p.x; + m.ty += p.y; + newglyphbbox = swf_TurnRect(glyphbbox, &m); + + if(ch<32) ch='?'; + + swf_ExpandRect2(&(bounds->r), &newglyphbbox); + if(verbose >= 2) { + printf("%5d %c, %d %d %d %d (%d %d %d %d) -> %d %d %d %d\n", + xpos[t], ch, + glyphbbox.xmin, glyphbbox.ymin, glyphbbox.xmax, glyphbbox.ymax, + newglyphbbox.xmin, newglyphbbox.ymin, newglyphbbox.xmax, newglyphbbox.ymax, + bounds->r.xmin, bounds->r.ymin, bounds->r.xmax, bounds->r.ymax); + } + + } +} + static void swf_OptimizeBoundingBoxes(SWF*swf) { TAG* tag = swf->firstTag; + while (tag) { if (tag->id == ST_DEFINESHAPE || tag->id == ST_DEFINESHAPE2 || - tag->id == ST_DEFINESHAPE3) { + tag->id == ST_DEFINESHAPE3 || + tag->id == ST_DEFINESHAPE4) { SHAPE2 s; if(verbose) printf("%s\n", swf_TagGetName(tag)); swf_ParseDefineShape(tag, &s); - swf_Shape2Optimize(&s); + if(optimize) + swf_Shape2Optimize(&s); tag->len = 2; tag->pos = 0; + if(!s.bbox) { + fprintf(stderr, "Internal error (5)\n"); + exit(1); + } + if(clip || checkclippings) { + *s.bbox = clipBBox(tag, swf->movieSize, *s.bbox); + } swf_SetShape2(tag, &s); } + if (tag->id == ST_DEFINETEXT || tag->id == ST_DEFINETEXT2) { + SRECT oldbox; + int matrix_offset; + int len; + U8*data; + textbounds_t bounds; + if(verbose) printf("%s\n", swf_TagGetName(tag)); + if(fontnum < 0) { + if(verbose) printf("Extracting fonts...\n"); + c_swf = swf; + fontnum = 0; + swf_FontEnumerate(swf,&fontcallback1,0); + fonts = (SWFFONT**)malloc(fontnum*sizeof(SWFFONT*)); + memset(fonts, 0, fontnum*sizeof(SWFFONT*)); + fontnum = 0; + swf_FontEnumerate(swf,&fontcallback2,0); + } + + memset(&bounds, 0, sizeof(bounds)); + + swf_SetTagPos(tag, 0); + swf_GetU16(tag); + swf_GetRect(tag,&oldbox); + swf_ResetReadBits(tag); + matrix_offset = tag->pos; + swf_GetMatrix(tag,&bounds.m); + swf_ParseDefineText(tag, textcallback, &bounds); + if(verbose) { + printf("\n"); + swf_DumpMatrix(stdout, &bounds.m); + printf("old: %d %d %d %d\n", oldbox.xmin, oldbox.ymin, oldbox.xmax, oldbox.ymax); + printf("new: %d %d %d %d\n", bounds.r.xmin, bounds.r.ymin, bounds.r.xmax, bounds.r.ymax); + } + if(!optimize) + bounds.r = oldbox; //set to old bounds from the tag header + if(clip || checkclippings) { + bounds.r = clipBBox(tag, swf->movieSize, bounds.r); + } + + /* now comes the tricky part: + we have to fiddle the data back in + thank heavens that the bbox is follow by a matrix + struct, which always starts on a byte boundary. + */ + len = tag->len - matrix_offset; + data = malloc(len); + memcpy(data, &tag->data[matrix_offset], len); + tag->writeBit = 0; + tag->len = 2; + swf_SetRect(tag, &bounds.r); + swf_SetBlock(tag, data, len); + free(data); + tag->pos = tag->readBit = 0; + } + tag = tag->next; } } @@ -360,7 +512,7 @@ static void showSwiftyOutput(SWF*swf) if (tag->id == ST_SHOWFRAME) { printf("}\n{\n\t{frame %d}\n", frame++); } - if (tag->id == ST_PLACEOBJECT || tag->id == ST_PLACEOBJECT2) { + if (swf_isPlaceTag(tag)) { if(hasid(tag)) { depth2id[swf_GetDepth(tag)] = swf_GetPlaceID(tag); } @@ -368,7 +520,7 @@ static void showSwiftyOutput(SWF*swf) depth2name[swf_GetDepth(tag)] = getname(tag); } } - if (tag->id == ST_PLACEOBJECT || tag->id == ST_PLACEOBJECT2) { + if (swf_isPlaceTag(tag)) { MATRIX m = getmatrix(tag); U16 id = depth2id[swf_GetDepth(tag)]; char*name = depth2name[swf_GetDepth(tag)]; @@ -395,13 +547,49 @@ static void showSwiftyOutput(SWF*swf) } printf("}\n"); } +static SRECT getMovieClipBBox(TAG*tag) +{ + //TAG*tag = swf->firstTag; + int frame=0; + SRECT movieSize; + U16 depth2id[65536]; + memset(depth2id, 0, sizeof(depth2id)); + + memset(&movieSize,0,sizeof(SRECT)); + while (tag && tag->id != ST_END) { + if (swf_isPlaceTag(tag)) { + if(hasid(tag)) { + depth2id[swf_GetDepth(tag)] = swf_GetPlaceID(tag); + } + } + if (swf_isPlaceTag(tag)) { + MATRIX m = getmatrix(tag); + U16 id = depth2id[swf_GetDepth(tag)]; + SRECT bbox = bboxes[id]; + + SRECT tbbox = swf_TurnRect(bbox, &m); + swf_ExpandRect2(&movieSize, &tbbox); + } + tag = tag->next; + } + return movieSize; +} + +static SRECT getSWFBBox(SWF*swf) +{ + SRECT movieSize = getMovieClipBBox(swf->firstTag); + return movieSize; +} + int main (int argc,char ** argv) { TAG*tag; SWF swf; int fi; + SRECT oldMovieSize; + SRECT newMovieSize; memset(bboxes, 0, sizeof(bboxes)); memset(depth2name, 0, sizeof(depth2name)); @@ -429,18 +617,35 @@ int main (int argc,char ** argv) close(fi); swf_OptimizeTagOrder(&swf); + + if(clip || checkclippings) { + placements = readPlacements(&swf); + } + swf_FoldAll(&swf); /* Optimize bounding boxes in case -O flag was set */ - if(optimize) { + if(optimize || checkclippings || clip) { swf_OptimizeBoundingBoxes(&swf); } /* Create an ID to Bounding Box table */ tag = swf.firstTag; while (tag) { - if(swf_isDefiningTag(tag) && tag->id != ST_DEFINESPRITE) { - bboxes[swf_GetDefineID(tag)] = swf_GetDefineBBox(tag); + if(swf_isDefiningTag(tag)) { + int id = swf_GetDefineID(tag); + if(tag->id != ST_DEFINESPRITE) { + bboxes[id] = swf_GetDefineBBox(tag); + } else { + swf_UnFoldSprite(tag); + bboxes[id] = getMovieClipBBox(tag); + swf_FoldSprite(tag); + if(verbose) { + printf("sprite %d is %.2fx%.2f\n", id, + (bboxes[id].xmax - bboxes[id].xmin)/20.0, + (bboxes[id].ymax - bboxes[id].ymin)/20.0); + } + } } tag = tag->next; } @@ -450,7 +655,14 @@ int main (int argc,char ** argv) showSwiftyOutput(&swf); } - if(optimize) { + oldMovieSize = swf.movieSize; + newMovieSize = getSWFBBox(&swf); + + if(optimize || expand) { + + if(expand) + swf.movieSize = newMovieSize; + fi = open(outfilename, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); if(swf_WriteSWF(fi, &swf) < 0) { fprintf(stderr, "Error writing file %s", outfilename); @@ -459,7 +671,32 @@ int main (int argc,char ** argv) } close(fi); } + + if(showbbox) { + if(verbose>=0) + printf("Real Movie Size (size of visible objects): "); + printf("%.2f x %.2f :%.2f :%.2f\n", + (newMovieSize.xmax-newMovieSize.xmin)/20.0, + (newMovieSize.ymax-newMovieSize.ymin)/20.0, + (newMovieSize.xmin)/20.0, + (newMovieSize.ymin)/20.0 + ); + } + if(showorigbbox) { + if(verbose>=0) + printf("Movie Size accordings to file header: "); + printf("%.2f x %.2f :%.2f :%.2f\n", + (oldMovieSize.xmax-oldMovieSize.xmin)/20.0, + (oldMovieSize.ymax-oldMovieSize.ymin)/20.0, + (oldMovieSize.xmin)/20.0, + (oldMovieSize.ymin)/20.0 + ); + } swf_FreeTags(&swf); + + if(placements) { + freePlacements(placements); + } return 0; }