X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Frfxswf.c;h=944418d6f172accd2bb53e0d65450690ec4b83c5;hp=93b17d9e625ec23d530bd764d8b8b70dc6008fb7;hb=6feed80959ad2c11f0427bf0e5a30aab8abd7083;hpb=57a0c65d0d2fee99e2899404b561aeccc121cfc8 diff --git a/lib/rfxswf.c b/lib/rfxswf.c index 93b17d9..944418d 100644 --- a/lib/rfxswf.c +++ b/lib/rfxswf.c @@ -1,5 +1,4 @@ /* vi: set sts=2 sw=2 :*/ - /* rfxswf.c Library for creating and reading SWF files or parts of it. @@ -8,33 +7,42 @@ Part of the swftools package. - Copyright (c) 2000, 2001 Rainer Böhme - - This file is distributed under the GPL, see file COPYING for details + Copyright (c) 2000-2003 Rainer Böhme + Copyright (c) 2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -*/ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rfxswf.h" -#ifdef HAVE_LIBJPEG -#ifdef HAVE_JPEGLIB_H +#ifdef HAVE_JPEGLIB #define HAVE_BOOLEAN #include -#define _JPEGLIB_INCLUDED_ -#endif // HAVE_JPEGLIB_H -#endif // HAVE_LIBJPEG +#endif // HAVE_JPEGLIB -#ifdef HAVE_LIBZ -#ifdef HAVE_ZLIB_H +#ifdef HAVE_ZLIB #include -#define _ZLIB_INCLUDED_ -#endif // HAVE_ZLIB_H -#endif // HAVE_LIBZ +#endif // HAVE_ZLIB -#define LAME +#ifndef RFXSWF_DISABLESOUND +#ifdef HAVE_LAME #include "lame/lame.h" +#endif +#endif #include "./bitio.h" +#include "./MD5.h" // internal constants @@ -48,7 +56,6 @@ 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]); } @@ -72,6 +79,13 @@ void swf_SetTagPos(TAG * t,U32 pos) #endif } +char* swf_GetString(TAG*t) +{ + char* str = ((char*)(&(t)->data[(t)->pos])); + while(swf_GetU8(t)); + return str; +} + U8 swf_GetU8(TAG * t) { swf_ResetReadBits(t); #ifdef DEBUG_RFXSWF @@ -249,7 +263,7 @@ int swf_SetRGB(TAG * t,RGBA * col) void swf_GetRGB(TAG * t, RGBA * col) { RGBA dummy; - if(!col); + if(!col) col = &dummy; col->r = swf_GetU8(t); col->g = swf_GetU8(t); @@ -282,6 +296,10 @@ void swf_GetGradient(TAG * tag, GRADIENT * gradient, char alpha) { GRADIENT dummy; int t; + if(!tag) { + memset(gradient, 0, sizeof(GRADIENT)); + return; + } if(!gradient) gradient = &dummy; gradient->num = swf_GetU8(tag); @@ -298,22 +316,53 @@ void swf_GetGradient(TAG * tag, GRADIENT * gradient, char alpha) } } +void swf_SetGradient(TAG * tag, GRADIENT * gradient, char alpha) +{ + int t; + if(!tag) { + memset(gradient, 0, sizeof(GRADIENT)); + return; + } + swf_SetU8(tag, gradient->num); + for(t=0; t<8 && tnum; t++) + { + swf_SetU8(tag, gradient->ratios[t]); + if(!alpha) + swf_SetRGB(tag, &gradient->rgba[t]); + else + swf_SetRGBA(tag, &gradient->rgba[t]); + } +} + +int swf_CountUBits(U32 v,int nbits) +{ int n = 32; + U32 m = 0x80000000; + if(v == 0x00000000) n = 0; + else + while (!(v&m)) + { n--; + m>>=1; + } + return (n>nbits)?n:nbits; +} + int swf_CountBits(U32 v,int nbits) { int n = 33; U32 m = 0x80000000; - if (!v) n = 0; else if (v&m) - { while (v&m) + { if(v == 0xffffffff) n = 1; + else + while (v&m) { n--; m>>=1; - if (!m) break; } } else - { while (!(v&m)) + { if(v == 0x00000000) n = 0; + else + while (!(v&m)) { n--; m>>=1; - if (!m) break; } } return (n>nbits)?n:nbits; @@ -322,7 +371,7 @@ int swf_CountBits(U32 v,int nbits) int swf_GetRect(TAG * t,SRECT * r) { int nbits; SRECT dummy; - if(!t) {r->xmin=r->xmax=r->ymin=r->ymax;return 0;} + if(!t) {r->xmin=r->xmax=r->ymin=r->ymax=0;return 0;} if (!r) r = &dummy; nbits = (int) swf_GetBits(t,5); r->xmin = swf_GetSBits(t,nbits); @@ -378,6 +427,8 @@ void swf_ExpandRect(SRECT*src, SPOINT add) } void swf_ExpandRect2(SRECT*src, SRECT*add) { + if((add->xmin | add->ymin | add->xmax | add->ymax)==0) + return; if(add->xmin < src->xmin) src->xmin = add->xmin; if(add->ymin < src->ymin) @@ -390,8 +441,8 @@ void swf_ExpandRect2(SRECT*src, SRECT*add) SPOINT swf_TurnPoint(SPOINT p, MATRIX* m) { SPOINT r; - r.x = (int)(m->sx*(1/65536.0)*p.x + m->r0*(1/65536.0)*p.y + 0.5) + m->tx; - r.y = (int)(m->r1*(1/65536.0)*p.x + m->sy*(1/65536.0)*p.y + 0.5) + m->ty; + r.x = (int)(m->sx*(1/65536.0)*p.x + m->r1*(1/65536.0)*p.y + 0.5) + m->tx; + r.y = (int)(m->r0*(1/65536.0)*p.x + m->sy*(1/65536.0)*p.y + 0.5) + m->ty; return r; } SRECT swf_TurnRect(SRECT r, MATRIX* m) @@ -600,23 +651,46 @@ int swf_SetCXForm(TAG * t,CXFORM * cx,U8 alpha) return 0; } -int swf_GetPoint(TAG * t,SPOINT * p) { return 0; } -int swf_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 +void swf_SetPassword(TAG * t, const char * password) +{ + /* WARNING: crypt_md5 is not reentrant */ + char* md5string = crypt_md5(password, "salt"); /* FIXME- get random salt */ + swf_SetString(t, md5string); +} -int swf_UpdateFrame(TAG * t,S8 delta) -// returns number of frames -{ int res = -1; - while (t) - { t->frame+=delta; - res = t->frame; - t = t->next; - } - return res; +int swf_VerifyPassword(TAG * t, const char * password) +{ + char*md5string1, *md5string2; + char*x; + char*md5, *salt; + int n; + + md5string1 = swf_GetString(t); + + if(!strncmp(md5string1, "$1$",3 )) { + return 0; + } + x = strchr(md5string1+3, '$'); + if(!x) + return 0; + n = x-(md5string1+3); + salt = (char*)malloc(n+1); + memcpy(salt, md5string1+3, n); + salt[n] = 0; + + md5string2 = crypt_md5(password, salt); + free(salt); + if(strcmp(md5string1, md5string2) != 0) + return 0; + return 1; } -TAG * swf_InsertTag(TAG * after,U16 id) // updates frames, if nescessary +// Tag List Manipulating Functions + +TAG * swf_InsertTag(TAG * after,U16 id) { TAG * t; t = (TAG *)malloc(sizeof(TAG)); @@ -625,23 +699,58 @@ TAG * swf_InsertTag(TAG * after,U16 id) // updates frames, if nescessary t->id = id; if (after) - { t->frame = after->frame; + { t->prev = after; t->next = after->next; after->next = t; if (t->next) t->next->prev = t; - - if (id==ST_SHOWFRAME) swf_UpdateFrame(t->next,+1); } } return t; } +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; + } + } + if(swf && swf->firstTag == before) { + swf->firstTag = t; + } + return t; +} + +void swf_ClearTag(TAG * t) +{ + if (t->data) free(t->data); + t->data = 0; + t->pos = 0; + t->len = 0; + t->readBit = 0; + t->writeBit = 0; + t->memsize = 0; +} + +void swf_ResetTag(TAG*tag, U16 id) +{ + tag->len = tag->pos = tag->readBit = tag->writeBit = 0; + tag->id = id; +} + int swf_DeleteTag(TAG * t) { if (!t) return -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; @@ -669,7 +778,7 @@ TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) } if (id==ST_DEFINESPRITE) len = 2*sizeof(U16); - // Sprite handling fix: Flaten sprite tree + // Sprite handling fix: Flatten sprite tree t = (TAG *)malloc(sizeof(TAG)); @@ -700,7 +809,7 @@ TAG * swf_ReadTag(struct reader_t*reader, TAG * prev) } if (prev) - { t->frame = prev->frame+((prev->id==ST_SHOWFRAME)?1:0); + { t->prev = prev; prev->next = t; } @@ -919,12 +1028,20 @@ void swf_FoldSprite(TAG * t) // t->prev = sprtag; } +int swf_IsFolded(TAG * t) +{ + return (t->id == ST_DEFINESPRITE && t->len>4); +} + void swf_FoldAll(SWF*swf) { TAG*tag = swf->firstTag; + //swf_DumpSWF(stdout, swf); while(tag) { - if(tag->id == ST_DEFINESPRITE) + if(tag->id == ST_DEFINESPRITE) { swf_FoldSprite(tag); + //swf_DumpSWF(stdout, swf); + } tag = swf_NextTag(tag); } } @@ -1094,29 +1211,37 @@ int swf_WriteSWF2(struct writer_t*writer, SWF * swf) // Writes SWF to file, swf_SetU16(&t2, swf->frameCount); l = swf_GetTagLen(&t2)+8; } + if(swf->compressed == 8) { + l -= 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 != 8) { + /* compressed flag set to 8 means "skip first 8 + header bytes". This is necessary if the caller wants to + create compressed SWFs himself */ + if(swf->compressed) { + char*id = "CWS"; + writer->write(writer, id, 3); + } + else { + char*id = "FWS"; + writer->write(writer, id, 3); + } - if(swf->compressed) { - writer_init_zlibdeflate(&zwriter, writer); - writer = &zwriter; + 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); @@ -1141,7 +1266,8 @@ 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 + if(swf->compressed != 8) + writer->finish(writer); // flush zlib buffers - only if _we_ initialized that writer. } } return (int)fileSize; @@ -1151,8 +1277,10 @@ int swf_WriteSWF(int handle, SWF * swf) // Writes SWF to file, returns leng { struct writer_t writer; swf->compressed = 0; - if(handle<0) + if(handle<0) { + writer_init_nullwriter(&writer); return swf_WriteSWF2(&writer, swf); + } writer_init_filewriter(&writer, handle); return swf_WriteSWF2(&writer, swf); } @@ -1161,8 +1289,10 @@ int swf_WriteSWC(int handle, SWF * swf) // Writes SWF to file, returns leng { struct writer_t writer; swf->compressed = 1; - if(handle<0) + if(handle<0) { + writer_init_nullwriter(&writer); return swf_WriteSWF2(&writer, swf); + } writer_init_filewriter(&writer, handle); return swf_WriteSWF2(&writer, swf); } @@ -1217,6 +1347,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" @@ -1224,4 +1355,4 @@ void swf_FreeTags(SWF * swf) // Frees all malloc'ed memory for t #include "modules/swfbits.c" #include "modules/swfaction.c" #include "modules/swfsound.c" - +#include "modules/swfdraw.c"