X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Fmodules%2Fswftools.c;h=8f6b418a901fef0480ffe0ccaecc0211d3c410ed;hb=b628ac5236f25c4729c0bb660cd6f4605af26b24;hp=3041337defb364f1599d785c5c6ae5672fc97294;hpb=aee9de2c6eb23628e54b6896f5b441d9b39317c1;p=swftools.git diff --git a/lib/modules/swftools.c b/lib/modules/swftools.c index 3041337..8f6b418 100644 --- a/lib/modules/swftools.c +++ b/lib/modules/swftools.c @@ -250,6 +250,7 @@ static int swf_pseudodefiningtagids[] = ST_NAMECHARACTER, ST_DOINITACTION, ST_VIDEOFRAME, + ST_GLYPHNAMES, -1 }; @@ -292,10 +293,9 @@ U8 swf_isPseudoDefiningTag(TAG * tag) return 0; } -U16 swf_GetDepth(TAG * t) -// up to SWF 4.0 +int swf_GetDepth(TAG * t) { - U16 depth = 0; + int depth = -1; U32 oldTagPos; oldTagPos = swf_GetTagPos(t); swf_SetTagPos(t,0); @@ -313,11 +313,36 @@ U16 swf_GetDepth(TAG * t) { U8 flags = swf_GetU8(t); depth = swf_GetU16(t); } break; + case ST_SETTABINDEX: + { + depth = swf_GetU16(t); + } } swf_SetTagPos(t,oldTagPos); return depth; } +void swf_SetDepth(TAG * t, U16 depth) +{ + switch (swf_GetTagID(t)) + { case ST_PLACEOBJECT: + case ST_REMOVEOBJECT: + PUT16(t->data, depth); + break; + case ST_REMOVEOBJECT2: + PUT16(t->data, depth); + break; + case ST_PLACEOBJECT2: + PUT16(&t->data[1], depth); + break; + case ST_SETTABINDEX: + PUT16(t->data, depth); + break; + default: + fprintf(stderr, "rfxswf: Error: tag %d has no depth\n", t->id); + } +} + char* swf_GetName(TAG * t) { char* name = 0; @@ -634,6 +659,7 @@ void enumerateUsedIDs(TAG * tag, int base, void (*callback)(TAG*, int, void*), v } break; } + case ST_GLYPHNAMES: case ST_DEFINEFONTINFO: case ST_DEFINEFONTINFO2: case ST_VIDEOFRAME: @@ -831,4 +857,74 @@ void swf_Relocate (SWF*swf, char*bitmap) tag=tag->next; } } - + +void swf_RelocateDepth(SWF*swf, char*bitmap) +{ + TAG*tag; + int nr; + tag = swf->firstTag; + for(nr=65535;nr>=0;nr--) { + if(bitmap[nr] != 0) + break; + } + // now nr is the highest used depth. So we start + // assigning depths at nr+1 + nr++; + + while(tag) + { + int depth = swf_GetDepth(tag); + if(depth>=0) { + int newdepth = depth+nr; + if(newdepth>65535) { + fprintf(stderr, "Couldn't relocate depths: too large values\n"); + newdepth = 65535; + } + swf_SetDepth(tag, newdepth); + } + tag=tag->next; + } +} + +TAG* swf_Concatenate (TAG*list1,TAG*list2) +{ + TAG*tag=0,*lasttag=0; + char bitmap[65536]; + char depthmap[65536]; + SWF swf1,swf2; + memset(bitmap, 0, sizeof(bitmap)); + memset(depthmap, 0, sizeof(depthmap)); + memset(&swf1, 0, sizeof(swf1)); + memset(&swf2, 0, sizeof(swf2)); + + swf1.firstTag = list1; + swf_FoldAll(&swf1); + swf2.firstTag = list2; + swf_FoldAll(&swf2); + + tag = list1; + while(tag) { + if(!swf_isDefiningTag(tag)) { + int id = swf_GetDefineID(tag); + bitmap[id] = 1; + } + if(tag->id == ST_PLACEOBJECT || + tag->id == ST_PLACEOBJECT2) { + int depth = swf_GetDepth(tag); + depthmap[depth] = 1; + } + if(tag->id == ST_REMOVEOBJECT || + tag->id == ST_REMOVEOBJECT2) { + int depth = swf_GetDepth(tag); + depthmap[depth] = 0; + } + tag = tag->next; + lasttag = tag; + } + swf_Relocate(&swf2, bitmap); + swf_RelocateDepth(&swf2, depthmap); + lasttag->next = swf2.firstTag; + swf2.firstTag->prev = lasttag; + + return swf1.firstTag; +}