fixed format warnings
[swftools.git] / src / swfextract.c
index a5794c6..e385f1f 100644 (file)
@@ -42,6 +42,7 @@ char* extractjpegids = 0;
 char* extractfontids = 0;
 char* extractpngids = 0;
 char* extractsoundids = 0;
+char* extractbinaryids = 0;
 char extractmp3 = 0;
 
 char* extractname = 0;
@@ -68,6 +69,7 @@ struct options_t options[] =
  {"f","frame"},
  {"F","font"},
  {"V","version"},
+ {"b","binary"},
  {0,0}
 };
 
@@ -114,6 +116,7 @@ int args_callback_option(char*name,char*val)
            fprintf(stderr, "Only one --jpegs argument is allowed. (Try to use a range, e.g. -j 1,2,3)\n");
            exit(1);
        }
+       /* TODO: count number of IDs in val range */
        numextracts++;
        extractjpegids = val;
        return 1;
@@ -136,6 +139,15 @@ int args_callback_option(char*name,char*val)
        extractsoundids = val;
        return 1;
     } 
+    else if(!strcmp(name, "b")) {
+       if(extractbinaryids) {
+           fprintf(stderr, "Only one --binary argument is allowed. (Try to use a range, e.g. -s 1,2,3)\n");
+           exit(1);
+       }
+       numextracts++;
+       extractbinaryids = val;
+       return 1;
+    } 
 #ifdef _ZLIB_INCLUDED_
     else if(!strcmp(name, "p")) {
        if(extractpngids) {
@@ -340,6 +352,8 @@ void extractTag(SWF*swf, char*filename)
        }
        if(srctag->id == ST_DEFINESPRITE)
            sprite = 1;
+        if(srctag->id == ST_JPEGTABLES)
+            copy = 1;
        if(swf_isDefiningTag(srctag)) {
            int id = swf_GetDefineID(srctag);
            if(used[id])  {
@@ -480,9 +494,12 @@ int isOfType(int t, TAG*tag)
     if(t == 4 && (tag->id == ST_DEFINESOUND)) {
        show = 1;
     }
-    if(t == 5 && (tag->id == ST_DEFINEFONT || tag->id == ST_DEFINEFONT2)) {
+    if(t == 5 && (tag->id == ST_DEFINEFONT || tag->id == ST_DEFINEFONT2 || tag->id == ST_DEFINEFONT3)) {
        show = 1;
     }
+    if (t== 6 && (tag->id == ST_DEFINEBINARY)) {
+        show = 1;
+    }
     return show;
 }
 
@@ -492,8 +509,8 @@ void listObjects(SWF*swf)
     char first;
     int t;
     int frame = 0;
-    char*names[] = {"Shape", "MovieClip", "JPEG", "PNG", "Sound", "Font"};
-    char*options[] = {"-i", "-i", "-j", "-p", "-s", "-F"};
+    char*names[] = {"Shape", "MovieClip", "JPEG", "PNG", "Sound", "Font", "Binary"};
+    char*options[] = {"-i", "-i", "-j", "-p", "-s", "-F","-b"};
     int mp3=0;
     printf("Objects in file %s:\n",filename);
     swf_FoldAll(swf);
@@ -583,21 +600,21 @@ void handlefont(SWF*swf, TAG*tag)
        printf("Couldn't extract font %d\n", id);
        return;
     }
-    if(!f->layout)
-       swf_FontCreateLayout(f);
 
     swf_WriteFont(f, filename);
     swf_FontFree(f);
 }
 
-U8*jpegtables = 0;
-int jpegtablessize;
+static char has_jpegtables=0;
+static U8*jpegtables = 0;
+static int jpegtablessize = 0;
 
 void handlejpegtables(TAG*tag)
 {
     if(tag->id == ST_JPEGTABLES) {
        jpegtables = tag->data;
        jpegtablessize = tag->len;
+       has_jpegtables = 1;
     }
 }
 
@@ -615,7 +632,7 @@ int findjpegboundary(U8*data, int len)
 {
     int t;
     int pos=-1;
-    for(t=0;t<len;t++) {
+    for(t=0;t<len-4;t++) {
        if(data[t  ]==0xff &&
           data[t+1]==0xd9 &&
           data[t+2]==0xff &&
@@ -642,10 +659,14 @@ void handlejpeg(TAG*tag)
     /* swf jpeg images have two streams, which both start with ff d8 and
        end with ff d9. The following code handles sorting the middle
        <ff d9 ff d8> bytes out, so that one stream remains */
-    if(tag->id == ST_DEFINEBITSJPEG && tag->len>2 && jpegtables) {
+    if(tag->id == ST_DEFINEBITSJPEG && tag->len>2 && has_jpegtables) {
        fi = save_fopen(filename, "wb");
-       fwrite(jpegtables, 1, jpegtablessize-2, fi); //don't write end tag (ff,d8)
-       fwrite(&tag->data[2+2], tag->len-2-2, 1, fi); //don't write start tag (ff,d9)
+       if(jpegtablessize>=2) {
+           fwrite(jpegtables, 1, jpegtablessize-2, fi); //don't write end tag (ff,d8)
+           fwrite(&tag->data[2+2], tag->len-2-2, 1, fi); //don't write start tag (ff,d9)
+       } else {
+           fwrite(tag->data+2, tag->len-2, 1, fi);
+       }
        fclose(fi);
     }
     else if(tag->id == ST_DEFINEBITSJPEG2 && tag->len>2) {
@@ -666,17 +687,21 @@ void handlejpeg(TAG*tag)
     else if(tag->id == ST_DEFINEBITSJPEG3 && tag->len>6) {
        U32 end = GET32(&tag->data[2])+6;
        int pos = findjpegboundary(&tag->data[6], tag->len-6);
-       if(pos<0)
-           return;
-       pos+=6;
-       fi = save_fopen(filename, "wb");
-       fwrite(&tag->data[6], pos-6, 1, fi);
-       fwrite(&tag->data[pos+4], end-(pos+4), 1, fi);
-       fclose(fi);
+       if(pos<0) {
+            fi = save_fopen(filename, "wb");
+            fwrite(&tag->data[6], end-6, 1, fi);
+            fclose(fi);
+        } else {
+            pos+=6;
+            fi = save_fopen(filename, "wb");
+            fwrite(&tag->data[6], pos-6, 1, fi);
+            fwrite(&tag->data[pos+4], end-(pos+4), 1, fi);
+            fclose(fi);
+        }
     }
     else {
        int id = GET16(tag->data);
-       fprintf(stderr, "Object %d is not a JPEG picture!\n",id);
+       fprintf(stderr, "Object %d is not a JPEG picture!\n", id);
        exit(1);
     }
 }
@@ -818,7 +843,7 @@ void handlelossless(TAG*tag)
     }
     msg("<verbose> Uncompressed image is %d bytes (%d colormap)", datalen, (3+alpha)*cols);
     pos = 0;
-    datalen2 = datalen;
+    datalen2 = datalen+16;
     data2 = malloc(datalen2);
     palette = (RGBA*)malloc(cols*sizeof(RGBA));
 
@@ -931,7 +956,7 @@ void handlelossless(TAG*tag)
 }
 #endif
 
-FILE*mp3file;
+static FILE*mp3file=0;
 void handlesoundstream(TAG*tag)
 {
     char*filename = "output.mp3";
@@ -1012,6 +1037,30 @@ void handledefinesound(TAG*tag)
     fclose(fi);
 }
 
+void handlebinary(TAG*tag) {
+    FILE *fout = NULL;
+    char buf[100];
+    char *filename = buf;
+    int len = tag->memsize;
+    int dx = 6; // offset to binary data
+    if (tag->id!=ST_DEFINEBINARY) {
+        fprintf(stderr, "Object %d is not a binary entity!\n",
+                        GET16(tag->data));
+        return;
+    }
+    sprintf(buf, "binary%d.bin", GET16(tag->data));
+    if(numextracts==1) {
+       filename = destfilename;
+       if(!strcmp(filename,"output.swf")) {
+           sprintf(buf, "output.bin");
+           filename = buf;
+       }
+    }
+    fout = fopen(filename, "wb");
+    fwrite(tag->data+dx,len-dx,1,fout);
+    fclose(fout);
+}
+
 int main (int argc,char ** argv)
 { 
     TAG*tag;
@@ -1025,7 +1074,7 @@ int main (int argc,char ** argv)
     processargs(argc, argv);
 
     if(!extractframes && !extractids && ! extractname && !extractjpegids && !extractpngids
-       && !extractmp3 && !extractsoundids && !extractfontids)
+       && !extractmp3 && !extractsoundids && !extractfontids && !extractbinaryids)
        listavailable = 1;
 
     if(!originalplaceobjects && movetozero) {
@@ -1110,8 +1159,9 @@ int main (int argc,char ** argv)
                handlesoundstream(tag);
        }
 
-       if(tag->id == ST_JPEGTABLES)
+       if(tag->id == ST_JPEGTABLES) {
            handlejpegtables(tag);
+       }
 
        if(swf_isDefiningTag(tag)) {
            int id = swf_GetDefineID(tag);
@@ -1129,6 +1179,9 @@ int main (int argc,char ** argv)
            if(extractsoundids && is_in_range(id, extractsoundids)) {
                handledefinesound(tag);
            }
+           if(extractbinaryids && is_in_range(id, extractbinaryids)) {
+               handlebinary(tag);
+           }
 #ifdef _ZLIB_INCLUDED_
            if(extractpngids && is_in_range(id, extractpngids)) {
                handlelossless(tag);
@@ -1173,8 +1226,13 @@ int main (int argc,char ** argv)
     if (found)
        extractTag(&swf, destfilename);
 
-    if(mp3file)
+    if(mp3file) {
        fclose(mp3file);
+    } else {
+        if(extractmp3) {
+            msg("<error> Didn't find a soundstream in file");
+        }
+    }
 
     swf_FreeTags(&swf);
     return 0;