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";
21 char* extractname = 0;
23 struct options_t options[] =
33 int args_callback_option(char*name,char*val)
35 if(!strcmp(name, "V")) {
36 printf("swfextract - part of %s %s\n", PACKAGE, VERSION);
39 if(!strcmp(name, "o")) {
43 if(!strcmp(name, "i")) {
44 extractid = atoi(val);
46 fprintf(stderr, "You can only supply either name or id\n");
51 if(!strcmp(name, "n")) {
54 fprintf(stderr, "You can only supply either name or id\n");
59 if(!strcmp(name, "v")) {
64 printf("Unknown option: -%s\n", name);
70 int args_callback_longoption(char*name,char*val)
72 return args_long2shortoption(options, name, val);
74 void args_callback_usage(char*name)
76 printf("Usage: %s [-v] [-i id] file.swf\n", name);
77 printf("\t-v , --verbose\t\t\t Be more verbose\n");
78 printf("\t-i , --id ID\t\t\t ID of the object to extract\n");
79 printf("\t-n , --name name\t\t\t instance name of the object to extract\n");
80 printf("\t-V , --version\t\t\t Print program version and exit\n");
82 int args_callback_command(char*name,char*val)
85 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
97 void idcallback(void*data)
99 if(!used[*(U16*)data]) {
101 used[*(U16*)data] = 1;
105 void enumerateIDs(TAG*tag, void(*callback)(void*))
111 data = (U8*)malloc(len);
112 *(U16*)data = (tag->id<<6)+63;
113 *(U32*)&data[2] = tag->len;
114 memcpy(&data[6], tag->data, tag->len);
117 data = (U8*)malloc(len);
118 *(U16*)data = (tag->id<<6)+tag->len;
119 memcpy(&data[2], tag->data, tag->len);
121 map_ids_mem(data, len, callback);
124 void extractTag(SWF*swf, TAG*maintag, char*filename)
134 int defineid = swf_GetDefineID(maintag);
135 memset(&newswf,0x00,sizeof(SWF)); // set global movie parameters
136 memset(used, 0,65536);
138 newswf.fileVersion = swf->fileVersion;
139 newswf.frameRate = swf->frameRate;
140 newswf.movieSize = swf->movieSize;
142 newswf.firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
143 desttag = newswf.firstTag;
147 swf_SetRGB(desttag,&rgb);
152 for(t=0;t<65536;t++) {
154 if(tags[t]->id==ST_DEFINESPRITE) {
156 while(tag->id != ST_END)
158 enumerateIDs(tag, idcallback);
163 enumerateIDs(tags[t], idcallback);
170 srctag = swf->firstTag;
171 while(srctag && (srctag->id || sprite)) {
175 if(srctag->id == ST_END) {
178 if(srctag->id == ST_DEFINESPRITE)
180 if(swf_isDefiningTag(srctag)) {
181 int id = swf_GetDefineID(srctag);
185 if(srctag->id == ST_PLACEOBJECT ||
186 srctag->id == ST_PLACEOBJECT2) {
187 if(swf_GetPlaceID(srctag) == defineid)
191 TAG*ttag = (TAG*)malloc(sizeof(TAG));
192 desttag = swf_InsertTag(desttag, srctag->id);
193 desttag->len = desttag->memsize = srctag->len;
194 desttag->data = malloc(srctag->len);
195 memcpy(desttag->data, srctag->data, srctag->len);
198 srctag = srctag->next;
200 desttag = swf_InsertTag(desttag,ST_SHOWFRAME);
202 f = open(filename, O_TRUNC|O_WRONLY|O_CREAT, 0644);
203 if FAILED(swf_WriteSWF(f,&newswf)) fprintf(stderr,"WriteSWF() failed.\n");
206 swf_FreeTags(&newswf); // cleanup
209 int main (int argc,char ** argv)
214 processargs(argc, argv);
218 fprintf(stderr, "You must supply a filename.\n");
221 initLog(0,-1,0,0,-1, verbose);
223 f = open(filename,O_RDONLY);
227 perror("Couldn't open file: ");
230 if FAILED(swf_ReadSWF(f,&swf))
232 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
240 if(swf_isDefiningTag(tag)) {
241 int id = swf_GetDefineID(tag);
244 else if (tag->id == ST_SETBACKGROUNDCOLOR) {
245 mainr = tag->data[0];
246 maing = tag->data[1];
247 mainb = tag->data[2];
249 else if(tag->id == ST_PLACEOBJECT2) {
250 char*name = swf_GetName(tag);
251 if(name && !strcmp(name, extractname)) {
252 int id = swf_GetPlaceID(tag);
253 if(extractid>=0 && id != extractid) {
254 fprintf(stderr, "Error: More than one instance with name \"%s\"", name);
257 extractid = swf_GetPlaceID(tag);
263 extractTag(&swf, tags[extractid], destfilename);