X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Frfxswf.c;h=ad3ad217d5db1aabad06bc267f39b4bab0a7082f;hp=beef81e75d618734b4c8d931b262ee97fdf95599;hb=f3784f411338b99aa3b04c5e881c995227c8a053;hpb=a1cb9cb40f74933888e5593dbd62f72707228ed2 diff --git a/lib/rfxswf.c b/lib/rfxswf.c index beef81e..ad3ad21 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -24,6 +24,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "mem.h" #include "rfxswf.h" #ifdef HAVE_JPEGLIB @@ -48,78 +49,6 @@ #include "./bitio.h" #include "./MD5.h" -// memory allocation - -void* rfx_alloc(int size) -{ - void*ptr; - if(size == 0) { - *(int*)0 = 0xdead; - fprintf(stderr, "Warning: Zero alloc\n"); - return 0; - } - - ptr = malloc(size); - if(!ptr) { - fprintf(stderr, "FATAL: Out of memory\n"); - /* TODO: we should send a signal, so that the debugger kicks in */ - exit(1); - } - return ptr; -} -void* rfx_realloc(void*data, int size) -{ - void*ptr; - if(size == 0) { - *(int*)0 = 0xdead; - fprintf(stderr, "Warning: Zero realloc\n"); - rfx_free(data); - return 0; - } - if(!data) { - ptr = malloc(size); - } else { - ptr = realloc(data, size); - } - - if(!ptr) { - fprintf(stderr, "FATAL: Out of memory\n"); - /* TODO: we should send a signal, so that the debugger kicks in */ - exit(1); - } - return ptr; -} -void* rfx_calloc(int size) -{ - void*ptr; - if(size == 0) { - *(int*)0 = 0xdead; - fprintf(stderr, "Warning: Zero alloc\n"); - return 0; - } -#ifdef HAVE_CALLOC - ptr = calloc(size); -#else - ptr = malloc(size); -#endif - if(!ptr) { - fprintf(stderr, "FATAL: Out of memory\n"); - /* TODO: we should send a signal, so that the debugger kicks in */ - exit(1); - } -#ifndef HAVE_CALLOC - memset(ptr, 0, size); -#endif - return ptr; -} - -void rfx_free(void*ptr) -{ - if(!ptr) - return; - free(ptr); -} - // internal constants #define MALLOC_SIZE 128 @@ -154,7 +83,16 @@ void swf_SetTagPos(TAG * t,U32 pos) char* swf_GetString(TAG*t) { char* str = ((char*)(&(t)->data[(t)->pos])); - while(swf_GetU8(t)); + while(t->pos < t->len && swf_GetU8(t)); + /* make sure we always have a trailing zero byte */ + if(t->pos == t->len) { + if(t->len == t->memsize) { + swf_ResetWriteBits(t); + swf_SetU8(t, 0); + t->len = t->pos; + } + t->data[t->len] = 0; + } return str; } @@ -295,10 +233,10 @@ S32 swf_GetSBits(TAG * t,int nbits) return (S32)res; } -U32 reader_GetBits(struct reader_t*reader, int nbits) +U32 reader_GetBits(reader_t*reader, int nbits) { return reader_readbits(reader, nbits); } -S32 reader_GetSBits(struct reader_t*reader, int nbits) +S32 reader_GetSBits(reader_t*reader, int nbits) { U32 res = reader_readbits(reader, nbits); if (res&(1<<(nbits-1))) res|=(0xffffffff<xmin) src->xmin = center.x - radius; if(center.x + radius > src->xmax) - src->xmax = center.x - radius; + src->xmax = center.x + radius; if(center.y - radius < src->ymin) src->ymin = center.y - radius; if(center.y + radius > src->ymax) - src->ymax = center.y - radius; + src->ymax = center.y + radius; } SPOINT swf_TurnPoint(SPOINT p, MATRIX* m) { @@ -549,6 +487,8 @@ SRECT swf_TurnRect(SRECT r, MATRIX* m) { SRECT g; SPOINT p1,p2,p3,p4,pp1,pp2,pp3,pp4; + if(!m) + return r; p1.x = r.xmin;p1.y = r.ymin; p2.x = r.xmax;p2.y = r.ymin; p3.x = r.xmin;p3.y = r.ymax; @@ -621,6 +561,7 @@ int swf_SetMatrix(TAG * t,MATRIX * m) nbits = swf_CountBits(m->sx,0); nbits = swf_CountBits(m->sy,nbits); if(nbits>=32) { + /* TODO: happens on AMD64 systems for normal values? */ fprintf(stderr,"rfxswf: Error: matrix values too large\n"); nbits = 31; } @@ -656,7 +597,7 @@ int swf_SetMatrix(TAG * t,MATRIX * m) return 0; } -int swf_GetCXForm(TAG * t,CXFORM * cx,U8 alpha) //FIXME: alpha should be type bool +int swf_GetCXForm(TAG * t,CXFORM * cx,U8 alpha) { CXFORM cxf; int hasadd; int hasmul; @@ -770,6 +711,7 @@ void swf_SetPassword(TAG * t, const char * password) fprintf(stderr, "rfxswf: Warning- no usable random generator found\n"); fprintf(stderr, "Your password will be vulnerable to dictionary attacks\n"); #endif + salt[2] = 0; md5string = crypt_md5(password, salt); @@ -887,7 +829,7 @@ int swf_DeleteTag(TAG * t) return 0; } -TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) +TAG * swf_ReadTag(reader_t*reader, TAG * prev) { TAG * t; U16 raw; U32 len; @@ -916,7 +858,12 @@ TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) if (t->len) { t->data = (U8*)rfx_alloc(t->len); t->memsize = t->len; - if (reader->read(reader, t->data, t->len) != t->len) return NULL; + if (reader->read(reader, t->data, t->len) != t->len) { + fprintf(stderr, "rfxswf: Warning: Short read (tagid %d). File truncated?\n", t->id); + free(t->data);t->data=0; + free(t); + return NULL; + } } if (prev) @@ -930,7 +877,7 @@ TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) int swf_DefineSprite_GetRealSize(TAG * t); -int swf_WriteTag2(struct writer_t*writer, TAG * t) +int swf_WriteTag2(writer_t*writer, TAG * t) // returns tag length in bytes (incl. Header), -1 = Error // writer = 0 -> no output { U16 raw[3]; @@ -941,7 +888,9 @@ int swf_WriteTag2(struct writer_t*writer, TAG * t) len = (t->id==ST_DEFINESPRITE)?swf_DefineSprite_GetRealSize(t):t->len; - short_tag = len<0x3f&&(t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2); + short_tag = len<0x3f&& + (t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2&&t->id!=ST_SOUNDSTREAMBLOCK&& + t->id!=ST_DEFINEBITSJPEG&&t->id!=ST_DEFINEBITSJPEG2&&t->id!=ST_DEFINEBITSJPEG3); if (writer) { if (short_tag) @@ -994,7 +943,7 @@ int swf_WriteTag2(struct writer_t*writer, TAG * t) int swf_WriteTag(int handle, TAG * t) { - struct writer_t writer; + writer_t writer; int len = 0; if(handle<0) return swf_WriteTag2(0, t); @@ -1118,7 +1067,10 @@ void swf_FoldSprite(TAG * t) do { - if(t->len<0x3f&&t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2) { + if(t->len<0x3f&& + (t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2&&t->id!=ST_SOUNDSTREAMBLOCK&& + t->id!=ST_DEFINEBITSJPEG&&t->id!=ST_DEFINEBITSJPEG2&&t->id!=ST_DEFINEBITSJPEG3) + ) { swf_SetU16(sprtag,t->len|(t->id<<6)); } else { swf_SetU16(sprtag,0x3f|(t->id<<6)); @@ -1212,7 +1164,10 @@ void swf_OptimizeTagOrder(SWF*swf) tag->next = level0; tag->prev = level0->prev; level0->prev = tag; - tag->prev->next = tag; + if(tag->prev) + tag->prev->next = tag; + else + swf->firstTag = tag; changes = 1; } } @@ -1227,7 +1182,7 @@ void swf_OptimizeTagOrder(SWF*swf) // Movie Functions -int swf_ReadSWF2(struct reader_t*reader, SWF * swf) // Reads SWF to memory (malloc'ed), returns length or <0 if fails +int swf_ReadSWF2(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)); @@ -1236,7 +1191,7 @@ int swf_ReadSWF2(struct reader_t*reader, SWF * swf) // Reads SWF to memory (ma int len; TAG * t; TAG t1; - struct reader_t zreader; + reader_t zreader; if ((len = reader->read(reader ,b,8))<8) return -1; @@ -1270,16 +1225,16 @@ int swf_ReadSWF2(struct reader_t*reader, SWF * swf) // Reads SWF to memory (ma int swf_ReadSWF(int handle, SWF * swf) { - struct reader_t reader; + 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 +int swf_WriteSWF2(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; + writer_t zwriter; int fileSize = 0; int inSprite = 0; int writer_lastpos = 0; @@ -1290,13 +1245,24 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, if(writer) writer_lastpos = writer->pos; + if(swf->fileVersion >= 8) { + if ((swf->firstTag && swf->firstTag->id != ST_FILEATTRIBUTES) && + (!swf->firstTag->next || swf->firstTag->next->id != ST_FILEATTRIBUTES)) + { + U32 flags = 0; // | 128 = usenetwork, | 8 = hasmetadata + swf_SetU32(swf_InsertTagBefore(swf, swf->firstTag,ST_FILEATTRIBUTES),flags); + } + } + // Insert REFLEX Tag #ifdef INSERT_RFX_TAG - if (swf->firstTag && swf_NextTag(swf->firstTag)) - if (swf_GetTagID(swf_NextTag(swf->firstTag))!=ST_REFLEX) + if ((swf->firstTag && swf->firstTag->id != ST_REFLEX) && + (!swf->firstTag->next || swf->firstTag->next->id != ST_REFLEX)) + { swf_SetBlock(swf_InsertTagBefore(swf, swf->firstTag,ST_REFLEX),"rfx",3); + } #endif // INSERT_RFX_TAG @@ -1407,13 +1373,14 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, int swf_WriteSWF(int handle, SWF * swf) // Writes SWF to file, returns length or <0 if fails { - struct writer_t writer; + writer_t writer; int len = 0; swf->compressed = 0; if(handle<0) { writer_init_nullwriter(&writer); len = swf_WriteSWF2(&writer, swf); + return len; } writer_init_filewriter(&writer, handle); len = swf_WriteSWF2(&writer, swf); @@ -1423,7 +1390,7 @@ int swf_WriteSWF(int handle, SWF * swf) // Writes SWF to file, returns leng int swf_WriteSWC(int handle, SWF * swf) // Writes SWF to file, returns length or <0 if fails { - struct writer_t writer; + writer_t writer; int len = 0; swf->compressed = 1; @@ -1437,7 +1404,7 @@ int swf_WriteSWC(int handle, SWF * swf) // Writes SWF to file, returns leng return len; } -int swf_WriteHeader2(struct writer_t*writer,SWF * swf) +int swf_WriteHeader2(writer_t*writer,SWF * swf) { SWF myswf; memcpy(&myswf,swf,sizeof(SWF)); @@ -1471,6 +1438,23 @@ int swf_WriteCGI(SWF * swf) return swf_WriteSWF(fileno(stdout),swf); } +SWF* swf_CopySWF(SWF*swf) +{ + SWF*nswf = rfx_alloc(sizeof(SWF)); + TAG*tag, *ntag; + memcpy(nswf, swf, sizeof(SWF)); + nswf->firstTag = 0; + tag = swf->firstTag; + ntag = 0; + while(tag) { + ntag = swf_CopyTag(ntag, tag); + if(!nswf->firstTag) + nswf->firstTag = ntag; + tag = tag->next; + } + return nswf; +} + void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for tags { TAG * t = swf->firstTag; @@ -1497,3 +1481,4 @@ void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for t #include "modules/swfaction.c" #include "modules/swfsound.c" #include "modules/swfdraw.c" +#include "modules/swfrender.c"