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(U32 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]");
386 if(handlerflags&256) printf("[data]");
387 if(handlerflags&512) printf("[initialize]");
388 if(handlerflags&1024) printf("[mouse press]");
389 if(handlerflags&2048) printf("[mouse release]");
390 if(handlerflags&4096) printf("[mouse release outside]");
391 if(handlerflags&8192) printf("[mouse rollover]");
392 if(handlerflags&16384) printf("[mouse rollout]");
393 if(handlerflags&32768) printf("[mouse drag over]");
395 if(handlerflags&0x10000) printf("[mouse drag out]");
396 if(handlerflags&0x20000) printf("[key press]");
397 if(handlerflags&0x40000) printf("[construct even]");
398 if(handlerflags&0xfff80000) printf("[???]");
400 void handleVideoStream(TAG*tag, char*prefix)
402 U16 id = swf_GetU16(tag);
403 U16 frames = swf_GetU16(tag);
404 U16 width = swf_GetU16(tag);
405 U16 height = swf_GetU16(tag);
406 U8 flags = swf_GetU8(tag); //5-2(videopacket 01=off 10=on)-1(smoothing 1=on)
407 U8 codec = swf_GetU8(tag);
408 printf(" (%d frames, %dx%d", frames, width, height);
412 printf(" sorenson h.263)");
414 printf(" codec 0x%02x)", codec);
416 void handleVideoFrame(TAG*tag, char*prefix)
418 U32 code, version, reference, sizeflags;
421 U16 id = swf_GetU16(tag);
422 U16 frame = swf_GetU16(tag);
423 U8 deblock,flags, tmp, bit;
425 char*types[] = {"I-frame", "P-frame", "disposable P-frame", "<reserved>"};
426 printf(" (frame %d) ", frame);
428 /* video packet follows */
429 code = swf_GetBits(tag, 17);
430 version = swf_GetBits(tag, 5);
431 reference = swf_GetBits(tag, 8);
433 sizeflags = swf_GetBits(tag, 3);
436 case 0: width = swf_GetBits(tag, 8); height = swf_GetBits(tag, 8); break;
437 case 1: width = swf_GetBits(tag, 16); height = swf_GetBits(tag, 16); break;
438 case 2: width = 352; height = 288; break;
439 case 3: width = 176; height = 144; break;
440 case 4: width = 128; height = 96; break;
441 case 5: width = 320; height = 240; break;
442 case 6: width = 160; height = 120; break;
443 case 7: width = -1; height = -1;/*reserved*/ break;
445 printf("%dx%d ", width, height);
446 type = swf_GetBits(tag, 2);
447 printf("%s", types[type]);
449 deblock = swf_GetBits(tag, 1);
451 printf(" deblock ", deblock);
452 quantizer = swf_GetBits(tag, 5);
453 printf(" quant: %d ", quantizer);
456 void handlePlaceObject2(TAG*tag, char*prefix)
458 U8 flags = swf_GetU8(tag);
462 int ppos[3] = {0,0,0};
463 swf_GetU16(tag); //depth
465 if(flags&2) swf_GetU16(tag); //id
467 swf_GetMatrix(tag,&m);
469 ppos[0] += sprintf(pstr[0], "| Matrix ");
470 ppos[1] += sprintf(pstr[1], "| %5.3f %5.3f %6.2f ", m.sx/65536.0, m.r1/65536.0, m.tx/20.0);
471 ppos[2] += sprintf(pstr[2], "| %5.3f %5.3f %6.2f ", m.r0/65536.0, m.sy/65536.0, m.ty/20.0);
475 swf_GetCXForm(tag, &cx, 1);
477 ppos[0] += sprintf(pstr[0]+ppos[0], "| CXForm r g b a ");
478 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);
479 ppos[2] += sprintf(pstr[2]+ppos[2], "| add %4d %4d %4d %4d ", cx.r1, cx.g1, cx.b1, cx.a1);
483 U16 ratio = swf_GetU16(tag); //ratio
485 ppos[0] += sprintf(pstr[0]+ppos[0], "| Ratio ");
486 ppos[1] += sprintf(pstr[1]+ppos[1], "| %-5d ", ratio);
487 ppos[2] += sprintf(pstr[2]+ppos[2], "| ");
491 U16 clip = swf_GetU16(tag); //clip
493 ppos[0] += sprintf(pstr[0]+ppos[0], "| Clip ");
494 ppos[1] += sprintf(pstr[1]+ppos[1], "| %-5d ", clip);
495 ppos[2] += sprintf(pstr[2]+ppos[2], "| ");
498 if(flags&32) { while(swf_GetU8(tag)); }
499 if(placements && ppos[0]) {
501 printf("%s %s\n", prefix, pstr[0]);
502 printf("%s %s\n", prefix, pstr[1]);
503 printf("%s %s", prefix, pstr[2]);
512 reserved = swf_GetU16(tag); // must be 0
513 globalflags = swf_GetU16(tag); //TODO: 32 if version>=6
515 printf("Unknown parameter field not zero: %04x\n", reserved);
518 printf("global flags: %04x\n", globalflags);
520 handlerflags = swf_GetU16(tag); //TODO: 32 if version>=6
522 handlerflags = swf_GetU32(tag);
525 while(handlerflags) {
530 globalflags &= ~handlerflags;
531 printf("%s flags %08x ",prefix, handlerflags);
532 printhandlerflags(handlerflags);
533 length = swf_GetU32(tag);
534 printf(", %d bytes actioncode\n",length);
535 a = swf_ActionGet(tag);
536 swf_DumpActions(a,prefix);
539 handlerflags = is32?swf_GetU32(tag):swf_GetU16(tag); //TODO: 32 if version>=6
541 if(globalflags) // should go to sterr.
542 printf("ERROR: unsatisfied handlerflags: %02x\n", globalflags);
544 printf(" has action code\n");
549 void handlePlaceObject(TAG*tag, char*prefix)
554 void fontcallback1(U16 id,U8 * name)
558 void fontcallback2(U16 id,U8 * name)
560 swf_FontExtract(&swf,id,&fonts[fontnum]);
564 static U8 printable(U8 a)
566 if(a<32 || a==127) return '.';
569 void hexdumpTag(TAG*tag, char* prefix)
573 printf(" %s-=> ",prefix);
574 for(t=0;t<tag->len;t++) {
575 printf("%02x ", tag->data[t]);
576 ascii[t&15] = printable(tag->data[t]);
577 if((t && ((t&15)==15)) || (t==tag->len-1))
579 int s,p=((t-1)&15)+1;
585 printf(" %s\n", ascii);
587 printf(" %s\n %s-=> ",ascii,prefix);
592 void handleExportAssets(TAG*tag, char* prefix)
598 num = swf_GetU16(tag);
601 id = swf_GetU16(tag);
602 name = swf_GetString(tag);
603 printf("%sexports %04d as \"%s\"\n", prefix, id, name);
607 void dumperror(const char* format, ...)
612 va_start(arglist, format);
613 vsprintf(buf, format, arglist);
617 printf("==== Error: %s ====\n", buf);
620 static char strbuf[800];
623 char* timestring(double f)
625 int hours = (int)(f/3600);
626 int minutes = (int)((f-hours*3600)/60);
627 int seconds = (int)((f-hours*3600-minutes*60));
628 int useconds = (int)((f-(int)f)*1000+0.5);
631 sprintf(&strbuf[bufpos], "%02d:%02d:%02d,%03d",hours,minutes,seconds,useconds);
632 return &strbuf[bufpos];
635 int main (int argc,char ** argv)
643 char issprite = 0; // are we inside a sprite definition?
646 char* spriteframelabel = 0;
647 char* framelabel = 0;
651 memset(idtab,0,65536);
653 processargs(argc, argv);
657 fprintf(stderr, "You must supply a filename.\n");
661 f = open(filename,O_RDONLY|O_BINARY);
666 sprintf(buffer, "Couldn't open %s", filename);
670 if FAILED(swf_ReadSWF(f,&swf))
672 fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);
679 if(statbuf.st_size != swf.fileSize && !swf.compressed)
680 dumperror("Real Filesize (%d) doesn't match header Filesize (%d)",
681 statbuf.st_size, swf.fileSize);
682 filesize = statbuf.st_size;
687 xsize = (swf.movieSize.xmax-swf.movieSize.xmin)/20;
688 ysize = (swf.movieSize.ymax-swf.movieSize.ymin)/20;
692 printf("-X %d", xsize);
698 printf("-Y %d", ysize);
704 printf("-r %d", swf.frameRate*100/256);
710 printf("-f %d", swf.frameCount);
717 char*fileversions[] = {"","1,0,0,0", "2,0,0,0","3,0,0,0","4,0,0,0",
718 "5,0,0,0","6,0,23,0","7,0,0,0","8,0,0,0"};
719 if(swf.fileVersion>8) {
720 fprintf(stderr, "Fileversion>8\n");
723 printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
725 //" BGCOLOR=#ffffffff\n"?
727 //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
728 " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
729 " <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
730 " <PARAM NAME=\"PLAY\" VALUE=\"true\">\n"
731 " <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
732 " <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
733 " <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
734 " PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
735 " TYPE=\"application/x-shockwave-flash\"\n"
736 " PLUGINSPAGE=\"http://www.macromedia.com/go/getflashplayer\">\n"
738 "</OBJECT>\n", xsize, ysize, fileversions[swf.fileVersion],
739 filename, filename, xsize, ysize);
742 printf("[HEADER] File version: %d\n", swf.fileVersion);
744 printf("[HEADER] File is zlib compressed.");
745 if(filesize && swf.fileSize)
746 printf(" Ratio: %02d%%\n", filesize*100/(swf.fileSize));
750 printf("[HEADER] File size: %ld%s\n", swf.fileSize, swf.compressed?" (Depacked)":"");
751 printf("[HEADER] Frame rate: %f\n",swf.frameRate/256.0);
752 printf("[HEADER] Frame count: %d\n",swf.frameCount);
753 printf("[HEADER] Movie width: %.2f",(swf.movieSize.xmax-swf.movieSize.xmin)/20.0);
754 if(swf.movieSize.xmin)
755 printf(" (left offset: %.2f)\n", swf.movieSize.xmin/20.0);
758 printf("[HEADER] Movie height: %.2f",(swf.movieSize.ymax-swf.movieSize.ymin)/20.0);
759 if(swf.movieSize.ymin)
760 printf(" (top offset: %.2f)\n", swf.movieSize.ymin/20.0);
768 swf_FontEnumerate(&swf,&fontcallback1);
769 fonts = (SWFFONT**)malloc(fontnum*sizeof(SWFFONT*));
771 swf_FontEnumerate(&swf,&fontcallback2);
775 char*name = swf_TagGetName(tag);
778 dumperror("Unknown tag:0x%03x", tag->id);
782 if(swf_TagGetName(tag)) {
783 printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, swf_TagGetName(tag));
785 printf("[%03x] %9ld %sUNKNOWN TAG %03x", tag->id, tag->len, prefix, tag->id);
788 if(tag->id == ST_FREECHARACTER) {
789 U16 id = swf_GetU16(tag);
793 if(swf_isDefiningTag(tag)) {
794 U16 id = swf_GetDefineID(tag);
795 printf(" defines id %04d", id);
797 dumperror("Id %04d is defined more than once.", id);
800 else if(swf_isPseudoDefiningTag(tag)) {
801 U16 id = swf_GetDefineID(tag);
802 printf(" adds information to id %04d", id);
804 dumperror("Id %04d is not yet defined.\n", id);
806 else if(tag->id == ST_PLACEOBJECT) {
807 printf(" places id %04d at depth %04x", swf_GetPlaceID(tag), swf_GetDepth(tag));
809 printf(" name \"%s\"",swf_GetName(tag));
810 handlePlaceObject(tag, myprefix);
812 else if(tag->id == ST_PLACEOBJECT2) {
819 printf(" id %04d",swf_GetPlaceID(tag));
823 printf(" at depth %04d", swf_GetDepth(tag));
825 printf(" name \"%s\"",swf_GetName(tag));
827 else if(tag->id == ST_REMOVEOBJECT) {
828 printf(" removes id %04d from depth %04d", swf_GetPlaceID(tag), swf_GetDepth(tag));
830 else if(tag->id == ST_REMOVEOBJECT2) {
831 printf(" removes object from depth %04d", swf_GetDepth(tag));
833 else if(tag->id == ST_FREECHARACTER) {
834 printf(" frees object %04d", swf_GetPlaceID(tag));
836 else if(tag->id == ST_STARTSOUND) {
839 id = swf_GetU16(tag);
840 flags = swf_GetU8(tag);
842 printf(" stops sound with id %04d", id);
844 printf(" starts sound with id %04d", id);
846 printf(" (if not already playing)");
852 printf(" looping %d times", swf_GetU16(tag));
855 else if(tag->id == ST_FRAMELABEL) {
856 int l = strlen(tag->data);
857 printf(" \"%s\"", tag->data);
859 printf(" has %d extra bytes", tag->len-1-l);
860 if(tag ->len-1-l == 1 && tag->data[tag->len-1] == 1)
863 if((framelabel && !issprite) ||
864 (spriteframelabel && issprite)) {
865 dumperror("Frame %d has more than one label",
866 issprite?spriteframe:mainframe);
868 if(issprite) spriteframelabel = tag->data;
869 else framelabel = tag->data;
871 else if(tag->id == ST_SHOWFRAME) {
872 char*label = issprite?spriteframelabel:framelabel;
873 int frame = issprite?spriteframe:mainframe;
876 while(tag->next && tag->next->id == ST_SHOWFRAME && tag->next->len == 0) {
878 if(issprite) spriteframe++;
884 printf(" %d (%s)", frame, timestring(frame*(256.0/(swf.frameRate+0.1))));
886 printf(" %d-%d (%s-%s)", frame, nframe,
887 timestring(frame*(256.0/(swf.frameRate+0.1))),
888 timestring(nframe*(256.0/(swf.frameRate+0.1)))
891 printf(" (label \"%s\")", label);
892 if(issprite) {spriteframe++; spriteframelabel = 0;}
893 if(!issprite) {mainframe++; framelabel = 0;}
896 if(tag->id == ST_SETBACKGROUNDCOLOR) {
897 U8 r = swf_GetU8(tag);
898 U8 g = swf_GetU8(tag);
899 U8 b = swf_GetU8(tag);
900 printf(" (%02x/%02x/%02x)\n",r,g,b);
902 else if(tag->id == ST_PROTECT) {
904 printf(" %s\n", swf_GetString(tag));
907 else if(tag->id == ST_DEFINEBITSLOSSLESS ||
908 tag->id == ST_DEFINEBITSLOSSLESS2) {
909 handleDefineBits(tag);
912 else if(tag->id == ST_DEFINESOUND) {
913 handleDefineSound(tag);
916 else if(tag->id == ST_VIDEOFRAME) {
917 handleVideoFrame(tag, myprefix);
920 else if(tag->id == ST_DEFINEVIDEOSTREAM) {
921 handleVideoStream(tag, myprefix);
924 else if(tag->id == ST_DEFINEEDITTEXT) {
928 else if(tag->id == ST_DEFINEMOVIE) {
929 U16 id = swf_GetU16(tag);
930 char*s = swf_GetString(tag);
931 printf(" URL: %s\n", s);
933 else if(tag->id == ST_DEFINETEXT || tag->id == ST_DEFINETEXT2) {
939 else if(tag->id == ST_PLACEOBJECT2) {
941 else if(tag->id == ST_NAMECHARACTER) {
943 printf(" \"%s\"\n", swf_GetString(tag));
949 sprintf(myprefix, " %s", prefix);
951 if(tag->id == ST_DEFINESPRITE) {
952 sprintf(prefix, " ");
954 dumperror("Sprite definition inside a sprite definition");
958 spriteframelabel = 0;
960 else if(tag->id == ST_END) {
963 spriteframelabel = 0;
965 dumperror("End Tag not empty");
967 else if(tag->id == ST_EXPORTASSETS) {
968 handleExportAssets(tag, myprefix);
970 else if(tag->id == ST_DOACTION && action) {
972 actions = swf_ActionGet(tag);
973 swf_DumpActions(actions, myprefix);
975 else if(tag->id == ST_DEFINEBUTTON && action) {
976 dumpButtonActions(tag, myprefix);
978 else if(tag->id == ST_DEFINEBUTTON2 && action) {
979 dumpButton2Actions(tag, myprefix);
981 else if(tag->id == ST_PLACEOBJECT2) {
982 handlePlaceObject2(tag, myprefix);
985 if(tag->len && used) {
986 int num = swf_GetNumUsedIDs(tag);
990 used = (int*)malloc(sizeof(int)*num);
991 swf_GetUsedIDs(tag, used);
992 printf("%s%suses IDs: ", indent, prefix);
994 swf_SetTagPos(tag, used[t]);
995 printf("%d%s", swf_GetU16(tag), t<num-1?", ":"");
1001 if(tag->len && hex) {
1002 hexdumpTag(tag, prefix);