X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=lib%2Frfxswf.c;h=ca87274c6113fa644307e687bd71f118ea7a36ef;hb=cc29df1f6cd189f1a5845f1813ca47aa7cbf960a;hp=09f89c5f7d8697a3d814a109366498d5292c70d1;hpb=74021a5785a3b96e71a515d25fb91cd4e8cbbea9;p=swftools.git diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 09f89c5..ca87274 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -35,8 +35,15 @@ #include #endif // HAVE_ZLIB -#define LAME +#ifndef RFXSWF_DISABLESOUND +#ifdef HAVE_LAME #include "lame/lame.h" +#endif +#endif + +#ifdef HAVE_TIME_H +#include +#endif #include "./bitio.h" #include "./MD5.h" @@ -58,11 +65,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) @@ -71,9 +73,11 @@ U32 swf_GetTagPos(TAG * t) { return t->pos; } 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 + else { +#ifdef DEBUG_RFXSWF + fprintf(stderr,"SetTagPos(%d) out of bounds: TagID = %i\n",pos, t->id); +#endif + } } char* swf_GetString(TAG*t) @@ -281,7 +285,7 @@ int swf_SetRGBA(TAG * t,RGBA * col) void swf_GetRGBA(TAG * t, RGBA * col) { RGBA dummy; - if(!col); + if(!col) col = &dummy; col->r = swf_GetU8(t); col->g = swf_GetU8(t); @@ -413,6 +417,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) @@ -426,6 +438,8 @@ void swf_ExpandRect2(SRECT*src, SRECT*add) { if((add->xmin | add->ymin | add->xmax | add->ymax)==0) return; + if((src->xmin | src->ymin | src->xmax | src->ymax)==0) + *src = *add; if(add->xmin < src->xmin) src->xmin = add->xmin; if(add->ymin < src->ymin) @@ -435,6 +449,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; @@ -654,7 +687,23 @@ int swf_SetCXForm(TAG * t,CXFORM * cx,U8 alpha) void swf_SetPassword(TAG * t, const char * password) { /* WARNING: crypt_md5 is not reentrant */ - char* md5string = crypt_md5(password, "salt"); /* FIXME- get random salt */ + char salt[3]; + char* md5string; + +#if defined(HAVE_LRAND48) && defined(HAVE_SRAND48) && defined(HAVE_TIME_H) && defined(HAVE_TIME) + srand48(time(0)); + salt[0] = "abcdefghijklmnopqrstuvwxyz0123456789"[lrand48()%36]; + salt[1] = "abcdefghijklmnopqrstuvwxyz0123456789"[lrand48()%36]; +#else + salt[0] = 'l'; + salt[1] = '8'; + fprintf(stderr, "rfxswf: Warning- no usable random generator found\n"); + fprintf(stderr, "Your password will be vulnerable to dictionary attacks\n"); +#endif + + md5string = crypt_md5(password, salt); + + swf_SetU16(t,0); swf_SetString(t, md5string); } @@ -665,14 +714,25 @@ int swf_VerifyPassword(TAG * t, const char * password) char*md5, *salt; int n; + if(t->len >= 5 && t->pos==0 && + t->data[0] == 0 && + t->data[1] == 0) { + swf_GetU16(t); + } else { + printf("%d %d %d %d\n", t->len, t->pos, t->data[0], t->data[1]); + } + md5string1 = swf_GetString(t); - if(!strncmp(md5string1, "$1$",3 )) { + if(strncmp(md5string1, "$1$",3 )) { + fprintf(stderr, "rfxswf: no salt in pw string\n"); return 0; } x = strchr(md5string1+3, '$'); - if(!x) + if(!x) { + fprintf(stderr, "rfxswf: invalid salt format in pw string\n"); return 0; + } n = x-(md5string1+3); salt = (char*)malloc(n+1); memcpy(salt, md5string1+3, n); @@ -827,7 +887,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) @@ -881,10 +941,13 @@ int swf_WriteTag2(struct writer_t*writer, TAG * t) int swf_WriteTag(int handle, TAG * t) { struct writer_t writer; + int len = 0; if(handle<0) return swf_WriteTag2(0, t); writer_init_filewriter(&writer, handle); - return swf_WriteTag2(&writer, t); + len = swf_WriteTag2(&writer, t); + writer.finish(&writer); + return len; } int swf_DefineSprite_GetRealSize(TAG * t) @@ -1001,7 +1064,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)); @@ -1164,8 +1227,14 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, int frameCount=0; struct writer_t zwriter; int fileSize = 0; + int inSprite = 0; + int writer_lastpos = 0; + int ret; if (!swf) return -1; + if (!writer) return -1; // the caller should provide a nullwriter, not 0, for querying SWF size + + if(writer) writer_lastpos = writer->pos; // Insert REFLEX Tag @@ -1173,7 +1242,7 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, 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); + swf_SetBlock(swf_InsertTagBefore(swf, swf->firstTag,ST_REFLEX),"rfx",3); #endif // INSERT_RFX_TAG @@ -1183,10 +1252,12 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, t = swf->firstTag; frameCount = 0; - while(t) - { len += swf_WriteTag(-1, t); - if (t->id==ST_SHOWFRAME) frameCount++; - t = swf_NextTag(t); + while(t) { + len += swf_WriteTag(-1,t); + if(t->id == ST_DEFINESPRITE) inSprite++; + else if(t->id == ST_END && inSprite) inSprite--; + else if(t->id == ST_SHOWFRAME && !inSprite) frameCount++; + t = swf_NextTag(t); } { TAG t1; @@ -1221,7 +1292,10 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, if(swf->compressed != 8) { /* compressed flag set to 8 means "skip first 8 header bytes". This is necessary if the caller wants to - create compressed SWFs himself */ + create compressed SWFs himself . + It also means that we don't initialize our own zlib + writer, but assume the caller provided one. + */ if(swf->compressed) { char*id = "CWS"; writer->write(writer, id, 3); @@ -1245,53 +1319,64 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, swf_SetU16(&t1,swf->frameRate); swf_SetU16(&t1,swf->frameCount); - if (writer) - { - int ret = writer->write(writer,b,swf_GetTagLen(&t1)); - if (ret!=swf_GetTagLen(&t1)) - { - #ifdef DEBUG_RFXSWF - fprintf(stderr, "ret:%d\n",ret); - perror("write:"); - fprintf(stderr,"WriteSWF() failed: Header.\n"); - #endif - return -1; - } + ret = writer->write(writer,b,swf_GetTagLen(&t1)); + if (ret!=swf_GetTagLen(&t1)) + { + #ifdef DEBUG_RFXSWF + fprintf(stderr, "ret:%d\n",ret); + perror("write:"); + fprintf(stderr,"WriteSWF() failed: Header.\n"); + #endif + return -1; + } - t = swf->firstTag; - while (t) - { if (swf_WriteTag2(writer, t)<0) return -1; - t = swf_NextTag(t); + t = swf->firstTag; + while (t) + { if (swf_WriteTag2(writer, t)<0) return -1; + t = swf_NextTag(t); + } + if(swf->compressed) { + if(swf->compressed != 8) { + zwriter.finish(&zwriter); + return writer->pos - writer_lastpos; } - if(swf->compressed != 8) - writer->finish(writer); // flush zlib buffers - only if _we_ initialized that writer. + return (int)fileSize; + } else { + return (int)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; + int len = 0; swf->compressed = 0; + if(handle<0) { writer_init_nullwriter(&writer); - return swf_WriteSWF2(&writer, swf); + len = swf_WriteSWF2(&writer, swf); } writer_init_filewriter(&writer, handle); - return swf_WriteSWF2(&writer, swf); + len = swf_WriteSWF2(&writer, swf); + writer.finish(&writer); + return len; } int swf_WriteSWC(int handle, SWF * swf) // Writes SWF to file, returns length or <0 if fails { struct writer_t writer; + int len = 0; swf->compressed = 1; + if(handle<0) { writer_init_nullwriter(&writer); - return swf_WriteSWF2(&writer, swf); + len = swf_WriteSWF2(&writer, swf); } writer_init_filewriter(&writer, handle); - return swf_WriteSWF2(&writer, swf); + len = swf_WriteSWF2(&writer, swf); + writer.finish(&writer); + return len; } int swf_WriteHeader2(struct writer_t*writer,SWF * swf) @@ -1337,6 +1422,7 @@ void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for t free(t); t = tnew; } + swf->firstTag = 0; } // include advanced functions @@ -1344,6 +1430,7 @@ void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for t #include "modules/swfdump.c" #include "modules/swfshape.c" #include "modules/swftext.c" +#include "modules/swffont.c" #include "modules/swfobject.c" #include "modules/swfbutton.c" #include "modules/swftools.c"