From 5e482c227a13ce3fa7c253a1fc648b42facfd141 Mon Sep 17 00:00:00 2001 From: kramm Date: Thu, 29 Nov 2001 18:21:11 +0000 Subject: [PATCH] added tool "swfextract". --- src/Makefile.in | 24 +++-- src/swfextract.c | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+), 7 deletions(-) create mode 100644 src/swfextract.c diff --git a/src/Makefile.in b/src/Makefile.in index 085b234..e524bfd 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -66,17 +66,19 @@ VERSION = @VERSION@ jpeg2swf_SOURCES = jpeg2swf.c swfdump_SOURCES = swfdump.c +swfextract_SOURCES = swfextract.c swfcombine_SOURCES = bitio.c bitio.h reloc.c reloc.h combine.c combine.h flash.c flash.h swfcombine.c types.h swfstrings_SOURCES = swfstrings.c jpeg2swf_LINK = $(CCLD) ../lib/rfxswf.o -o $@ swfdump_LINK = $(CCLD) ../lib/rfxswf.o -o $@ +swfextract_LINK = $(CCLD) ../lib/log.o ../lib/rfxswf.o -o $@ swfcombine_LINK = $(CCLD) ../lib/log.o -o $@ swfstrings_LINK = $(CCLD) ../lib/log.o ../lib/rfxswf.o -o $@ -man_MANS = swfcombine.1 swfstrings.1 swfdump.1 jpeg2swf.1 +man_MANS = swfcombine.1 swfstrings.1 swfextract.1 swfextract.1 swfdump.1 jpeg2swf.1 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../config.h CONFIG_CLEAN_FILES = -bin_PROGRAMS = swfcombine$(EXEEXT) swfstrings$(EXEEXT) swfdump$(EXEEXT) @JPEG2SWF@ +bin_PROGRAMS = swfcombine$(EXEEXT) swfstrings$(EXEEXT) swfextract$(EXEEXT) swfdump$(EXEEXT) @JPEG2SWF@ PROGRAMS = $(bin_PROGRAMS) @@ -96,6 +98,10 @@ swfdump_OBJECTS = swfdump.o swfdump_LDADD = $(LDADD) swfdump_DEPENDENCIES = swfdump_LDFLAGS = +swfextract_OBJECTS = swfextract.o reloc.o bitio.o flash.o +swfextract_LDADD = $(LDADD) +swfextract_DEPENDENCIES = +swfextract_LDFLAGS = jpeg2swf_OBJECTS = jpeg2swf.o jpeg2swf_LDADD = $(LDADD) jpeg2swf_DEPENDENCIES = @@ -116,10 +122,10 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP_ENV = --best DEP_FILES = .deps/bitio.P .deps/combine.P .deps/flash.P \ -.deps/jpeg2swf.P .deps/reloc.P .deps/swfcombine.P .deps/swfdump.P \ +.deps/jpeg2swf.P .deps/reloc.P .deps/swfcombine.P .deps/swfextract.P .deps/swfdump.P \ .deps/swfstrings.P -SOURCES = $(swfcombine_SOURCES) $(swfstrings_SOURCES) $(swfdump_SOURCES) $(jpeg2swf_SOURCES) -OBJECTS = $(swfcombine_OBJECTS) $(swfstrings_OBJECTS) $(swfdump_OBJECTS) $(jpeg2swf_OBJECTS) +SOURCES = $(swfcombine_SOURCES) $(swfstrings_SOURCES) $(swfextract_SOURCES) $(swfdump_SOURCES) $(jpeg2swf_SOURCES) +OBJECTS = $(swfcombine_OBJECTS) $(swfstrings_OBJECTS) $(swfextract_SOURCES) $(swfdump_OBJECTS) $(jpeg2swf_OBJECTS) all: all-redirect .SUFFIXES: @@ -170,7 +176,7 @@ swfcombine$(EXEEXT): $(swfcombine_OBJECTS) $(swfcombine_DEPENDENCIES) @rm -f swfcombine$(EXEEXT) $(swfcombine_LINK) $(swfcombine_LDFLAGS) $(swfcombine_OBJECTS) $(swfcombine_LDADD) $(LIBS) -swfstrings$(EXEEXT): $(swfstrings_OBJECTS) $(swfstrings_DEPENDENCIES) +swfstrings$(EXEEXT): $(swfstrings_OBJECTS) $(swfstrings_DEPENDENCIES) ../lib/rfxswf.o @rm -f swfstrings$(EXEEXT) $(swfstrings_LINK) $(swfstrings_LDFLAGS) $(swfstrings_OBJECTS) $(swfstrings_LDADD) $(LIBS) @@ -178,7 +184,11 @@ swfdump$(EXEEXT): $(swfdump_OBJECTS) $(swfdump_DEPENDENCIES) ../lib/rfxswf.o @rm -f swfdump$(EXEEXT) $(swfdump_LINK) $(swfdump_LDFLAGS) $(swfdump_OBJECTS) $(swfdump_LDADD) $(LIBS) -jpeg2swf$(EXEEXT): $(jpeg2swf_OBJECTS) $(jpeg2swf_DEPENDENCIES) +swfextract$(EXEEXT): $(swfextract_OBJECTS) $(swfextract_DEPENDENCIES) ../lib/rfxswf.o + @rm -f swfextract$(EXEEXT) + $(swfextract_LINK) $(swfextract_LDFLAGS) $(swfextract_OBJECTS) $(swfextract_LDADD) $(LIBS) + +jpeg2swf$(EXEEXT): $(jpeg2swf_OBJECTS) $(jpeg2swf_DEPENDENCIES) ../lib/rfxswf.o @rm -f jpeg2swf$(EXEEXT) $(jpeg2swf_LINK) $(jpeg2swf_LDFLAGS) $(jpeg2swf_OBJECTS) $(jpeg2swf_LDADD) $(LIBS) diff --git a/src/swfextract.c b/src/swfextract.c new file mode 100644 index 0000000..d0dc2fc --- /dev/null +++ b/src/swfextract.c @@ -0,0 +1,268 @@ +/* swfextract.c + Allows to extract parts of the swf into a new file. + + Part of the swftools package. + + Copyright (c) 2001 Matthias Kramm + + This file is distributed under the GPL, see file COPYING for details */ + +#include +#include +#include +#include "../lib/rfxswf.h" +#include "../lib/args.h" +#include "reloc.h" + +char * filename = 0; +char * destfilename = "output.swf"; +int verbose = 2; +int extractid = -1; +char* extractname = 0; + +struct options_t options[] = +{ + {"o","output"}, + {"v","verbose"}, + {"i","id"}, + {"n","name"}, + {"V","version"}, + {0,0} +}; + +int args_callback_option(char*name,char*val) +{ + if(!strcmp(name, "V")) { + printf("swfextract - part of %s %s\n", PACKAGE, VERSION); + exit(0); + } + if(!strcmp(name, "o")) { + destfilename = val; + return 1; + } + if(!strcmp(name, "i")) { + extractid = atoi(val); + if(extractname) { + fprintf(stderr, "You can only supply either name or id\n"); + exit(1); + } + return 1; + } + if(!strcmp(name, "n")) { + extractname = val; + if(extractid>=0) { + fprintf(stderr, "You can only supply either name or id\n"); + exit(1); + } + return 1; + } + if(!strcmp(name, "v")) { + verbose ++; + return 0; + } + else { + printf("Unknown option: -%s\n", name); + return 0; + } + + return 0; +} +int args_callback_longoption(char*name,char*val) +{ + return args_long2shortoption(options, name, val); +} +void args_callback_usage(char*name) +{ + printf("Usage: %s [-v] [-i id] file.swf\n", name); + printf("\t-v , --verbose\t\t\t Be more verbose\n"); + printf("\t-i , --id ID\t\t\t ID of the object to extract\n"); + printf("\t-n , --name name\t\t\t instance name of the object to extract\n"); + printf("\t-V , --version\t\t\t Print program version and exit\n"); +} +int args_callback_command(char*name,char*val) +{ + if(filename) { + fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n", + filename, name); + } + filename = name; + return 0; +} + +U8 mainr,maing,mainb; +char used[65536]; +TAG*tags[65536]; +int changed; + +void idcallback(void*data) +{ + if(!used[*(U16*)data]) { + changed = 1; + used[*(U16*)data] = 1; + } +} + +void enumerateIDs(TAG*tag, void(*callback)(void*)) +{ + U8*data; + int len = tag->len; + if(tag->len>=64) { + len += 6; + data = (U8*)malloc(len); + *(U16*)data = (tag->id<<6)+63; + *(U32*)&data[2] = tag->len; + memcpy(&data[6], tag->data, tag->len); + } else { + len += 2; + data = (U8*)malloc(len); + *(U16*)data = (tag->id<<6)+tag->len; + memcpy(&data[2], tag->data, tag->len); + } + map_ids_mem(data, len, callback); +} + +void extractTag(SWF*swf, TAG*maintag, char*filename) +{ + SWF newswf; + TAG*desttag; + TAG*srctag; + RGBA rgb; + char sprite; + int f; + int t; + int copy = 0; + int defineid = swf_GetDefineID(maintag); + memset(&newswf,0x00,sizeof(SWF)); // set global movie parameters + memset(used, 0,65536); + + newswf.fileVersion = swf->fileVersion; + newswf.frameRate = swf->frameRate; + newswf.movieSize = swf->movieSize; + + newswf.firstTag = swf_InsertTag(NULL,ST_SETBACKGROUNDCOLOR); + desttag = newswf.firstTag; + rgb.r = mainr; + rgb.g = maing; + rgb.b = mainb; + swf_SetRGB(desttag,&rgb); + + used[defineid] = 1; + do { + changed = 0; + for(t=0;t<65536;t++) { + if(used[t]==1) { + if(tags[t]->id==ST_DEFINESPRITE) { + TAG*tag = tags[t]; + while(tag->id != ST_END) + { + enumerateIDs(tag, idcallback); + tag = tag->next; + } + } + else + enumerateIDs(tags[t], idcallback); + used[t] = 2; + } + } + } + while(changed); + + srctag = swf->firstTag; + while(srctag && (srctag->id || sprite)) { + if(!sprite) { + copy = 0; + } + if(srctag->id == ST_END) { + sprite = 0; + } + if(srctag->id == ST_DEFINESPRITE) + sprite = 1; + if(swf_isDefiningTag(srctag)) { + int id = swf_GetDefineID(srctag); + if(used[id]) + copy = 1; + } else + if(srctag->id == ST_PLACEOBJECT || + srctag->id == ST_PLACEOBJECT2) { + if(swf_GetPlaceID(srctag) == defineid) + copy = 1; + } + if(copy) { + TAG*ttag = (TAG*)malloc(sizeof(TAG)); + desttag = swf_InsertTag(desttag, srctag->id); + desttag->len = desttag->memsize = srctag->len; + desttag->data = malloc(srctag->len); + memcpy(desttag->data, srctag->data, srctag->len); + } + + srctag = srctag->next; + } + desttag = swf_InsertTag(desttag,ST_SHOWFRAME); + + f = open(filename, O_TRUNC|O_WRONLY|O_CREAT, 0644); + if FAILED(swf_WriteSWF(f,&newswf)) fprintf(stderr,"WriteSWF() failed.\n"); + close(f); + + swf_FreeTags(&newswf); // cleanup +} + +int main (int argc,char ** argv) +{ + TAG*tag; + SWF swf; + int f; + processargs(argc, argv); + + if(!filename) + { + fprintf(stderr, "You must supply a filename.\n"); + return 1; + } + initLog(0,-1,0,0,-1, verbose); + + f = open(filename,O_RDONLY); + + if (f<0) + { + perror("Couldn't open file: "); + exit(1); + } + if FAILED(swf_ReadSWF(f,&swf)) + { + fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename); + close(f); + exit(1); + } + + tag = swf.firstTag; + + while(tag) { + if(swf_isDefiningTag(tag)) { + int id = swf_GetDefineID(tag); + tags[id] = tag; + } + else if (tag->id == ST_SETBACKGROUNDCOLOR) { + mainr = tag->data[0]; + maing = tag->data[1]; + mainb = tag->data[2]; + } + else if(tag->id == ST_PLACEOBJECT2) { + char*name = swf_GetName(tag); + if(name && !strcmp(name, extractname)) { + int id = swf_GetPlaceID(tag); + if(extractid>=0 && id != extractid) { + fprintf(stderr, "Error: More than one instance with name \"%s\"", name); + exit(1); + } + extractid = swf_GetPlaceID(tag); + } + } + tag = tag->next; + } + if(tags[extractid]) + extractTag(&swf, tags[extractid], destfilename); + + swf_FreeTags(&swf); + return 0; +} + -- 1.7.10.4