added flash 8 fill styles
[swftools.git] / src / swfdump.c
index 051b8a2..4bb5284 100644 (file)
@@ -51,18 +51,21 @@ static char * indent = "                ";
 static int placements = 0;
 static int action = 0;
 static int html = 0;
+static int xhtml = 0;
 static int xy = 0;
 static int showtext = 0;
 static int showshapes = 0;
 static int hex = 0;
 static int used = 0;
 static int bbox = 0;
+static int cumulative = 0;
 
 static struct options_t options[] = {
 {"h", "help"},
 {"D", "full"},
 {"V", "version"},
 {"e", "html"},
+{"E", "xhtml"},
 {"a", "action"},
 {"t", "text"},
 {"s", "shapes"},
@@ -103,6 +106,15 @@ int args_callback_option(char*name,char*val)
         html = 1;
         return 0;
     }
+    else if(name[0]=='c') {
+        cumulative = 1;
+        return 0;
+    }
+    else if(name[0]=='E') {
+        html = 1;
+        xhtml = 1;
+        return 0;
+    }
     else if(name[0]=='X') {
        xy |= 1;
        return 0;
@@ -155,6 +167,7 @@ void args_callback_usage(char *name)
     printf("-D , --full                    Show everything. Same as -atp\n");
     printf("-V , --version                 Print version info and exit\n");
     printf("-e , --html                    Print out html code for embedding the file\n");
+    printf("-E , --xhtml                   Print out xhtml code for embedding the file\n");
     printf("-a , --action                  Disassemble action tags\n");
     printf("-t , --text                    Show text fields (like swfstrings).\n");
     printf("-s , --shapes                  Show shape coordinates/styles\n");
@@ -263,8 +276,12 @@ void textcallback(void*self, int*glyphs, int*ypos, int nr, int fontid, int fonts
            if(glyphs[t] >= fonts[font]->numchars  /*glyph is in range*/
                    || !fonts[font]->glyph2ascii /* font has ascii<->glyph mapping */
              ) a = glyphs[t];
-           else
-               a = fonts[font]->glyph2ascii[glyphs[t]];
+           else {
+               if(fonts[font]->glyph2ascii[glyphs[t]])
+                   a = fonts[font]->glyph2ascii[glyphs[t]];
+               else
+                   a = glyphs[t];
+           }
        } else {
            a = glyphs[t];
        }
@@ -286,7 +303,7 @@ void handleDefineSound(TAG*tag)
 {
     U16 id = swf_GetU16(tag);
     U8 flags = swf_GetU8(tag);
-    int compression = (flags>>4)&3;
+    int compression = (flags>>4)&7;
     int rate = (flags>>2)&3;
     int bits = flags&2?16:8;
     int stereo = flags&1;
@@ -294,6 +311,8 @@ void handleDefineSound(TAG*tag)
     if(compression == 0) printf("Raw ");
     else if(compression == 1) printf("ADPCM ");
     else if(compression == 2) printf("MP3 ");
+    else if(compression == 3) printf("Raw little-endian ");
+    else if(compression == 6) printf("ASAO ");
     else printf("? ");
     if(rate == 0) printf("5.5Khz ");
     if(rate == 1) printf("11Khz ");
@@ -456,11 +475,13 @@ void handleVideoFrame(TAG*tag, char*prefix)
 
 void handlePlaceObject2(TAG*tag, char*prefix)
 {
-    U8 flags = swf_GetU8(tag);
+    U8 flags;
     MATRIX m;
     CXFORM cx;
     char pstr[3][160];
     int ppos[3] = {0,0,0};
+    swf_SetTagPos(tag, 0);
+    flags = swf_GetU8(tag);
     swf_GetU16(tag); //depth
 
     //flags&1: move
@@ -551,16 +572,19 @@ void handlePlaceObject2(TAG*tag, char*prefix)
 void handlePlaceObject(TAG*tag, char*prefix)
 {
     TAG*tag2 = swf_InsertTag(0, ST_PLACEOBJECT2);
-
-    U16 id = swf_GetU16(tag);
-    U16 depth = swf_GetU16(tag);
+    U16 id, depth;
     MATRIX matrix; 
     CXFORM cxform;
+
+    swf_SetTagPos(tag, 0);
+    id = swf_GetU16(tag);
+    depth = swf_GetU16(tag);
     swf_GetMatrix(tag, &matrix);
     swf_GetCXForm(tag, &cxform, 0);
 
-    swf_SetU8(tag2, 14);
+    swf_SetU8(tag2, 14 /* char, matrix, cxform */);
     swf_SetU16(tag2, depth);
+    swf_SetU16(tag2, id);
     swf_SetMatrix(tag2, &matrix);
     swf_SetCXForm(tag2, &cxform, 1);
 
@@ -576,9 +600,15 @@ char* fillstyle2str(FILLSTYLE*style)
        case 0x10: case 0x12:
            sprintf(stylebuf, "GRADIENT (%d steps)", style->gradient.num);
            break;
-       case 0x40: case 0x41:
+       case 0x40: case 0x42:
            /* TODO: display information about that bitmap */
-           sprintf(stylebuf, "BITMAP %d", style->id_bitmap);
+           sprintf(stylebuf, "BITMAPt%s %d", (style->type&2)?"n":"", style->id_bitmap);
+           /* TODO: show matrix */
+           break;
+       case 0x41: case 0x43:
+           /* TODO: display information about that bitmap */
+           sprintf(stylebuf, "BITMAPc%s %d", (style->type&2)?"n":"", style->id_bitmap);
+           /* TODO: show matrix */
            break;
        default:
            sprintf(stylebuf, "UNKNOWN[%02x]",style->type);
@@ -743,6 +773,7 @@ int main (int argc,char ** argv)
     char* framelabel = 0;
     char prefix[128];
     int filesize = 0;
+    int filepos = 0;
     prefix[0] = 0;
     memset(idtab,0,65536);
 
@@ -816,23 +847,34 @@ int main (int argc,char ** argv)
            fprintf(stderr, "Fileversion>9\n");
            exit(1);
        }
-       printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
-              " WIDTH=\"%d\"\n"
-              //" BGCOLOR=#ffffffff\n"?
-              " HEIGHT=\"%d\"\n"
-              //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
-              " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
-               "  <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
-              "  <PARAM NAME=\"PLAY\" VALUE=\"true\">\n" 
-              "  <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
-              "  <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
-              "  <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
-              "   PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
-              "   TYPE=\"application/x-shockwave-flash\"\n"
-              "   PLUGINSPAGE=\"http://www.macromedia.com/go/getflashplayer\">\n"
-               "  </EMBED>\n" 
-              "</OBJECT>\n", xsize, ysize, fileversions[swf.fileVersion], 
-                             filename, filename, xsize, ysize);
+
+       if(xhtml) {
+           printf("<object type=\"application/x-shockwave-flash\" data=\"%s\" width=\"%d\" height=\"%d\">\n"
+                           "<param name=\"movie\" value=\"%s\"/>\n"
+                           "<param name=\"play\" value=\"true\"/>\n"
+                           "<param name=\"loop\" value=\"false\"/>\n"
+                           "<param name=\"quality\" value=\"high\"/>\n"
+                           "<param name=\"loop\" value=\"false\"/>\n"
+                           "</object>\n\n", filename, xsize, ysize, filename);
+       } else {
+           printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
+                  " WIDTH=\"%d\"\n"
+                  //" BGCOLOR=#ffffffff\n"?
+                  " HEIGHT=\"%d\"\n"
+                  //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
+                  " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
+                  "  <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
+                  "  <PARAM NAME=\"PLAY\" VALUE=\"true\">\n" 
+                  "  <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
+                  "  <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
+                  "  <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
+                  "   PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
+                  "   TYPE=\"application/x-shockwave-flash\"\n"
+                  "   PLUGINSPAGE=\"http://www.macromedia.com/go/getflashplayer\">\n"
+                  "  </EMBED>\n" 
+                  "</OBJECT>\n", xsize, ysize, fileversions[swf.fileVersion], 
+                                 filename, filename, xsize, ysize);
+       }
        return 0;
     } 
     printf("[HEADER]        File version: %d\n", swf.fileVersion);
