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;
56 static int showtext
= 0;
57 static int showshapes
= 0;
61 static int cumulative
= 0;
62 static int showfonts
= 0;
63 static int showbuttons
= 0;
65 static struct options_t options
[] = {
87 int args_callback_option(char*name
,char*val
)
89 if(!strcmp(name
, "V")) {
90 printf("swfdump - part of %s %s\n", PACKAGE
, VERSION
);
93 else if(name
[0]=='a') {
97 else if(name
[0]=='p') {
101 else if(name
[0]=='t') {
105 else if(name
[0]=='s') {
109 else if(name
[0]=='e') {
113 else if(name
[0]=='c') {
117 else if(name
[0]=='E') {
122 else if(name
[0]=='X') {
126 else if(name
[0]=='Y') {
130 else if(name
[0]=='r') {
134 else if(name
[0]=='f') {
138 else if(name
[0]=='F') {
142 else if(name
[0]=='d') {
146 else if(name
[0]=='u') {
150 else if(name
[0]=='b') {
154 else if(name
[0]=='B') {
158 else if(name
[0]=='D') {
159 showbuttons
= action
= placements
= showtext
= showshapes
= 1;
163 printf("Unknown option: -%s\n", name
);
169 int args_callback_longoption(char*name
,char*val
)
171 return args_long2shortoption(options
, name
, val
);
173 void args_callback_usage(char *name
)
176 printf("Usage: %s [-atpdu] file.swf\n", name
);
178 printf("-h , --help Print short help message and exit\n");
179 printf("-D , --full Show everything. Same as -atp\n");
180 printf("-V , --version Print version info and exit\n");
181 printf("-e , --html Print out html code for embedding the file\n");
182 printf("-E , --xhtml Print out xhtml code for embedding the file\n");
183 printf("-a , --action Disassemble action tags\n");
184 printf("-t , --text Show text fields (like swfstrings).\n");
185 printf("-s , --shapes Show shape coordinates/styles\n");
186 printf("-F , --fonts Show font information\n");
187 printf("-p , --placements Show placement information\n");
188 printf("-B , --buttons Show button information\n");
189 printf("-b , --bbox Print tag's bounding boxes\n");
190 printf("-X , --width Prints out a string of the form \"-X width\".\n");
191 printf("-Y , --height Prints out a string of the form \"-Y height\".\n");
192 printf("-r , --rate Prints out a string of the form \"-r rate\".\n");
193 printf("-f , --frames Prints out a string of the form \"-f framenum\".\n");
194 printf("-d , --hex Print hex output of tag data, too.\n");
195 printf("-u , --used Show referred IDs for each Tag.\n");
198 int args_callback_command(char*name
,char*val
)
201 fprintf(stderr
, "Only one file allowed. You supplied at least two. (%s and %s)\n",
209 char* testfunc(char*str
)
211 printf("%s: %s\n", what
, str
);
215 void dumpButton2Actions(TAG
*tag
, char*prefix
)
221 oldTagPos
= swf_GetTagPos(tag
);
223 // scan DefineButton2 Record
225 swf_GetU16(tag
); // Character ID
226 swf_GetU8(tag
); // Flags;
228 offsetpos
= swf_GetTagPos(tag
); // first offset
231 while (swf_GetU8(tag
)) // state -> parse ButtonRecord
232 { swf_GetU16(tag
); // id
233 swf_GetU16(tag
); // layer
234 swf_GetMatrix(tag
,NULL
); // matrix
235 swf_GetCXForm(tag
,NULL
,1); // cxform
242 if(tag
->pos
>= tag
->len
)
245 offsetpos
= swf_GetU16(tag
);
246 condition
= swf_GetU16(tag
); // condition
248 actions
= swf_ActionGet(tag
);
249 printf("%s condition %04x\n", prefix
, condition
);
250 swf_DumpActions(actions
, prefix
);
253 swf_SetTagPos(tag
,oldTagPos
);
257 void dumpButtonActions(TAG
*tag
, char*prefix
)
260 swf_SetTagPos(tag
, 0);
261 swf_GetU16(tag
); // id
262 while (swf_GetU8(tag
)) // state -> parse ButtonRecord
263 { swf_GetU16(tag
); // id
264 swf_GetU16(tag
); // layer
265 swf_GetMatrix(tag
,NULL
); // matrix
267 actions
= swf_ActionGet(tag
);
268 swf_DumpActions(actions
, prefix
);
269 swf_ActionFree(actions
);
272 void dumpButton(TAG
*tag
, char*prefix
)
274 swf_SetTagPos(tag
, 0);
275 swf_GetU16(tag
); // id
277 U8 flags
= swf_GetU8(tag
);
280 U16 id
= swf_GetU16(tag
);
281 U16 depth
= swf_GetU16(tag
);
283 sprintf(event
, "%s%s%s%s",
284 (flags
&BS_HIT
)?"[hit]":"",
285 (flags
&BS_DOWN
)?"[down]":"",
286 (flags
&BS_OVER
)?"[over]":"",
287 (flags
&BS_UP
)?"[up]":"");
289 printf("%s | Show %d at depth %d for %s flags=%02x\n", prefix
, id
, depth
, event
, flags
);
291 printf("%s | Show %d at depth %d for %s\n", prefix
, id
, depth
, event
);
293 swf_GetMatrix(tag
,NULL
); // matrix
297 void dumpFont(TAG
*tag
, char*prefix
)
299 SWFFONT
* font
= malloc(sizeof(SWFFONT
));
300 memset(font
, 0, sizeof(SWFFONT
));
301 if(tag
->id
== ST_DEFINEFONT2
|| tag
->id
== ST_DEFINEFONT3
) {
302 swf_FontExtract_DefineFont2(0, font
, tag
);
303 } else if(tag
->id
== ST_DEFINEFONT
) {
304 swf_FontExtract_DefineFont(0, font
, tag
);
306 printf("%sCan't parse %s yet\n", prefix
,swf_TagGetName(tag
));
308 printf("%sID: %d\n", prefix
,font
->id
);
309 printf("%sVersion: %d\n", prefix
,font
->version
);
310 printf("%sname: %s\n", prefix
,font
->name
);
311 printf("%scharacters: %d\n", prefix
,font
->numchars
);
312 printf("%shightest mapped unicode value: %d\n", prefix
,font
->maxascii
);
315 printf("%sascent:%.2f\n", prefix
,font
->layout
->ascent
/ 20.0);
316 printf("%sdescent:%.2f\n", prefix
,font
->layout
->descent
/ 20.0);
317 printf("%sleading:%.2f\n", prefix
,font
->layout
->leading
/ 20.0);
318 printf("%skerning records:%d\n", prefix
,font
->layout
->kerningcount
);
320 printf("%sstyle: %d\n", prefix
,font
->style
);
321 printf("%sencoding: %02x\n", prefix
,font
->encoding
);
322 printf("%slanguage: %02x\n", prefix
,font
->language
);
324 for(t
=0;t
<font
->numchars
;t
++) {
325 int u
= font
->glyph2ascii
?font
->glyph2ascii
[t
]:-1;
327 if(u
>=32) sprintf(ustr
, " '%c'", u
);
328 else sprintf(ustr
, " 0x%02x", u
);
329 printf("%s== Glyph %d: advance=%d encoding=%d%s ==\n", prefix
, t
, font
->glyph
[t
].advance
, u
, ustr
);
330 SHAPE2
* shape
= swf_ShapeToShape2(font
->glyph
[t
].shape
);
331 SHAPELINE
*line
= shape
->lines
;
334 if(line
->type
== moveTo
) {
335 printf("%smoveTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
336 } else if(line
->type
== lineTo
) {
337 printf("%slineTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
338 } else if(line
->type
== splineTo
) {
339 printf("%ssplineTo (%.2f %.2f) %.2f %.2f\n", prefix
,
340 line
->sx
/20.0, line
->sy
/20.0,
341 line
->x
/20.0, line
->y
/20.0
346 swf_Shape2Free(shape
);
353 printf("%sencoding table:", prefix, prefix);
354 char filled0=0, lastfilled=0;
355 for(t=0;t<font->maxascii;t++) {
357 printf("\n%s%08x ", prefix, t);
360 for(s=t;s<font->maxascii;s++) {
361 if(font->ascii2glyph[s]>=0) break;
370 for(s=t;s<t+16 && s<font->maxascii;s++) {
371 if(font->ascii2glyph[s]>=0) filled0=1;
374 printf("%4d ", font->ascii2glyph[t]);
382 static int fontnum
= 0;
383 static SWFFONT
**fonts
;
385 void textcallback(void*self
, int*glyphs
, int*xpos
, int nr
, int fontid
, int fontsize
, int startx
, int starty
, RGBA
*color
)
390 printf(" <%2d glyphs in font %04d size %d, color #%02x%02x%02x%02x at %.2f,%.2f> ",nr
, fontid
, fontsize
, color
->r
, color
->g
, color
->b
, color
->a
, (startx
+xpos
[0])/20.0, starty
/20.0);
391 for(t
=0;t
<fontnum
;t
++)
393 if(fonts
[t
]->id
== fontid
) {
403 if(glyphs
[t
] >= fonts
[font
]->numchars
/*glyph is in range*/
404 || !fonts
[font
]->glyph2ascii
/* font has ascii<->glyph mapping */
407 if(fonts
[font
]->glyph2ascii
[glyphs
[t
]])
408 a
= fonts
[font
]->glyph2ascii
[glyphs
[t
]];
418 printf("\\x%x", (int)a
);
423 void handleText(TAG
*tag
, char*prefix
)
427 swf_SetTagPos(tag
, 0);
430 swf_ResetReadBits(tag
);
432 swf_GetMatrix(tag
, &m
);
433 printf("%s| Matrix\n",prefix
);
434 printf("%s| %5.3f %5.3f %6.2f\n", prefix
, m
.sx
/65536.0, m
.r1
/65536.0, m
.tx
/20.0);
435 printf("%s| %5.3f %5.3f %6.2f\n", prefix
, m
.r0
/65536.0, m
.sy
/65536.0, m
.ty
/20.0);
436 swf_SetTagPos(tag
, 0);
439 swf_ParseDefineText(tag
,textcallback
, 0);
443 void handleDefineSound(TAG
*tag
)
445 U16 id
= swf_GetU16(tag
);
446 U8 flags
= swf_GetU8(tag
);
447 int compression
= (flags
>>4)&7;
448 int rate
= (flags
>>2)&3;
449 int bits
= flags
&2?16:8;
450 int stereo
= flags
&1;
452 if(compression
== 0) printf("Raw ");
453 else if(compression
== 1) printf("ADPCM ");
454 else if(compression
== 2) printf("MP3 ");
455 else if(compression
== 3) printf("Raw little-endian ");
456 else if(compression
== 6) printf("ASAO ");
458 if(rate
== 0) printf("5.5Khz ");
459 if(rate
== 1) printf("11Khz ");
460 if(rate
== 2) printf("22Khz ");
461 if(rate
== 3) printf("44Khz ");
462 printf("%dBit ", bits
);
463 if(stereo
) printf("stereo");
468 void handleDefineBits(TAG
*tag
)
474 id
= swf_GetU16(tag
);
475 mode
= swf_GetU8(tag
);
476 width
= swf_GetU16(tag
);
477 height
= swf_GetU16(tag
);
478 printf(" image %dx%d",width
,height
);
479 if(mode
== 3) printf(" (8 bpp)");
480 else if(mode
== 4) printf(" (16 bpp)");
481 else if(mode
== 5) printf(" (32 bpp)");
482 else printf(" (? bpp)");
485 void handleEditText(TAG
*tag
)
490 id
= swf_GetU16(tag
);
493 //swf_ResetReadBits(tag);
499 flags
= swf_GetBits(tag
,16);
500 if(flags
& ET_HASFONT
) {
501 swf_GetU16(tag
); //font
502 swf_GetU16(tag
); //fontheight
504 if(flags
& ET_HASTEXTCOLOR
) {
505 swf_GetU8(tag
); //rgba
510 if(flags
& ET_HASMAXLENGTH
) {
511 swf_GetU16(tag
); //maxlength
513 if(flags
& ET_HASLAYOUT
) {
514 swf_GetU8(tag
); //align
515 swf_GetU16(tag
); //left margin
516 swf_GetU16(tag
); //right margin
517 swf_GetU16(tag
); //indent
518 swf_GetU16(tag
); //leading
520 printf(" variable \"%s\" ", &tag
->data
[tag
->pos
]);
521 if(flags
& ET_HTML
) printf("(html)");
522 if(flags
& ET_NOSELECT
) printf("(noselect)");
523 if(flags
& ET_PASSWORD
) printf("(password)");
524 if(flags
& ET_READONLY
) printf("(readonly)");
526 if(flags
& (ET_X1
| ET_X3
))
528 printf(" undefined flags: %08x (%08x)", (flags
&(ET_X1
|ET_X3
)), flags
);
531 while(tag
->data
[tag
->pos
++]);
532 if(flags
& ET_HASTEXT
)
533 // printf(" text \"%s\"\n", &tag->data[tag->pos]) //TODO
536 void printhandlerflags(U32 handlerflags
)
538 if(handlerflags
&1) printf("[on load]");
539 if(handlerflags
&2) printf("[enter frame]");
540 if(handlerflags
&4) printf("[unload]");
541 if(handlerflags
&8) printf("[mouse move]");
542 if(handlerflags
&16) printf("[mouse down]");
543 if(handlerflags
&32) printf("[mouse up]");
544 if(handlerflags
&64) printf("[key down]");
545 if(handlerflags
&128) printf("[key up]");
547 if(handlerflags
&256) printf("[data]");
548 if(handlerflags
&512) printf("[initialize]");
549 if(handlerflags
&1024) printf("[mouse press]");
550 if(handlerflags
&2048) printf("[mouse release]");
551 if(handlerflags
&4096) printf("[mouse release outside]");
552 if(handlerflags
&8192) printf("[mouse rollover]");
553 if(handlerflags
&16384) printf("[mouse rollout]");
554 if(handlerflags
&32768) printf("[mouse drag over]");
556 if(handlerflags
&0x10000) printf("[mouse drag out]");
557 if(handlerflags
&0x20000) printf("[key press]");
558 if(handlerflags
&0x40000) printf("[construct even]");
559 if(handlerflags
&0xfff80000) printf("[???]");
561 void handleVideoStream(TAG
*tag
, char*prefix
)
563 U16 id
= swf_GetU16(tag
);
564 U16 frames
= swf_GetU16(tag
);
565 U16 width
= swf_GetU16(tag
);
566 U16 height
= swf_GetU16(tag
);
567 U8 flags
= swf_GetU8(tag
); //5-2(videopacket 01=off 10=on)-1(smoothing 1=on)
568 U8 codec
= swf_GetU8(tag
);
569 printf(" (%d frames, %dx%d", frames
, width
, height
);
573 printf(" sorenson h.263)");
575 printf(" codec 0x%02x)", codec
);
577 void handleVideoFrame(TAG
*tag
, char*prefix
)
579 U32 code
, version
, reference
, sizeflags
;
580 U32 width
=0, height
=0;
582 U16 id
= swf_GetU16(tag
);
583 U16 frame
= swf_GetU16(tag
);
584 U8 deblock
,flags
, tmp
, bit
;
586 char*types
[] = {"I-frame", "P-frame", "disposable P-frame", "<reserved>"};
587 printf(" (frame %d) ", frame
);
589 /* video packet follows */
590 code
= swf_GetBits(tag
, 17);
591 version
= swf_GetBits(tag
, 5);
592 reference
= swf_GetBits(tag
, 8);
594 sizeflags
= swf_GetBits(tag
, 3);
597 case 0: width
= swf_GetBits(tag
, 8); height
= swf_GetBits(tag
, 8); break;
598 case 1: width
= swf_GetBits(tag
, 16); height
= swf_GetBits(tag
, 16); break;
599 case 2: width
= 352; height
= 288; break;
600 case 3: width
= 176; height
= 144; break;
601 case 4: width
= 128; height
= 96; break;
602 case 5: width
= 320; height
= 240; break;
603 case 6: width
= 160; height
= 120; break;
604 case 7: width
= -1; height
= -1;/*reserved*/ break;
606 printf("%dx%d ", width
, height
);
607 type
= swf_GetBits(tag
, 2);
608 printf("%s", types
[type
]);
610 deblock
= swf_GetBits(tag
, 1);
612 printf(" deblock %d ", deblock
);
613 quantizer
= swf_GetBits(tag
, 5);
614 printf(" quant: %d ", quantizer
);
617 void dumpFilter(FILTER
*filter
)
619 if(filter
->type
== FILTERTYPE_BLUR
) {
620 FILTER_BLUR
*f
= (FILTER_BLUR
*)filter
;
621 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
622 printf("passes: %d\n", f
->passes
);
623 } if(filter
->type
== FILTERTYPE_GLOW
) {
624 FILTER_GLOW
*f
= (FILTER_GLOW
*)filter
;
625 printf("color %02x%02x%02x%02x\n", f
->rgba
.r
,f
->rgba
.g
,f
->rgba
.b
,f
->rgba
.a
);
626 printf("blurx: %f blury: %f strength: %f\n", f
->blurx
, f
->blury
, f
->strength
);
627 printf("passes: %d\n", f
->passes
);
628 printf("flags: %s%s%s\n",
629 f
->knockout
?"knockout ":"",
630 f
->composite
?"composite ":"",
631 f
->innerglow
?"innerglow":"");
632 } if(filter
->type
== FILTERTYPE_DROPSHADOW
) {
633 FILTER_DROPSHADOW
*f
= (FILTER_DROPSHADOW
*)filter
;
634 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
635 printf("passes: %d\n", f
->passes
);
636 printf("angle: %f distance: %f\n", f
->angle
, f
->distance
);
637 printf("strength: %f passes: %d\n", f
->strength
, f
->passes
);
638 printf("flags: %s%s%s\n",
639 f
->knockout
?"knockout ":"",
640 f
->composite
?"composite ":"",
641 f
->innershadow
?"innershadow ":"");
642 } if(filter
->type
== FILTERTYPE_BEVEL
) {
643 FILTER_BEVEL
*f
= (FILTER_BEVEL
*)filter
;
644 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
645 printf("passes: %d\n", f
->passes
);
646 printf("angle: %f distance: %f\n", f
->angle
, f
->distance
);
647 printf("strength: %f passes: %d\n", f
->strength
, f
->passes
);
648 printf("flags: %s%s%s%s\n",
650 f
->knockout
?"knockout ":"",
651 f
->composite
?"composite ":"",
652 f
->innershadow
?"innershadow ":"");
653 } if(filter
->type
== FILTERTYPE_GRADIENTGLOW
) {
654 FILTER_GRADIENTGLOW
*f
= (FILTER_GRADIENTGLOW
*)filter
;
655 swf_DumpGradient(stdout
, f
->gradient
);
656 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
657 printf("angle: %f distance: %f\n", f
->angle
, f
->distance
);
658 printf("strength: %f passes: %d\n", f
->strength
, f
->passes
);
659 printf("flags: %s%s%s%s\n",
660 f
->knockout
?"knockout ":"",
661 f
->ontop
?"ontop ":"",
662 f
->composite
?"composite ":"",
663 f
->innershadow
?"innershadow ":"");
668 void handlePlaceObject23(TAG
*tag
, char*prefix
)
674 int ppos
[3] = {0,0,0};
675 swf_SetTagPos(tag
, 0);
676 flags
= swf_GetU8(tag
);
677 if(tag
->id
== ST_PLACEOBJECT3
)
678 flags2
= swf_GetU8(tag
);
679 swf_GetU16(tag
); //depth
682 if(flags
&2) swf_GetU16(tag
); //id
684 swf_GetMatrix(tag
,&m
);
686 ppos
[0] += sprintf(pstr
[0], "| Matrix ");
687 ppos
[1] += sprintf(pstr
[1], "| %5.3f %5.3f %6.2f ", m
.sx
/65536.0, m
.r1
/65536.0, m
.tx
/20.0);
688 ppos
[2] += sprintf(pstr
[2], "| %5.3f %5.3f %6.2f ", m
.r0
/65536.0, m
.sy
/65536.0, m
.ty
/20.0);
692 swf_GetCXForm(tag
, &cx
, 1);
694 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| CXForm r g b a ");
695 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);
696 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| add %4d %4d %4d %4d ", cx
.r1
, cx
.g1
, cx
.b1
, cx
.a1
);
700 U16 ratio
= swf_GetU16(tag
); //ratio
702 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| Ratio ");
703 ppos
[1] += sprintf(pstr
[1]+ppos
[1], "| %-5d ", ratio
);
704 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| ");
708 U16 clip
= swf_GetU16(tag
); //clip
710 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| Clip ");
711 ppos
[1] += sprintf(pstr
[1]+ppos
[1], "| %-4d ", clip
);
712 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| ");
715 if(flags
&32) { while(swf_GetU8(tag
)); }
717 if(flags2
&1) { // filter list
718 U8 num
= swf_GetU8(tag
);
720 printf("\n%d filters\n", num
);
721 char*filtername
[] = {"dropshadow","blur","glow","bevel","gradientglow","convolution","colormatrix","gradientbevel"};
724 FILTER
*filter
= swf_GetFilter(tag
);
730 printf("filter %d: %02x (%s)\n", t
, filter
->type
, (filter
->type
<sizeof(filtername
)/sizeof(filtername
[0]))?filtername
[filter
->type
]:"?");
735 if(flags2
&2) { // blend mode
736 U8 blendmode
= swf_GetU8(tag
);
740 sprintf(name
, "%-5d", blendmode
);
741 for(t
=0;blendModeNames
[t
];t
++) {
743 sprintf(name
, "%-5s", blendModeNames
[t
]);
747 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| Blend ");
748 ppos
[1] += sprintf(pstr
[1]+ppos
[1], "| %s ", name
);
749 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| ");
753 if(placements
&& ppos
[0]) {
755 printf("%s %s\n", prefix
, pstr
[0]);
756 printf("%s %s\n", prefix
, pstr
[1]);
757 printf("%s %s", prefix
, pstr
[2]);
766 reserved
= swf_GetU16(tag
); // must be 0
767 globalflags
= swf_GetU16(tag
); //TODO: 32 if version>=6
769 printf("Unknown parameter field not zero: %04x\n", reserved
);
772 printf("global flags: %04x\n", globalflags
);
774 handlerflags
= swf_GetU16(tag
); //TODO: 32 if version>=6
776 handlerflags
= swf_GetU32(tag
);
779 while(handlerflags
) {
784 globalflags
&= ~handlerflags
;
785 printf("%s flags %08x ",prefix
, handlerflags
);
786 printhandlerflags(handlerflags
);
787 length
= swf_GetU32(tag
);
788 printf(", %d bytes actioncode\n",length
);
789 a
= swf_ActionGet(tag
);
790 swf_DumpActions(a
,prefix
);
793 handlerflags
= is32
?swf_GetU32(tag
):swf_GetU16(tag
); //TODO: 32 if version>=6
795 if(globalflags
) // should go to sterr.
796 printf("ERROR: unsatisfied handlerflags: %02x\n", globalflags
);
798 printf(" has action code\n");
803 void handlePlaceObject(TAG
*tag
, char*prefix
)
805 TAG
*tag2
= swf_InsertTag(0, ST_PLACEOBJECT2
);
810 swf_SetTagPos(tag
, 0);
811 id
= swf_GetU16(tag
);
812 depth
= swf_GetU16(tag
);
813 swf_GetMatrix(tag
, &matrix
);
814 swf_GetCXForm(tag
, &cxform
, 0);
816 swf_SetU8(tag2
, 14 /* char, matrix, cxform */);
817 swf_SetU16(tag2
, depth
);
818 swf_SetU16(tag2
, id
);
819 swf_SetMatrix(tag2
, &matrix
);
820 swf_SetCXForm(tag2
, &cxform
, 1);
822 handlePlaceObject23(tag2
, prefix
);
825 char* fillstyle2str(FILLSTYLE
*style
)
827 switch(style
->type
) {
829 sprintf(stylebuf
, "SOLID %02x%02x%02x%02x", style
->color
.r
, style
->color
.g
, style
->color
.b
, style
->color
.a
);
831 case 0x10: case 0x11: case 0x12: case 0x13:
832 sprintf(stylebuf
, "GRADIENT (%d steps)", style
->gradient
.num
);
834 case 0x40: case 0x42:
835 /* TODO: display information about that bitmap */
836 sprintf(stylebuf
, "BITMAPt%s %d", (style
->type
&2)?"n":"", style
->id_bitmap
);
837 /* TODO: show matrix */
838 //swf_DumpMatrix(stdout, &style->m);
840 case 0x41: case 0x43:
841 /* TODO: display information about that bitmap */
842 sprintf(stylebuf
, "BITMAPc%s %d", (style
->type
&2)?"n":"", style
->id_bitmap
);
843 /* TODO: show matrix */
844 //swf_DumpMatrix(stdout, &style->m);
847 sprintf(stylebuf
, "UNKNOWN[%02x]",style
->type
);
851 char* linestyle2str(LINESTYLE
*style
)
853 sprintf(stylebuf
, "%.2f %02x%02x%02x%02x", style
->width
/20.0, style
->color
.r
, style
->color
.g
, style
->color
.b
, style
->color
.a
);
857 void handleShape(TAG
*tag
, char*prefix
)
865 swf_ParseDefineShape(tag
, &shape
);
867 max
= shape
.numlinestyles
> shape
.numfillstyles
?shape
.numlinestyles
:shape
.numfillstyles
;
869 if(max
) printf("%s | fillstyles(%02d) linestyles(%02d)\n",
874 else printf("%s | (Neither line nor fill styles)\n", prefix
);
877 printf("%s", prefix
);
878 if(t
< shape
.numfillstyles
) {
879 printf(" | %-2d) %-18.18s", t
+1, fillstyle2str(&shape
.fillstyles
[t
]));
883 if(t
< shape
.numlinestyles
) {
884 printf("%-2d) %s", t
+1, linestyle2str(&shape
.linestyles
[t
]));
887 //if(shape.fillstyles[t].type&0x40) {
888 // MATRIX m = shape.fillstyles[t].m;
889 // swf_DumpMatrix(stdout, &m);
893 printf("%s |\n", prefix
);
897 printf("%s | fill: %02d/%02d line:%02d - ",
902 if(line
->type
== moveTo
) {
903 printf("moveTo %.2f %.2f\n", line
->x
/20.0, line
->y
/20.0);
904 } else if(line
->type
== lineTo
) {
905 printf("lineTo %.2f %.2f\n", line
->x
/20.0, line
->y
/20.0);
906 } else if(line
->type
== splineTo
) {
907 printf("splineTo (%.2f %.2f) %.2f %.2f\n",
908 line
->sx
/20.0, line
->sy
/20.0,
909 line
->x
/20.0, line
->y
/20.0
914 printf("%s |\n", prefix
);
917 void fontcallback1(void*self
, U16 id
,U8
* name
)
921 void fontcallback2(void*self
, U16 id
,U8
* name
)
923 swf_FontExtract(&swf
,id
,&fonts
[fontnum
]);
927 static U8
printable(U8 a
)
929 if(a
<32 || a
==127) return '.';
932 void hexdumpTag(TAG
*tag
, char* prefix
)
936 printf(" %s-=> ",prefix
);
937 for(t
=0;t
<tag
->len
;t
++) {
938 printf("%02x ", tag
->data
[t
]);
939 ascii
[t
&15] = printable(tag
->data
[t
]);
940 if((t
&& ((t
&15)==15)) || (t
==tag
->len
-1))
944 for(s
=p
-1;s
<16;s
++) {
948 printf(" %s\n", ascii
);
950 printf(" %s\n %s-=> ",ascii
,prefix
);
955 void handleImportAssets(TAG
*tag
, char* prefix
, int assets2
)
961 url
= swf_GetString(tag
);
962 printf("%sfrom %s\n", prefix
, url
);
965 swf_GetU8(tag
); // Reserved: Must be 1
966 swf_GetU8(tag
); // Reserved: Must be 0
968 num
= swf_GetU16(tag
);
971 id
= swf_GetU16(tag
);
972 name
= swf_GetString(tag
);
973 printf("%s import %04d named \"%s\"\n", prefix
, id
, name
);
977 void handleExportAssets(TAG
*tag
, char* prefix
)
983 num
= swf_GetU16(tag
);
986 id
= swf_GetU16(tag
);
987 name
= swf_GetString(tag
);
988 printf("%sexports %04d as \"%s\"\n", prefix
, id
, name
);
992 static void handleFontAlign1(TAG
*tag
)
994 swf_SetTagPos(tag
, 0);
995 U16 id
= swf_GetU16(tag
);
996 U8 flags
= swf_GetU8(tag
);
997 printf(" for font %04d, ", id
);
998 if((flags
&3)==0) printf("thin, ");
999 else if((flags
&3)==1) printf("medium, ");
1000 else if((flags
&3)==2) printf("thick, ");
1003 while(tag
->pos
< tag
->len
) {
1004 int nr
= swf_GetU8(tag
); // should be 2
1007 printf("*** unsupported multiboxes ***, ");
1011 float v1
= swf_GetF16(tag
);
1012 float v2
= swf_GetF16(tag
);
1014 U8 xyflags
= swf_GetU8(tag
);
1017 printf(" %d glyphs", num
);
1020 #define ALIGN_WITH_GLYPHS
1021 static void handleFontAlign2(TAG
*tag
, char*prefix
)
1025 swf_SetTagPos(tag
, 0);
1026 U16 id
= swf_GetU16(tag
);
1029 #ifdef ALIGN_WITH_GLYPHS
1032 while(swf
.firstTag
->prev
) swf
.firstTag
= swf
.firstTag
->prev
;
1034 swf_FontExtract(&swf
, id
, &font
);
1036 swf_SetTagPos(tag
, 3);
1037 while(tag
->pos
< tag
->len
) {
1038 printf("%sglyph %d) ", prefix
, num
);
1039 int nr
= swf_GetU8(tag
); // should be 2
1043 float v
= swf_GetF16(tag
);
1044 printf("%f ", v
*1024.0);
1047 for(s
=0;s
<nr
-1;s
++) {
1050 float v
= swf_GetF16(tag
);
1051 printf("+%f ", v
*1024.0);
1054 U8 xyflags
= swf_GetU8(tag
);
1055 printf("xy:%02x\n", xyflags
);
1057 #ifdef ALIGN_WITH_GLYPHS
1058 if(font
&& num
<font
->numchars
) {
1059 SHAPE2
* shape
= swf_ShapeToShape2(font
->glyph
[num
].shape
);
1060 SHAPELINE
*line
= shape
->lines
;
1062 if(line
->type
== moveTo
) {
1063 printf("%smoveTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
1064 } else if(line
->type
== lineTo
) {
1065 printf("%slineTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
1066 } else if(line
->type
== splineTo
) {
1067 printf("%ssplineTo (%.2f %.2f) %.2f %.2f\n", prefix
,
1068 line
->sx
/20.0, line
->sy
/20.0,
1069 line
->x
/20.0, line
->y
/20.0
1074 swf_Shape2Free(shape
);
1077 if(num
==font
->numchars
-1) break;
1084 void dumperror(const char* format
, ...)
1089 va_start(arglist
, format
);
1090 vsnprintf(buf
, sizeof(buf
)-1, format
, arglist
);
1094 printf("==== Error: %s ====\n", buf
);
1097 static char strbuf
[800];
1098 static int bufpos
=0;
1100 char* timestring(double f
)
1102 int hours
= (int)(f
/3600);
1103 int minutes
= (int)((f
-hours
*3600)/60);
1104 int seconds
= (int)((f
-hours
*3600-minutes
*60));
1105 int useconds
= (int)((f
-(int)f
)*1000+0.5);
1108 sprintf(&strbuf
[bufpos
], "%02d:%02d:%02d,%03d",hours
,minutes
,seconds
,useconds
);
1109 return &strbuf
[bufpos
];
1112 int main (int argc
,char ** argv
)
1116 struct stat statbuf
;
1120 char issprite
= 0; // are we inside a sprite definition?
1121 int spriteframe
= 0;
1123 char* spriteframelabel
= 0;
1124 char* framelabel
= 0;
1129 memset(idtab
,0,65536);
1131 processargs(argc
, argv
);
1135 fprintf(stderr
, "You must supply a filename.\n");
1139 f
= open(filename
,O_RDONLY
|O_BINARY
);
1143 sprintf(buffer
, "Couldn't open %.200s", filename
);
1149 char compressed
= (header
[0]=='C');
1150 char isflash
= (header
[0]=='F' && header
[1] == 'W' && header
[2] == 'S') ||
1151 (header
[0]=='C' && header
[1] == 'W' && header
[2] == 'S');
1154 int fl
=strlen(filename
);
1155 if(!isflash
&& fl
>3 && !strcmp(&filename
[fl
-4], ".abc")) {
1156 swf_ReadABCfile(filename
, &swf
);
1158 f
= open(filename
,O_RDONLY
|O_BINARY
);
1159 if FAILED(swf_ReadSWF(f
,&swf
))
1161 fprintf(stderr
, "%s is not a valid SWF file or contains errors.\n",filename
);
1168 if(statbuf
.st_size
!= swf
.fileSize
&& !compressed
)
1169 dumperror("Real Filesize (%d) doesn't match header Filesize (%d)",
1170 statbuf
.st_size
, swf
.fileSize
);
1171 filesize
= statbuf
.st_size
;
1176 //if(action && swf.fileVersion>=9) {
1177 // fprintf(stderr, "Actionscript parsing (-a) not yet supported for SWF versions>=9\n");
1181 xsize
= (swf
.movieSize
.xmax
-swf
.movieSize
.xmin
)/20;
1182 ysize
= (swf
.movieSize
.ymax
-swf
.movieSize
.ymin
)/20;
1186 printf("-X %d", xsize
);
1188 if((xy
&1) && (xy
&6))
1192 printf("-Y %d", ysize
);
1194 if((xy
&3) && (xy
&4))
1198 printf("-r %.2f", swf
.frameRate
/256.0);
1200 if((xy
&7) && (xy
&8))
1204 printf("-f %d", swf
.frameCount
);
1211 char*fileversions
[] = {"","1,0,0,0", "2,0,0,0","3,0,0,0","4,0,0,0",
1212 "5,0,0,0","6,0,23,0","7,0,0,0","8,0,0,0","9,0,0,0","10,0,0,0", "11,0,0,0", "12,0,0,0"};
1213 if(swf
.fileVersion
>10) {
1214 fprintf(stderr
, "Fileversion>10\n");
1219 printf("<object type=\"application/x-shockwave-flash\" data=\"%s\" width=\"%d\" height=\"%d\">\n"
1220 "<param name=\"movie\" value=\"%s\"/>\n"
1221 "<param name=\"play\" value=\"true\"/>\n"
1222 "<param name=\"loop\" value=\"false\"/>\n"
1223 "<param name=\"quality\" value=\"high\"/>\n"
1224 "<param name=\"loop\" value=\"false\"/>\n"
1225 "</object>\n\n", filename
, xsize
, ysize
, filename
);
1227 printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
1229 //" BGCOLOR=#ffffffff\n"?
1231 //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
1232 " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
1233 " <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
1234 " <PARAM NAME=\"PLAY\" VALUE=\"true\">\n"
1235 " <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
1236 " <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
1237 " <PARAM NAME=\"ALLOWSCRIPTACCESS\" VALUE=\"always\">\n"
1238 " <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
1239 " PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
1240 " TYPE=\"application/x-shockwave-flash\"\n"
1241 " ALLOWSCRIPTACCESS=\"always\"\n"
1242 " PLUGINSPAGE=\"http://get.adobe.com/flashplayer/\">\n"
1244 "</OBJECT>\n", xsize
, ysize
, fileversions
[swf
.fileVersion
],
1245 filename
, filename
, xsize
, ysize
);
1249 printf("[HEADER] File version: %d\n", swf
.fileVersion
);
1251 printf("[HEADER] File is zlib compressed.");
1252 if(filesize
&& swf
.fileSize
)
1253 printf(" Ratio: %02d%%\n", filesize
*100/(swf
.fileSize
));
1257 printf("[HEADER] File size: %d%s\n", swf
.fileSize
, swf
.compressed
?" (Depacked)":"");
1258 printf("[HEADER] Frame rate: %f\n",swf
.frameRate
/256.0);
1259 printf("[HEADER] Frame count: %d\n",swf
.frameCount
);
1260 printf("[HEADER] Movie width: %.2f",(swf
.movieSize
.xmax
-swf
.movieSize
.xmin
)/20.0);
1261 if(swf
.movieSize
.xmin
)
1262 printf(" (left offset: %.2f)\n", swf
.movieSize
.xmin
/20.0);
1265 printf("[HEADER] Movie height: %.2f",(swf
.movieSize
.ymax
-swf
.movieSize
.ymin
)/20.0);
1266 if(swf
.movieSize
.ymin
)
1267 printf(" (top offset: %.2f)\n", swf
.movieSize
.ymin
/20.0);
1275 swf_FontEnumerate(&swf
,&fontcallback1
, 0);
1276 fonts
= (SWFFONT
**)malloc(fontnum
*sizeof(SWFFONT
*));
1278 swf_FontEnumerate(&swf
,&fontcallback2
, 0);
1282 char*name
= swf_TagGetName(tag
);
1285 dumperror("Unknown tag:0x%03x", tag
->id
);
1290 name
= "UNKNOWN TAG";
1293 filepos
+= tag
->len
;
1294 printf("[%03x] %9d %9d %s%s", tag
->id
, tag
->len
, filepos
, prefix
, swf_TagGetName(tag
));
1296 printf("[%03x] %9d %s%s", tag
->id
, tag
->len
, prefix
, swf_TagGetName(tag
));
1299 if(tag
->id
== ST_PLACEOBJECT
) {
1300 printf(" places id %04d at depth %04x", swf_GetPlaceID(tag
), swf_GetDepth(tag
));
1301 if(swf_GetName(tag
))
1302 printf(" name \"%s\"",swf_GetName(tag
));
1304 else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
1311 printf(" id %04d",swf_GetPlaceID(tag
));
1315 printf(" at depth %04d", swf_GetDepth(tag
));
1317 if(tag
->id
== ST_PLACEOBJECT3
&& tag
->data
[1]&4)
1318 printf(" as bitmap");
1320 swf_SetTagPos(tag
, 0);
1321 if(tag
->data
[0]&64) {
1323 swf_GetPlaceObject(tag
, &po
);
1324 printf(" (clip to %04d)", po
.clipdepth
);
1325 swf_PlaceObjectFree(&po
);
1327 if(swf_GetName(tag
))
1328 printf(" name \"%s\"",swf_GetName(tag
));
1331 else if(tag
->id
== ST_REMOVEOBJECT
) {
1332 printf(" removes id %04d from depth %04d", swf_GetPlaceID(tag
), swf_GetDepth(tag
));
1334 else if(tag
->id
== ST_REMOVEOBJECT2
) {
1335 printf(" removes object from depth %04d", swf_GetDepth(tag
));
1337 else if(tag
->id
== ST_FREECHARACTER
) {
1338 printf(" frees object %04d", swf_GetPlaceID(tag
));
1340 else if(tag
->id
== ST_FILEATTRIBUTES
) {
1341 swf_SetTagPos(tag
, 0);
1342 U32 flags
= swf_GetU32(tag
);
1343 if(flags
&FILEATTRIBUTE_USENETWORK
) printf(" usenetwork");
1344 if(flags
&FILEATTRIBUTE_AS3
) printf(" as3");
1345 if(flags
&FILEATTRIBUTE_SYMBOLCLASS
) printf(" symbolclass");
1346 if(flags
&FILEATTRIBUTE_USEHARDWAREGPU
) printf(" hardware-gpu");
1347 if(flags
&FILEATTRIBUTE_USEACCELERATEDBLIT
) printf(" accelerated-blit");
1348 if(flags
&~(1|8|16|32|64))
1349 printf(" flags=%02x", flags
);
1351 else if(tag
->id
== ST_DOABC
) {
1352 swf_SetTagPos(tag
, 0);
1353 U32 flags
= swf_GetU32(tag
);
1354 char*s
= swf_GetString(tag
);
1356 printf(" flags=%08x", flags
);
1359 printf(" \"%s\"", s
);
1364 printf(" lazy load");
1366 swf_SetTagPos(tag
, 0);
1368 else if(tag
->id
== ST_STARTSOUND
) {
1371 id
= swf_GetU16(tag
);
1372 flags
= swf_GetU8(tag
);
1374 printf(" stops sound with id %04d", id
);
1376 printf(" starts sound with id %04d", id
);
1378 printf(" (if not already playing)");
1384 printf(" looping %d times", swf_GetU16(tag
));
1387 else if(tag
->id
== ST_FRAMELABEL
) {
1388 int l
= strlen((char*)tag
->data
);
1389 printf(" \"%s\"", tag
->data
);
1390 if((l
+1) < tag
->len
) {
1391 printf(" has %d extra bytes", tag
->len
-1-l
);
1392 if(tag
->len
- (l
+1) == 1 && tag
->data
[tag
->len
-1] == 1)
1393 printf(" (ANCHOR)");
1395 if((framelabel
&& !issprite
) ||
1396 (spriteframelabel
&& issprite
)) {
1397 dumperror("Frame %d has more than one label",
1398 issprite
?spriteframe
:mainframe
);
1400 if(issprite
) spriteframelabel
= (char*)tag
->data
;
1401 else framelabel
= (char*)tag
->data
;
1403 else if(tag
->id
== ST_SHOWFRAME
) {
1404 char*label
= issprite
?spriteframelabel
:framelabel
;
1405 int frame
= issprite
?spriteframe
:mainframe
;
1408 while(tag
->next
&& tag
->next
->id
== ST_SHOWFRAME
&& tag
->next
->len
== 0) {
1410 if(issprite
) spriteframe
++;
1416 printf(" %d (%s)", frame
+1, timestring(frame
*(256.0/(swf
.frameRate
+0.1))));
1418 printf(" %d-%d (%s-%s)", frame
+1, nframe
+1,
1419 timestring(frame
*(256.0/(swf
.frameRate
+0.1))),
1420 timestring(nframe
*(256.0/(swf
.frameRate
+0.1)))
1423 printf(" (label \"%s\")", label
);
1424 if(issprite
) {spriteframe
++; spriteframelabel
= 0;}
1425 if(!issprite
) {mainframe
++; framelabel
= 0;}
1427 else if(tag
->id
== ST_SETBACKGROUNDCOLOR
) {
1428 U8 r
= swf_GetU8(tag
);
1429 U8 g
= swf_GetU8(tag
);
1430 U8 b
= swf_GetU8(tag
);
1431 printf(" (%02x/%02x/%02x)",r
,g
,b
);
1433 else if(tag
->id
== ST_PROTECT
) {
1435 printf(" %s", swf_GetString(tag
));
1438 else if(tag
->id
== ST_DEFINEFONTALIGNZONES
) {
1439 handleFontAlign1(tag
);
1441 else if(tag
->id
== ST_CSMTEXTSETTINGS
) {
1442 U16 id
= swf_GetU16(tag
);
1443 U8 flags
= swf_GetU8(tag
);
1446 printf("flashtype,");
1448 switch(((flags
>>3)&7)) {
1449 case 0:printf("no grid,");break;
1450 case 1:printf("pixel grid,");break;
1451 case 2:printf("subpixel grid,");break;
1452 case 3:printf("unknown grid,");break;
1455 printf("unknown[%08x],", flags
);
1456 float thickness
= swf_GetFixed(tag
);
1457 float sharpness
= swf_GetFixed(tag
);
1458 printf("s=%.2f,t=%.2f)", thickness
, sharpness
);
1461 else if(swf_isDefiningTag(tag
)) {
1462 U16 id
= swf_GetDefineID(tag
);
1463 printf(" defines id %04d", id
);
1465 dumperror("Id %04d is defined more than once.", id
);
1468 else if(swf_isPseudoDefiningTag(tag
)) {
1469 U16 id
= swf_GetDefineID(tag
);
1470 printf(" adds information to id %04d", id
);
1472 dumperror("Id %04d is not yet defined.\n", id
);
1475 if(tag
->id
== ST_DEFINEBITSLOSSLESS
||
1476 tag
->id
== ST_DEFINEBITSLOSSLESS2
) {
1477 handleDefineBits(tag
);
1480 else if(tag
->id
== ST_DEFINESOUND
) {
1481 handleDefineSound(tag
);
1484 else if(tag
->id
== ST_VIDEOFRAME
) {
1485 handleVideoFrame(tag
, myprefix
);
1488 else if(tag
->id
== ST_DEFINEVIDEOSTREAM
) {
1489 handleVideoStream(tag
, myprefix
);
1492 else if(tag
->id
== ST_DEFINEEDITTEXT
) {
1493 handleEditText(tag
);
1496 else if(tag
->id
== ST_DEFINEMOVIE
) {
1497 U16 id
= swf_GetU16(tag
);
1498 char*s
= swf_GetString(tag
);
1499 printf(" URL: %s\n", s
);
1501 else if(tag
->id
== ST_DEFINETEXT
|| tag
->id
== ST_DEFINETEXT2
) {
1502 handleText(tag
, myprefix
);
1504 else if(tag
->id
== ST_DEFINESCALINGGRID
) {
1505 U16 id
= swf_GetU16(tag
);
1507 swf_GetRect(tag
, &r
);
1508 printf(" (%.2f,%.2f)-(%.2f,%.2f)\n", r
.xmin
/20.0, r
.ymin
/20.0, r
.xmax
/20.0, r
.ymax
/20.0);
1510 else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
1512 else if(tag
->id
== ST_NAMECHARACTER
|| tag
->id
==ST_DEFINEFONTNAME
) {
1514 printf(" \"%s\"\n", swf_GetString(tag
));
1520 if(bbox
&& swf_isDefiningTag(tag
) && tag
->id
!= ST_DEFINESPRITE
) {
1521 SRECT r
= swf_GetDefineBBox(tag
);
1522 printf(" %s bbox [%.2f, %.2f, %.2f, %.2f]\n", prefix
,
1529 sprintf(myprefix
, " %s", prefix
);
1531 if(tag
->id
== ST_DEFINESPRITE
) {
1532 sprintf(prefix
, " ");
1534 dumperror("Sprite definition inside a sprite definition");
1538 spriteframelabel
= 0;
1540 else if(tag
->id
== ST_END
) {
1543 spriteframelabel
= 0;
1545 dumperror("End Tag not empty");
1547 else if(tag
->id
== ST_IMPORTASSETS
|| tag
->id
== ST_IMPORTASSETS2
) {
1548 handleImportAssets(tag
, myprefix
, tag
->id
==ST_IMPORTASSETS2
?1:0);
1550 else if(tag
->id
== ST_EXPORTASSETS
|| tag
->id
== ST_SYMBOLCLASS
) {
1551 handleExportAssets(tag
, myprefix
);
1553 else if(tag
->id
== ST_DOACTION
&& action
) {
1555 actions
= swf_ActionGet(tag
);
1556 swf_DumpActions(actions
, myprefix
);
1558 else if((tag
->id
== ST_DOABC
|| tag
->id
== ST_RAWABC
) && action
) {
1559 void*abccode
= swf_ReadABC(tag
);
1560 swf_DumpABC(stdout
, abccode
, "");
1561 swf_FreeABC(abccode
);
1563 else if(tag
->id
== ST_DOINITACTION
&& action
) {
1565 swf_GetU16(tag
); // id
1566 actions
= swf_ActionGet(tag
);
1567 swf_DumpActions(actions
, myprefix
);
1569 else if(tag
->id
== ST_DEFINEBUTTON
) {
1571 dumpButton(tag
, myprefix
);
1574 dumpButtonActions(tag
, myprefix
);
1577 else if(swf_isFontTag(tag
) && showfonts
) {
1578 dumpFont(tag
, myprefix
);
1580 else if(tag
->id
== ST_DEFINEBUTTON2
) {
1582 dumpButton2Actions(tag
, myprefix
);
1585 else if(tag
->id
== ST_PLACEOBJECT
) {
1586 handlePlaceObject(tag
, myprefix
);
1588 else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
1589 handlePlaceObject23(tag
, myprefix
);
1591 else if(tag
->id
== ST_DEFINEFONTALIGNZONES
) {
1592 handleFontAlign2(tag
, myprefix
);
1594 else if(tag
->id
== ST_DEFINEFONTNAME
) {
1595 swf_SetTagPos(tag
, 0);
1596 swf_GetU16(tag
); //id
1597 swf_GetString(tag
); //name
1598 char* copyright
= swf_GetString(tag
);
1599 printf("%s%s\n", myprefix
, copyright
);
1601 else if(tag
->id
== ST_DEFINESHAPE
||
1602 tag
->id
== ST_DEFINESHAPE2
||
1603 tag
->id
== ST_DEFINESHAPE3
||
1604 tag
->id
== ST_DEFINESHAPE4
) {
1606 handleShape(tag
, myprefix
);
1609 if(tag
->len
&& used
) {
1610 int num
= swf_GetNumUsedIDs(tag
);
1614 used
= (int*)malloc(sizeof(int)*num
);
1615 swf_GetUsedIDs(tag
, used
);
1616 printf("%s%suses IDs: ", indent
, prefix
);
1617 for(t
=0;t
<num
;t
++) {
1619 swf_SetTagPos(tag
, used
[t
]);
1620 id
= swf_GetU16(tag
);
1621 printf("%d%s", id
, t
<num
-1?", ":"");
1623 dumperror("Id %04d is not yet defined.\n", id
);
1630 if(tag
->id
== ST_FREECHARACTER
) {
1632 swf_SetTagPos(tag
, 0);
1633 id
= swf_GetU16(tag
);
1637 if(tag
->len
&& hex
) {
1638 hexdumpTag(tag
, prefix
);