2 A tool for modifying swfs on the tag level
4 Part of the swftools package.
6 Copyright (c) 2008/2009 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22 #include "../config.h"
27 #include "../lib/rfxswf.h"
28 #include "../lib/args.h"
30 static char * filename = 0;
33 static struct options_t options[] = {
40 int args_callback_option(char*name,char*val)
42 if(!strcmp(name, "V")) {
43 printf("swfedit - part of %s %s\n", PACKAGE, VERSION);
45 } else if(!strcmp(name, "v")) {
49 printf("Unknown option: -%s\n", name);
54 int args_callback_longoption(char*name,char*val)
56 return args_long2shortoption(options, name, val);
58 void args_callback_usage(char *name)
61 printf("Usage: %s [-v] file.swf > file.hexdump\n", name);
62 printf("OR: %s file.hexdump\n", name);
64 printf("-h , --help Print help and exit\n");
65 printf("-v , --verbose Be more verbose\n");
66 printf("-V , --version Print program version and exit\n");
69 int args_callback_command(char*name,char*val)
72 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n", filename, name);
78 void dumpTag(FILE*fo, char*prefix, TAG*tag)
81 for(t=0;t<tag->len;t++) {
83 fprintf(fo, "%s| ", prefix);
84 fprintf(fo, "%02x ", tag->data[t]);
85 if((t && ((t&15)==15)) || (t==tag->len-1)) {
91 void dumpFile(SWF*swf, FILE*fo)
93 TAG* tag = swf->firstTag;
99 memset(whitespace, 32, 32); whitespace[32] = 0;
101 fprintf(fo, "Version: %d\n", swf->fileVersion);
102 fprintf(fo, "FrameRate: %f\n",swf->frameRate/256.0);
103 fprintf(fo, "FrameCount: %d\n",swf->frameCount);
104 fprintf(fo, "Width: %.2f\n",(swf->movieSize.xmax-swf->movieSize.xmin)/20.0);
105 fprintf(fo, "X-Offset: %.2f\n", swf->movieSize.xmin/20.0);
106 fprintf(fo, "Height: %.2f\n",(swf->movieSize.ymax-swf->movieSize.ymin)/20.0);
107 fprintf(fo, "Y-Offset: %.2f\n", swf->movieSize.ymin/20.0);
112 if(swf_isDefiningTag(tag)) {
113 fprintf(fo, "%s%s <%d>\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag));
114 swf_SetTagPos(tag, 2);
115 dumpTag(fo, prefix, tag);
116 } else if(swf_isPseudoDefiningTag(tag)) {
117 fprintf(fo, "%s%s <%d>\n", prefix, swf_TagGetName(tag), swf_GetDefineID(tag));
118 swf_SetTagPos(tag, 2);
119 dumpTag(fo, prefix, tag);
120 } else if(tag->id == ST_PLACEOBJECT || tag->id == ST_PLACEOBJECT2) {
122 swf_GetPlaceObject(tag, &po);
123 fprintf(fo, "%s%s <%d>\n", prefix,swf_TagGetName(tag), po.id);
125 swf_SetTagPos(tag, 0);
126 dumpTag(fo, prefix, tag);
127 swf_PlaceObjectFree(&po);
129 fprintf(fo, "%s%s\n", prefix, swf_TagGetName(tag));
130 dumpTag(fo, prefix, tag);
133 if(tag->id == ST_DEFINESPRITE) {
137 prefix = &whitespace[32-indent];
138 } else if(tag->id == ST_END) {
142 prefix = &whitespace[32-indent];
149 static void readline(FILE*fi, char*line, int maxlen) {
152 if(!fread(&line[pos],1,1,fi))
155 /* cut of preceding whitespace */
156 if(pos == 0 && (line[0] == 32 || line[0] == '\t'))
159 if(line[pos] == 13 || line[pos]==10)
166 /* cut off comments */
167 char*x=strchr(line,'#');
173 /* cut off trailing whitespace */
174 while(pos>=1 && (line[pos-1]==32 || line[pos-1]==9)) {
184 while(*s==32 || *s=='\t') s++;
185 sscanf(s, "%f%n", &x, &n);
187 fprintf(stderr, "Not a float: %s\n", s);
194 while(*s==32 || *s=='\t') s++;
195 sscanf(s, "%d%n", &i, &n);
197 fprintf(stderr, "Not an integer: %s\n", s);
202 return (int)(getFloat(x)*20);
207 int swf_TagNameToID(char*name)
211 memset(&tag, 0, sizeof(tag));
213 lookup = (char**)malloc(sizeof(char*)*65536);
214 for(t=0;t<65536;t++) {
216 lookup[t] = swf_TagGetName(&tag);
219 for(t=0;t<65536;t++) {
220 if(lookup[t] && !strcasecmp(name, lookup[t]))
223 fprintf(stderr, "Not a tag name: \"%s\"\n", name);
227 void parseFile(FILE*fi, SWF*swf)
231 memset(swf, 0, sizeof(SWF));
234 readline(fi, line, 1024);
237 colon = strchr(line, ':');
239 int num = colon - line;
241 if(num == 9 && !strncmp(line, "FrameRate", num)) {
242 swf->frameRate = getFloat(colon+1)*256;
243 } else if(num == 10 && !strncmp(line, "FrameCount", num)) {
244 swf->frameCount = getInt(colon+1);
245 } else if(num == 7 && !strncmp(line, "Version", num)) {
246 swf->fileVersion = getInt(colon+1);
247 } else if(num == 5 && !strncmp(line, "Width", num)) {
248 int width = getTwip(colon+1);
249 swf->movieSize.xmax += width;
250 } else if(num == 6 && !strncmp(line, "Height", num)) {
251 int height = getTwip(colon+1);
252 swf->movieSize.ymax += height;
253 } else if(num == 8 && !strncmp(line, "X-Offset", num)) {
254 int xoffset = getTwip(colon+1);
255 swf->movieSize.xmin += xoffset;
256 swf->movieSize.xmax += xoffset;
257 } else if(num == 8 && !strncmp(line, "Y-Offset", num)) {
258 int yoffset = getTwip(colon+1);
259 swf->movieSize.ymin += yoffset;
260 swf->movieSize.ymax += yoffset;
262 fprintf(stderr, "Ignored line \"%s\"\n", line);
269 readline(fi, line, 1024);
272 s = strchr(line, ' ');
273 br = strchr(line, '|');
276 /* DEFINESHAPE <id> ... type line */
278 tagname = strdup(line);
280 tagname = strdup(line);
283 id = swf_TagNameToID(tagname);
286 fprintf(stderr, "Ignored line \"%s\"\n", line);
289 tag = swf_InsertTag(tag, id);
293 /* | 00 34 fe c7 ... type line */
299 fprintf(stderr, "Discarded unassignable data %s\n", line);
305 if((*p>='a' && *p<='f') ||
306 (*p>='A' && *p<='F')) {
311 else if(*p>='0' && *p<='9') {
328 char swf_IsSWF(char*filename)
330 int fi = open(filename,O_RDONLY|O_BINARY);
336 if((buf[0] == 'F' || buf[0] == 'C') && buf[1] == 'W' && buf[2] == 'S')
341 int main (int argc,char ** argv)
347 processargs(argc, argv);
350 fprintf(stderr, "You must supply a filename.\n");
353 if(swf_IsSWF(filename)) {
354 fi = open(filename,O_RDONLY|O_BINARY);
356 perror("Couldn't open file: ");
359 if FAILED(swf_ReadSWF(fi,&swf)) {
360 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
364 dumpFile(&swf, stdout);
368 FILE*fi = fopen(filename, "rb");
369 parseFile(fi, &newswf);
372 char*sname = "output.swf";
373 f = open(sname,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
374 if FAILED(swf_WriteSWF(f,&newswf)) {
375 fprintf(stderr, "Unable to write output file: %s\n", sname);