2 main routine for swfcombine(1), which is a tool for merging .swf-files.
4 Part of the swftools package.
6 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
8 This file is distributed under the GPL, see file COPYING for details */
13 #include "../lib/args.h"
18 #include "../config.h"
20 char * master_filename = 0;
21 char * master_name = 0;
22 char * slave_filename[128];
23 char * slave_name[128];
26 float slave_scalex[128];
27 float slave_scaley[128];
30 char * outputname = "output.swf";
32 int args_callback_option(char*name,char*val) {
38 else if(!strcmp(name,"l"))
43 else if (!strcmp(name, "o"))
48 else if (!strcmp(name, "v"))
53 else if (!strcmp(name, "a"))
58 else if (!strcmp(name, "A"))
63 else if (!strcmp(name, "x"))
65 config.movex = atoi(val);
68 else if (!strcmp(name, "y"))
70 config.movey = atoi(val);
73 else if (!strcmp(name, "d"))
78 else if (!strcmp(name, "r"))
80 config.framerate = atoi(val)*256/100;
83 else if (!strcmp(name, "X"))
85 config.sizex = atoi(val)*20;
89 else if (!strcmp(name, "Y"))
91 config.sizey = atoi(val)*20;
95 else if (!strcmp(name, "s"))
97 config.scalex = config.scaley = atoi(val)/100.0;
100 else if (!strcmp(name, "t"))
102 if(master_filename) {
103 fprintf(stderr, "error with arguments. Try --help.\n");
107 master_filename = "__none__";
110 else if (!strcmp(name, "V"))
112 printf("swfcombine - part of %s %s\n", PACKAGE, VERSION);
117 fprintf(stderr, "Unknown option: -%s\n", name);
122 struct options_t options[] =
140 int args_callback_longoption(char*name,char*val) {
141 return args_long2shortoption(options, name, val);
144 int args_callback_command(char*name, char*val) {
145 char*myname = strdup(name);
147 filename = strchr(myname, '=');
152 // argument has no explicit name field. guess one from the file name
153 char*path = strrchr(myname, '/');
154 char*ext = strrchr(myname, '.');
155 if(!path) path = myname;
162 if(!master_filename) {
164 master_filename = filename;
165 master_name = myname;
167 logf("<verbose> slave entity %s (named \"%s\")\n", filename, myname);
169 slave_filename[numslaves] = filename;
170 slave_name[numslaves] = myname;
171 slave_movex[numslaves] = config.movex;
172 slave_movey[numslaves] = config.movey;
173 slave_scalex[numslaves] = config.scalex;
174 slave_scaley[numslaves] = config.scaley;
175 config.movex = config.movey = 0;
176 config.scalex = config.scaley = 1.0;
182 void args_callback_usage(char*name)
184 printf("Usage: %s [-l][-t] [-o outputfile] [[name=]masterfile] [-x xpos] [-y ypos] [-s scale] [name1=]slavefile1 .. [-x xpos] [-y ypos] [-s scale] [nameN=]slavefileN\n", name);
186 printf("-o outputfile (output) explicitly specify output file. (otherwise, output.swf will be used)\n");
187 printf("-t (stack) place each slave into a seperate frame (no master movie)\n");
188 printf("-a (cat) concatenate all slave files (no master movie)\n");
189 printf("-l (overlay) Don't remove any master objects, only overlay new objects\n");
190 printf("-c (clip) Clip the slave objects by the corresponding master objects\n");
191 printf("-v (verbose) Use more than one -v for greater effect \n");
192 printf("-d (dummy) Don't require slave objects \n");
193 printf("-x xpos (move x) Adjust position of slave by xpos twips (1/20 pixel)\n");
194 printf("-y ypos (move y) Adjust position of slave by ypos twips (1/20 pixel)\n");
195 printf("-s scale (scale) Adjust size of slave by scale%\n");
196 printf("-r framerate (rate) Set movie framerate (100 frames/sec)\n");
197 printf("-X width (width) Force movie width to scale (default: use master width) (not with -t)\n");
198 printf("-Y height (height) Force movie height to scale (default: use master height) (not with -t)\n");
201 /* read a whole file in memory */
202 char* fi_slurp(FILE*fi, unsigned int * setlength)
205 long long int length; //;)
206 long long int pos = 0;
207 fseek(fi,0,SEEK_END);
209 fseek(fi,0,SEEK_SET);
212 mem = malloc(length);
217 pos += fread(&mem[pos], 1, 65536, fi);
224 void fi_dump(FILE*fi, void*_mem, int length)
226 char*mem = (char*)_mem;
231 if (size > (length - pos))
232 size = (length - pos);
233 pos += fwrite(&mem[pos], 1, size, fi);
237 void makestackmaster(u8**masterdata, int*masterlength)
239 u8 head[] = {'F','W','S'};
247 /* scan all slaves for bounding box */
248 for(t=0;t<numslaves;t++)
250 FILE*fi=fopen(slave_filename[t],"rb");
253 struct flash_header head;
254 strlength += strlen(slave_name[t]) + 9;
256 logf("<fatal> Couldn't open %s.", slave_filename[t]);
259 ret = fread(data,1,256,fi);
261 logf("<fatal> File %s is to small (%d bytes)", slave_filename[t], ret);
265 head = swf_read_header();
266 logf("<verbose> File %s has bounding box %d:%d:%d:%d\n",
268 head.boundingBox.x1, head.boundingBox.y1,
269 head.boundingBox.x2, head.boundingBox.y2);
270 if(head.version > fileversion)
271 fileversion = head.version;
273 box = head.boundingBox;
275 if(head.boundingBox.x1 < box.x1)
276 box.x1 = head.boundingBox.x1;
277 if(head.boundingBox.y1 < box.y1)
278 box.y1 = head.boundingBox.y1;
279 if(head.boundingBox.x2 > box.x2)
280 box.x2 = head.boundingBox.x2;
281 if(head.boundingBox.y2 > box.y2)
282 box.y2 = head.boundingBox.y2;
284 logf("<verbose> New master bounding box is %d:%d:%d:%d\n",
290 /* we don't have a master, so we create one ourselves. */
291 /* (please notice the philosophical content) */
292 *masterlength = (numslaves + 1) * 32 + strlength;
293 *masterdata = (u8*)malloc(*masterlength);
295 memcpy(pos, head, sizeof(head));
297 *pos++ = fileversion;
299 *(u32*)pos = 0x12345678; // to be overwritten
301 writeRECT(&pos, &box);
302 *(u16*)pos = 0x2000; // framerate
304 *(u16*)pos = numslaves;
306 for(t=0;t<numslaves;t++)
312 sprintf(buf, "Frame%02d", t);
313 slave_name[t] = strdup(buf);
315 namelen = strlen(slave_name[t]);
317 *(u16*)&pos[0] = (u16)(TAGID_DEFINESPRITE<<6) + 6;
318 *(u16*)&pos[2] = t+1; //ID
319 *(u16*)&pos[4] = 0; // Frames
320 *(u16*)&pos[6] = 0; // TAG1
321 *(u16*)&pos[8] = (u16)(TAGID_PLACEOBJECT2<<6) + 6 + namelen;
322 *(u16*)&pos[10]= 34; //flags: id+name
323 *(u16*)&pos[11]= 1; // depth
324 *(u16*)&pos[13]= t+1; // id
325 sprintf(&pos[15],slave_name[t]);
326 pos += 15 + namelen + 1;
327 *(u16*)&pos[0]= (u16)(TAGID_SHOWFRAME<<6) + 0;
331 *(u16*)&pos[0]= (u16)(TAGID_REMOVEOBJECT2<<6) + 2;
332 *(u16*)&pos[2]= 1; // depth;
336 *(u16*)pos = TAGID_END<<6 + 0;
337 *masterlength = pos - *masterdata;
338 *fixpos = *masterlength;
341 struct config_t config;
342 int main(int argn, char *argv[])
346 unsigned int masterlength;
348 unsigned int slavelength;
350 unsigned int newlength;
354 config.antistream = 0;
355 config.alloctest = 0;
367 config.framerate = 0;
371 processargs(argn, argv);
372 initLog(0,-1,0,0,-1,config.loglevel);
377 logf("<error> Can't combine -l and -t");
381 logf("<error> Can't combine -c and -t");
384 logf("<verbose> (stacking) %d files found\n", numslaves);
386 makestackmaster(&masterdata,&masterlength);
388 logf("<verbose> Generated %d bytes of master data", masterlength);
391 logf("<verbose> master entity %s (named \"%s\")\n", master_filename, master_name);
392 fi = fopen(master_filename, "rb");
394 fprintf(stderr, "Failed to open %s\n", master_filename);
397 masterdata = fi_slurp(fi, &masterlength);
399 fprintf(stderr, "Failed to read from %s\n", master_filename);
402 logf("<debug> Read %d bytes from masterfile\n", masterlength);
406 for(t=0;t<numslaves;t++)
407 logf("<verbose> slave entity(%d) %s (named \"%s\")\n", t+1, slave_filename[t], slave_name[t]);
413 logf("<error> --dummy (-d) implies there are zero slave objects. You supplied %d.", numslaves);
417 slave_filename[t] = "!!dummy!!";
418 slave_name[t] = "!!dummy!!";
421 if (config.alloctest)
423 int*bitmap = malloc(sizeof(int)*65536);
424 memset(bitmap, -1, 65536*sizeof(int));
425 memset(bitmap, 1, 101*sizeof(int));
426 swf_relocate(masterdata, masterlength, bitmap);
427 newdata = masterdata;
428 newlength = masterlength;
435 logf("<error> You must have at least one slave entity.");
438 for(t = 0; t < numslaves; t++)
440 config.movex = slave_movex[t];
441 config.movey = slave_movey[t];
442 config.scalex = slave_scalex[t];
443 config.scaley = slave_scaley[t];
445 logf("<notice> Combine [%s]%s and [%s]%s", master_name, master_filename,
446 slave_name[t], slave_filename[t]);
449 fi = fopen(slave_filename[t], "rb");
451 fprintf(stderr, "Failed to open %s\n", slave_filename[t]);
454 slavedata = fi_slurp(fi, &slavelength);
456 fprintf(stderr, "Failed to read from %s\n", slave_filename[t]);
459 logf("<debug> Read %d bytes from slavefile\n", slavelength);
464 slavedata = (u8*)malloc(16);
468 slavedata[3] = 4; //version
469 *(u32*)&slavedata[4] = 14; // length
470 slavedata[8] = 0; // boundingbox
471 *(u16*)&slavedata[9] = 0; // rate
472 *(u16*)&slavedata[11] = 0; // count
473 *(u16*)&slavedata[13] = 0; // end tag
477 newdata = combine(masterdata, masterlength, slave_name[t], slavedata, slavelength, &newlength);
479 logf("<fatal> Aborting.");
484 masterdata = newdata;
485 masterlength = newlength;
489 logf("<debug> New File is %d bytes \n", newlength);
490 if(newdata && newlength) {
491 FILE*fi = fopen(outputname, "wb");
492 fi_dump(fi, newdata, newlength);