2 Allows to extract parts of the swf into a new file.
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/rfxswf.h"
14 #include "../lib/args.h"
18 char * destfilename = "output.swf";
22 char* extractframes = 0;
24 char* extractname = 0;
28 struct options_t options[] =
40 int args_callback_option(char*name,char*val)
42 if(!strcmp(name, "V")) {
43 printf("swfextract - part of %s %s\n", PACKAGE, VERSION);
46 else if(!strcmp(name, "o")) {
50 else if(!strcmp(name, "i")) {
53 fprintf(stderr, "You can only supply either name or id\n");
58 else if(!strcmp(name, "n")) {
61 fprintf(stderr, "You can only supply either name or id\n");
66 else if(!strcmp(name, "v")) {
70 else if(!strcmp(name, "f")) {
74 else if(!strcmp(name, "w")) {
79 printf("Unknown option: -%s\n", name);
85 int args_callback_longoption(char*name,char*val)
87 return args_long2shortoption(options, name, val);
89 void args_callback_usage(char*name)
91 printf("Usage: %s [-v] [-i id] file.swf\n", name);
92 printf("\t-v , --verbose\t\t\t Be more verbose\n");
93 printf("\t-o , --output filename\t\t set output filename\n");
94 printf("\t-i , --id ID\t\t\t ID of the object to extract\n");
95 printf("\t-n , --name name\t\t instance name of the object to extract\n");
96 printf("\t-f , --frame frame\t\t frame number to extract\n");
97 printf("\t-w , --hollow\t\t\t hollow mode: don't remove empty frames\n");
98 printf("\t-V , --version\t\t\t Print program version and exit\n");
100 int args_callback_command(char*name,char*val)
103 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
110 U8 mainr,maing,mainb;
111 /* 1 = used, not expanded,
113 5 = wanted, not expanded
121 void idcallback(void*data)
123 if(!(used[*(U16*)data]&1)) {
125 used[*(U16*)data] |= 1;
129 void enumerateIDs(TAG*tag, void(*callback)(void*))
135 data = (U8*)malloc(len);
136 *(U16*)data = (tag->id<<6)+63;
137 *(U32*)&data[2] = tag->len;
138 memcpy(&data[6], tag->data, tag->len);
141 data = (U8*)malloc(len);
142 *(U16*)data = (tag->id<<6)+tag->len;
143 memcpy(&data[2], tag->data, tag->len);
145 map_ids_mem(data, len, callback);
148 void extractTag(SWF*swf, char*filename)
159 memset(&newswf,0x00,sizeof(SWF)); // set global movie parameters
161 newswf.fileVersion = swf->fileVersion;
162 newswf.frameRate = swf->frameRate;
163 newswf.movieSize = swf->movieSize;
165 newswf.firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
166 desttag = newswf.firstTag;
170 swf_SetRGB(desttag,&rgb);
174 for(t=0;t<65536;t++) {
175 if(used[t] && !(used[t]&2)) {
176 if(tags[t]->id==ST_DEFINESPRITE) {
178 while(tag->id != ST_END)
180 enumerateIDs(tag, idcallback);
185 enumerateIDs(tags[t], idcallback);
192 srctag = swf->firstTag;
195 while(srctag && (srctag->id || sprite)) {
200 if(srctag->id == ST_END) {
203 if(srctag->id == ST_DEFINESPRITE)
205 if(swf_isDefiningTag(srctag)) {
206 int id = swf_GetDefineID(srctag);
210 if (((srctag->id == ST_PLACEOBJECT ||
211 srctag->id == ST_PLACEOBJECT2 ||
212 srctag->id == ST_STARTSOUND) && (used[swf_GetPlaceID(srctag)]&4) ) ||
213 (swf_isPseudoDefiningTag(srctag) && used[swf_GetDefineID(srctag)]) ||
220 if(srctag->id == ST_REMOVEOBJECT) {
221 if(!used[swf_GetPlaceID(srctag)])
226 TAG*ttag = (TAG*)malloc(sizeof(TAG));
227 desttag = swf_InsertTag(desttag, srctag->id);
228 desttag->len = desttag->memsize = srctag->len;
229 desttag->data = malloc(srctag->len);
230 memcpy(desttag->data, srctag->data, srctag->len);
235 srctag = srctag->next;
238 if(!extractframes && !hollow)
239 desttag = swf_InsertTag(desttag,ST_SHOWFRAME);
241 desttag = swf_InsertTag(desttag,ST_END);
243 f = open(filename, O_TRUNC|O_WRONLY|O_CREAT, 0644);
244 if FAILED(swf_WriteSWF(f,&newswf)) fprintf(stderr,"WriteSWF() failed.\n");
247 swf_FreeTags(&newswf); // cleanup
250 void listObjects(SWF*swf)
256 char*names[] = {"Shapes","MovieClips","Bitmaps","Sounds","Frames"};
257 printf("Objects in file %s:\n",filename);
265 (tag->id == ST_DEFINESHAPE ||
266 tag->id == ST_DEFINESHAPE2 ||
267 tag->id == ST_DEFINESHAPE3)) {
269 sprintf(text,"%d", swf_GetDefineID(tag));
272 if(tag->id == ST_DEFINESPRITE) {
275 sprintf(text,"%d", swf_GetDefineID(tag));
278 while(tag->id != ST_END)
282 if(t == 2 && (tag->id == ST_DEFINEBITSLOSSLESS ||
283 tag->id == ST_DEFINEBITSJPEG2 ||
284 tag->id == ST_DEFINEBITSLOSSLESS2 ||
285 tag->id == ST_DEFINEBITSJPEG3)) {
287 sprintf(text,"%d", swf_GetDefineID(tag));
290 if(t == 3 && (tag->id == ST_DEFINESOUND)) {
292 sprintf(text,"%d", swf_GetDefineID(tag));
295 if(t == 4 && (tag->id == ST_SHOWFRAME)) {
297 sprintf(text,"%d", frame);
305 printf("%s: ", names[t]);
316 int main (int argc,char ** argv)
325 char listavailable = 0;
326 processargs(argc, argv);
328 if(!extractframes && !extractids && ! extractname)
333 fprintf(stderr, "You must supply a filename.\n");
336 initLog(0,-1,0,0,-1, verbose);
338 f = open(filename,O_RDONLY);
342 perror("Couldn't open file: ");
345 if (swf_ReadSWF(f,&swf) < 0)
347 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
366 tagused = (char*)malloc(tagnum);
367 memset(tagused, 0, tagnum);
368 memset(used, 0, 65536);
369 memset(depths, 0, 65536);
374 if(swf_isAllowedSpriteTag(tag)) {
376 if(extractframes && is_in_range(frame, extractframes)) {
378 if(tag->id == ST_PLACEOBJECT || tag->id == ST_PLACEOBJECT2) {
379 depths[swf_GetDepth(tag)] = 1;
381 if(tag->id == ST_REMOVEOBJECT || tag->id == ST_REMOVEOBJECT2) {
382 int depth = swf_GetDepth(tag);
385 depths[swf_GetDepth(tag)] = 0;
388 if((tag->id == ST_REMOVEOBJECT || tag->id == ST_REMOVEOBJECT2) &&
389 (depths[swf_GetDepth(tag)]) && hollow) {
391 depths[swf_GetDepth(tag)] = 0;
395 enumerateIDs(tag, idcallback);
401 if(swf_isDefiningTag(tag)) {
402 int id = swf_GetDefineID(tag);
404 if(extractids && is_in_range(id, extractids)) {
409 else if (tag->id == ST_SETBACKGROUNDCOLOR) {
410 mainr = tag->data[0];
411 maing = tag->data[1];
412 mainb = tag->data[2];
414 else if(tag->id == ST_PLACEOBJECT2) {
415 char*name = swf_GetName(tag);
416 if(name && extractname && !strcmp(name, extractname)) {
417 int id = swf_GetPlaceID(tag);
421 depths[swf_GetDepth(tag)] = 1;
424 else if(tag->id == ST_SHOWFRAME) {
432 if(tag->id == ST_DEFINESPRITE) {
433 while(tag->id != ST_END) {
442 extractTag(&swf, destfilename);