@@ -875,17 +917,16 @@ int main (int argc,char ** argv)
             //tag = tag->next;
             //continue;
         }
-       if(swf_TagGetName(tag)) {
-           printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
+       if(!name) {
+           name = "UNKNOWN TAG";
+       }
+       if(cumulative) {
+           filepos += tag->len;
+           printf("[%03x] %9ld %9ld %s%s", tag->id, tag->len, filepos, prefix, swf_TagGetName(tag));
        } else {
-           printf("[%03x] %9ld %sUNKNOWN TAG %03x", tag->id, tag->len, prefix, tag->id);
+           printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
        }
        
-       if(tag->id == ST_FREECHARACTER) {
-           U16 id = swf_GetU16(tag);
-           idtab[id] = 0;
-       }
-
         if(swf_isDefiningTag(tag)) {
             U16 id = swf_GetDefineID(tag);
             printf(" defines id %04d", id);
@@ -916,7 +957,8 @@ int main (int argc,char ** argv)
                printf(" object");
 
             printf(" at depth %04d", swf_GetDepth(tag));
-           
+          
+           swf_SetTagPos(tag, 0);
            if(tag->data[0]&64) {
                SWFPLACEOBJECT po;
                swf_GetPlaceObject(tag, &po);
@@ -958,9 +1000,9 @@ int main (int argc,char ** argv)
        else if(tag->id == ST_FRAMELABEL) {
            int l = strlen(tag->data);
            printf(" \"%s\"", tag->data);
-           if(l < tag->len-1) {
+           if((l+1) < tag->len) {
                printf(" has %d extra bytes", tag->len-1-l);
-               if(tag ->len-1-l == 1 && tag->data[tag->len-1] == 1)
+               if(tag ->len - (l+1) == 1 && tag->data[tag->len-1] == 1)
                    printf(" (ANCHOR)");
            }
            if((framelabel && !issprite) ||
@@ -1131,6 +1173,13 @@ int main (int argc,char ** argv)
                printf("\n");
            }
        }
+       
+       if(tag->id == ST_FREECHARACTER) {
+           U16 id;
+           swf_SetTagPos(tag, 0);
+           id = swf_GetU16(tag);
+           idtab[id] = 0;
+       }
 
        if(tag->len && hex) {
            hexdumpTag(tag, prefix);