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;
59 struct options_t options[] =
77 int args_callback_option(char*name,char*val)
79 if(!strcmp(name, "V")) {
80 printf("swfdump - part of %s %s\n", PACKAGE, VERSION);
83 else if(name[0]=='a') {
87 else if(name[0]=='p') {
91 else if(name[0]=='t') {
95 else if(name[0]=='e') {
99 else if(name[0]=='X') {
103 else if(name[0]=='Y') {
107 else if(name[0]=='r') {
111 else if(name[0]=='f') {
115 else if(name[0]=='d') {
119 else if(name[0]=='u') {
123 else if(name[0]=='D') {
124 action = placements = showtext = 1;
128 printf("Unknown option: -%s\n", name);
134 int args_callback_longoption(char*name,char*val)
136 return args_long2shortoption(options, name, val);
138 void args_callback_usage(char*name)
140 printf("Usage: %s [-at] file.swf\n", name);
141 printf("\t-h , --help\t\t Print help and exit\n");
142 printf("\t-D , --full\t\t Show everything. The same as -atMp\n");
143 printf("\t-e , --html\t\t Create html output embedding the file (simple, but useful)\n");
144 printf("\t-X , --width\t\t Prints out a string of the form \"-X width\"\n");
145 printf("\t-Y , --height\t\t Prints out a string of the form \"-Y height\"\n");
146 printf("\t-r , --rate\t\t Prints out a string of the form \"-r rate\"\n");
147 printf("\t-f , --frames\t\t Prints out a string of the form \"-f framenum\"\n");
148 printf("\t-a , --action\t\t Disassemble action tags\n");
149 printf("\t-p , --placements\t Show extra placement information\n");
150 printf("\t-t , --text\t\t Show text data\n");
151 printf("\t-d , --hex\t\t Print hex output of tag data, too\n");
152 printf("\t-u , --used\t\t Show referred IDs for each Tag\n");
153 printf("\t-V , --version\t\t Print program version and exit\n");
155 int args_callback_command(char*name,char*val)
158 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
166 char* testfunc(char*str)
168 printf("%s: %s\n", what, str);
172 void dumpButton2Actions(TAG*tag, char*prefix)
178 oldTagPos = swf_GetTagPos(tag);
180 // scan DefineButton2 Record
182 swf_GetU16(tag); // Character ID
183 swf_GetU8(tag); // Flags;
185 offsetpos = swf_GetTagPos(tag); // first offset
188 while (swf_GetU8(tag)) // state -> parse ButtonRecord
189 { swf_GetU16(tag); // id
190 swf_GetU16(tag); // layer
191 swf_GetMatrix(tag,NULL); // matrix
192 swf_GetCXForm(tag,NULL,1); // cxform
199 if(tag->pos >= tag->len)
202 offsetpos = swf_GetU16(tag);
203 condition = swf_GetU16(tag); // condition
205 actions = swf_ActionGet(tag);
206 printf("%s condition %04x\n", prefix, condition);
207 swf_DumpActions(actions, prefix);
210 swf_SetTagPos(tag,oldTagPos);
214 void dumpButtonActions(TAG*tag, char*prefix)
217 swf_GetU16(tag); // id
218 while (swf_GetU8(tag)) // state -> parse ButtonRecord
219 { swf_GetU16(tag); // id
220 swf_GetU16(tag); // layer
221 swf_GetMatrix(tag,NULL); // matrix
223 actions = swf_ActionGet(tag);
224 swf_DumpActions(actions, prefix);
227 #define ET_HASTEXT 32768
228 #define ET_WORDWRAP 16384
229 #define ET_MULTILINE 8192
230 #define ET_PASSWORD 4096
231 #define ET_READONLY 2048
232 #define ET_HASTEXTCOLOR 1024
233 #define ET_HASMAXLENGTH 512
234 #define ET_HASFONT 256
237 #define ET_HASLAYOUT 32
238 #define ET_NOSELECT 16
242 #define ET_USEOUTLINES 1
248 void textcallback(int*glyphs, int nr, int fontid)
251 printf(" <%2d glyphs in font %2d> ",nr, fontid);
252 for(t=0;t<fontnum;t++)
254 if(fonts[t]->id == fontid) {
264 if(glyphs[t] >= fonts[font]->numchars /*glyph is in range*/
265 || !fonts[font]->glyph2ascii /* font has ascii<->glyph mapping */
268 a = fonts[font]->glyph2ascii[glyphs[t]];
275 printf("\\x%x", (int)a);
280 void handleText(TAG*tag)
283 swf_FontExtract_DefineTextCallback(-1,0,tag,4, textcallback);
286 void handleDefineSound(TAG*tag)
288 U16 id = swf_GetU16(tag);
289 U8 flags = swf_GetU8(tag);
290 int compression = (flags>>4)&3;
291 int rate = (flags>>2)&3;
292 int bits = flags&2?16:8;
293 int stereo = flags&1;
295 if(compression == 0) printf("Raw ");
296 else if(compression == 1) printf("ADPCM ");
297 else if(compression == 2) printf("MP3 ");
299 if(rate == 0) printf("5.5Khz ");
300 if(rate == 1) printf("11Khz ");
301 if(rate == 2) printf("22Khz ");
302 if(rate == 3) printf("44Khz ");
303 printf("%dBit ", bits);
304 if(stereo) printf("stereo");
309 void handleDefineBits(TAG*tag)
315 id = swf_GetU16(tag);
316 mode = swf_GetU8(tag);
317 width = swf_GetU16(tag);
318 height = swf_GetU16(tag);
319 printf(" image %dx%d",width,height);
320 if(mode == 3) printf(" (8 bpp)");
321 else if(mode == 4) printf(" (16 bpp)");
322 else if(mode == 5) printf(" (32 bpp)");
323 else printf(" (? bpp)");
326 void handleEditText(TAG*tag)
331 id = swf_GetU16(tag);
333 //swf_ResetReadBits(tag);
338 flags = swf_GetBits(tag,16);
339 if(flags & ET_HASFONT) {
340 swf_GetU16(tag); //font
341 swf_GetU16(tag); //fontheight
343 if(flags & ET_HASTEXTCOLOR) {
344 swf_GetU8(tag); //rgba
349 if(flags & ET_HASMAXLENGTH) {
350 swf_GetU16(tag); //maxlength
352 if(flags & ET_HASLAYOUT) {
353 swf_GetU8(tag); //align
354 swf_GetU16(tag); //left margin
355 swf_GetU16(tag); //right margin
356 swf_GetU16(tag); //indent
357 swf_GetU16(tag); //leading
359 printf(" variable \"%s\"", &tag->data[tag->pos]);
361 if(flags & (ET_X1 | ET_X2 | ET_X3 | ET_X0))
363 printf(" undefined flags: %d%d%d%d",
370 while(tag->data[tag->pos++]);
371 if(flags & ET_HASTEXT)
372 // printf(" text \"%s\"\n", &tag->data[tag->pos])
375 void printhandlerflags(U16 handlerflags)
377 if(handlerflags&1) printf("[on load]");
378 if(handlerflags&2) printf("[enter frame]");
379 if(handlerflags&4) printf("[unload]");
380 if(handlerflags&8) printf("[mouse move]");
381 if(handlerflags&16) printf("[mouse down]");
382 if(handlerflags&32) printf("[mouse up]");
383 if(handlerflags&64) printf("[key down]");
384 if(handlerflags&128) printf("[key up]");
385 if(handlerflags&256) printf("[data]");
386 if(handlerflags&0xfe00) printf("[???]");
388 void handleVideoStream(TAG*tag, char*prefix)
390 U16 id = swf_GetU16(tag);
391 U16 frames = swf_GetU16(tag);
392 U16 width = swf_GetU16(tag);
393 U16 height = swf_GetU16(tag);
394 U8 flags = swf_GetU8(tag); //5-2(videopacket 01=off 10=on)-1(smoothing 1=on)
395 U8 codec = swf_GetU8(tag);
396 printf(" (%d frames, %dx%d", frames, width, height);
400 printf(" sorenson h.263)");
402 printf(" codec 0x%02x)", codec);
404 void handleVideoFrame(TAG*tag, char*prefix)
406 U32 code, version, reference, sizeflags;
409 U16 id = swf_GetU16(tag);
410 U16 frame = swf_GetU16(tag);
411 U8 deblock,flags, tmp, bit;
413 char*types[] = {"I-frame", "P-frame", "disposable P-frame", "<reserved>"};
414 printf(" (frame %d) ", frame);
416 /* video packet follows */
417 code = swf_GetBits(tag, 17);
418 version = swf_GetBits(tag, 5);
419 reference = swf_GetBits(tag, 8);
421 sizeflags = swf_GetBits(tag, 3);
424 case 0: width = swf_GetBits(tag, 8); height = swf_GetBits(tag, 8); break;
425 case 1: width = swf_GetBits(tag, 16); height = swf_GetBits(tag, 16); break;
426 case 2: width = 352; height = 288; break;
427 case 3: width = 176; height = 144; break;
428 case 4: width = 128; height = 96; break;
429 case 5: width = 320; height = 240; break;
430 case 6: width = 160; height = 120; break;
431 case 7: width = -1; height = -1;/*reserved*/ break;
433 printf("%dx%d ", width, height);
434 type = swf_GetBits(tag, 2);
435 printf("%s", types[type]);
437 deblock = swf_GetBits(tag, 1);
439 printf(" deblock ", deblock);
440 quantizer = swf_GetBits(tag, 5);
441 printf(" quant: %d ", quantizer);
444 void handlePlaceObject2(TAG*tag, char*prefix)
446 U8 flags = swf_GetU8(tag);
450 int ppos[3] = {0,0,0};
451 swf_GetU16(tag); //depth
453 if(flags&2) swf_GetU16(tag); //id
455 swf_GetMatrix(tag,&m);
457 ppos[0] += sprintf(pstr[0], "| Matrix ");
458 ppos[1] += sprintf(pstr[1], "| %5.3f %5.3f %6.2f ", m.sx/65536.0, m.r1/65536.0, m.tx/20.0);
459 ppos[2] += sprintf(pstr[2], "| %5.3f %5.3f %6.2f ", m.r0/65536.0, m.sy/65536.0, m.ty/20.0);
463 swf_GetCXForm(tag, &cx, 1);
465 ppos[0] += sprintf(pstr[0]+ppos[0], "| CXForm r g b a ");
466 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);
467 ppos[2] += sprintf(pstr[2]+ppos[2], "| add %4d %4d %4d %4d ", cx.r1, cx.g1, cx.b1, cx.a1);
471 U16 ratio = swf_GetU16(tag); //ratio
473 ppos[0] += sprintf(pstr[0]+ppos[0], "| Ratio ");
474 ppos[1] += sprintf(pstr[1]+ppos[1], "| %-5d ", ratio);
475 ppos[2] += sprintf(pstr[2]+ppos[2], "| ");
479 U16 clip = swf_GetU16(tag); //clip
481 ppos[0] += sprintf(pstr[0]+ppos[0], "| Clip ");
482 ppos[1] += sprintf(pstr[1]+ppos[1], "| %-5d ", clip);
483 ppos[2] += sprintf(pstr[2]+ppos[2], "| ");
486 if(flags&32) { while(swf_GetU8(tag)); }
487 if(placements && ppos[0]) {
489 printf("%s %s\n", prefix, pstr[0]);
490 printf("%s %s\n", prefix, pstr[1]);
491 printf("%s %s", prefix, pstr[2]);
500 unknown = swf_GetU16(tag);
501 globalflags = swf_GetU16(tag);
503 printf("Unknown parameter field not zero: %04x\n", unknown);
506 printf("global flags: %04x\n", globalflags);
507 handlerflags = swf_GetU16(tag);
509 handlerflags = swf_GetU32(tag);
512 while(handlerflags) {
517 globalflags &= ~handlerflags;
518 printf("%s flags %08x ",prefix, handlerflags);
519 printhandlerflags(handlerflags);
520 length = swf_GetU32(tag);
521 printf(", %d bytes actioncode\n",length);
522 a = swf_ActionGet(tag);
523 swf_DumpActions(a,prefix);
526 handlerflags = is32?swf_GetU32(tag):swf_GetU16(tag);
528 if(globalflags) // should go to sterr.
529 printf("ERROR: unsatisfied handlerflags: %02x\n", globalflags);
531 printf(" has action code\n");
536 void handlePlaceObject(TAG*tag, char*prefix)
541 void fontcallback1(U16 id,U8 * name)
545 void fontcallback2(U16 id,U8 * name)
547 swf_FontExtract(&swf,id,&fonts[fontnum]);
551 static U8 printable(U8 a)
553 if(a<32 || a==127) return '.';
556 void hexdumpTag(TAG*tag, char* prefix)
560 printf(" %s-=> ",prefix);
561 for(t=0;t<tag->len;t++) {
562 printf("%02x ", tag->data[t]);
563 ascii[t&15] = printable(tag->data[t]);
564 if((t && ((t&15)==15)) || (t==tag->len-1))
566 int s,p=((t-1)&15)+1;
572 printf(" %s\n", ascii);
574 printf(" %s\n %s-=> ",ascii,prefix);
579 void handleExportAssets(TAG*tag, char* prefix)
585 num = swf_GetU16(tag);
588 id = swf_GetU16(tag);
589 name = swf_GetString(tag);
590 printf("%sexports %04d as \"%s\"\n", prefix, id, name);
594 void dumperror(const char* format, ...)
599 va_start(arglist, format);
600 vsprintf(buf, format, arglist);
604 printf("==== Error: %s ====\n", buf);
607 static char strbuf[800];
610 char* timestring(double f)
612 int hours = (int)(f/3600);
613 int minutes = (int)((f-hours*3600)/60);
614 int seconds = (int)((f-hours*3600-minutes*60));
615 int useconds = (int)((f-(int)f)*1000+0.5);
618 sprintf(&strbuf[bufpos], "%02d:%02d:%02d,%03d",hours,minutes,seconds,useconds);
619 return &strbuf[bufpos];
622 int main (int argc,char ** argv)
630 char issprite = 0; // are we inside a sprite definition?
633 char* spriteframelabel = 0;
634 char* framelabel = 0;
638 memset(idtab,0,65536);
640 processargs(argc, argv);
644 fprintf(stderr, "You must supply a filename.\n");
648 f = open(filename,O_RDONLY|O_BINARY);
652 perror("Couldn't open file: ");
655 if FAILED(swf_ReadSWF(f,&swf))
657 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
664 if(statbuf.st_size != swf.fileSize && !swf.compressed)
665 dumperror("Real Filesize (%d) doesn't match header Filesize (%d)",
666 statbuf.st_size, swf.fileSize);
667 filesize = statbuf.st_size;
672 xsize = (swf.movieSize.xmax-swf.movieSize.xmin)/20;
673 ysize = (swf.movieSize.ymax-swf.movieSize.ymin)/20;
677 printf("-X %d", xsize);
683 printf("-Y %d", ysize);
689 printf("-r %d", swf.frameRate*100/256);
695 printf("-f %d", swf.frameCount);
702 char*fileversions[] = {"","1,0,0,0", "2,0,0,0","3,0,0,0","4,0,0,0",
703 "5,0,0,0","6,0,23,0","7,0,0,0","8,0,0,0"};
704 if(swf.fileVersion>8) {
705 fprintf(stderr, "Fileversion>8\n");
708 printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
710 //" BGCOLOR=#ffffffff\n"?
712 //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
713 " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
714 " <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
715 " <PARAM NAME=\"PLAY\" VALUE=\"true\">\n"
716 " <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
717 " <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
718 " <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
719 " PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
720 " TYPE=\"application/x-shockwave-flash\"\n"
721 " PLUGINSPAGE=\"http://www.macromedia.com/go/getflashplayer\">\n"
723 "</OBJECT>\n", xsize, ysize, fileversions[swf.fileVersion],
724 filename, filename, xsize, ysize);
727 printf("[HEADER] File version: %d\n", swf.fileVersion);
729 printf("[HEADER] File is zlib compressed.");
730 if(filesize && swf.fileSize)
731 printf(" Ratio: %02d%%\n", filesize*100/(swf.fileSize));
735 printf("[HEADER] File size: %ld%s\n", swf.fileSize, swf.compressed?" (Depacked)":"");
736 printf("[HEADER] Frame rate: %f\n",swf.frameRate/256.0);
737 printf("[HEADER] Frame count: %d\n",swf.frameCount);
738 printf("[HEADER] Movie width: %.2f",(swf.movieSize.xmax-swf.movieSize.xmin)/20.0);
739 if(swf.movieSize.xmin)
740 printf(" (left offset: %.2f)\n", swf.movieSize.xmin/20.0);
743 printf("[HEADER] Movie height: %.2f",(swf.movieSize.ymax-swf.movieSize.ymin)/20.0);
744 if(swf.movieSize.ymin)
745 printf(" (top offset: %.2f)\n", swf.movieSize.ymin/20.0);
753 swf_FontEnumerate(&swf,&fontcallback1);
754 fonts = (SWFFONT**)malloc(fontnum*sizeof(SWFFONT*));
756 swf_FontEnumerate(&swf,&fontcallback2);
760 char*name = swf_TagGetName(tag);
763 dumperror("Unknown tag:0x%03x", tag->id);
767 if(swf_TagGetName(tag)) {
768 printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
770 printf("[%03x] %9ld %sUNKNOWN TAG %03x", tag->id, tag->len, prefix, tag->id);
773 if(tag->id == ST_FREECHARACTER) {
774 U16 id = swf_GetU16(tag);
778 if(swf_isDefiningTag(tag)) {
779 U16 id = swf_GetDefineID(tag);
780 printf(" defines id %04d", id);
782 dumperror("Id %04d is defined more than once.", id);
785 else if(swf_isPseudoDefiningTag(tag)) {
786 U16 id = swf_GetDefineID(tag);
787 printf(" adds information to id %04d", id);
789 dumperror("Id %04d is not yet defined.\n", id);
791 else if(tag->id == ST_PLACEOBJECT) {
792 printf(" places id %04d at depth %04x", swf_GetPlaceID(tag), swf_GetDepth(tag));
794 printf(" name \"%s\"",swf_GetName(tag));
795 handlePlaceObject(tag, myprefix);
797 else if(tag->id == ST_PLACEOBJECT2) {
804 printf(" id %04d",swf_GetPlaceID(tag));
808 printf(" at depth %04d", swf_GetDepth(tag));
810 printf(" name \"%s\"",swf_GetName(tag));
812 else if(tag->id == ST_REMOVEOBJECT) {
813 printf(" removes id %04d from depth %04d", swf_GetPlaceID(tag), swf_GetDepth(tag));
815 else if(tag->id == ST_REMOVEOBJECT2) {
816 printf(" removes object from depth %04d", swf_GetDepth(tag));
818 else if(tag->id == ST_FREECHARACTER) {
819 printf(" frees object %04d", swf_GetPlaceID(tag));
821 else if(tag->id == ST_STARTSOUND) {
824 id = swf_GetU16(tag);
825 flags = swf_GetU8(tag);
827 printf(" stops sound with id %04d", id);
829 printf(" starts sound with id %04d", id);
831 printf(" (if not already playing)");
837 printf(" looping %d times", swf_GetU16(tag));
840 else if(tag->id == ST_FRAMELABEL) {
841 int l = strlen(tag->data);
842 printf(" \"%s\"", tag->data);
844 printf(" has %d extra bytes", tag->len-1-l);
845 if(tag ->len-1-l == 1 && tag->data[tag->len-1] == 1)
848 if((framelabel && !issprite) ||
849 (spriteframelabel && issprite)) {
850 dumperror("Frame %d has more than one label",
851 issprite?spriteframe:mainframe);
853 if(issprite) spriteframelabel = tag->data;
854 else framelabel = tag->data;
856 else if(tag->id == ST_SHOWFRAME) {
857 char*label = issprite?spriteframelabel:framelabel;
858 int frame = issprite?spriteframe:mainframe;
861 while(tag->next && tag->next->id == ST_SHOWFRAME && tag->next->len == 0) {
863 if(issprite) spriteframe++;
869 printf(" %d (%s)", frame, timestring(frame*(256.0/(swf.frameRate+0.1))));
871 printf(" %d-%d (%s-%s)", frame, nframe,
872 timestring(frame*(256.0/(swf.frameRate+0.1))),
873 timestring(nframe*(256.0/(swf.frameRate+0.1)))
876 printf(" (label \"%s\")", label);
877 if(issprite) {spriteframe++; spriteframelabel = 0;}
878 if(!issprite) {mainframe++; framelabel = 0;}
881 if(tag->id == ST_SETBACKGROUNDCOLOR) {
882 U8 r = swf_GetU8(tag);
883 U8 g = swf_GetU8(tag);
884 U8 b = swf_GetU8(tag);
885 printf(" (%02x/%02x/%02x)\n",r,g,b);
887 else if(tag->id == ST_PROTECT) {
889 printf(" %s\n", swf_GetString(tag));
892 else if(tag->id == ST_DEFINEBITSLOSSLESS ||
893 tag->id == ST_DEFINEBITSLOSSLESS2) {
894 handleDefineBits(tag);
897 else if(tag->id == ST_DEFINESOUND) {
898 handleDefineSound(tag);
901 else if(tag->id == ST_VIDEOFRAME) {
902 handleVideoFrame(tag, myprefix);
905 else if(tag->id == ST_DEFINEVIDEOSTREAM) {
906 handleVideoStream(tag, myprefix);
909 else if(tag->id == ST_DEFINEEDITTEXT) {
913 else if(tag->id == ST_DEFINEMOVIE) {
914 U16 id = swf_GetU16(tag);
915 char*s = swf_GetString(tag);
916 printf(" URL: %s\n", s);
918 else if(tag->id == ST_DEFINETEXT || tag->id == ST_DEFINETEXT2) {
924 else if(tag->id == ST_PLACEOBJECT2) {
926 else if(tag->id == ST_NAMECHARACTER) {
928 printf(" \"%s\"\n", swf_GetString(tag));
934 sprintf(myprefix, " %s", prefix);
936 if(tag->id == ST_DEFINESPRITE) {
937 sprintf(prefix, " ");
939 dumperror("Sprite definition inside a sprite definition");
943 spriteframelabel = 0;
945 else if(tag->id == ST_END) {
948 spriteframelabel = 0;
950 dumperror("End Tag not empty");
952 else if(tag->id == ST_EXPORTASSETS) {
953 handleExportAssets(tag, myprefix);
955 else if(tag->id == ST_DOACTION && action) {
957 actions = swf_ActionGet(tag);
958 swf_DumpActions(actions, myprefix);
960 else if(tag->id == ST_DEFINEBUTTON && action) {
961 dumpButtonActions(tag, myprefix);
963 else if(tag->id == ST_DEFINEBUTTON2 && action) {
964 dumpButton2Actions(tag, myprefix);
966 else if(tag->id == ST_PLACEOBJECT2) {
967 handlePlaceObject2(tag, myprefix);
970 if(tag->len && used) {
971 int num = swf_GetNumUsedIDs(tag);
975 used = (int*)malloc(sizeof(int)*num);
976 swf_GetUsedIDs(tag, used);
977 printf("%s%suses IDs: ", indent, prefix);
979 swf_SetTagPos(tag, used[t]);
980 printf("%d%s", swf_GetU16(tag), t<num-1?", ":"");
986 if(tag->len && hex) {
987 hexdumpTag(tag, prefix);