X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Frfxswf.c;h=0e000060965b70e4302f4a2669aed417325bec83;hp=7824deec67ae310757fe9adac934e2290145930e;hb=34de503961eb25613a5b3f2a8e5bdb5d1f5de0e9;hpb=5bc790960480ec72730ee25fe60d45cf92f7439f diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 7824dee..0e00006 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -16,20 +16,14 @@ #include "rfxswf.h" -#ifdef HAVE_LIBJPEG -#ifdef HAVE_JPEGLIB_H +#ifdef HAVE_JPEGLIB #define HAVE_BOOLEAN #include -#define _JPEGLIB_INCLUDED_ -#endif // HAVE_JPEGLIB_H -#endif // HAVE_LIBJPEG +#endif // HAVE_JPEGLIB -#ifdef HAVE_LIBZ -#ifdef HAVE_ZLIB_H +#ifdef HAVE_ZLIB #include -#define _ZLIB_INCLUDED_ -#endif // HAVE_ZLIB_H -#endif // HAVE_LIBZ +#endif // HAVE_ZLIB #define LAME #include "lame/lame.h" @@ -72,6 +66,13 @@ void swf_SetTagPos(TAG * t,U32 pos) #endif } +char* swf_GetString(TAG*t) +{ + char* str = ((char*)(&(t)->data[(t)->pos])); + while(swf_GetU8(t)); + return str; +} + U8 swf_GetU8(TAG * t) { swf_ResetReadBits(t); #ifdef DEBUG_RFXSWF @@ -322,6 +323,7 @@ int swf_CountBits(U32 v,int nbits) int swf_GetRect(TAG * t,SRECT * r) { int nbits; SRECT dummy; + if(!t) {r->xmin=r->xmax=r->ymin=r->ymax=0;return 0;} if (!r) r = &dummy; nbits = (int) swf_GetBits(t,5); r->xmin = swf_GetSBits(t,nbits); @@ -364,6 +366,58 @@ int swf_SetRect(TAG * t,SRECT * r) return 0; } +void swf_ExpandRect(SRECT*src, SPOINT add) +{ + if(add.x < src->xmin) + src->xmin = add.x; + if(add.x > src->xmax) + src->xmax = add.x; + if(add.y < src->ymin) + src->ymin = add.y; + if(add.y > src->ymax) + src->ymax = add.y; +} +void swf_ExpandRect2(SRECT*src, SRECT*add) +{ + if((add->xmin | add->ymin | add->xmax | add->ymax)==0) + return; + if(add->xmin < src->xmin) + src->xmin = add->xmin; + if(add->ymin < src->ymin) + src->ymin = add->ymin; + if(add->xmax > src->xmax) + src->xmax = add->xmax; + if(add->ymax > src->ymax) + src->ymax = add->ymax; +} +SPOINT swf_TurnPoint(SPOINT p, MATRIX* m) +{ + SPOINT r; + r.x = (int)(m->sx*(1/65536.0)*p.x + m->r1*(1/65536.0)*p.y + 0.5) + m->tx; + r.y = (int)(m->r0*(1/65536.0)*p.x + m->sy*(1/65536.0)*p.y + 0.5) + m->ty; + return r; +} +SRECT swf_TurnRect(SRECT r, MATRIX* m) +{ + SRECT g; + SPOINT p1,p2,p3,p4,pp1,pp2,pp3,pp4; + p1.x = r.xmin;p1.y = r.ymin; + p2.x = r.xmax;p2.y = r.ymin; + p3.x = r.xmin;p3.y = r.ymax; + p4.x = r.xmax;p4.y = r.ymax; + pp1 = swf_TurnPoint(p1, m); + pp2 = swf_TurnPoint(p2, m); + pp3 = swf_TurnPoint(p3, m); + pp4 = swf_TurnPoint(p4, m); + g.xmin = g.xmax = pp1.x; + g.ymin = g.ymax = pp1.y; + swf_ExpandRect(&g, pp2); + swf_ExpandRect(&g, pp3); + swf_ExpandRect(&g, pp4); + return g; +} + + int swf_GetMatrix(TAG * t,MATRIX * m) { MATRIX dummy; int nbits; @@ -586,6 +640,17 @@ TAG * swf_InsertTag(TAG * after,U16 id) // updates frames, if nescessary return t; } +void swf_ClearTag(TAG * t) +{ + if (t->data) free(t->data); + t->data = 0; + t->pos = 0; + t->len = 0; + t->readBit = 0; + t->writeBit = 0; + t->memsize = 0; +} + int swf_DeleteTag(TAG * t) { if (!t) return -1; @@ -738,7 +803,7 @@ int swf_DefineSprite_GetRealSize(TAG * t) } do { t = swf_NextTag(t); - if (t->id!=ST_DEFINESPRITE) len += swf_WriteTag(-1, t); + if (t && t->id!=ST_DEFINESPRITE) len += swf_WriteTag(-1, t); else t = NULL; } while (t&&(t->id!=ST_END)); return len; @@ -750,6 +815,7 @@ void swf_UnFoldSprite(TAG * t) U32 len; TAG*next = t; U16 spriteid,spriteframes; + int level; if(t->id!=ST_DEFINESPRITE) return; if(t->len<=4) // not folded @@ -760,12 +826,19 @@ void swf_UnFoldSprite(TAG * t) spriteid = swf_GetU16(t); //id spriteframes = swf_GetU16(t); //frames - tmp = swf_GetU16(t); - len = tmp&0x3f; - id = tmp>>6; - while(id) + level = 1; + + while(1) { TAG*it = 0; + tmp = swf_GetU16(t); + len = tmp&0x3f; + id = tmp>>6; + if(id == ST_END) + level--; + if(id == ST_DEFINESPRITE && len<=4) + level++; + if (len==0x3f) len = swf_GetU32(t); it = swf_InsertTag(next, id); @@ -773,13 +846,13 @@ void swf_UnFoldSprite(TAG * t) it->len = len; it->id = id; if (it->len) - { it->data = (U8*)malloc(t->len); + { it->data = (U8*)malloc(it->len); it->memsize = it->len; swf_GetBlock(t, it->data, it->len); } - tmp = swf_GetU16(t); - len = tmp&0x3f; - id = tmp>>6; + + if(!level) + break; } free(t->data); t->data = 0; @@ -793,6 +866,7 @@ void swf_FoldSprite(TAG * t) { TAG*sprtag=t,*tmp; U16 id,frames,tmpid; + int level; if(t->id!=ST_DEFINESPRITE) return; if(!t->len) { @@ -806,26 +880,35 @@ void swf_FoldSprite(TAG * t) t->pos = 0; id = swf_GetU16(t); - //frames = swf_GetU16(t); free(t->data); t->len = t->pos = t->memsize = 0; t->data = 0; frames = 0; + t = swf_NextTag(sprtag); + level = 1; + do { if(t->id==ST_SHOWFRAME) frames++; + if(t->id == ST_DEFINESPRITE && t->len<=4) + level++; + if(t->id == ST_END) + level--; t = swf_NextTag(t); - } while(t&&t!=ST_END); + } while(t && level); + if(level) + fprintf(stderr, "rfxswf error: sprite doesn't end(1)\n"); - t = swf_NextTag(sprtag); swf_SetU16(sprtag, id); swf_SetU16(sprtag, frames); + t = swf_NextTag(sprtag); + level = 1; + do { - tmpid= t->id; if(t->len<0x3f) { swf_SetU16(sprtag,t->len|(t->id<<6)); } else { @@ -835,15 +918,26 @@ void swf_FoldSprite(TAG * t) if(t->len) swf_SetBlock(sprtag,t->data, t->len); tmp = t; + if(t->id == ST_DEFINESPRITE && t->len<=4) + level++; + if(t->id == ST_END) + level--; t = swf_NextTag(t); swf_DeleteTag(tmp); } - while (t&&(tmpid!=ST_END)); + while (t && level); + if(level) + fprintf(stderr, "rfxswf error: sprite doesn't end(2)\n"); // sprtag->next = t; // t->prev = sprtag; } +int swf_IsFolded(TAG * t) +{ + return (t->id == ST_DEFINESPRITE && t->len>4); +} + void swf_FoldAll(SWF*swf) { TAG*tag = swf->firstTag; @@ -858,13 +952,67 @@ 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; + 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) { + if(tag->len>4) { + /* ??? all sprites are supposed to be unfolded */ + fprintf(stderr, "librfxswf error - internal error in OptimizeTagOrder/UnfoldAll\n"); + } + 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; + if(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 @@ -1000,7 +1148,7 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, if (ret!=swf_GetTagLen(&t1)) { #ifdef DEBUG_RFXSWF - printf("ret:%d\n",ret); + fprintf(stderr, "ret:%d\n",ret); perror("write:"); fprintf(stderr,"WriteSWF() failed: Header.\n"); #endif @@ -1095,4 +1243,3 @@ void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for t #include "modules/swfbits.c" #include "modules/swfaction.c" #include "modules/swfsound.c" -