X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Frfxswf.c;h=7824deec67ae310757fe9adac934e2290145930e;hb=80c5ca6a38fdb2d948c9db114ee648af63ef6c67;hp=70b2dbcb2537dcccd933499dde92f58073f89867;hpb=0c0096d3d1a78c2d6dd2874125b528c4a2f72049;p=swftools.git diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 70b2dbc..7824dee 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -1,4 +1,4 @@ -/* vi:sts=2 sw=2 */ +/* vi: set sts=2 sw=2 :*/ /* rfxswf.c @@ -31,6 +31,11 @@ #endif // HAVE_ZLIB_H #endif // HAVE_LIBZ +#define LAME +#include "lame/lame.h" + +#include "./bitio.h" + // internal constants #define MALLOC_SIZE 128 @@ -128,6 +133,7 @@ int swf_SetBlock(TAG * t,U8 * b,int l) { #ifdef DEBUG_RFXSWF fprintf(stderr,"Fatal Error: malloc()/realloc() failed (1). (%d bytes)\n", newmem); + *(int*)0=0; #endif return 0; } @@ -198,9 +204,6 @@ U32 swf_GetBits(TAG * t,int nbits) return res; } -/* reader/writer stuff - from ../src/bitio.c */ -#include "./bitio.c" - S32 swf_GetSBits(TAG * t,int nbits) { U32 res = swf_GetBits(t,nbits); if (res&(1<<(nbits-1))) res|=(0xffffffff<xmax,nbits); nbits = swf_CountBits(r->ymin,nbits); nbits = swf_CountBits(r->ymax,nbits); + if(nbits>=32) { + fprintf(stderr, "rfxswf: Warning: num_bits overflow in swf_SetRect\n"); + nbits=31; + } swf_SetBits(t,nbits,5); swf_SetBits(t,r->xmin,nbits); @@ -737,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; @@ -747,6 +799,10 @@ void swf_FoldSprite(TAG * t) fprintf(stderr, "Error: Sprite has no ID!"); return; } + if(t->len>4) { + /* sprite is already folded */ + return; + } t->pos = 0; id = swf_GetU16(t); @@ -798,9 +854,20 @@ 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; + } +} + // Movie Functions -int swf_ReadSWF2(struct reader_t*reader2, 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)); @@ -810,7 +877,6 @@ int swf_ReadSWF2(struct reader_t*reader2, SWF * swf) // Reads SWF to memory (m TAG * t; TAG t1; struct reader_t zreader; - struct reader_t* reader; if ((len = reader->read(reader ,b,8))<8) return -1; @@ -821,12 +887,9 @@ int swf_ReadSWF2(struct reader_t*reader2, SWF * swf) // Reads SWF to memory (m swf->compressed = (b[0]=='C')?1:0; swf->fileSize = GET32(&b[4]); - /* TODO: start decompression here */ if(swf->compressed) { - reader_init_zlibinflate(&zreader, reader2); + reader_init_zlibinflate(&zreader, reader); reader = &zreader; - } else { - reader = reader2; } reader_GetRect(reader, &swf->movieSize); @@ -842,7 +905,7 @@ int swf_ReadSWF2(struct reader_t*reader2, SWF * swf) // Reads SWF to memory (m t1.next->prev = NULL; } - return 0; + return reader->pos; } int swf_ReadSWF(int handle, SWF * swf) @@ -855,6 +918,9 @@ int swf_ReadSWF(int handle, SWF * 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; + int fileSize = 0; if (!swf) return -1; @@ -872,43 +938,66 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, len = 0; t = swf->firstTag; - swf->frameCount = 0; + frameCount = 0; while(t) { len += swf_WriteTag(-1, t); - if (t->id==ST_SHOWFRAME) swf->frameCount++; + 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; - swf_SetU8(&t1,'F'); - swf_SetU8(&t1,'W'); - swf_SetU8(&t1,'S'); - swf_SetU8(&t1,swf->fileVersion); - - swf_SetU32(&t1,swf->fileSize); // Keep space for filesize + { // 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; + } + + fileSize = l+len; + if(len) {// don't touch headers without tags + swf->fileSize = fileSize; + 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; + } + swf_SetRect(&t1,&swf->movieSize); swf_SetU16(&t1,swf->frameRate); swf_SetU16(&t1,swf->frameCount); - l = swf_GetTagLen(&t1); - swf->fileSize = l+len; - if(swf->firstTag) { - t1.len = 4; // bad & ugly trick ! - swf_SetU32(&t1,swf->fileSize); - } - if (writer) { - int ret = writer->write(writer,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\n",ret); @@ -923,27 +1012,46 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, { 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)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 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; - swf_WriteSWF(handle, &myswf); - return 0; + return swf_WriteSWF(handle, &myswf); } int swf_WriteCGI(SWF * swf)