2 Shows the structure of a swf file
4 Part of the swftools package.
6 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22 #include "../config.h"
24 #ifdef HAVE_SYS_STAT_H
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
40 #include "../lib/rfxswf.h"
41 #include "../lib/args.h"
43 static char * filename = 0;
45 /* idtab stores the ids which are defined in the file. This allows us
46 to detect errors in the file. (i.e. ids which are defined more than
48 static char idtab[65536];
49 static char * indent = " ";
51 static int placements = 0;
52 static int action = 0;
55 static int showtext = 0;
56 static int showshapes = 0;
60 static struct options_t options[] = {
78 int args_callback_option(char*name,char*val)
80 if(!strcmp(name, "V")) {
81 printf("swfdump - part of %s %s\n", PACKAGE, VERSION);
84 else if(name[0]=='a') {
88 else if(name[0]=='p') {
92 else if(name[0]=='t') {
96 else if(name[0]=='s') {
100 else if(name[0]=='e') {
104 else if(name[0]=='X') {
108 else if(name[0]=='Y') {
112 else if(name[0]=='r') {
116 else if(name[0]=='f') {
120 else if(name[0]=='d') {
124 else if(name[0]=='u') {
128 else if(name[0]=='D') {
129 action = placements = showtext = showshapes = 1;
133 printf("Unknown option: -%s\n", name);
139 int args_callback_longoption(char*name,char*val)
141 return args_long2shortoption(options, name, val);
143 void args_callback_usage(char *name)
146 printf("Usage: %s [-atpdu] file.swf\n", name);
148 printf("-h , --help Print short help message and exit\n");
149 printf("-D , --full Show everything. Same as -atp\n");
150 printf("-V , --version Print version info and exit\n");
151 printf("-e , --html Print out html code for embedding the file\n");
152 printf("-a , --action Disassemble action tags\n");
153 printf("-t , --text Show text fields (like swfstrings).\n");
154 printf("-p , --placements Show placement information\n");
155 printf("-X , --width Prints out a string of the form \"-X width\".\n");
156 printf("-Y , --height Prints out a string of the form \"-Y height\".\n");
157 printf("-r , --rate Prints out a string of the form \"-r rate\".\n");
158 printf("-f , --frames Prints out a string of the form \"-f framenum\".\n");
159 printf("-d , --hex Print hex output of tag data, too.\n");
160 printf("-u , --used Show referred IDs for each Tag.\n");
163 int args_callback_command(char*name,char*val)
166 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
174 char* testfunc(char*str)
176 printf("%s: %s\n", what, str);
180 void dumpButton2Actions(TAG*tag, char*prefix)
186 oldTagPos = swf_GetTagPos(tag);
188 // scan DefineButton2 Record
190 swf_GetU16(tag); // Character ID
191 swf_GetU8(tag); // Flags;
193 offsetpos = swf_GetTagPos(tag); // first offset
196 while (swf_GetU8(tag)) // state -> parse ButtonRecord
197 { swf_GetU16(tag); // id
198 swf_GetU16(tag); // layer
199 swf_GetMatrix(tag,NULL); // matrix
200 swf_GetCXForm(tag,NULL,1); // cxform
207 if(tag->pos >= tag->len)
210 offsetpos = swf_GetU16(tag);
211 condition = swf_GetU16(tag); // condition
213 actions = swf_ActionGet(tag);
214 printf("%s condition %04x\n", prefix, condition);
215 swf_DumpActions(actions, prefix);
218 swf_SetTagPos(tag,oldTagPos);
222 void dumpButtonActions(TAG*tag, char*prefix)
225 swf_GetU16(tag); // id
226 while (swf_GetU8(tag)) // state -> parse ButtonRecord
227 { swf_GetU16(tag); // id
228 swf_GetU16(tag); // layer
229 swf_GetMatrix(tag,NULL); // matrix
231 actions = swf_ActionGet(tag);
232 swf_DumpActions(actions, prefix);
235 #define ET_HASTEXT 32768
236 #define ET_WORDWRAP 16384
237 #define ET_MULTILINE 8192
238 #define ET_PASSWORD 4096
239 #define ET_READONLY 2048
240 #define ET_HASTEXTCOLOR 1024
241 #define ET_HASMAXLENGTH 512
242 #define ET_HASFONT 256
245 #define ET_HASLAYOUT 32
246 #define ET_NOSELECT 16
250 #define ET_USEOUTLINES 1
256 void textcallback(void*self, int*glyphs, int*ypos, int nr, int fontid, int fontsize, int startx, int starty, RGBA*color)
259 printf(" <%2d glyphs in font %2d, color #%02x%02x%02x%02x> ",nr, fontid, color->r, color->g, color->b, color->a);
260 for(t=0;t<fontnum;t++)
262 if(fonts[t]->id == fontid) {
272 if(glyphs[t] >= fonts[font]->numchars /*glyph is in range*/
273 || !fonts[font]->glyph2ascii /* font has ascii<->glyph mapping */
276 a = fonts[font]->glyph2ascii[glyphs[t]];
283 printf("\\x%x", (int)a);
288 void handleText(TAG*tag)
291 swf_ParseDefineText(tag,textcallback, 0);
294 void handleDefineSound(TAG*tag)
296 U16 id = swf_GetU16(tag);
297 U8 flags = swf_GetU8(tag);
298 int compression = (flags>>4)&3;
299 int rate = (flags>>2)&3;
300 int bits = flags&2?16:8;
301 int stereo = flags&1;
303 if(compression == 0) printf("Raw ");
304 else if(compression == 1) printf("ADPCM ");
305 else if(compression == 2) printf("MP3 ");
307 if(rate == 0) printf("5.5Khz ");
308 if(rate == 1) printf("11Khz ");
309 if(rate == 2) printf("22Khz ");
310 if(rate == 3) printf("44Khz ");
311 printf("%dBit ", bits);
312 if(stereo) printf("stereo");
317 void handleDefineBits(TAG*tag)
323 id = swf_GetU16(tag);
324 mode = swf_GetU8(tag);
325 width = swf_GetU16(tag);
326 height = swf_GetU16(tag);
327 printf(" image %dx%d",width,height);
328 if(mode == 3) printf(" (8 bpp)");
329 else if(mode == 4) printf(" (16 bpp)");
330 else if(mode == 5) printf(" (32 bpp)");
331 else printf(" (? bpp)");
334 void handleEditText(TAG*tag)
339 id = swf_GetU16(tag);
341 //swf_ResetReadBits(tag);
346 flags = swf_GetBits(tag,16);
347 if(flags & ET_HASFONT) {
348 swf_GetU16(tag); //font
349 swf_GetU16(tag); //fontheight
351 if(flags & ET_HASTEXTCOLOR) {
352 swf_GetU8(tag); //rgba
357 if(flags & ET_HASMAXLENGTH) {
358 swf_GetU16(tag); //maxlength
360 if(flags & ET_HASLAYOUT) {
361 swf_GetU8(tag); //align
362 swf_GetU16(tag); //left margin
363 swf_GetU16(tag); //right margin
364 swf_GetU16(tag); //indent
365 swf_GetU16(tag); //leading
367 printf(" variable \"%s\"", &tag->data[tag->pos]);
369 if(flags & (ET_X1 | ET_X2 | ET_X3 | ET_X0))
371 printf(" undefined flags: %d%d%d%d",
378 while(tag->data[tag->pos++]);
379 if(flags & ET_HASTEXT)
380 // printf(" text \"%s\"\n", &tag->data[tag->pos]) //TODO
383 void printhandlerflags(U32 handlerflags)
385 if(handlerflags&1) printf("[on load]");
386 if(handlerflags&2) printf("[enter frame]");
387 if(handlerflags&4) printf("[unload]");
388 if(handlerflags&8) printf("[mouse move]");
389 if(handlerflags&16) printf("[mouse down]");
390 if(handlerflags&32) printf("[mouse up]");
391 if(handlerflags&64) printf("[key down]");
392 if(handlerflags&128) printf("[key up]");
394 if(handlerflags&256) printf("[data]");
395 if(handlerflags&512) printf("[initialize]");
396 if(handlerflags&1024) printf("[mouse press]");
397 if(handlerflags&2048) printf("[mouse release]");
398 if(handlerflags&4096) printf("[mouse release outside]");
399 if(handlerflags&8192) printf("[mouse rollover]");
400 if(handlerflags&16384) printf("[mouse rollout]");
401 if(handlerflags&32768) printf("[mouse drag over]");
403 if(handlerflags&0x10000) printf("[mouse drag out]");
404 if(handlerflags&0x20000) printf("[key press]");
405 if(handlerflags&0x40000) printf("[construct even]");
406 if(handlerflags&0xfff80000) printf("[???]");
408 void handleVideoStream(TAG*tag, char*prefix)
410 U16 id = swf_GetU16(tag);
411 U16 frames = swf_GetU16(tag);
412 U16 width = swf_GetU16(tag);
413 U16 height = swf_GetU16(tag);
414 U8 flags = swf_GetU8(tag); //5-2(videopacket 01=off 10=on)-1(smoothing 1=on)
415 U8 codec = swf_GetU8(tag);
416 printf(" (%d frames, %dx%d", frames, width, height);
420 printf(" sorenson h.263)");
422 printf(" codec 0x%02x)", codec);
424 void handleVideoFrame(TAG*tag, char*prefix)
426 U32 code, version, reference, sizeflags;
427 U32 width=0, height=0;
429 U16 id = swf_GetU16(tag);
430 U16 frame = swf_GetU16(tag);
431 U8 deblock,flags, tmp, bit;
433 char*types[] = {"I-frame", "P-frame", "disposable P-frame", "<reserved>"};
434 printf(" (frame %d) ", frame);
436 /* video packet follows */
437 code = swf_GetBits(tag, 17);
438 version = swf_GetBits(tag, 5);
439 reference = swf_GetBits(tag, 8);
441 sizeflags = swf_GetBits(tag, 3);
444 case 0: width = swf_GetBits(tag, 8); height = swf_GetBits(tag, 8); break;
445 case 1: width = swf_GetBits(tag, 16); height = swf_GetBits(tag, 16); break;
446 case 2: width = 352; height = 288; break;
447 case 3: width = 176; height = 144; break;
448 case 4: width = 128; height = 96; break;
449 case 5: width = 320; height = 240; break;
450 case 6: width = 160; height = 120; break;
451 case 7: width = -1; height = -1;/*reserved*/ break;
453 printf("%dx%d ", width, height);
454 type = swf_GetBits(tag, 2);
455 printf("%s", types[type]);
457 deblock = swf_GetBits(tag, 1);
459 printf(" deblock ", deblock);
460 quantizer = swf_GetBits(tag, 5);
461 printf(" quant: %d ", quantizer);
464 void handlePlaceObject2(TAG*tag, char*prefix)
466 U8 flags = swf_GetU8(tag);
470 int ppos[3] = {0,0,0};
471 swf_GetU16(tag); //depth
474 if(flags&2) swf_GetU16(tag); //id
476 swf_GetMatrix(tag,&m);
478 ppos[0] += sprintf(pstr[0], "| Matrix ");
479 ppos[1] += sprintf(pstr[1], "| %5.3f %5.3f %6.2f ", m.sx/65536.0, m.r1/65536.0, m.tx/20.0);
480 ppos[2] += sprintf(pstr[2], "| %5.3f %5.3f %6.2f ", m.r0/65536.0, m.sy/65536.0, m.ty/20.0);
484 swf_GetCXForm(tag, &cx, 1);
486 ppos[0] += sprintf(pstr[0]+ppos[0], "| CXForm r g b a ");
487 ppos[1] += sprintf(pstr[1]+ppos[1], "| mul %4.1f %4.1f %4.1f %4.1f ", cx.r0/256.0, cx.g0/256.0, cx.b0/256.0, cx.a0/256.0);
488 ppos[2] += sprintf(pstr[2]+ppos[2], "| add %4d %4d %4d %4d ", cx.r1, cx.g1, cx.b1, cx.a1);
492 U16 ratio = swf_GetU16(tag); //ratio
494 ppos[0] += sprintf(pstr[0]+ppos[0], "| Ratio ");
495 ppos[1] += sprintf(pstr[1]+ppos[1], "| %-5d ", ratio);
496 ppos[2] += sprintf(pstr[2]+ppos[2], "| ");
500 U16 clip = swf_GetU16(tag); //clip
502 ppos[0] += sprintf(pstr[0]+ppos[0], "| Clip ");
503 ppos[1] += sprintf(pstr[1]+ppos[1], "| %-5d ", clip);
504 ppos[2] += sprintf(pstr[2]+ppos[2], "| ");
507 if(flags&32) { while(swf_GetU8(tag)); }
508 if(placements && ppos[0]) {
510 printf("%s %s\n", prefix, pstr[0]);
511 printf("%s %s\n", prefix, pstr[1]);
512 printf("%s %s", prefix, pstr[2]);
521 reserved = swf_GetU16(tag); // must be 0
522 globalflags = swf_GetU16(tag); //TODO: 32 if version>=6
524 printf("Unknown parameter field not zero: %04x\n", reserved);
527 printf("global flags: %04x\n", globalflags);
529 handlerflags = swf_GetU16(tag); //TODO: 32 if version>=6
531 handlerflags = swf_GetU32(tag);
534 while(handlerflags) {
539 globalflags &= ~handlerflags;
540 printf("%s flags %08x ",prefix, handlerflags);
541 printhandlerflags(handlerflags);
542 length = swf_GetU32(tag);
543 printf(", %d bytes actioncode\n",length);
544 a = swf_ActionGet(tag);
545 swf_DumpActions(a,prefix);
548 handlerflags = is32?swf_GetU32(tag):swf_GetU16(tag); //TODO: 32 if version>=6
550 if(globalflags) // should go to sterr.
551 printf("ERROR: unsatisfied handlerflags: %02x\n", globalflags);
553 printf(" has action code\n");
558 void handlePlaceObject(TAG*tag, char*prefix)
560 TAG*tag2 = swf_InsertTag(0, ST_PLACEOBJECT2);
562 U16 id = swf_GetU16(tag);
563 U16 depth = swf_GetU16(tag);
564 MATRIX matrix; swf_GetMatrix(tag, &matrix);
565 CXFORM cxform; swf_GetCXForm(tag, &cxform, 0);
568 swf_SetU16(tag2, depth);
569 swf_SetMatrix(tag2, &matrix);
570 swf_SetCXForm(tag2, &cxform, 1);
572 handlePlaceObject2(tag2, prefix);
574 void handleShape(TAG*tag, char*prefix)
581 swf_ParseDefineShape(tag, &shape);
584 void fontcallback1(U16 id,U8 * name)
588 void fontcallback2(U16 id,U8 * name)
590 swf_FontExtract(&swf,id,&fonts[fontnum]);
594 static U8 printable(U8 a)
596 if(a<32 || a==127) return '.';
599 void hexdumpTag(TAG*tag, char* prefix)
603 printf(" %s-=> ",prefix);
604 for(t=0;t<tag->len;t++) {
605 printf("%02x ", tag->data[t]);
606 ascii[t&15] = printable(tag->data[t]);
607 if((t && ((t&15)==15)) || (t==tag->len-1))
609 int s,p=((t-1)&15)+1;
615 printf(" %s\n", ascii);
617 printf(" %s\n %s-=> ",ascii,prefix);
622 void handleExportAssets(TAG*tag, char* prefix)
628 num = swf_GetU16(tag);
631 id = swf_GetU16(tag);
632 name = swf_GetString(tag);
633 printf("%sexports %04d as \"%s\"\n", prefix, id, name);
637 void dumperror(const char* format, ...)
642 va_start(arglist, format);
643 vsprintf(buf, format, arglist);
647 printf("==== Error: %s ====\n", buf);
650 static char strbuf[800];
653 char* timestring(double f)
655 int hours = (int)(f/3600);
656 int minutes = (int)((f-hours*3600)/60);
657 int seconds = (int)((f-hours*3600-minutes*60));
658 int useconds = (int)((f-(int)f)*1000+0.5);
661 sprintf(&strbuf[bufpos], "%02d:%02d:%02d,%03d",hours,minutes,seconds,useconds);
662 return &strbuf[bufpos];
665 int main (int argc,char ** argv)
673 char issprite = 0; // are we inside a sprite definition?
676 char* spriteframelabel = 0;
677 char* framelabel = 0;
681 memset(idtab,0,65536);
683 processargs(argc, argv);
687 fprintf(stderr, "You must supply a filename.\n");
691 f = open(filename,O_RDONLY|O_BINARY);
696 sprintf(buffer, "Couldn't open %s", filename);
700 if FAILED(swf_ReadSWF(f,&swf))
702 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
709 if(statbuf.st_size != swf.fileSize && !swf.compressed)
710 dumperror("Real Filesize (%d) doesn't match header Filesize (%d)",
711 statbuf.st_size, swf.fileSize);
712 filesize = statbuf.st_size;
717 xsize = (swf.movieSize.xmax-swf.movieSize.xmin)/20;
718 ysize = (swf.movieSize.ymax-swf.movieSize.ymin)/20;
722 printf("-X %d", xsize);
728 printf("-Y %d", ysize);
734 printf("-r %.2f", swf.frameRate/256.0);
740 printf("-f %d", swf.frameCount);
747 char*fileversions[] = {"","1,0,0,0", "2,0,0,0","3,0,0,0","4,0,0,0",
748 "5,0,0,0","6,0,23,0","7,0,0,0","8,0,0,0"};
749 if(swf.fileVersion>8) {
750 fprintf(stderr, "Fileversion>8\n");
753 printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
755 //" BGCOLOR=#ffffffff\n"?
757 //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
758 " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
759 " <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
760 " <PARAM NAME=\"PLAY\" VALUE=\"true\">\n"
761 " <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
762 " <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
763 " <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
764 " PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
765 " TYPE=\"application/x-shockwave-flash\"\n"
766 " PLUGINSPAGE=\"http://www.macromedia.com/go/getflashplayer\">\n"
768 "</OBJECT>\n", xsize, ysize, fileversions[swf.fileVersion],
769 filename, filename, xsize, ysize);
772 printf("[HEADER] File version: %d\n", swf.fileVersion);
774 printf("[HEADER] File is zlib compressed.");
775 if(filesize && swf.fileSize)
776 printf(" Ratio: %02d%%\n", filesize*100/(swf.fileSize));
780 printf("[HEADER] File size: %ld%s\n", swf.fileSize, swf.compressed?" (Depacked)":"");
781 printf("[HEADER] Frame rate: %f\n",swf.frameRate/256.0);
782 printf("[HEADER] Frame count: %d\n",swf.frameCount);
783 printf("[HEADER] Movie width: %.2f",(swf.movieSize.xmax-swf.movieSize.xmin)/20.0);
784 if(swf.movieSize.xmin)
785 printf(" (left offset: %.2f)\n", swf.movieSize.xmin/20.0);
788 printf("[HEADER] Movie height: %.2f",(swf.movieSize.ymax-swf.movieSize.ymin)/20.0);
789 if(swf.movieSize.ymin)
790 printf(" (top offset: %.2f)\n", swf.movieSize.ymin/20.0);
798 swf_FontEnumerate(&swf,&fontcallback1);
799 fonts = (SWFFONT**)malloc(fontnum*sizeof(SWFFONT*));
801 swf_FontEnumerate(&swf,&fontcallback2);
805 char*name = swf_TagGetName(tag);
808 dumperror("Unknown tag:0x%03x", tag->id);
812 if(swf_TagGetName(tag)) {
813 printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
815 printf("[%03x] %9ld %sUNKNOWN TAG %03x", tag->id, tag->len, prefix, tag->id);
818 if(tag->id == ST_FREECHARACTER) {
819 U16 id = swf_GetU16(tag);
823 if(swf_isDefiningTag(tag)) {
824 U16 id = swf_GetDefineID(tag);
825 printf(" defines id %04d", id);
827 dumperror("Id %04d is defined more than once.", id);
830 else if(swf_isPseudoDefiningTag(tag)) {
831 U16 id = swf_GetDefineID(tag);
832 printf(" adds information to id %04d", id);
834 dumperror("Id %04d is not yet defined.\n", id);
836 else if(tag->id == ST_PLACEOBJECT) {
837 printf(" places id %04d at depth %04x", swf_GetPlaceID(tag), swf_GetDepth(tag));
839 printf(" name \"%s\"",swf_GetName(tag));
841 else if(tag->id == ST_PLACEOBJECT2) {
848 printf(" id %04d",swf_GetPlaceID(tag));
852 printf(" at depth %04d", swf_GetDepth(tag));
854 printf(" name \"%s\"",swf_GetName(tag));
856 else if(tag->id == ST_REMOVEOBJECT) {
857 printf(" removes id %04d from depth %04d", swf_GetPlaceID(tag), swf_GetDepth(tag));
859 else if(tag->id == ST_REMOVEOBJECT2) {
860 printf(" removes object from depth %04d", swf_GetDepth(tag));
862 else if(tag->id == ST_FREECHARACTER) {
863 printf(" frees object %04d", swf_GetPlaceID(tag));
865 else if(tag->id == ST_STARTSOUND) {
868 id = swf_GetU16(tag);
869 flags = swf_GetU8(tag);
871 printf(" stops sound with id %04d", id);
873 printf(" starts sound with id %04d", id);
875 printf(" (if not already playing)");
881 printf(" looping %d times", swf_GetU16(tag));
884 else if(tag->id == ST_FRAMELABEL) {
885 int l = strlen(tag->data);
886 printf(" \"%s\"", tag->data);
888 printf(" has %d extra bytes", tag->len-1-l);
889 if(tag ->len-1-l == 1 && tag->data[tag->len-1] == 1)
892 if((framelabel && !issprite) ||
893 (spriteframelabel && issprite)) {
894 dumperror("Frame %d has more than one label",
895 issprite?spriteframe:mainframe);
897 if(issprite) spriteframelabel = tag->data;
898 else framelabel = tag->data;
900 else if(tag->id == ST_SHOWFRAME) {
901 char*label = issprite?spriteframelabel:framelabel;
902 int frame = issprite?spriteframe:mainframe;
905 while(tag->next && tag->next->id == ST_SHOWFRAME && tag->next->len == 0) {
907 if(issprite) spriteframe++;
913 printf(" %d (%s)", frame, timestring(frame*(256.0/(swf.frameRate+0.1))));
915 printf(" %d-%d (%s-%s)", frame, nframe,
916 timestring(frame*(256.0/(swf.frameRate+0.1))),
917 timestring(nframe*(256.0/(swf.frameRate+0.1)))
920 printf(" (label \"%s\")", label);
921 if(issprite) {spriteframe++; spriteframelabel = 0;}
922 if(!issprite) {mainframe++; framelabel = 0;}
925 if(tag->id == ST_SETBACKGROUNDCOLOR) {
926 U8 r = swf_GetU8(tag);
927 U8 g = swf_GetU8(tag);
928 U8 b = swf_GetU8(tag);
929 printf(" (%02x/%02x/%02x)\n",r,g,b);
931 else if(tag->id == ST_PROTECT) {
933 printf(" %s\n", swf_GetString(tag));
936 else if(tag->id == ST_DEFINEBITSLOSSLESS ||
937 tag->id == ST_DEFINEBITSLOSSLESS2) {
938 handleDefineBits(tag);
941 else if(tag->id == ST_DEFINESOUND) {
942 handleDefineSound(tag);
945 else if(tag->id == ST_VIDEOFRAME) {
946 handleVideoFrame(tag, myprefix);
949 else if(tag->id == ST_DEFINEVIDEOSTREAM) {
950 handleVideoStream(tag, myprefix);
953 else if(tag->id == ST_DEFINEEDITTEXT) {
957 else if(tag->id == ST_DEFINEMOVIE) {
958 U16 id = swf_GetU16(tag);
959 char*s = swf_GetString(tag);
960 printf(" URL: %s\n", s);
962 else if(tag->id == ST_DEFINETEXT || tag->id == ST_DEFINETEXT2) {
968 else if(tag->id == ST_PLACEOBJECT2) {
970 else if(tag->id == ST_NAMECHARACTER) {
972 printf(" \"%s\"\n", swf_GetString(tag));
978 sprintf(myprefix, " %s", prefix);
980 if(tag->id == ST_DEFINESPRITE) {
981 sprintf(prefix, " ");
983 dumperror("Sprite definition inside a sprite definition");
987 spriteframelabel = 0;
989 else if(tag->id == ST_END) {
992 spriteframelabel = 0;
994 dumperror("End Tag not empty");
996 else if(tag->id == ST_EXPORTASSETS) {
997 handleExportAssets(tag, myprefix);
999 else if(tag->id == ST_DOACTION && action) {
1001 actions = swf_ActionGet(tag);
1002 swf_DumpActions(actions, myprefix);
1004 else if(tag->id == ST_DEFINEBUTTON && action) {
1005 dumpButtonActions(tag, myprefix);
1007 else if(tag->id == ST_DEFINEBUTTON2 && action) {
1008 dumpButton2Actions(tag, myprefix);
1010 else if(tag->id == ST_PLACEOBJECT) {
1011 handlePlaceObject(tag, myprefix);
1013 else if(tag->id == ST_PLACEOBJECT2) {
1014 handlePlaceObject2(tag, myprefix);
1016 else if(tag->id == ST_DEFINESHAPE ||
1017 tag->id == ST_DEFINESHAPE2 ||
1018 tag->id == ST_DEFINESHAPE3) {
1020 handleShape(tag, myprefix);
1023 if(tag->len && used) {
1024 int num = swf_GetNumUsedIDs(tag);
1028 used = (int*)malloc(sizeof(int)*num);
1029 swf_GetUsedIDs(tag, used);
1030 printf("%s%suses IDs: ", indent, prefix);
1031 for(t=0;t<num;t++) {
1033 swf_SetTagPos(tag, used[t]);
1034 id = swf_GetU16(tag);
1035 printf("%d%s", id, t<num-1?", ":"");
1037 dumperror("Id %04d is not yet defined.\n", id);
1044 if(tag->len && hex) {
1045 hexdumpTag(tag, prefix);