X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Frfxswf.c;h=28891e4736e0f1b5e404979cffb60b52a7e53fc7;hb=79d1c8f25ee9082844d8a85d50e2c1e4127e2480;hp=9b962355d6df9ce123e5d3da2ad0058fcdf75d73;hpb=de0e909835e1cb1d2c0bb675f4dbed62bb452a9c;p=swftools.git diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 9b96235..28891e4 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -744,6 +744,51 @@ int swf_DefineSprite_GetRealSize(TAG * t) return len; } +void swf_UnFoldSprite(TAG * t) +{ + U16 id,tmp; + U32 len; + TAG*next = t; + U16 spriteid,spriteframes; + if(t->id!=ST_DEFINESPRITE) + return; + if(t->len<=4) // not folded + return; + + swf_SetTagPos(t,0); + + spriteid = swf_GetU16(t); //id + spriteframes = swf_GetU16(t); //frames + + tmp = swf_GetU16(t); + len = tmp&0x3f; + id = tmp>>6; + while(id) + { + TAG*it = 0; + if (len==0x3f) + len = swf_GetU32(t); + it = swf_InsertTag(next, id); + next = it; + it->len = len; + it->id = id; + if (it->len) + { it->data = (U8*)malloc(t->len); + it->memsize = it->len; + swf_GetBlock(t, it->data, it->len); + } + tmp = swf_GetU16(t); + len = tmp&0x3f; + id = tmp>>6; + } + + free(t->data); t->data = 0; + t->memsize = t->len = t->pos = 0; + + swf_SetU16(t, spriteid); + swf_SetU16(t, spriteframes); +} + void swf_FoldSprite(TAG * t) { TAG*sprtag=t,*tmp; @@ -809,6 +854,67 @@ void swf_FoldAll(SWF*swf) } } +void swf_UnFoldAll(SWF*swf) +{ + TAG*tag = swf->firstTag; + while(tag) { + TAG*next = swf_NextTag(tag); + if(tag->id == ST_DEFINESPRITE) + swf_UnFoldSprite(tag); + tag = next; + } +} + +void swf_OptimizeTagOrder(SWF*swf) +{ + TAG*tag,*next; + TAG*level0; + int level; + int changes; + swf_UnFoldAll(swf); + /* at the moment, we don't actually do optimizing, + only fixing of non-spec-conformant things like + sprite tags */ + + do { + changes = 0; + level = 0; + level0 = 0; + tag = swf->firstTag; + while(tag) { + next = tag->next; + if(tag->id == ST_DEFINESPRITE) { + level++; + if(level==1) { + level0 = tag; + tag = next; + continue; + } + } + if(level>=1) { + /* move non-sprite tags out of sprite */ + if(!swf_isAllowedSpriteTag(tag) || level>=2) { + /* remove tag from current position */ + tag->prev->next = tag->next; + tag->next->prev = tag->prev; + + /* insert before tag level0 */ + tag->next = level0; + tag->prev = level0->prev; + level0->prev = tag; + tag->prev->next = tag; + changes = 1; + } + } + if(tag->id == ST_END) { + level--; + } + + tag = next; + } + } while(changes); +} + // Movie Functions int swf_ReadSWF2(struct reader_t*reader, SWF * swf) // Reads SWF to memory (malloc'ed), returns length or <0 if fails