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, int defineid, char*filename)
134 memset(&newswf,0x00,sizeof(SWF)); // set global movie parameters
135 memset(used, 0,65536);
137 newswf.fileVersion = swf->fileVersion;
138 newswf.frameRate = swf->frameRate;
139 newswf.movieSize = swf->movieSize;
141 newswf.firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR);
142 desttag = newswf.firstTag;
146 swf_SetRGB(desttag,&rgb);
151 for(t=0;t<65536;t++) {
153 if(tags[t]->id==ST_DEFINESPRITE) {
155 while(tag->id != ST_END)
157 enumerateIDs(tag, idcallback);
162 enumerateIDs(tags[t], idcallback);
169 srctag = swf->firstTag;
170 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) && swf_GetPlaceID(srctag) == defineid) ||
187 (swf_isPseudoDefiningTag(srctag) && used[swf_GetDefineID(srctag)]))
195 TAG*ttag = (TAG*)malloc(sizeof(TAG));
196 desttag = swf_InsertTag(desttag, srctag->id);
197 desttag->len = desttag->memsize = srctag->len;
198 desttag->data = malloc(srctag->len);
199 memcpy(desttag->data, srctag->data, srctag->len);
204 srctag = srctag->next;
206 desttag = swf_InsertTag(desttag,ST_SHOWFRAME);
207 desttag = swf_InsertTag(desttag,ST_END);
209 f = open(filename, O_TRUNC|O_WRONLY|O_CREAT, 0644);
210 if FAILED(swf_WriteSWF(f,&newswf)) fprintf(stderr,"WriteSWF() failed.\n");
213 swf_FreeTags(&newswf); // cleanup
216 int main (int argc,char ** argv)
221 processargs(argc, argv);
225 fprintf(stderr, "You must supply a filename.\n");
228 initLog(0,-1,0,0,-1, verbose);
230 f = open(filename,O_RDONLY);
234 perror("Couldn't open file: ");
237 if FAILED(swf_ReadSWF(f,&swf))
239 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
247 if(swf_isDefiningTag(tag)) {
248 int id = swf_GetDefineID(tag);
251 else if (tag->id == ST_SETBACKGROUNDCOLOR) {
252 mainr = tag->data[0];
253 maing = tag->data[1];
254 mainb = tag->data[2];
256 else if(tag->id == ST_PLACEOBJECT2) {
257 char*name = swf_GetName(tag);
258 if(name && extractname && !strcmp(name, extractname)) {
259 int id = swf_GetPlaceID(tag);
260 if(extractid>=0 && id != extractid) {
261 fprintf(stderr, "Error: More than one instance with name \"%s\"", name);
264 extractid = swf_GetPlaceID(tag);
270 extractTag(&swf, extractid, destfilename);