X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswftools.c;h=e3d20eeb6ea89a3d949cf9d485d0770fd7ffd6ce;hb=8526dcf3a698c688e2cc4430ae106b5ecf70677f;hp=d195817ccdadcffbb010d5ea01016384a2004041;hpb=d6162e08c1dbc4066ece3612982de8f32f788531;p=swftools.git diff --git a/lib/modules/swftools.c b/lib/modules/swftools.c index d195817..e3d20ee 100644 --- a/lib/modules/swftools.c +++ b/lib/modules/swftools.c @@ -122,6 +122,8 @@ U16 swf_GetDefineID(TAG * t) case ST_DOINITACTION: //pseudodefine id = swf_GetU16(t); break; + default: + fprintf(stderr, "rfxswf: Error: tag %d (%s) has no id\n", t->id, swf_TagGetName(t)); } swf_SetTagPos(t,oldTagPos); @@ -558,7 +560,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 */ @@ -842,7 +844,7 @@ void swf_Relocate (SWF*swf, char*bitmap) } num = swf_GetNumUsedIDs(tag); - ptr = malloc(sizeof(int)*num); + ptr = rfx_alloc(sizeof(int)*num); swf_GetUsedIDs(tag, ptr); for(t=0;tid == ST_DEFINESHAPE || + tag->id == ST_DEFINESHAPE2 || + tag->id == ST_DEFINESHAPE3) + return 1; + return 0; +} + +U8 swf_isImageTag(TAG*tag) +{ + if(tag->id == ST_DEFINEBITSJPEG || + tag->id == ST_DEFINEBITSJPEG2 || + tag->id == ST_DEFINEBITSJPEG3 || + tag->id == ST_DEFINEBITSLOSSLESS || + tag->id == ST_DEFINEBITSLOSSLESS2) + return 1; + return 0; +} + TAG* swf_Concatenate (TAG*list1,TAG*list2) { TAG*tag=0,*lasttag=0; @@ -936,46 +958,59 @@ static int tagHash(TAG*tag) { int t, h=0; unsigned int a = 0x6b973e5a; - for(t=0;tlen;t++) { + /* start at pos 2, as 0 and 1 are the id */ + for(t=2;tlen;t++) { unsigned int b = a; a >>= 8; a += tag->data[t]*0xefbc35a5*b*(t+1); } - return a; + return a&0x7fffffff; //always return unsigned } void swf_Optimize(SWF*swf) { - TAG* tag = swf->firstTag; - int hash_size = 131072; - U16* remap = malloc(sizeof(U16)*65536); - TAG** hashmap = malloc(sizeof(TAG*)*hash_size); - memset(hashmap, 0, sizeof(TAG*)*hash_size); + const int hash_size = 131072; + 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; int t; for(t=0;t<65536;t++) { remap[t] = t; } + + swf_FoldAll(swf); + + tag = swf->firstTag; + while(tag) { + /* make sure we don't remap to this tag, + as it might have different "helper tags" + FIXME: a better way would be to compare + the helper tags, too. + */ + if(swf_isPseudoDefiningTag(tag)) { + //dontremap[swf_GetDefineID(tag)] = 1; //FIXME + } + tag=tag->next; + } + tag = swf->firstTag; while(tag) { + int doremap=1; + TAG*next = tag->next; - if(!swf_isDefiningTag(tag)) { - 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); - } - tag = tag->next; - } else { + + if(swf_isDefiningTag(tag)) { TAG*tag2; + int id = swf_GetDefineID(tag); int hash = tagHash(tag); int match=0; + if(!dontremap[id]) while((tag2 = hashmap[hash%hash_size])) { - if(tag->len == tag2->len) { + if(tag2 != (TAG*)(-1) && tag->len == tag2->len) { int t; - for(t=0;tlen;t++) { + /* start at pos 2, as 0 and 1 are the id */ + for(t=2;tlen;t++) { if(tag->data[t] != tag2->data[t]) break; } @@ -986,7 +1021,7 @@ void swf_Optimize(SWF*swf) if(match) { /* we found two identical tags- remap one of them */ - remap[swf_GetDefineID(tag2)] = swf_GetDefineID(tag); + remap[id] = swf_GetDefineID(tag2); break; } hash++; @@ -998,8 +1033,40 @@ void swf_Optimize(SWF*swf) swf_DeleteTag(tag); if(tag == swf->firstTag) swf->firstTag = next; + doremap = 0; + } + } else if(swf_isPseudoDefiningTag(tag)) { + int id = swf_GetDefineID(tag); + if(remap[id]!=id) { + /* if this tag was remapped, we don't + need the helper tag anymore. Discard + it. */ + swf_DeleteTag(tag); + if(tag == swf->firstTag) + swf->firstTag = next; + doremap = 0; } } + + if(doremap) + { + 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; + } + tag = next; } + rfx_free(dontremap); + rfx_free(remap); + rfx_free(id2tag); + rfx_free(hashmap); }