X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Frfxswf.c;h=2f80c888a4b48f17ac6706ef072fb952db1e218a;hb=607c5dadd6089768b618cc99346de1b37a2c46f1;hp=441e19dd74eb4a278a73449e74233f37ca8287e2;hpb=1b376de4a5d3ee2905cf962ecbde7766616d5347;p=swftools.git diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 441e19d..2f80c88 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -48,6 +48,88 @@ #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); +} + +#ifdef MEMORY_INFO +long rfx_memory_used() +{ +} + +char* rfx_memory_used_str() +{ +} +#endif + // internal constants #define MALLOC_SIZE 128 @@ -55,7 +137,6 @@ #define MEMSIZE(l) (((l/MALLOC_SIZE)+1)*MALLOC_SIZE) - // inline wrapper functions TAG * swf_NextTag(TAG * t) { return t->next; } @@ -65,11 +146,6 @@ 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 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/bitpos #define swf_SaveTagPos(tag) @@ -148,15 +224,7 @@ int swf_SetBlock(TAG * t,U8 * b,int l) 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 (1). (%d bytes)\n", newmem); - *(int*)0=0; - #endif - return 0; - } + U8 * newdata = (U8*)(rfx_realloc(t->data,newmem)); t->memsize = newmem; t->data = newdata; } @@ -184,6 +252,13 @@ int swf_SetU16(TAG * t,U16 v) t->data[t->len++] = a[1]; return 0; } +void swf_SetS16(TAG * t,int v) +{ + if(v>32767 || v<-32768) { + fprintf(stderr, "Warning: S16 overflow: %d\n", v); + } + swf_SetU16(t, (S16)v); +} int swf_SetU32(TAG * t,U32 v) { U8 a[4]; @@ -422,6 +497,14 @@ int swf_SetRect(TAG * t,SRECT * r) void swf_ExpandRect(SRECT*src, SPOINT add) { + if((src->xmin | src->ymin | src->xmax | src->ymax)==0) { + src->xmin = add.x; + src->ymin = add.y; + src->xmax = add.x; + src->ymax = add.y; + if((add.x|add.y) == 0) src->xmax++; //make sure the bbox is not NULL anymore + return; + } if(add.x < src->xmin) src->xmin = add.x; if(add.x > src->xmax) @@ -446,6 +529,25 @@ void swf_ExpandRect2(SRECT*src, SRECT*add) if(add->ymax > src->ymax) src->ymax = add->ymax; } +void swf_ExpandRect3(SRECT*src, SPOINT center, int radius) +{ + if((src->xmin | src->ymin | src->xmax | src->ymax)==0) { + src->xmin = center.x-radius; + src->ymin = center.y-radius; + src->xmax = center.x+radius; + src->ymax = center.y+radius; + if((center.x|center.y|radius) == 0) src->xmax++; //make sure the bbox is not NULL anymore + return; + } + if(center.x - radius < src->xmin) + src->xmin = center.x - radius; + if(center.x + radius > src->xmax) + 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; +} SPOINT swf_TurnPoint(SPOINT p, MATRIX* m) { SPOINT r; @@ -457,6 +559,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; @@ -712,12 +816,12 @@ int swf_VerifyPassword(TAG * t, const char * password) return 0; } n = x-(md5string1+3); - salt = (char*)malloc(n+1); + salt = (char*)rfx_alloc(n+1); memcpy(salt, md5string1+3, n); salt[n] = 0; md5string2 = crypt_md5(password, salt); - free(salt); + rfx_free(salt); if(strcmp(md5string1, md5string2) != 0) return 0; return 1; @@ -728,18 +832,15 @@ int swf_VerifyPassword(TAG * t, const char * password) TAG * swf_InsertTag(TAG * after,U16 id) { TAG * t; - t = (TAG *)malloc(sizeof(TAG)); - if (t) - { memset(t,0x00,sizeof(TAG)); - t->id = id; - - if (after) - { - t->prev = after; - t->next = after->next; - after->next = t; - if (t->next) t->next->prev = t; - } + t = (TAG *)rfx_calloc(sizeof(TAG)); + t->id = id; + + if (after) + { + t->prev = after; + t->next = after->next; + after->next = t; + if (t->next) t->next->prev = t; } return t; } @@ -747,18 +848,15 @@ TAG * swf_InsertTag(TAG * after,U16 id) TAG * swf_InsertTagBefore(SWF* swf, TAG * before,U16 id) { TAG * t; - t = (TAG *)malloc(sizeof(TAG)); - if (t) - { memset(t,0x00,sizeof(TAG)); - t->id = id; - - if (before) - { - t->next = before; - t->prev = before->prev; - before->prev = t; - if (t->prev) t->prev->next = t; - } + t = (TAG *)rfx_calloc(sizeof(TAG)); + t->id = id; + + if (before) + { + t->next = before; + t->prev = before->prev; + before->prev = t; + if (t->prev) t->prev->next = t; } if(swf && swf->firstTag == before) { swf->firstTag = t; @@ -768,7 +866,7 @@ TAG * swf_InsertTagBefore(SWF* swf, TAG * before,U16 id) void swf_ClearTag(TAG * t) { - if (t->data) free(t->data); + if (t->data) rfx_free(t->data); t->data = 0; t->pos = 0; t->len = 0; @@ -783,14 +881,21 @@ void swf_ResetTag(TAG*tag, U16 id) tag->id = id; } +TAG* swf_CopyTag(TAG*tag, TAG*to_copy) +{ + tag = swf_InsertTag(tag, to_copy->id); + swf_SetBlock(tag, to_copy->data, to_copy->len); + return tag; +} + int swf_DeleteTag(TAG * t) { if (!t) return -1; if (t->prev) t->prev->next = t->next; if (t->next) t->next->prev = t->prev; - if (t->data) free(t->data); - free(t); + if (t->data) rfx_free(t->data); + rfx_free(t); return 0; } @@ -815,32 +920,20 @@ TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) if (id==ST_DEFINESPRITE) len = 2*sizeof(U16); // Sprite handling fix: Flatten sprite tree - t = (TAG *)malloc(sizeof(TAG)); - - if (!t) - { - #ifdef DEBUG_RFXSWF - fprintf(stderr,"Fatal Error: malloc()/realloc() failed (2). (%d bytes)\n", sizeof(TAG)); - #endif - return NULL; - } - - memset(t,0x00,sizeof(TAG)); + t = (TAG *)rfx_calloc(sizeof(TAG)); t->len = len; t->id = id; if (t->len) - { t->data = (U8*)malloc(t->len); - if (!t->data) - { - #ifdef DEBUG_RFXSWF - fprintf(stderr,"Fatal Error: malloc()/realloc() failed (3). (%d bytes)\n", t->len); - #endif + { t->data = (U8*)rfx_alloc(t->len); + t->memsize = t->len; + 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; } - t->memsize = t->len; - if (reader->read(reader, t->data, t->len) != t->len) return NULL; } if (prev) @@ -865,7 +958,7 @@ int swf_WriteTag2(struct writer_t*writer, TAG * t) len = (t->id==ST_DEFINESPRITE)?swf_DefineSprite_GetRealSize(t):t->len; - short_tag = len<0x3f; + short_tag = len<0x3f&&(t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2); if (writer) { if (short_tag) @@ -979,7 +1072,7 @@ void swf_UnFoldSprite(TAG * t) it->len = len; it->id = id; if (it->len) - { it->data = (U8*)malloc(it->len); + { it->data = (U8*)rfx_alloc(it->len); it->memsize = it->len; swf_GetBlock(t, it->data, it->len); } @@ -988,7 +1081,7 @@ void swf_UnFoldSprite(TAG * t) break; } - free(t->data); t->data = 0; + rfx_free(t->data); t->data = 0; t->memsize = t->len = t->pos = 0; swf_SetU16(t, spriteid); @@ -1013,7 +1106,7 @@ void swf_FoldSprite(TAG * t) t->pos = 0; id = swf_GetU16(t); - free(t->data); + rfx_free(t->data); t->len = t->pos = t->memsize = 0; t->data = 0; @@ -1042,7 +1135,7 @@ void swf_FoldSprite(TAG * t) do { - if(t->len<0x3f) { + if(t->len<0x3f&&t->id!=ST_DEFINEBITSLOSSLESS&&t->id!=ST_DEFINEBITSLOSSLESS2) { swf_SetU16(sprtag,t->len|(t->id<<6)); } else { swf_SetU16(sprtag,0x3f|(t->id<<6)); @@ -1218,9 +1311,11 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, #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->next && + (swf->firstTag->id != ST_REFLEX || swf->firstTag->next->id != ST_REFLEX) + ) { swf_SetBlock(swf_InsertTagBefore(swf, swf->firstTag,ST_REFLEX),"rfx",3); + } #endif // INSERT_RFX_TAG @@ -1232,8 +1327,12 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, while(t) { len += swf_WriteTag(-1,t); - if(t->id == ST_DEFINESPRITE) inSprite++; + if(t->id == ST_DEFINESPRITE && !swf_IsFolded(t)) inSprite++; else if(t->id == ST_END && inSprite) inSprite--; + else if(t->id == ST_END && !inSprite) { + if(t->prev && t->prev->id!=ST_SHOWFRAME) + frameCount++; + } else if(t->id == ST_SHOWFRAME && !inSprite) frameCount++; t = swf_NextTag(t); } @@ -1391,13 +1490,29 @@ int swf_WriteCGI(SWF * swf) return swf_WriteSWF(fileno(stdout),swf); } +SWF* swf_CopySWF(SWF*swf) +{ + SWF*nswf = rfx_alloc(sizeof(SWF)); + memcpy(nswf, swf, sizeof(SWF)); + nswf->firstTag = 0; + TAG*tag = swf->firstTag; + TAG*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; while (t) { TAG * tnew = t->next; - if (t->data) free(t->data); - free(t); + if (t->data) rfx_free(t->data); + rfx_free(t); t = tnew; } swf->firstTag = 0; @@ -1417,3 +1532,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"