X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Frfxswf.c;h=4a7035cf3fbbf49e291a57e8989b3dfff12a1df7;hb=064caea40b3bcb69d965fa2b0d6df268cc0735b4;hp=1c9bd667667258fd9422aa05d8e8bdafc0758ca8;hpb=cfb06dab4b1674078f1306d1c537ad03d00def26;p=swftools.git diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 1c9bd66..4a7035c 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -1,4 +1,6 @@ -/* rfxswf.c +/* vi: set sts=2 sw=2 :*/ + +/* rfxswf.c Library for creating and reading SWF files or parts of it. There's a module directory which provides some extended functionality. @@ -16,21 +18,23 @@ #ifdef HAVE_LIBJPEG #ifdef HAVE_JPEGLIB_H +#define HAVE_BOOLEAN #include #define _JPEGLIB_INCLUDED_ -#endif //HAVE_JPEGLIB_H -#endif //HAVE_LIBJPEG - -// Win32 support may be broken since it was only tested in an older version for Watcom C -#ifdef __NT__ -# include -# include -# include -# ifdef DEBUG_RFXSWF -# include -# endif -#else -#endif +#endif // HAVE_JPEGLIB_H +#endif // HAVE_LIBJPEG + +#ifdef HAVE_LIBZ +#ifdef HAVE_ZLIB_H +#include +#define _ZLIB_INCLUDED_ +#endif // HAVE_ZLIB_H +#endif // HAVE_LIBZ + +#define LAME +#include "lame/lame.h" + +#include "./bitio.h" // internal constants @@ -39,36 +43,37 @@ #define MEMSIZE(l) (((l/MALLOC_SIZE)+1)*MALLOC_SIZE) + // inline wrapper functions -TAG * NextTag(TAG * t) { return t->next; } -TAG * PrevTag(TAG * t) { return t->prev; } -int GetFrameNo(TAG * t) { return t->frame; } -U16 GetTagID(TAG * t) { return t->id; } -U32 GetDataSize(TAG * t) { return t->len; } -U8* GetDataSizePtr(TAG * t) { return &(t->data[t->len]); } -U32 GetTagPos(TAG * t) { return t->pos; } +TAG * swf_NextTag(TAG * t) { return t->next; } +TAG * swf_PrevTag(TAG * t) { return t->prev; } +int swf_GetFrameNo(TAG * t) { return t->frame; } +U16 swf_GetTagID(TAG * t) { return t->id; } +U32 swf_GetTagLen(TAG * t) { return t->len; } +U8* swf_GetTagLenPtr(TAG * t) { return &(t->data[t->len]); } +U32 swf_GetTagPos(TAG * t) { return t->pos; } // Basic Data Access Functions -#define ResetBitmask(tag) if (tag->bitmask) { tag->pos++; tag->bitmask = 0; } -#define ResetBitcount(tag) if (tag->bitcount) { tag->bitcount = 0; } +#define swf_ResetReadBits(tag) if (tag->readBit) { tag->pos++; tag->readBit = 0; } +#define swf_ResetWriteBits(tag) if (tag->writeBit) { tag->writeBit = 0; } -// for future purpose: avoid high level lib functions to change tagpos/bitcount +// for future purpose: avoid high level lib functions to change tagpos/bitpos -#define SaveTagPos(tag) -#define RestoreTagPos(tag) +#define swf_SaveTagPos(tag) +#define swf_RestoreTagPos(tag) -void SetTagPos(TAG * t,U32 pos) -{ ResetBitmask(t); +void swf_SetTagPos(TAG * t,U32 pos) +{ swf_ResetReadBits(t); if (pos<=t->len) t->pos = pos; #ifdef DEBUG_RFXSWF else fprintf(stderr,"SetTagPos() out of bounds: TagID = %i\n",t->id); #endif } -U8 GetU8(TAG * t) -{ ResetBitmask(t); +U8 swf_GetU8(TAG * t) +{ swf_ResetReadBits(t); #ifdef DEBUG_RFXSWF if (t->pos>=t->len) { fprintf(stderr,"GetU8() out of bounds: TagID = %i\n",t->id); @@ -78,9 +83,9 @@ U8 GetU8(TAG * t) return t->data[t->pos++]; } -U16 GetU16(TAG * t) +U16 swf_GetU16(TAG * t) { U16 res; - ResetBitmask(t); + swf_ResetReadBits(t); #ifdef DEBUG_RFXSWF if (t->pos>(t->len-2)) { fprintf(stderr,"GetU16() out of bounds: TagID = %i\n",t->id); @@ -92,9 +97,9 @@ U16 GetU16(TAG * t) return res; } -U32 GetU32(TAG * t) +U32 swf_GetU32(TAG * t) { U32 res; - ResetBitmask(t); + swf_ResetReadBits(t); #ifdef DEBUG_RFXSWF if (t->pos>(t->len-4)) { fprintf(stderr,"GetU32() out of bounds: TagID = %i\n",t->id); @@ -107,27 +112,28 @@ U32 GetU32(TAG * t) return res; } -int GetBlock(TAG * t,U8 * b,int l) +int swf_GetBlock(TAG * t,U8 * b,int l) // returns number of bytes written (<=l) // b = NULL -> skip data -{ ResetBitmask(t); +{ swf_ResetReadBits(t); if ((t->len-t->pos)len-t->pos; if (b && l) memcpy(b,&t->data[t->pos],l); t->pos+=l; return l; } -int SetBlock(TAG * t,U8 * b,int l) +int swf_SetBlock(TAG * t,U8 * b,int l) // Appends Block to the end of Tagdata, returns size { U32 newlen = t->len + l; - ResetBitcount(t); + swf_ResetWriteBits(t); if (newlen>t->memsize) { U32 newmem = MEMSIZE(newlen); U8 * newdata = (U8*)((t->data)?realloc(t->data,newmem):malloc(newmem)); if (!newdata) { #ifdef DEBUG_RFXSWF - fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n"); + fprintf(stderr,"Fatal Error: malloc()/realloc() failed (1). (%d bytes)\n", newmem); + *(int*)0=0; #endif return 0; } @@ -140,34 +146,34 @@ int SetBlock(TAG * t,U8 * b,int l) return l; } -int SetU8(TAG * t,U8 v) -{ ResetBitcount(t); - if ((t->len+1)>t->memsize) return (SetBlock(t,&v,1)==1)?0:-1; +int swf_SetU8(TAG * t,U8 v) +{ swf_ResetWriteBits(t); + if ((t->len+1)>t->memsize) return (swf_SetBlock(t,&v,1)==1)?0:-1; t->data[t->len++] = v; return 0; } -int SetU16(TAG * t,U16 v) +int swf_SetU16(TAG * t,U16 v) { U8 a[2]; a[0] = v&0xff; a[1] = v>>8; - ResetBitcount(t); - if ((t->len+2)>t->memsize) return (SetBlock(t,a,2)==2)?0:-1; + swf_ResetWriteBits(t); + if ((t->len+2)>t->memsize) return (swf_SetBlock(t,a,2)==2)?0:-1; t->data[t->len++] = a[0]; t->data[t->len++] = a[1]; return 0; } -int SetU32(TAG * t,U32 v) +int swf_SetU32(TAG * t,U32 v) { U8 a[4]; a[0] = v&0xff; // to ensure correct handling of non-intel byteorder a[1] = (v>>8)&0xff; a[2] = (v>>16)&0xff; a[3] = (v>>24)&0xff; - ResetBitcount(t); - if ((t->len+4)>t->memsize) return (SetBlock(t,a,4)==4)?0:-1; + swf_ResetWriteBits(t); + if ((t->len+4)>t->memsize) return (swf_SetBlock(t,a,4)==4)?0:-1; t->data[t->len++] = a[0]; t->data[t->len++] = a[1]; t->data[t->len++] = a[2]; @@ -175,17 +181,17 @@ int SetU32(TAG * t,U32 v) return 0; } -U32 GetBits(TAG * t,int nbits) +U32 swf_GetBits(TAG * t,int nbits) { U32 res = 0; if (!nbits) return 0; - if (!t->bitmask) t->bitmask = 0x80; + if (!t->readBit) t->readBit = 0x80; while (nbits) { res<<=1; - if (t->data[t->pos]&t->bitmask) res|=1; - t->bitmask>>=1; + if (t->data[t->pos]&t->readBit) res|=1; + t->readBit>>=1; nbits--; - if (!t->bitmask) - { if (nbits) t->bitmask = 0x80; + if (!t->readBit) + { if (nbits) t->readBit = 0x80; #ifdef DEBUG_RFXSWF if (t->pos>=t->len) { fprintf(stderr,"GetBits() out of bounds: TagID = %i\n",t->id); @@ -198,23 +204,32 @@ U32 GetBits(TAG * t,int nbits) return res; } -S32 GetSBits(TAG * t,int nbits) -{ U32 res = GetBits(t,nbits); +S32 swf_GetSBits(TAG * t,int nbits) +{ U32 res = swf_GetBits(t,nbits); + if (res&(1<<(nbits-1))) res|=(0xffffffff<bitcount) - { if (FAILED(SetU8(t,0))) return -1; - t->bitcount = 0x80; + { if (!t->writeBit) + { if (FAILED(swf_SetU8(t,0))) return -1; + t->writeBit = 0x80; } - if (v&bm) t->data[t->len-1] |= t->bitcount; + if (v&bm) t->data[t->len-1] |= t->writeBit; bm>>=1; - t->bitcount>>=1; + t->writeBit>>=1; nbits--; } return 0; @@ -222,28 +237,91 @@ int SetBits(TAG * t,U32 v,int nbits) // Advanced Data Access Functions -int SetRGB(TAG * t,RGBA * col) +int swf_SetRGB(TAG * t,RGBA * col) { if (!t) return -1; if (col) - { SetU8(t,col->r); - SetU8(t,col->g); - SetU8(t,col->b); - } else SetBlock(t,NULL,3); + { swf_SetU8(t,col->r); + swf_SetU8(t,col->g); + swf_SetU8(t,col->b); + } else swf_SetBlock(t,NULL,3); return 0; } +void swf_GetRGB(TAG * t, RGBA * col) +{ + RGBA dummy; + if(!col); + col = &dummy; + col->r = swf_GetU8(t); + col->g = swf_GetU8(t); + col->b = swf_GetU8(t); + col->a = 255; +} -int SetRGBA(TAG * t,RGBA * col) +int swf_SetRGBA(TAG * t,RGBA * col) { if (!t) return -1; if (col) - { SetU8(t,col->r); - SetU8(t,col->g); - SetU8(t,col->b); - SetU8(t,col->a); - } else SetBlock(t,NULL,4); + { swf_SetU8(t,col->r); + swf_SetU8(t,col->g); + swf_SetU8(t,col->b); + swf_SetU8(t,col->a); + } else swf_SetBlock(t,NULL,4); return 0; } +void swf_GetRGBA(TAG * t, RGBA * col) +{ + RGBA dummy; + if(!col); + col = &dummy; + col->r = swf_GetU8(t); + col->g = swf_GetU8(t); + col->b = swf_GetU8(t); + col->a = swf_GetU8(t); +} + +void swf_GetGradient(TAG * tag, GRADIENT * gradient, char alpha) +{ + GRADIENT dummy; + int t; + if(!gradient) + gradient = &dummy; + gradient->num = swf_GetU8(tag); + for(t=0;tnum;t++) + { + int s=t; + if(s>=8) //FIXME + s=7; + gradient->ratios[t] = swf_GetU8(tag); + if(!alpha) + swf_GetRGB(tag, &gradient->rgba[t]); + else + swf_GetRGBA(tag, &gradient->rgba[t]); + } +} -int CountBits(U32 v,int nbits) +void swf_GetMorphGradient(TAG * tag, GRADIENT * gradient1, GRADIENT * gradient2) +{ + GRADIENT dummy1; + GRADIENT dummy2; + int t; + if(!gradient1) + gradient1 = &dummy1; + if(!gradient2) + gradient2 = &dummy2; + gradient1->num = + gradient2->num = swf_GetU8(tag); + for(t=0;tnum;t++) + { + int s=t; + if(s>=8) //FIXME + s=7; + gradient1->ratios[t] = swf_GetU8(tag); + swf_GetRGBA(tag, &gradient1->rgba[t]); + gradient2->ratios[t] = swf_GetU8(tag); + swf_GetRGBA(tag, &gradient2->rgba[t]); + } +} + +int swf_CountBits(U32 v,int nbits) { int n = 33; U32 m = 0x80000000; if (!v) n = 0; else @@ -264,36 +342,48 @@ int CountBits(U32 v,int nbits) return (n>nbits)?n:nbits; } -int GetRect(TAG * t,SRECT * r) +int swf_GetRect(TAG * t,SRECT * r) { int nbits; SRECT dummy; if (!r) r = &dummy; - nbits = (int) GetBits(t,5); - r->xmin = GetSBits(t,nbits); - r->xmax = GetSBits(t,nbits); - r->ymin = GetSBits(t,nbits); - r->ymax = GetSBits(t,nbits); + nbits = (int) swf_GetBits(t,5); + r->xmin = swf_GetSBits(t,nbits); + r->xmax = swf_GetSBits(t,nbits); + r->ymin = swf_GetSBits(t,nbits); + r->ymax = swf_GetSBits(t,nbits); return 0; } -int SetRect(TAG * t,SRECT * r) +int reader_GetRect(struct reader_t*reader,SRECT * r) +{ int nbits; + SRECT dummy; + if (!r) r = &dummy; + nbits = (int) reader_GetBits(reader,5); + r->xmin = reader_GetSBits(reader,nbits); + r->xmax = reader_GetSBits(reader,nbits); + r->ymin = reader_GetSBits(reader,nbits); + r->ymax = reader_GetSBits(reader,nbits); + return 0; +} + +int swf_SetRect(TAG * t,SRECT * r) { int nbits; - nbits = CountBits(r->xmin,0); - nbits = CountBits(r->xmax,nbits); - nbits = CountBits(r->ymin,nbits); - nbits = CountBits(r->ymax,nbits); + nbits = swf_CountBits(r->xmin,0); + nbits = swf_CountBits(r->xmax,nbits); + nbits = swf_CountBits(r->ymin,nbits); + nbits = swf_CountBits(r->ymax,nbits); - SetBits(t,nbits,5); - SetBits(t,r->xmin,nbits); - SetBits(t,r->xmax,nbits); - SetBits(t,r->ymin,nbits); - SetBits(t,r->ymax,nbits); + swf_SetBits(t,nbits,5); + swf_SetBits(t,r->xmin,nbits); + swf_SetBits(t,r->xmax,nbits); + swf_SetBits(t,r->ymin,nbits); + swf_SetBits(t,r->ymax,nbits); return 0; } -int GetMatrix(TAG * t,MATRIX * m) +int swf_GetMatrix(TAG * t,MATRIX * m) { MATRIX dummy; int nbits; @@ -306,30 +396,30 @@ int GetMatrix(TAG * t,MATRIX * m) return -1; } - ResetBitmask(t); + swf_ResetReadBits(t); - if (GetBits(t,1)) - { nbits = GetBits(t,5); - m->sx = GetSBits(t,nbits); - m->sy = GetSBits(t,nbits); + if (swf_GetBits(t,1)) + { nbits = swf_GetBits(t,5); + m->sx = swf_GetSBits(t,nbits); + m->sy = swf_GetSBits(t,nbits); } else m->sx = m->sy = 0x10000; - if (GetBits(t,1)) - { nbits = GetBits(t,5); - m->r0 = GetSBits(t,nbits); - m->r1 = GetSBits(t,nbits); + if (swf_GetBits(t,1)) + { nbits = swf_GetBits(t,5); + m->r0 = swf_GetSBits(t,nbits); + m->r1 = swf_GetSBits(t,nbits); } else m->r0 = m->r1 = 0x0; - nbits = GetBits(t,5); - m->tx = GetSBits(t,nbits); - m->ty = GetSBits(t,nbits); + nbits = swf_GetBits(t,5); + m->tx = swf_GetSBits(t,nbits); + m->ty = swf_GetSBits(t,nbits); return 0; } -int SetMatrix(TAG * t,MATRIX * m) +int swf_SetMatrix(TAG * t,MATRIX * m) { int nbits; MATRIX ma; @@ -340,38 +430,50 @@ int SetMatrix(TAG * t,MATRIX * m) ma.tx = ma.ty = 0; } - ResetBitcount(t); + swf_ResetWriteBits(t); - if ((m->sx==0x10000)&&(m->sy==0x10000)) SetBits(t,0,1); + if ((m->sx==0x10000)&&(m->sy==0x10000)) swf_SetBits(t,0,1); else - { SetBits(t,1,1); - nbits = CountBits(m->sx,0); - nbits = CountBits(m->sy,nbits); - SetBits(t,nbits,5); - SetBits(t,m->sx,nbits); - SetBits(t,m->sy,nbits); + { swf_SetBits(t,1,1); + nbits = swf_CountBits(m->sx,0); + nbits = swf_CountBits(m->sy,nbits); + if(nbits>=32) { + fprintf(stderr,"rfxswf: Error: matrix values too large\n"); + nbits = 31; + } + swf_SetBits(t,nbits,5); + swf_SetBits(t,m->sx,nbits); + swf_SetBits(t,m->sy,nbits); } - if ((!m->r0)&&(!m->r1)) SetBits(t,0,1); + if ((!m->r0)&&(!m->r1)) swf_SetBits(t,0,1); else - { SetBits(t,1,1); - nbits = CountBits(m->r0,0); - nbits = CountBits(m->r1,nbits); - SetBits(t,nbits,5); - SetBits(t,m->r0,nbits); - SetBits(t,m->r1,nbits); + { swf_SetBits(t,1,1); + nbits = swf_CountBits(m->r0,0); + nbits = swf_CountBits(m->r1,nbits); + if(nbits>=32) { + fprintf(stderr,"rfxswf: Error: matrix values too large\n"); + nbits = 31; + } + swf_SetBits(t,nbits,5); + swf_SetBits(t,m->r0,nbits); + swf_SetBits(t,m->r1,nbits); } - nbits = CountBits(m->tx,0); - nbits = CountBits(m->ty,nbits); - SetBits(t,nbits,5); - SetBits(t,m->tx,nbits); - SetBits(t,m->ty,nbits); + nbits = swf_CountBits(m->tx,0); + nbits = swf_CountBits(m->ty,nbits); + if(nbits>=32) { + fprintf(stderr,"rfxswf: Error: matrix values too large\n"); + nbits = 31; + } + swf_SetBits(t,nbits,5); + swf_SetBits(t,m->tx,nbits); + swf_SetBits(t,m->ty,nbits); return 0; } -int GetCXForm(TAG * t,CXFORM * cx,U8 alpha) //FIXME: alpha should be type bool +int swf_GetCXForm(TAG * t,CXFORM * cx,U8 alpha) //FIXME: alpha should be type bool { CXFORM cxf; int hasadd; int hasmul; @@ -384,31 +486,31 @@ int GetCXForm(TAG * t,CXFORM * cx,U8 alpha) //FIXME: alpha should be type bool if (!t) return 0; - ResetBitmask(t); - hasadd = GetBits(t,1); - hasmul = GetBits(t,1); - nbits = GetBits(t,4); + swf_ResetReadBits(t); + hasadd = swf_GetBits(t,1); + hasmul = swf_GetBits(t,1); + nbits = swf_GetBits(t,4); if (hasmul) - { cx->r0 = (S16)GetSBits(t,nbits); - cx->g0 = (S16)GetSBits(t,nbits); - cx->b0 = (S16)GetSBits(t,nbits); + { cx->r0 = (S16)swf_GetSBits(t,nbits); + cx->g0 = (S16)swf_GetSBits(t,nbits); + cx->b0 = (S16)swf_GetSBits(t,nbits); if (alpha) - cx->a0 = (S16)GetSBits(t,nbits); + cx->a0 = (S16)swf_GetSBits(t,nbits); } if (hasadd) - { cx->r1 = (S16)GetSBits(t,nbits); - cx->g1 = (S16)GetSBits(t,nbits); - cx->b1 = (S16)GetSBits(t,nbits); + { cx->r1 = (S16)swf_GetSBits(t,nbits); + cx->g1 = (S16)swf_GetSBits(t,nbits); + cx->b1 = (S16)swf_GetSBits(t,nbits); if (alpha) - cx->a1 = (S16)GetSBits(t,nbits); + cx->a1 = (S16)swf_GetSBits(t,nbits); } return 0; } -int SetCXForm(TAG * t,CXFORM * cx,U8 alpha) +int swf_SetCXForm(TAG * t,CXFORM * cx,U8 alpha) { CXFORM cxf; int hasadd; int hasmul; @@ -431,47 +533,47 @@ int SetCXForm(TAG * t,CXFORM * cx,U8 alpha) hasadd = cx->a1|cx->r1|cx->g1|cx->b1; if (hasmul) - { if (alpha) nbits = CountBits((S32)cx->a0,nbits); - nbits = CountBits((S32)cx->r0,nbits); - nbits = CountBits((S32)cx->g0,nbits); - nbits = CountBits((S32)cx->b0,nbits); + { if (alpha) nbits = swf_CountBits((S32)cx->a0,nbits); + nbits = swf_CountBits((S32)cx->r0,nbits); + nbits = swf_CountBits((S32)cx->g0,nbits); + nbits = swf_CountBits((S32)cx->b0,nbits); } if (hasadd) - { if (alpha) nbits = CountBits((S32)cx->a1,nbits); - nbits = CountBits((S32)cx->r1,nbits); - nbits = CountBits((S32)cx->g1,nbits); - nbits = CountBits((S32)cx->b1,nbits); + { if (alpha) nbits = swf_CountBits((S32)cx->a1,nbits); + nbits = swf_CountBits((S32)cx->r1,nbits); + nbits = swf_CountBits((S32)cx->g1,nbits); + nbits = swf_CountBits((S32)cx->b1,nbits); } - ResetBitcount(t); - SetBits(t,hasadd?1:0,1); - SetBits(t,hasmul?1:0,1); - SetBits(t,nbits,4); + swf_ResetWriteBits(t); + swf_SetBits(t,hasadd?1:0,1); + swf_SetBits(t,hasmul?1:0,1); + swf_SetBits(t,nbits,4); if (hasmul) - { SetBits(t,cx->r0,nbits); - SetBits(t,cx->g0,nbits); - SetBits(t,cx->b0,nbits); - if (alpha) SetBits(t,cx->a0,nbits); + { swf_SetBits(t,cx->r0,nbits); + swf_SetBits(t,cx->g0,nbits); + swf_SetBits(t,cx->b0,nbits); + if (alpha) swf_SetBits(t,cx->a0,nbits); } if (hasadd) - { SetBits(t,cx->r1,nbits); - SetBits(t,cx->g1,nbits); - SetBits(t,cx->b1,nbits); - if (alpha) SetBits(t,cx->a1,nbits); + { swf_SetBits(t,cx->r1,nbits); + swf_SetBits(t,cx->g1,nbits); + swf_SetBits(t,cx->b1,nbits); + if (alpha) swf_SetBits(t,cx->a1,nbits); } return 0; } -int GetPoint(TAG * t,SPOINT * p) { return 0; } -int SetPoint(TAG * t,SPOINT * p) { return 0; } +int swf_GetPoint(TAG * t,SPOINT * p) { return 0; } +int swf_SetPoint(TAG * t,SPOINT * p) { return 0; } // Tag List Manipulating Functions -int RFXSWF_UpdateFrame(TAG * t,S8 delta) +int swf_UpdateFrame(TAG * t,S8 delta) // returns number of frames { int res = -1; while (t) @@ -482,16 +584,13 @@ int RFXSWF_UpdateFrame(TAG * t,S8 delta) return res; } -#define UpdateFrame(a,b) RFXSWF_UpdateFrame(a,b) - -TAG * InsertTag(TAG * after,U16 id) // updates frames, if nescessary +TAG * swf_InsertTag(TAG * after,U16 id) // updates frames, if nescessary { TAG * t; t = (TAG *)malloc(sizeof(TAG)); if (t) { memset(t,0x00,sizeof(TAG)); t->id = id; - t->bitcount = 0x80; if (after) { t->frame = after->frame; @@ -500,16 +599,16 @@ TAG * InsertTag(TAG * after,U16 id) // updates frames, if nescessary after->next = t; if (t->next) t->next->prev = t; - if (id==ST_SHOWFRAME) UpdateFrame(t->next,+1); + if (id==ST_SHOWFRAME) swf_UpdateFrame(t->next,+1); } } return t; } -int DeleteTag(TAG * t) +int swf_DeleteTag(TAG * t) { if (!t) return -1; - if (t->id==ST_SHOWFRAME) UpdateFrame(t->next,-1); + if (t->id==ST_SHOWFRAME) swf_UpdateFrame(t->next,-1); if (t->prev) t->prev->next = t->next; if (t->next) t->next->prev = t->prev; @@ -519,19 +618,22 @@ int DeleteTag(TAG * t) return 0; } -TAG * RFXSWF_ReadTag(int handle,TAG * prev) +TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) { TAG * t; U16 raw; U32 len; int id; - if (read(handle,&raw,2)!=2) return NULL; + if (reader->read(reader, &raw, 2) !=2 ) return NULL; + raw = SWAP16(raw); len = raw&0x3f; id = raw>>6; if (len==0x3f) - { if (read(handle,&len,4)!=4) return NULL; + { + if (reader->read(reader, &len, 4) != 4) return NULL; + len = SWAP32(len); } if (id==ST_DEFINESPRITE) len = 2*sizeof(U16); @@ -542,7 +644,7 @@ TAG * RFXSWF_ReadTag(int handle,TAG * prev) if (!t) { #ifdef DEBUG_RFXSWF - fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n"); + fprintf(stderr,"Fatal Error: malloc()/realloc() failed (2). (%d bytes)\n", sizeof(TAG)); #endif return NULL; } @@ -557,12 +659,12 @@ TAG * RFXSWF_ReadTag(int handle,TAG * prev) if (!t->data) { #ifdef DEBUG_RFXSWF - fprintf(stderr,"Fatal Error: malloc()/realloc() failed.\n"); + fprintf(stderr,"Fatal Error: malloc()/realloc() failed (3). (%d bytes)\n", t->len); #endif return NULL; } t->memsize = t->len; - if (read(handle,t->data,t->len)!=t->len) return NULL; + if (reader->read(reader, t->data, t->len) != t->len) return NULL; } if (prev) @@ -574,25 +676,25 @@ TAG * RFXSWF_ReadTag(int handle,TAG * prev) return t; } -int DefineSprite_GetRealSize(TAG * t); +int swf_DefineSprite_GetRealSize(TAG * t); -int RFXSWF_WriteTag(int handle,TAG * t) +int swf_WriteTag2(struct writer_t*writer, TAG * t) // returns tag length in bytes (incl. Header), -1 = Error -// handle = -1 -> no output +// writer = 0 -> no output { U16 raw[3]; U32 len; int short_tag; if (!t) return -1; - len = (t->id==ST_DEFINESPRITE)?DefineSprite_GetRealSize(t):t->len; + len = (t->id==ST_DEFINESPRITE)?swf_DefineSprite_GetRealSize(t):t->len; short_tag = len<0x3f; - if (handle>=0) + if (writer) { if (short_tag) - { raw[0] = len|((t->id&0x3ff)<<6); - if (write(handle,raw,2)!=2) + { raw[0] = SWAP16(len|((t->id&0x3ff)<<6)); + if (writer->write(writer,raw,2)!=2) { #ifdef DEBUG_RFXSWF fprintf(stderr,"WriteTag() failed: Short Header.\n"); @@ -601,20 +703,28 @@ int RFXSWF_WriteTag(int handle,TAG * t) } } else - { raw[0] = (t->id<<6)|0x3f; - raw[1] = (U16)(len&0xffff); - raw[2] = (U16)(len>>16); - if (write(handle,raw,6)!=6) + { + raw[0] = SWAP16((t->id<<6)|0x3f); + if (writer->write(writer,raw,2)!=2) + { +#ifdef DEBUG_RFXSWF + fprintf(stderr,"WriteTag() failed: Long Header (1).\n"); +#endif + return -1; + } + + len = SWAP32(len); + if (writer->write(writer,&len,4)!=4) { #ifdef DEBUG_RFXSWF - fprintf(stderr,"WriteTag() failed: Long Header.\n"); + fprintf(stderr,"WriteTag() failed: Long Header (2).\n"); #endif return -1; } } if (t->data) - { if (write(handle,t->data,t->len)!=t->len) + { if (writer->write(writer,t->data,t->len)!=t->len) { #ifdef DEBUG_RFXSWF fprintf(stderr,"WriteTag() failed: Data.\n"); @@ -630,61 +740,149 @@ int RFXSWF_WriteTag(int handle,TAG * t) return t->len+(short_tag?2:6); } -int DefineSprite_GetRealSize(TAG * t) +int swf_WriteTag(int handle, TAG * t) +{ + struct writer_t writer; + if(handle<0) + return swf_WriteTag2(0, t); + writer_init_filewriter(&writer, handle); + return swf_WriteTag2(&writer, t); +} + +int swf_DefineSprite_GetRealSize(TAG * t) // Sprite Handling: Helper function to pack DefineSprite-Tag { U32 len = t->len; + if(len>4) { // folded sprite + return t->len; + } do - { t = NextTag(t); - if (t->id!=ST_DEFINESPRITE) len += RFXSWF_WriteTag(-1,t); + { t = swf_NextTag(t); + if (t->id!=ST_DEFINESPRITE) len += swf_WriteTag(-1, t); else t = NULL; } while (t&&(t->id!=ST_END)); return len; } -#define ReadTag(a,b) RFXSWF_ReadTag(a,b) -#define WriteTag(a,b) RFXSWF_WriteTag(a,b) +void swf_FoldSprite(TAG * t) +{ + TAG*sprtag=t,*tmp; + U16 id,frames,tmpid; + if(t->id!=ST_DEFINESPRITE) + return; + if(!t->len) { + fprintf(stderr, "Error: Sprite has no ID!"); + return; + } + if(t->len>4) { + /* sprite is already folded */ + return; + } + + 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; + + do + { + if(t->id==ST_SHOWFRAME) frames++; + t = swf_NextTag(t); + } while(t&&t!=ST_END); + + t = swf_NextTag(sprtag); + swf_SetU16(sprtag, id); + swf_SetU16(sprtag, frames); + + do + { + tmpid= t->id; + if(t->len<0x3f) { + swf_SetU16(sprtag,t->len|(t->id<<6)); + } else { + swf_SetU16(sprtag,0x3f|(t->id<<6)); + swf_SetU32(sprtag,t->len); + } + if(t->len) + swf_SetBlock(sprtag,t->data, t->len); + tmp = t; + t = swf_NextTag(t); + swf_DeleteTag(tmp); + } + while (t&&(tmpid!=ST_END)); + +// sprtag->next = t; +// t->prev = sprtag; +} + +void swf_FoldAll(SWF*swf) +{ + TAG*tag = swf->firstTag; + while(tag) { + if(tag->id == ST_DEFINESPRITE) + swf_FoldSprite(tag); + tag = swf_NextTag(tag); + } +} // Movie Functions -int ReadSWF(int handle,SWF * swf) // Reads SWF to memory (malloc'ed), returns length or <0 if fails +int swf_ReadSWF2(struct reader_t*reader, SWF * swf) // Reads SWF to memory (malloc'ed), returns length or <0 if fails { if (!swf) return -1; memset(swf,0x00,sizeof(SWF)); - { char b[32]; // Header lesen - TAG t1; + { char b[32]; // read Header + int len; TAG * t; + TAG t1; + struct reader_t zreader; - memset(&t1,0x00,sizeof(TAG)); + if ((len = reader->read(reader ,b,8))<8) return -1; + + if (b[0]!='F' && b[0]!='C') return -1; + if (b[1]!='W') return -1; + if (b[2]!='S') return -1; + swf->fileVersion = b[3]; + swf->compressed = (b[0]=='C')?1:0; + swf->fileSize = GET32(&b[4]); - if ((t1.len=read(handle,b,32))<21) return -1; - t1.data = (U8*)b; - - if (GetU8(&t1)!=(U8)'F') return -1; - if (GetU8(&t1)!=(U8)'W') return -1; - if (GetU8(&t1)!=(U8)'S') return -1; + if(swf->compressed) { + reader_init_zlibinflate(&zreader, reader); + reader = &zreader; + } - swf->FileVersion = GetU8(&t1); - swf->FileSize = GetU32(&t1); - GetRect(&t1,&swf->MovieSize); - swf->FrameRate = GetU16(&t1); - swf->FrameCount = GetU16(&t1); + reader_GetRect(reader, &swf->movieSize); + reader->read(reader, &swf->frameRate, 2); + swf->frameRate = SWAP16(swf->frameRate); + reader->read(reader, &swf->frameCount, 2); + swf->frameCount = SWAP16(swf->frameCount); - GetU8(&t1); - lseek(handle,GetTagPos(&t1)-1,SEEK_SET); - - // Tags lesen und verketten + /* read tags and connect to list */ t = &t1; - while (t) t = ReadTag(handle,t); - swf->FirstTag = t1.next; + while (t) t = swf_ReadTag(reader,t); + swf->firstTag = t1.next; t1.next->prev = NULL; } - return 0; + return reader->pos; } -int WriteSWF(int handle,SWF * swf) // Writes SWF to file, returns length or <0 if fails + +int swf_ReadSWF(int handle, SWF * swf) +{ + struct reader_t reader; + reader_init_filereader(&reader, handle); + return swf_ReadSWF2(&reader, swf); +} + +int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, returns length or <0 if fails { U32 len; TAG * t; + int frameCount=0; + struct writer_t zwriter; if (!swf) return -1; @@ -692,75 +890,136 @@ int WriteSWF(int handle,SWF * swf) // Writes SWF to file, returns length or #ifdef INSERT_RFX_TAG - if (NextTag(swf->FirstTag)) - if (GetTagID(NextTag(swf->FirstTag))!=ST_REFLEX) - SetBlock(InsertTag(swf->FirstTag,ST_REFLEX),"rfx",3); + if (swf->firstTag && swf_NextTag(swf->firstTag)) + if (swf_GetTagID(swf_NextTag(swf->firstTag))!=ST_REFLEX) + swf_SetBlock(swf_InsertTag(swf->firstTag,ST_REFLEX),"rfx",3); #endif // INSERT_RFX_TAG // Count Frames + File Size len = 0; - t = swf->FirstTag; - swf->FrameCount = 0; + t = swf->firstTag; + frameCount = 0; while(t) - { len += WriteTag(-1,t); - if (t->id==ST_SHOWFRAME) swf->FrameCount++; - t = NextTag(t); + { len += swf_WriteTag(-1, t); + if (t->id==ST_SHOWFRAME) frameCount++; + t = swf_NextTag(t); } { TAG t1; - char b[64]; + char b[64],b4[4]; U32 l; memset(&t1,0x00,sizeof(TAG)); t1.data = (U8*)b; t1.memsize = 64; - SetU8(&t1,'F'); - SetU8(&t1,'W'); - SetU8(&t1,'S'); - SetU8(&t1,swf->FileVersion); - - SetU32(&t1,0); // Keep space for filesize - SetRect(&t1,&swf->MovieSize); - SetU16(&t1,swf->FrameRate); - SetU16(&t1,swf->FrameCount); + { // measure header file size + TAG t2; + char b2[64]; + memset(&t2,0x00,sizeof(TAG)); + t2.data = (U8*)b2; + t2.memsize = 64; + swf_SetRect(&t2, &swf->movieSize); + swf_SetU16(&t2, swf->frameRate); + swf_SetU16(&t2, swf->frameCount); + l = swf_GetTagLen(&t2)+8; + } - l = GetDataSize(&t1); - swf->FileSize = l+len; - t1.len = 4; // bad & ugly trick ! - SetU32(&t1,swf->FileSize); + if(len) {// don't touch headers without tags + swf->fileSize = l+len; + swf->frameCount = frameCount; + } + + if(swf->compressed) { + char*id = "CWS"; + writer->write(writer, id, 3); + } + else { + char*id = "FWS"; + writer->write(writer, id, 3); + } + + writer->write(writer, &swf->fileVersion, 1); + PUT32(b4, swf->fileSize); + writer->write(writer, b4, 4); + + if(swf->compressed) { + writer_init_zlibdeflate(&zwriter, writer); + writer = &zwriter; + } - if (handle>=0) + swf_SetRect(&t1,&swf->movieSize); + swf_SetU16(&t1,swf->frameRate); + swf_SetU16(&t1,swf->frameCount); + + if (writer) { - int ret = write(handle,b,l); - if (ret!=l) + int ret = writer->write(writer,b,swf_GetTagLen(&t1)); + if (ret!=swf_GetTagLen(&t1)) { #ifdef DEBUG_RFXSWF - printf("ret:%d (fd:%d)\n",ret, handle); - perror("write:"); + printf("ret:%d\n",ret); + perror("write:"); fprintf(stderr,"WriteSWF() failed: Header.\n"); #endif return -1; } - t = swf->FirstTag; + t = swf->firstTag; while (t) - { if (WriteTag(handle,t)<0) return -1; - t = NextTag(t); + { if (swf_WriteTag2(writer, t)<0) return -1; + t = swf_NextTag(t); } + writer->finish(writer); //e.g. flush zlib buffers } } - return (int)swf->FileSize; + return (int)swf->fileSize; +} + +int swf_WriteSWF(int handle, SWF * swf) // Writes SWF to file, returns length or <0 if fails +{ + struct writer_t writer; + swf->compressed = 0; + if(handle<0) + return swf_WriteSWF2(&writer, swf); + writer_init_filewriter(&writer, handle); + return swf_WriteSWF2(&writer, swf); +} + +int swf_WriteSWC(int handle, SWF * swf) // Writes SWF to file, returns length or <0 if fails +{ + struct writer_t writer; + swf->compressed = 1; + if(handle<0) + return swf_WriteSWF2(&writer, swf); + writer_init_filewriter(&writer, handle); + return swf_WriteSWF2(&writer, swf); } -int WriteCGI(SWF * swf) +int swf_WriteHeader2(struct writer_t*writer,SWF * swf) +{ + SWF myswf; + memcpy(&myswf,swf,sizeof(SWF)); + myswf.firstTag = 0; + return swf_WriteSWF2(writer, &myswf); +} + +int swf_WriteHeader(int handle,SWF * swf) +{ + SWF myswf; + memcpy(&myswf,swf,sizeof(SWF)); + myswf.firstTag = 0; + return swf_WriteSWF(handle, &myswf); +} + +int swf_WriteCGI(SWF * swf) { int len; char s[1024]; - len = WriteSWF(-1,swf); + len = swf_WriteSWF(-1,swf); if (len<0) return -1; @@ -771,11 +1030,11 @@ int WriteCGI(SWF * swf) "\n",len); write(fileno(stdout),s,strlen(s)); - return WriteSWF(fileno(stdout),swf); + return swf_WriteSWF(fileno(stdout),swf); } -void FreeTags(SWF * swf) // Frees all malloc'ed memory for tags -{ TAG * t = swf->FirstTag; +void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for tags +{ TAG * t = swf->firstTag; while (t) { TAG * tnew = t->next; @@ -787,19 +1046,6 @@ void FreeTags(SWF * swf) // Frees all malloc'ed memory for tags // include advanced functions -#ifdef __NT__ - -#include "modules\swfdump.c" -#include "modules\swfshape.c" -#include "modules\swftext.c" -#include "modules\swfobject.c" -#include "modules\swfbutton.c" -#include "modules\swftools.c" -#include "modules\swfcgi.c" -#include "modules\swfbits.c" - -#else - #include "modules/swfdump.c" #include "modules/swfshape.c" #include "modules/swftext.c" @@ -808,7 +1054,6 @@ void FreeTags(SWF * swf) // Frees all malloc'ed memory for tags #include "modules/swftools.c" #include "modules/swfcgi.c" #include "modules/swfbits.c" - -#endif - +#include "modules/swfaction.c" +#include "modules/swfsound.c"