X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswftools.c;h=1099bc3b4cf5e8826fda87e6442792e6761ba482;hb=1baa73fc6c64b3a3f97ed3807321ca5a46a5a756;hp=b192f338b3b29fe5ddef6ff21c558c2cdd70a6ef;hpb=6d22f1376c2fcad7c872db608630468d3abcca23;p=swftools.git diff --git a/lib/modules/swftools.c b/lib/modules/swftools.c index b192f33..1099bc3 100644 --- a/lib/modules/swftools.c +++ b/lib/modules/swftools.c @@ -26,8 +26,11 @@ #define S64 long long SFIXED RFXSWF_SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2) { S64 a; - a = (S64)a1*(S64)b1+(S64)a2*(S64)b2; - return (SFIXED)(a>>16); + a = ((S64)a1*(S64)b1+(S64)a2*(S64)b2)>>16; + SFIXED result = (SFIXED)(a); + if(a!=result) + fprintf(stderr, "Warning: overflow in matrix multiplication"); + return result; } SFIXED RFXSWF_QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED { S64 z = zaehler<<16; @@ -42,13 +45,14 @@ MATRIX * swf_MatrixJoin(MATRIX * d,MATRIX * s1,MATRIX * s2) if (!s1) return (s2)?(MATRIX *)memcpy(d,s2,sizeof(MATRIX)):NULL; if (!s2) return (MATRIX *)memcpy(d,s1,sizeof(MATRIX)); - d->tx = s1->tx + s2->tx; - d->ty = s1->ty + s2->ty; + d->tx = s1->tx + RFXSWF_SP(s1->sx,s1->r1,s2->tx,s2->ty); + d->ty = s1->ty + RFXSWF_SP(s1->r0,s1->sy,s2->tx,s2->ty); d->sx = RFXSWF_SP(s1->sx,s1->r1,s2->sx,s2->r0); - d->sy = RFXSWF_SP(s1->r0,s1->sy,s2->r1,s2->sy); d->r0 = RFXSWF_SP(s1->r0,s1->sy,s2->sx,s2->r0); + d->r1 = RFXSWF_SP(s1->sx,s1->r1,s2->r1,s2->sy); + d->sy = RFXSWF_SP(s1->r0,s1->sy,s2->r1,s2->sy); //DumpMatrix(NULL,d); @@ -136,6 +140,7 @@ SRECT swf_GetDefineBBox(TAG * t) U32 oldTagPos; U16 id = 0; SRECT b1,b2; + memset(&b1, 0, sizeof(b1)); oldTagPos = swf_GetTagPos(t); swf_SetTagPos(t,0); @@ -408,7 +413,7 @@ void swf_GetMorphGradient(TAG * tag, GRADIENT * gradient1, GRADIENT * gradient2) #define DEBUG_ENUMERATE if(0) -static void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph) +void enumerateUsedIDs_styles(TAG * tag, void (*callback)(TAG*, int, void*), void*callback_data, int num, int morph) { U16 count; int t; @@ -481,7 +486,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v tag->pos = 0; switch(tag->id) { - case ST_DEFINEBUTTONCXFORM: { + case ST_DEFINEBUTTONSOUND: { int t; callback(tag, tag->pos + base, callback_data); for(t=0;t<4;t++) { @@ -508,7 +513,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v } } } break; - case ST_DEFINEBUTTONSOUND: + case ST_DEFINEBUTTONCXFORM: callback(tag, tag->pos + base, callback_data); //button id break; @@ -560,7 +565,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v if(id == ST_END) break; tag2->len = tag2->memsize = len; - tag2->data = malloc(len); + tag2->data = rfx_alloc(len); memcpy(tag2->data, &tag->data[tag->pos], len); /* I never saw recursive sprites, but they are (theoretically) possible, so better add base here again */ @@ -844,17 +849,20 @@ void swf_Relocate (SWF*swf, char*bitmap) } num = swf_GetNumUsedIDs(tag); - ptr = malloc(sizeof(int)*num); - swf_GetUsedIDs(tag, ptr); - - for(t=0;tdata[ptr[t]]); - if(slaveids[id]<0) { - fprintf(stderr, "swf_Relocate: Mapping id never encountered before: %d\n", id); - return ; + if(num) { + ptr = rfx_alloc(sizeof(int)*num); + swf_GetUsedIDs(tag, ptr); + + for(t=0;tdata[ptr[t]]); + if(slaveids[id]<0) { + fprintf(stderr, "swf_Relocate: Mapping id (%d) never encountered before in %s\n", id, + swf_TagGetName(tag)); + return ; + } + id = slaveids[id]; + PUT16(&tag->data[ptr[t]], id); } - id = slaveids[id]; - PUT16(&tag->data[ptr[t]], id); } tag=tag->next; } @@ -900,6 +908,30 @@ U8 swf_isShapeTag(TAG*tag) return 0; } +U8 swf_isPlaceTag(TAG*tag) +{ + if(tag->id == ST_PLACEOBJECT || + tag->id == ST_PLACEOBJECT2) + return 1; + return 0; +} +U8 swf_isTextTag(TAG*tag) +{ + if(tag->id == ST_DEFINETEXT || + tag->id == ST_DEFINETEXT2) + return 1; + return 0; +} + +U8 swf_isFontTag(TAG*tag) +{ + if(tag->id == ST_DEFINEFONT || + tag->id == ST_DEFINEFONT2 || + tag->id == ST_DEFINEFONTINFO) + return 1; + return 0; +} + U8 swf_isImageTag(TAG*tag) { if(tag->id == ST_DEFINEBITSJPEG || @@ -964,20 +996,17 @@ static int tagHash(TAG*tag) a >>= 8; a += tag->data[t]*0xefbc35a5*b*(t+1); } - return a&0x7fffffff; //always return unsigned + return a&0x7fffffff; //always return positive number } void swf_Optimize(SWF*swf) { const int hash_size = 131072; - char* dontremap = malloc(sizeof(char)*65536); - U16* remap = malloc(sizeof(U16)*65536); - TAG* id2tag = malloc(sizeof(TAG*)*65536); - TAG** hashmap = malloc(sizeof(TAG*)*hash_size); + char* dontremap = rfx_calloc(sizeof(char)*65536); + U16* remap = rfx_alloc(sizeof(U16)*65536); + TAG* id2tag = rfx_calloc(sizeof(TAG*)*65536); + TAG** hashmap = rfx_calloc(sizeof(TAG*)*hash_size); TAG* tag; - memset(dontremap, 0, sizeof(char)*65536); - memset(hashmap, 0, sizeof(TAG*)*hash_size); - memset(id2tag, 0, sizeof(TAG*)*65536); int t; for(t=0;t<65536;t++) { remap[t] = t; @@ -992,8 +1021,9 @@ void swf_Optimize(SWF*swf) FIXME: a better way would be to compare the helper tags, too. */ - if(swf_isPseudoDefiningTag(tag)) { - //dontremap[swf_GetDefineID(tag)] = 1; //FIXME + if(swf_isPseudoDefiningTag(tag) && + tag->id != ST_NAMECHARACTER) { + dontremap[swf_GetDefineID(tag)] = 1; } tag=tag->next; } @@ -1002,7 +1032,22 @@ void swf_Optimize(SWF*swf) int doremap=1; TAG*next = tag->next; - + + /* remap the tag */ + int num = swf_GetNumUsedIDs(tag); + int*positions = rfx_alloc(sizeof(int)*num); + int t; + swf_GetUsedIDs(tag, positions); + for(t=0;tdata[positions[t]]); + id = remap[id]; + PUT16(&tag->data[positions[t]], id); + } + rfx_free(positions); + tag = tag->next; + + /* now look for previous tags with the same + content */ if(swf_isDefiningTag(tag)) { TAG*tag2; int id = swf_GetDefineID(tag); @@ -1051,25 +1096,67 @@ void swf_Optimize(SWF*swf) } } - if(doremap) - { - int num = swf_GetNumUsedIDs(tag); - int*positions = malloc(sizeof(int)*num); - int t; - swf_GetUsedIDs(tag, positions); - for(t=0;tdata[positions[t]]); - id = remap[id]; - PUT16(&tag->data[positions[t]], id); - } - free(positions); - tag = tag->next; - } - tag = next; } - free(dontremap); - free(remap); - free(id2tag); - free(hashmap); + rfx_free(dontremap); + rfx_free(remap); + rfx_free(id2tag); + rfx_free(hashmap); +} + +void swf_SetDefineBBox(TAG * tag, SRECT newbbox) +{ + U16 id = 0; + SRECT b1; + swf_SetTagPos(tag,0); + + switch (swf_GetTagID(tag)) + { + case ST_DEFINESHAPE: + case ST_DEFINESHAPE2: + case ST_DEFINESHAPE3: + case ST_DEFINEEDITTEXT: + case ST_DEFINETEXT: + case ST_DEFINETEXT2: + case ST_DEFINEVIDEOSTREAM: { + U32 after_bbox_offset = 0, len; + U8*data; + id = swf_GetU16(tag); + swf_GetRect(tag, &b1); + swf_ResetReadBits(tag); + after_bbox_offset = tag->pos; + len = tag->len - after_bbox_offset; + data = malloc(len); + memcpy(data, &tag->data[after_bbox_offset], len); + tag->writeBit = 0; + tag->len = 2; + swf_SetRect(tag, &newbbox); + swf_SetBlock(tag, data, len); + free(data); + tag->pos = tag->readBit = 0; + + } break; + default: + fprintf(stderr, "rfxswf: Tag %d (%s) has no bbox\n", tag->id, swf_TagGetName(tag)); + } } + +RGBA swf_GetSWFBackgroundColor(SWF*swf) +{ + TAG*t=swf->firstTag; + RGBA color; + color.r = color.b = color.g = 0; + color.a = 255; + while(t) { + if(t->id == ST_SETBACKGROUNDCOLOR) { + swf_SetTagPos(t, 0); + color.r = swf_GetU8(t); + color.g = swf_GetU8(t); + color.b = swf_GetU8(t); + break; + } + t=t->next; + } + return color; +} +