case ST_DEFINESPRITE:
case ST_DEFINEMOVIE:
case ST_DEFINEVIDEOSTREAM:
+ case ST_GLYPHNAMES: //pseudodefine
case ST_VIDEOFRAME: //pseudodefine
case ST_NAMECHARACTER: //pseudodefine
+ case ST_DOINITACTION: //pseudodefine
id = swf_GetU16(t);
break;
}
case ST_DEFINESHAPE2:
case ST_DEFINESHAPE3:
case ST_DEFINEEDITTEXT:
- case ST_DEFINEBUTTON:
- case ST_DEFINEBUTTON2:
case ST_DEFINETEXT:
case ST_DEFINETEXT2:
case ST_DEFINEVIDEOSTREAM:
ST_NAMECHARACTER,
ST_DOINITACTION,
ST_VIDEOFRAME,
+ ST_GLYPHNAMES,
-1
};
}
break;
}
+ case ST_GLYPHNAMES:
case ST_DEFINEFONTINFO:
case ST_DEFINEFONTINFO2:
case ST_VIDEOFRAME:
while(tag)
{
+ /* TODO * clip depths
+ * sprites
+ */
int depth = swf_GetDepth(tag);
if(depth>=0) {
int newdepth = depth+nr;
TAG*tag=0,*lasttag=0;
char bitmap[65536];
char depthmap[65536];
+ SWF swf1,swf2;
memset(bitmap, 0, sizeof(bitmap));
memset(depthmap, 0, sizeof(depthmap));
- SWF swf1,swf2;
memset(&swf1, 0, sizeof(swf1));
memset(&swf2, 0, sizeof(swf2));
return swf1.firstTag;
}
+
+static int tagHash(TAG*tag)
+{
+ int t, h=0;
+ unsigned int a = 0x6b973e5a;
+ for(t=0;t<tag->len;t++) {
+ unsigned int b = a;
+ a >>= 8;
+ a += tag->data[t]*0xefbc35a5*b*(t+1);
+ }
+ return a;
+}
+
+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);
+ int t;
+ for(t=0;t<65536;t++) {
+ remap[t] = t;
+ }
+ while(tag) {
+ 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;t<num;t++) {
+ int id = GET16(&tag->data[positions[t]]);
+ id = remap[id];
+ PUT16(&tag->data[positions[t]], id);
+ }
+ tag = tag->next;
+ } else {
+ TAG*tag2;
+ int hash = tagHash(tag);
+ int match=0;
+ while((tag2 = hashmap[hash%hash_size])) {
+ if(tag->len == tag2->len) {
+ int t;
+ for(t=0;t<tag->len;t++) {
+ if(tag->data[t] != tag2->data[t])
+ break;
+ }
+ if(t == tag->len) {
+ match=1;
+ }
+ }
+ if(match) {
+ /* we found two identical tags- remap one
+ of them */
+ remap[swf_GetDefineID(tag2)] = swf_GetDefineID(tag);
+ break;
+ }
+ hash++;
+ }
+ if(!match) {
+ while(hashmap[hash%hash_size]) hash++;
+ hashmap[hash%hash_size] = tag;
+ } else {
+ swf_DeleteTag(tag);
+ if(tag == swf->firstTag)
+ swf->firstTag = next;
+ }
+ }
+ tag = next;
+ }
+}