From: kramm Date: Tue, 6 Jan 2009 21:44:08 +0000 (+0000) Subject: added swfbytes source code X-Git-Tag: release-0-9-0~352 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=7915fcb341e26520259263042671a42dcfd833fe added swfbytes source code --- diff --git a/src/swfbytes.c b/src/swfbytes.c new file mode 100644 index 0000000..1b80f41 --- /dev/null +++ b/src/swfbytes.c @@ -0,0 +1,378 @@ +/* swfbytes.c + A tool for modifying swf files + + Part of the swftools package. + + Copyright (c) 2008/2009 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 "../config.h" +#include +#include +#include +#include +#include "../lib/rfxswf.h" +#include "../lib/args.h" + +static char * filename = 0; +static int verbose; + +struct options_t options[] = +{ + {"v","verbose"}, + {"V","version"}, + {0,0} +}; + +int args_callback_option(char*name,char*val) +{ + if(!strcmp(name, "V")) { + printf("swfedit - part of %s %s\n", PACKAGE, VERSION); + return 0; + } else if(!strcmp(name, "v")) { + verbose++; + return 0; + } else { + printf("Unknown option: -%s\n", name); + return 0; + } + return 0; +} +int args_callback_longoption(char*name,char*val) +{ + return args_long2shortoption(options, name, val); +} +void args_callback_usage(char*name) +{ + printf("Usage: %s [-at] file.swf\n", name); + printf("\t-h , --help\t\t Print help and exit\n"); + printf("\t-v , --verbose\t\t Be more verbose\n"); + printf("\t-V , --version\t\t Print program version and exit\n"); +} +int args_callback_command(char*name,char*val) +{ + if(filename) { + fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n", filename, name); + } + filename = name; + return 0; +} + +void dumpTag(FILE*fo, char*prefix, TAG*tag) +{ + int t; + for(t=0;tlen;t++) { + if(!(t&15)) + fprintf(fo, "%s| ", prefix); + fprintf(fo, "%02x ", tag->data[t]); + if((t && ((t&15)==15)) || (t==tag->len-1)) { + fprintf(fo, "\n"); + } + } +} + +void dumpFile(SWF*swf, FILE*fo) +{ + TAG* tag = swf->firstTag; + int indent = 0; + int t; + char whitespace[33]; + char*prefix = ""; + + memset(whitespace, 32, 32); whitespace[32] = 0; + + fprintf(fo, "Version: %d\n", swf->fileVersion); + fprintf(fo, "FrameRate: %f\n",swf->frameRate/256.0); + fprintf(fo, "FrameCount: %d\n",swf->frameCount); + fprintf(fo, "Width: %.2f\n",(swf->movieSize.xmax-swf->movieSize.xmin)/20.0); + fprintf(fo, "X-Offset: %.2f\n", swf->movieSize.xmin/20.0); + fprintf(fo, "Height: %.2f\n",(swf->movieSize.ymax-swf->movieSize.ymin)/20.0); + fprintf(fo, "Y-Offset: %.2f\n", swf->movieSize.ymin/20.0); + fprintf(fo, "\n"); + + while(tag) + { + if(swf_isDefiningTag(tag)) { + fprintf(fo, "%s%s <%d>\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag)); + swf_SetTagPos(tag, 2); + dumpTag(fo, prefix, tag); + } else if(swf_isPseudoDefiningTag(tag)) { + fprintf(fo, "%s%s <%d>\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag)); + swf_SetTagPos(tag, 2); + dumpTag(fo, prefix, tag); + } else if(tag->id == ST_PLACEOBJECT || tag->id == ST_PLACEOBJECT2) { + SWFPLACEOBJECT po; + swf_GetPlaceObject(tag, &po); + fprintf(fo, "%s%s <%d>\n", prefix,swf_TagGetName(tag), po.id); + /* for now */ + swf_SetTagPos(tag, 0); + dumpTag(fo, prefix, tag); + swf_PlaceObjectFree(&po); + } else { + fprintf(fo, "%s%s\n", prefix, swf_TagGetName(tag)); + dumpTag(fo, prefix, tag); + } + + if(tag->id == ST_DEFINESPRITE) { + indent+=4; + if(indent>32) + indent = 32; + prefix = &whitespace[32-indent]; + } else if(tag->id == ST_END) { + indent-=4; + if(indent<0) + indent = 0; + prefix = &whitespace[32-indent]; + } + + tag = tag->next; + } +} + +static void readline(FILE*fi, char*line, int maxlen) { + int pos = 0; + while(!feof(fi)) { + if(!fread(&line[pos],1,1,fi)) + break; + + /* cut of preceding whitespace */ + if(pos == 0 && (line[0] == 32 || line[0] == '\t')) + continue; + + if(line[pos] == 13 || line[pos]==10) + break; + if(pos=1 && (line[pos-1]==32 || line[pos-1]==9)) { + pos--; + line[pos]=0; + } +} + +int getFloat(char*s) +{ + float x; + int n; + while(*s==32 || *s=='\t') s++; + sscanf(s, "%f%n", &x, &n); + if(n==0) + fprintf(stderr, "Not a float: %s\n", s); + return x; +} +int getInt(char*s) +{ + int i; + int n; + while(*s==32 || *s=='\t') s++; + sscanf(s, "%d%n", &i, &n); + if(n==0) + fprintf(stderr, "Not an integer: %s\n", s); + return i; +} +int getTwip(char*x) +{ + return (int)(getFloat(x)*20); +} + + +static char**lookup; +int swf_TagNameToID(char*name) +{ + int t; + TAG tag; + memset(&tag, 0, sizeof(tag)); + if(!lookup) { + lookup = (char**)malloc(sizeof(char*)*65536); + for(t=0;t<65536;t++) { + tag.id = t; + lookup[t] = swf_TagGetName(&tag); + } + } + for(t=0;t<65536;t++) { + if(lookup[t] && !strcasecmp(name, lookup[t])) + return t; + } + fprintf(stderr, "Not a tag name: \"%s\"\n", name); + return -1; +} + +void parseFile(FILE*fi, SWF*swf) +{ + TAG*tag = 0; + char line[1024]; + memset(swf, 0, sizeof(SWF)); + while(1) { + char*colon = 0; + readline(fi, line, 1024); + if(!line[0]) + break; + colon = strchr(line, ':'); + if(colon) { + int num = colon - line; + int n; + if(num == 9 && !strncmp(line, "FrameRate", num)) { + swf->frameRate = getFloat(colon+1)*256; + } else if(num == 10 && !strncmp(line, "FrameCount", num)) { + swf->frameCount = getInt(colon+1); + } else if(num == 7 && !strncmp(line, "Version", num)) { + swf->fileVersion = getInt(colon+1); + } else if(num == 5 && !strncmp(line, "Width", num)) { + int width = getTwip(colon+1); + swf->movieSize.xmax += width; + } else if(num == 6 && !strncmp(line, "Height", num)) { + int height = getTwip(colon+1); + swf->movieSize.ymax += height; + } else if(num == 8 && !strncmp(line, "X-Offset", num)) { + int xoffset = getTwip(colon+1); + swf->movieSize.xmin += xoffset; + swf->movieSize.xmax += xoffset; + } else if(num == 8 && !strncmp(line, "Y-Offset", num)) { + int yoffset = getTwip(colon+1); + swf->movieSize.ymin += yoffset; + swf->movieSize.ymax += yoffset; + } else { + fprintf(stderr, "Ignored line \"%s\"\n", line); + } + } + } + while(!feof(fi)) { + char*s, *tagname; + char*br; + readline(fi, line, 1024); + if(!line[0]) + continue; + s = strchr(line, ' '); + br = strchr(line, '|'); + if(!br) { + int id = 0; + /* DEFINESHAPE ... type line */ + if(!s) { + tagname = strdup(line); + } else { + tagname = strdup(line); + tagname[s-line] = 0; + } + id = swf_TagNameToID(tagname); + free(tagname); + if(id<0) { + fprintf(stderr, "Ignored line \"%s\"\n", line); + continue; + } + tag = swf_InsertTag(tag, id); + if(!swf->firstTag) + swf->firstTag = tag; + } else { + /* | 00 34 fe c7 ... type line */ + char*p = line; + int num = 0; + int digits = 0; + + if(!tag) { + fprintf(stderr, "Discarded unassignable data %s\n", line); + continue; + } + + while(*p) { + int n = 0; + if((*p>='a' && *p<='f') || + (*p>='A' && *p<='F')) { + n = 9 + (*p & 15); + num = (num<<4) | n; + digits++; + } + else if(*p>='0' && *p<='9') { + n = *p & 15; + num = (num<<4) | n; + digits++; + } else if(digits) { + swf_SetU8(tag, num); + num = 0; + digits = 0; + } + p++; + } + if(digits) + swf_SetU8(tag, num); + } + } +} + +char swf_IsSWF(char*filename) +{ + int fi = open(filename,O_RDONLY|O_BINARY); + U8 buf[3] = {0,0,0}; + if(fi<0) + return 0; + read(fi, buf, 3); + close(fi); + if((buf[0] == 'F' || buf[0] == 'C') && buf[1] == 'W' && buf[2] == 'S') + return 1; + return 0; +} + +int main (int argc,char ** argv) +{ + int fi; + TAG*tag = 0; + SWF swf; + + processargs(argc, argv); + + if(!filename) { + fprintf(stderr, "You must supply a filename.\n"); + return -1; + } + if(swf_IsSWF(filename)) { + fi = open(filename,O_RDONLY|O_BINARY); + if (fi<0) { + perror("Couldn't open file: "); + exit(1); + } + if FAILED(swf_ReadSWF(fi,&swf)) { + fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename); + close(fi); + exit(1); + } + dumpFile(&swf, stdout); + swf_FreeTags(&swf); + } else { + SWF newswf; + FILE*fi = fopen(filename, "rb"); + parseFile(fi, &newswf); + fclose(fi); + int f; + char*sname = "output.swf"; + f = open(sname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644); + if FAILED(swf_WriteSWF(f,&newswf)) { + fprintf(stderr, "Unable to write output file: %s\n", sname); + } + close(f); + } + + return 0; +} + diff --git a/src/swfbytes.doc b/src/swfbytes.doc index 7ea4b9b..d7b5e36 100644 --- a/src/swfbytes.doc +++ b/src/swfbytes.doc @@ -12,6 +12,3 @@ editing operations on SWF files. -V, --version Print program version and exit -.SH AUTHOR - -Matthias Kramm