added tool "swfextract".
authorkramm <kramm>
Thu, 29 Nov 2001 18:21:11 +0000 (18:21 +0000)
committerkramm <kramm>
Thu, 29 Nov 2001 18:21:11 +0000 (18:21 +0000)
src/Makefile.in
src/swfextract.c [new file with mode: 0644]

index 085b234..e524bfd 100644 (file)
@@ -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 (file)
index 0000000..d0dc2fc
--- /dev/null
@@ -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 <kramm@quiss.org>
+
+   This file is distributed under the GPL, see file COPYING for details */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#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;
+}
+