From 57a0c65d0d2fee99e2899404b561aeccc121cfc8 Mon Sep 17 00:00:00 2001 From: kramm Date: Fri, 17 Jan 2003 12:31:34 +0000 Subject: [PATCH] * bugfixes in sprite handling. * bounding Box routines added. --- lib/modules/swfobject.c | 8 ++++ lib/rfxswf.c | 115 +++++++++++++++++++++++++++++++++++++++-------- lib/rfxswf.h | 10 ++++- 3 files changed, 114 insertions(+), 19 deletions(-) diff --git a/lib/modules/swfobject.c b/lib/modules/swfobject.c index a3f1fda..4867d67 100644 --- a/lib/modules/swfobject.c +++ b/lib/modules/swfobject.c @@ -24,6 +24,10 @@ int swf_ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name) { U8 flags; if (!t) return -1; + if(cx && cx->r1==0 && cx->g1==0 && cx->b1==0 && cx->a1==0 + && cx->r0==256 && cx->g0==256 && cx->b0==256 && cx->a0==256) + cx = 0; + flags = (id?PF_CHAR:0)|(m?PF_MATRIX:0)|(cx?PF_CXFORM:0)|(name?PF_NAME:0)|((m||cx)&&(!id)?PF_MOVE:0); swf_SetU8(t,flags); @@ -40,6 +44,10 @@ int swf_ObjectPlace(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name) int swf_ObjectPlaceClip(TAG * t,U16 id,U16 depth,MATRIX * m,CXFORM * cx,U8 * name, U16 clipaction) { U8 flags; if (!t) return -1; + + if(cx && cx->r1==0 && cx->g1==0 && cx->b1==0 && cx->a1==0 + && cx->r0==256 && cx->g0==256 && cx->b0==256 && cx->a0==256) + cx = 0; flags = (id?PF_CHAR:0)|(m?PF_MATRIX:0)|(cx?PF_CXFORM:0)|(name?PF_NAME:0)| ((m||cx)&&(!id)?PF_MOVE:0)|(clipaction?PF_CLIPACTION:0); diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 28891e4..93b17d9 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -322,6 +322,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;return 0;} if (!r) r = &dummy; nbits = (int) swf_GetBits(t,5); r->xmin = swf_GetSBits(t,nbits); @@ -364,6 +365,56 @@ 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 < 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->r0*(1/65536.0)*p.y + 0.5) + m->tx; + r.y = (int)(m->r1*(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; @@ -738,7 +789,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 +801,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 +812,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 +832,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 +852,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 +866,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,10 +904,16 @@ 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; @@ -858,10 +933,9 @@ 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; } } @@ -884,6 +958,10 @@ void swf_OptimizeTagOrder(SWF*swf) 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; @@ -896,7 +974,8 @@ void swf_OptimizeTagOrder(SWF*swf) if(!swf_isAllowedSpriteTag(tag) || level>=2) { /* remove tag from current position */ tag->prev->next = tag->next; - tag->next->prev = tag->prev; + if(tag->next) + tag->next->prev = tag->prev; /* insert before tag level0 */ tag->next = level0; @@ -1050,7 +1129,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 diff --git a/lib/rfxswf.h b/lib/rfxswf.h index 01059d4..9fb2546 100644 --- a/lib/rfxswf.h +++ b/lib/rfxswf.h @@ -95,7 +95,7 @@ typedef struct _MATRIX } MATRIX, * LPMATRIX; typedef struct _CXFORM -{ S16 a0, a1; +{ S16 a0, a1; /* mult, add */ S16 r0, r1; S16 g0, g1; S16 b0, b1; @@ -228,6 +228,13 @@ int swf_SetCXForm(TAG * t,CXFORM * cx,U8 alpha); int swf_SetRGB(TAG * t,RGBA * col); int swf_SetRGBA(TAG * t,RGBA * col); +// helper functions: + +void swf_ExpandRect(SRECT*src, SPOINT add); +void swf_ExpandRect2(SRECT*src, SRECT*add); +SPOINT swf_TurnPoint(SPOINT p, MATRIX* m); +SRECT swf_TurnRect(SRECT r, MATRIX* m); + // Function Macros #define swf_GetS8(tag) ((S8)swf_GetU8(tag)) @@ -235,6 +242,7 @@ int swf_SetRGBA(TAG * t,RGBA * col); #define swf_GetS32(tag) ((S32)swf_GetU32(tag)) #define swf_GetCoord(tag) ((SCOORD)swf_GetU32(tag)) #define swf_GetFixed(tag) ((SFIXED)swf_GetU32(tag)) +#define swf_GetString(t) ((char*)(&(t)->data[(t)->pos])) #define swf_SetS8(tag,v) swf_SetU8(tag,(U8)v) #define swf_SetS16(tag,v) swf_SetU16(tag,(U16)v) -- 1.7.10.4