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"
42 #include "../lib/utf8.h"
44 static char * filename
= 0;
46 /* idtab stores the ids which are defined in the file. This allows us
47 to detect errors in the file. (i.e. ids which are defined more than
49 static char idtab
[65536];
50 static char * indent
= " ";
52 static int placements
= 0;
53 static int action
= 0;
57 static int showtext
= 0;
58 static int showshapes
= 0;
62 static int cumulative
= 0;
63 static int showfonts
= 0;
64 static int showbuttons
= 0;
66 static struct options_t options
[] = {
88 int args_callback_option(char*name
,char*val
)
90 if(!strcmp(name
, "V")) {
91 printf("swfdump - part of %s %s\n", PACKAGE
, VERSION
);
94 else if(name
[0]=='a') {
98 else if(name
[0]=='p') {
102 else if(name
[0]=='t') {
106 else if(name
[0]=='s') {
110 else if(name
[0]=='e') {
114 else if(name
[0]=='c') {
118 else if(name
[0]=='E') {
123 else if(name
[0]=='X') {
127 else if(name
[0]=='Y') {
131 else if(name
[0]=='r') {
135 else if(name
[0]=='f') {
139 else if(name
[0]=='F') {
143 else if(name
[0]=='d') {
147 else if(name
[0]=='u') {
151 else if(name
[0]=='b') {
155 else if(name
[0]=='B') {
159 else if(name
[0]=='D') {
160 showbuttons
= action
= placements
= showtext
= showshapes
= 1;
164 printf("Unknown option: -%s\n", name
);
170 int args_callback_longoption(char*name
,char*val
)
172 return args_long2shortoption(options
, name
, val
);
174 void args_callback_usage(char *name
)
177 printf("Usage: %s [-atpdu] file.swf\n", name
);
179 printf("-h , --help Print short help message and exit\n");
180 printf("-D , --full Show everything. Same as -atp\n");
181 printf("-V , --version Print version info and exit\n");
182 printf("-e , --html Print out html code for embedding the file\n");
183 printf("-E , --xhtml Print out xhtml code for embedding the file\n");
184 printf("-a , --action Disassemble action tags\n");
185 printf("-t , --text Show text fields (like swfstrings).\n");
186 printf("-s , --shapes Show shape coordinates/styles\n");
187 printf("-F , --fonts Show font information\n");
188 printf("-p , --placements Show placement information\n");
189 printf("-B , --buttons Show button information\n");
190 printf("-b , --bbox Print tag's bounding boxes\n");
191 printf("-X , --width Prints out a string of the form \"-X width\".\n");
192 printf("-Y , --height Prints out a string of the form \"-Y height\".\n");
193 printf("-r , --rate Prints out a string of the form \"-r rate\".\n");
194 printf("-f , --frames Prints out a string of the form \"-f framenum\".\n");
195 printf("-d , --hex Print hex output of tag data, too.\n");
196 printf("-u , --used Show referred IDs for each Tag.\n");
199 int args_callback_command(char*name
,char*val
)
202 fprintf(stderr
, "Only one file allowed. You supplied at least two. (%s and %s)\n",
210 char* testfunc(char*str
)
212 printf("%s: %s\n", what
, str
);
216 void dumpButton2Actions(TAG
*tag
, char*prefix
)
222 oldTagPos
= swf_GetTagPos(tag
);
224 // scan DefineButton2 Record
226 swf_GetU16(tag
); // Character ID
227 swf_GetU8(tag
); // Flags;
229 offsetpos
= swf_GetTagPos(tag
); // first offset
232 while (swf_GetU8(tag
)) // state -> parse ButtonRecord
233 { swf_GetU16(tag
); // id
234 swf_GetU16(tag
); // layer
235 swf_GetMatrix(tag
,NULL
); // matrix
236 swf_GetCXForm(tag
,NULL
,1); // cxform
243 if(tag
->pos
>= tag
->len
)
246 offsetpos
= swf_GetU16(tag
);
247 condition
= swf_GetU16(tag
); // condition
249 actions
= swf_ActionGet(tag
);
250 printf("%s condition %04x\n", prefix
, condition
);
251 swf_DumpActions(actions
, prefix
);
254 swf_SetTagPos(tag
,oldTagPos
);
258 void dumpButtonActions(TAG
*tag
, char*prefix
)
261 swf_SetTagPos(tag
, 0);
262 swf_GetU16(tag
); // id
263 while (swf_GetU8(tag
)) // state -> parse ButtonRecord
264 { swf_GetU16(tag
); // id
265 swf_GetU16(tag
); // layer
266 swf_GetMatrix(tag
,NULL
); // matrix
268 actions
= swf_ActionGet(tag
);
269 swf_DumpActions(actions
, prefix
);
270 swf_ActionFree(actions
);
273 void dumpButton(TAG
*tag
, char*prefix
)
275 swf_SetTagPos(tag
, 0);
276 swf_GetU16(tag
); // id
278 U8 flags
= swf_GetU8(tag
);
281 U16 id
= swf_GetU16(tag
);
282 U16 depth
= swf_GetU16(tag
);
284 sprintf(event
, "%s%s%s%s",
285 (flags
&BS_HIT
)?"[hit]":"",
286 (flags
&BS_DOWN
)?"[down]":"",
287 (flags
&BS_OVER
)?"[over]":"",
288 (flags
&BS_UP
)?"[up]":"");
290 printf("%s | Show %d at depth %d for %s flags=%02x\n", prefix
, id
, depth
, event
, flags
);
292 printf("%s | Show %d at depth %d for %s\n", prefix
, id
, depth
, event
);
294 swf_GetMatrix(tag
,NULL
); // matrix
298 void dumpFont(TAG
*tag
, char*prefix
)
300 SWFFONT
* font
= malloc(sizeof(SWFFONT
));
301 memset(font
, 0, sizeof(SWFFONT
));
302 if(tag
->id
== ST_DEFINEFONT2
|| tag
->id
== ST_DEFINEFONT3
) {
303 swf_FontExtract_DefineFont2(0, font
, tag
);
304 } else if(tag
->id
== ST_DEFINEFONT
) {
305 swf_FontExtract_DefineFont(0, font
, tag
);
307 printf("%sCan't parse %s yet\n", prefix
,swf_TagGetName(tag
));
309 printf("%sID: %d\n", prefix
,font
->id
);
310 printf("%sVersion: %d\n", prefix
,font
->version
);
311 printf("%sname: %s\n", prefix
,font
->name
);
312 printf("%scharacters: %d\n", prefix
,font
->numchars
);
313 printf("%shightest mapped unicode value: %d\n", prefix
,font
->maxascii
);
316 printf("%sascent:%.2f\n", prefix
,font
->layout
->ascent
/ 20.0);
317 printf("%sdescent:%.2f\n", prefix
,font
->layout
->descent
/ 20.0);
318 printf("%sleading:%.2f\n", prefix
,font
->layout
->leading
/ 20.0);
319 printf("%skerning records:%d\n", prefix
,font
->layout
->kerningcount
);
321 printf("%sstyle: %d\n", prefix
,font
->style
);
322 printf("%sencoding: %02x\n", prefix
,font
->encoding
);
323 printf("%slanguage: %02x\n", prefix
,font
->language
);
325 for(t
=0;t
<font
->numchars
;t
++) {
326 int u
= font
->glyph2ascii
?font
->glyph2ascii
[t
]:-1;
328 if(u
>=32) sprintf(ustr
, " '%c'", u
);
329 else sprintf(ustr
, " 0x%02x", u
);
330 printf("%s== Glyph %d: advance=%d encoding=%d%s ==\n", prefix
, t
, font
->glyph
[t
].advance
, u
, ustr
);
331 SHAPE2
* shape
= swf_ShapeToShape2(font
->glyph
[t
].shape
);
332 SHAPELINE
*line
= shape
->lines
;
335 if(line
->type
== moveTo
) {
336 printf("%smoveTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
337 } else if(line
->type
== lineTo
) {
338 printf("%slineTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
339 } else if(line
->type
== splineTo
) {
340 printf("%ssplineTo (%.2f %.2f) %.2f %.2f\n", prefix
,
341 line
->sx
/20.0, line
->sy
/20.0,
342 line
->x
/20.0, line
->y
/20.0
347 swf_Shape2Free(shape
);
354 printf("%sencoding table:", prefix, prefix);
355 char filled0=0, lastfilled=0;
356 for(t=0;t<font->maxascii;t++) {
358 printf("\n%s%08x ", prefix, t);
361 for(s=t;s<font->maxascii;s++) {
362 if(font->ascii2glyph[s]>=0) break;
371 for(s=t;s<t+16 && s<font->maxascii;s++) {
372 if(font->ascii2glyph[s]>=0) filled0=1;
375 printf("%4d ", font->ascii2glyph[t]);
383 static int fontnum
= 0;
384 static SWFFONT
**fonts
;
386 void textcallback(void*self
, int*glyphs
, int*xpos
, int nr
, int fontid
, int fontsize
, int startx
, int starty
, RGBA
*color
)
391 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);
392 for(t
=0;t
<fontnum
;t
++)
394 if(fonts
[t
]->id
== fontid
) {
404 if(glyphs
[t
] >= fonts
[font
]->numchars
/*glyph is in range*/
405 || !fonts
[font
]->glyph2ascii
/* font has ascii<->glyph mapping */
408 if(fonts
[font
]->glyph2ascii
[glyphs
[t
]])
409 a
= fonts
[font
]->glyph2ascii
[glyphs
[t
]];
417 char* utf8
= getUTF8(a
);
420 printf("\\x%x", (int)a
);
426 void handleText(TAG
*tag
, char*prefix
)
430 swf_SetTagPos(tag
, 0);
433 swf_ResetReadBits(tag
);
435 swf_GetMatrix(tag
, &m
);
436 printf("%s| Matrix\n",prefix
);
437 printf("%s| %5.3f %5.3f %6.2f\n", prefix
, m
.sx
/65536.0, m
.r1
/65536.0, m
.tx
/20.0);
438 printf("%s| %5.3f %5.3f %6.2f\n", prefix
, m
.r0
/65536.0, m
.sy
/65536.0, m
.ty
/20.0);
439 swf_SetTagPos(tag
, 0);
442 swf_ParseDefineText(tag
,textcallback
, 0);
446 void handleDefineSound(TAG
*tag
)
448 U16 id
= swf_GetU16(tag
);
449 U8 flags
= swf_GetU8(tag
);
450 int compression
= (flags
>>4)&7;
451 int rate
= (flags
>>2)&3;
452 int bits
= flags
&2?16:8;
453 int stereo
= flags
&1;
455 if(compression
== 0) printf("Raw ");
456 else if(compression
== 1) printf("ADPCM ");
457 else if(compression
== 2) printf("MP3 ");
458 else if(compression
== 3) printf("Raw little-endian ");
459 else if(compression
== 6) printf("ASAO ");
461 if(rate
== 0) printf("5.5Khz ");
462 if(rate
== 1) printf("11Khz ");
463 if(rate
== 2) printf("22Khz ");
464 if(rate
== 3) printf("44Khz ");
465 printf("%dBit ", bits
);
466 if(stereo
) printf("stereo");
471 void handleDefineBits(TAG
*tag
)
477 id
= swf_GetU16(tag
);
478 mode
= swf_GetU8(tag
);
479 width
= swf_GetU16(tag
);
480 height
= swf_GetU16(tag
);
481 printf(" image %dx%d",width
,height
);
482 if(mode
== 3) printf(" (8 bpp)");
483 else if(mode
== 4) printf(" (16 bpp)");
484 else if(mode
== 5) printf(" (32 bpp)");
485 else printf(" (? bpp)");
488 void handleEditText(TAG
*tag
)
493 id
= swf_GetU16(tag
);
496 //swf_ResetReadBits(tag);
502 flags
= swf_GetBits(tag
,16);
503 if(flags
& ET_HASFONT
) {
504 swf_GetU16(tag
); //font
505 swf_GetU16(tag
); //fontheight
507 if(flags
& ET_HASTEXTCOLOR
) {
508 swf_GetU8(tag
); //rgba
513 if(flags
& ET_HASMAXLENGTH
) {
514 swf_GetU16(tag
); //maxlength
516 if(flags
& ET_HASLAYOUT
) {
517 swf_GetU8(tag
); //align
518 swf_GetU16(tag
); //left margin
519 swf_GetU16(tag
); //right margin
520 swf_GetU16(tag
); //indent
521 swf_GetU16(tag
); //leading
523 printf(" variable \"%s\" ", &tag
->data
[tag
->pos
]);
524 if(flags
& ET_HTML
) printf("(html)");
525 if(flags
& ET_NOSELECT
) printf("(noselect)");
526 if(flags
& ET_PASSWORD
) printf("(password)");
527 if(flags
& ET_READONLY
) printf("(readonly)");
529 if(flags
& (ET_X1
| ET_X3
))
531 printf(" undefined flags: %08x (%08x)", (flags
&(ET_X1
|ET_X3
)), flags
);
534 while(tag
->data
[tag
->pos
++]);
535 if(flags
& ET_HASTEXT
)
536 // printf(" text \"%s\"\n", &tag->data[tag->pos]) //TODO
539 void printhandlerflags(U32 handlerflags
)
541 if(handlerflags
&1) printf("[on load]");
542 if(handlerflags
&2) printf("[enter frame]");
543 if(handlerflags
&4) printf("[unload]");
544 if(handlerflags
&8) printf("[mouse move]");
545 if(handlerflags
&16) printf("[mouse down]");
546 if(handlerflags
&32) printf("[mouse up]");
547 if(handlerflags
&64) printf("[key down]");
548 if(handlerflags
&128) printf("[key up]");
550 if(handlerflags
&256) printf("[data]");
551 if(handlerflags
&512) printf("[initialize]");
552 if(handlerflags
&1024) printf("[mouse press]");
553 if(handlerflags
&2048) printf("[mouse release]");
554 if(handlerflags
&4096) printf("[mouse release outside]");
555 if(handlerflags
&8192) printf("[mouse rollover]");
556 if(handlerflags
&16384) printf("[mouse rollout]");
557 if(handlerflags
&32768) printf("[mouse drag over]");
559 if(handlerflags
&0x10000) printf("[mouse drag out]");
560 if(handlerflags
&0x20000) printf("[key press]");
561 if(handlerflags
&0x40000) printf("[construct even]");
562 if(handlerflags
&0xfff80000) printf("[???]");
564 void handleVideoStream(TAG
*tag
, char*prefix
)
566 U16 id
= swf_GetU16(tag
);
567 U16 frames
= swf_GetU16(tag
);
568 U16 width
= swf_GetU16(tag
);
569 U16 height
= swf_GetU16(tag
);
570 U8 flags
= swf_GetU8(tag
); //5-2(videopacket 01=off 10=on)-1(smoothing 1=on)
571 U8 codec
= swf_GetU8(tag
);
572 printf(" (%d frames, %dx%d", frames
, width
, height
);
576 printf(" sorenson h.263)");
578 printf(" codec 0x%02x)", codec
);
580 void handleVideoFrame(TAG
*tag
, char*prefix
)
582 U32 code
, version
, reference
, sizeflags
;
583 U32 width
=0, height
=0;
585 U16 id
= swf_GetU16(tag
);
586 U16 frame
= swf_GetU16(tag
);
587 U8 deblock
,flags
, tmp
, bit
;
589 char*types
[] = {"I-frame", "P-frame", "disposable P-frame", "<reserved>"};
590 printf(" (frame %d) ", frame
);
592 /* video packet follows */
593 code
= swf_GetBits(tag
, 17);
594 version
= swf_GetBits(tag
, 5);
595 reference
= swf_GetBits(tag
, 8);
597 sizeflags
= swf_GetBits(tag
, 3);
600 case 0: width
= swf_GetBits(tag
, 8); height
= swf_GetBits(tag
, 8); break;
601 case 1: width
= swf_GetBits(tag
, 16); height
= swf_GetBits(tag
, 16); break;
602 case 2: width
= 352; height
= 288; break;
603 case 3: width
= 176; height
= 144; break;
604 case 4: width
= 128; height
= 96; break;
605 case 5: width
= 320; height
= 240; break;
606 case 6: width
= 160; height
= 120; break;
607 case 7: width
= -1; height
= -1;/*reserved*/ break;
609 printf("%dx%d ", width
, height
);
610 type
= swf_GetBits(tag
, 2);
611 printf("%s", types
[type
]);
613 deblock
= swf_GetBits(tag
, 1);
615 printf(" deblock %d ", deblock
);
616 quantizer
= swf_GetBits(tag
, 5);
617 printf(" quant: %d ", quantizer
);
620 void dumpFilter(FILTER
*filter
)
622 if(filter
->type
== FILTERTYPE_BLUR
) {
623 FILTER_BLUR
*f
= (FILTER_BLUR
*)filter
;
624 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
625 printf("passes: %d\n", f
->passes
);
626 } if(filter
->type
== FILTERTYPE_GLOW
) {
627 FILTER_GLOW
*f
= (FILTER_GLOW
*)filter
;
628 printf("color %02x%02x%02x%02x\n", f
->rgba
.r
,f
->rgba
.g
,f
->rgba
.b
,f
->rgba
.a
);
629 printf("blurx: %f blury: %f strength: %f\n", f
->blurx
, f
->blury
, f
->strength
);
630 printf("passes: %d\n", f
->passes
);
631 printf("flags: %s%s%s\n",
632 f
->knockout
?"knockout ":"",
633 f
->composite
?"composite ":"",
634 f
->innerglow
?"innerglow":"");
635 } if(filter
->type
== FILTERTYPE_DROPSHADOW
) {
636 FILTER_DROPSHADOW
*f
= (FILTER_DROPSHADOW
*)filter
;
637 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
638 printf("passes: %d\n", f
->passes
);
639 printf("angle: %f distance: %f\n", f
->angle
, f
->distance
);
640 printf("strength: %f passes: %d\n", f
->strength
, f
->passes
);
641 printf("flags: %s%s%s\n",
642 f
->knockout
?"knockout ":"",
643 f
->composite
?"composite ":"",
644 f
->innershadow
?"innershadow ":"");
645 } if(filter
->type
== FILTERTYPE_BEVEL
) {
646 FILTER_BEVEL
*f
= (FILTER_BEVEL
*)filter
;
647 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
648 printf("passes: %d\n", f
->passes
);
649 printf("angle: %f distance: %f\n", f
->angle
, f
->distance
);
650 printf("strength: %f passes: %d\n", f
->strength
, f
->passes
);
651 printf("flags: %s%s%s%s\n",
653 f
->knockout
?"knockout ":"",
654 f
->composite
?"composite ":"",
655 f
->innershadow
?"innershadow ":"");
656 } if(filter
->type
== FILTERTYPE_GRADIENTGLOW
) {
657 FILTER_GRADIENTGLOW
*f
= (FILTER_GRADIENTGLOW
*)filter
;
658 swf_DumpGradient(stdout
, f
->gradient
);
659 printf("blurx: %f blury: %f\n", f
->blurx
, f
->blury
);
660 printf("angle: %f distance: %f\n", f
->angle
, f
->distance
);
661 printf("strength: %f passes: %d\n", f
->strength
, f
->passes
);
662 printf("flags: %s%s%s%s\n",
663 f
->knockout
?"knockout ":"",
664 f
->ontop
?"ontop ":"",
665 f
->composite
?"composite ":"",
666 f
->innershadow
?"innershadow ":"");
671 void handlePlaceObject23(TAG
*tag
, char*prefix
)
677 int ppos
[3] = {0,0,0};
678 swf_SetTagPos(tag
, 0);
679 flags
= swf_GetU8(tag
);
680 if(tag
->id
== ST_PLACEOBJECT3
)
681 flags2
= swf_GetU8(tag
);
682 swf_GetU16(tag
); //depth
685 if(flags
&2) swf_GetU16(tag
); //id
687 swf_GetMatrix(tag
,&m
);
689 ppos
[0] += sprintf(pstr
[0], "| Matrix ");
690 ppos
[1] += sprintf(pstr
[1], "| %5.3f %5.3f %6.2f ", m
.sx
/65536.0, m
.r1
/65536.0, m
.tx
/20.0);
691 ppos
[2] += sprintf(pstr
[2], "| %5.3f %5.3f %6.2f ", m
.r0
/65536.0, m
.sy
/65536.0, m
.ty
/20.0);
695 swf_GetCXForm(tag
, &cx
, 1);
697 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| CXForm r g b a ");
698 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);
699 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| add %4d %4d %4d %4d ", cx
.r1
, cx
.g1
, cx
.b1
, cx
.a1
);
703 U16 ratio
= swf_GetU16(tag
); //ratio
705 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| Ratio ");
706 ppos
[1] += sprintf(pstr
[1]+ppos
[1], "| %-5d ", ratio
);
707 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| ");
711 U16 clip
= swf_GetU16(tag
); //clip
713 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| Clip ");
714 ppos
[1] += sprintf(pstr
[1]+ppos
[1], "| %-4d ", clip
);
715 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| ");
718 if(flags
&32) { while(swf_GetU8(tag
)); }
720 if(flags2
&1) { // filter list
721 U8 num
= swf_GetU8(tag
);
723 printf("\n%d filters\n", num
);
724 char*filtername
[] = {"dropshadow","blur","glow","bevel","gradientglow","convolution","colormatrix","gradientbevel"};
727 FILTER
*filter
= swf_GetFilter(tag
);
733 printf("filter %d: %02x (%s)\n", t
, filter
->type
, (filter
->type
<sizeof(filtername
)/sizeof(filtername
[0]))?filtername
[filter
->type
]:"?");
738 if(flags2
&2) { // blend mode
739 U8 blendmode
= swf_GetU8(tag
);
743 sprintf(name
, "%-5d", blendmode
);
744 for(t
=0;blendModeNames
[t
];t
++) {
746 sprintf(name
, "%-5s", blendModeNames
[t
]);
750 ppos
[0] += sprintf(pstr
[0]+ppos
[0], "| Blend ");
751 ppos
[1] += sprintf(pstr
[1]+ppos
[1], "| %s ", name
);
752 ppos
[2] += sprintf(pstr
[2]+ppos
[2], "| ");
756 if(placements
&& ppos
[0]) {
758 printf("%s %s\n", prefix
, pstr
[0]);
759 printf("%s %s\n", prefix
, pstr
[1]);
760 printf("%s %s", prefix
, pstr
[2]);
769 reserved
= swf_GetU16(tag
); // must be 0
770 globalflags
= swf_GetU16(tag
); //TODO: 32 if version>=6
772 printf("Unknown parameter field not zero: %04x\n", reserved
);
775 printf("global flags: %04x\n", globalflags
);
777 handlerflags
= swf_GetU16(tag
); //TODO: 32 if version>=6
779 handlerflags
= swf_GetU32(tag
);
782 while(handlerflags
) {
787 globalflags
&= ~handlerflags
;
788 printf("%s flags %08x ",prefix
, handlerflags
);
789 printhandlerflags(handlerflags
);
790 length
= swf_GetU32(tag
);
791 printf(", %d bytes actioncode\n",length
);
792 a
= swf_ActionGet(tag
);
793 swf_DumpActions(a
,prefix
);
796 handlerflags
= is32
?swf_GetU32(tag
):swf_GetU16(tag
); //TODO: 32 if version>=6
798 if(globalflags
) // should go to sterr.
799 printf("ERROR: unsatisfied handlerflags: %02x\n", globalflags
);
801 printf(" has action code\n");
806 void handlePlaceObject(TAG
*tag
, char*prefix
)
808 TAG
*tag2
= swf_InsertTag(0, ST_PLACEOBJECT2
);
813 swf_SetTagPos(tag
, 0);
814 id
= swf_GetU16(tag
);
815 depth
= swf_GetU16(tag
);
816 swf_GetMatrix(tag
, &matrix
);
817 swf_GetCXForm(tag
, &cxform
, 0);
819 swf_SetU8(tag2
, 14 /* char, matrix, cxform */);
820 swf_SetU16(tag2
, depth
);
821 swf_SetU16(tag2
, id
);
822 swf_SetMatrix(tag2
, &matrix
);
823 swf_SetCXForm(tag2
, &cxform
, 1);
825 handlePlaceObject23(tag2
, prefix
);
828 char* fillstyle2str(FILLSTYLE
*style
)
830 switch(style
->type
) {
832 sprintf(stylebuf
, "SOLID %02x%02x%02x%02x", style
->color
.r
, style
->color
.g
, style
->color
.b
, style
->color
.a
);
834 case 0x10: case 0x11: case 0x12: case 0x13:
835 sprintf(stylebuf
, "GRADIENT (%d steps)", style
->gradient
.num
);
837 case 0x40: case 0x42:
838 /* TODO: display information about that bitmap */
839 sprintf(stylebuf
, "BITMAPt%s %d", (style
->type
&2)?"n":"", style
->id_bitmap
);
840 /* TODO: show matrix */
841 //swf_DumpMatrix(stdout, &style->m);
843 case 0x41: case 0x43:
844 /* TODO: display information about that bitmap */
845 sprintf(stylebuf
, "BITMAPc%s %d", (style
->type
&2)?"n":"", style
->id_bitmap
);
846 /* TODO: show matrix */
847 //swf_DumpMatrix(stdout, &style->m);
850 sprintf(stylebuf
, "UNKNOWN[%02x]",style
->type
);
854 char* linestyle2str(LINESTYLE
*style
)
856 sprintf(stylebuf
, "%.2f %02x%02x%02x%02x", style
->width
/20.0, style
->color
.r
, style
->color
.g
, style
->color
.b
, style
->color
.a
);
860 void handleShape(TAG
*tag
, char*prefix
)
868 swf_ParseDefineShape(tag
, &shape
);
870 max
= shape
.numlinestyles
> shape
.numfillstyles
?shape
.numlinestyles
:shape
.numfillstyles
;
872 if(max
) printf("%s | fillstyles(%02d) linestyles(%02d)\n",
877 else printf("%s | (Neither line nor fill styles)\n", prefix
);
880 printf("%s", prefix
);
881 if(t
< shape
.numfillstyles
) {
882 printf(" | %-2d) %-18.18s", t
+1, fillstyle2str(&shape
.fillstyles
[t
]));
886 if(t
< shape
.numlinestyles
) {
887 printf("%-2d) %s", t
+1, linestyle2str(&shape
.linestyles
[t
]));
890 //if(shape.fillstyles[t].type&0x40) {
891 // MATRIX m = shape.fillstyles[t].m;
892 // swf_DumpMatrix(stdout, &m);
896 printf("%s |\n", prefix
);
900 printf("%s | fill: %02d/%02d line:%02d - ",
905 if(line
->type
== moveTo
) {
906 printf("moveTo %.2f %.2f\n", line
->x
/20.0, line
->y
/20.0);
907 } else if(line
->type
== lineTo
) {
908 printf("lineTo %.2f %.2f\n", line
->x
/20.0, line
->y
/20.0);
909 } else if(line
->type
== splineTo
) {
910 printf("splineTo (%.2f %.2f) %.2f %.2f\n",
911 line
->sx
/20.0, line
->sy
/20.0,
912 line
->x
/20.0, line
->y
/20.0
917 printf("%s |\n", prefix
);
920 void fontcallback1(void*self
, U16 id
,U8
* name
)
924 void fontcallback2(void*self
, U16 id
,U8
* name
)
926 swf_FontExtract(&swf
,id
,&fonts
[fontnum
]);
930 static U8
printable(U8 a
)
932 if(a
<32 || a
==127) return '.';
935 void hexdumpTag(TAG
*tag
, char* prefix
)
939 printf(" %s-=> ",prefix
);
940 for(t
=0;t
<tag
->len
;t
++) {
941 printf("%02x ", tag
->data
[t
]);
942 ascii
[t
&15] = printable(tag
->data
[t
]);
943 if((t
&& ((t
&15)==15)) || (t
==tag
->len
-1))
947 for(s
=p
-1;s
<16;s
++) {
951 printf(" %s\n", ascii
);
953 printf(" %s\n %s-=> ",ascii
,prefix
);
958 void handleImportAssets(TAG
*tag
, char* prefix
, int assets2
)
964 url
= swf_GetString(tag
);
965 printf("%sfrom %s\n", prefix
, url
);
968 swf_GetU8(tag
); // Reserved: Must be 1
969 swf_GetU8(tag
); // Reserved: Must be 0
971 num
= swf_GetU16(tag
);
974 id
= swf_GetU16(tag
);
975 name
= swf_GetString(tag
);
976 printf("%s import %04d named \"%s\"\n", prefix
, id
, name
);
980 void handleExportAssets(TAG
*tag
, char* prefix
)
986 num
= swf_GetU16(tag
);
989 id
= swf_GetU16(tag
);
990 name
= swf_GetString(tag
);
991 printf("%sexports %04d as \"%s\"\n", prefix
, id
, name
);
995 static void handleFontAlign1(TAG
*tag
)
997 swf_SetTagPos(tag
, 0);
998 U16 id
= swf_GetU16(tag
);
999 U8 flags
= swf_GetU8(tag
);
1000 printf(" for font %04d, ", id
);
1001 if((flags
&3)==0) printf("thin, ");
1002 else if((flags
&3)==1) printf("medium, ");
1003 else if((flags
&3)==2) printf("thick, ");
1006 while(tag
->pos
< tag
->len
) {
1007 int nr
= swf_GetU8(tag
); // should be 2
1010 printf("*** unsupported multiboxes ***, ");
1014 float v1
= swf_GetF16(tag
);
1015 float v2
= swf_GetF16(tag
);
1017 U8 xyflags
= swf_GetU8(tag
);
1020 printf(" %d glyphs", num
);
1023 #define ALIGN_WITH_GLYPHS
1024 static void handleFontAlign2(TAG
*tag
, char*prefix
)
1028 swf_SetTagPos(tag
, 0);
1029 U16 id
= swf_GetU16(tag
);
1032 #ifdef ALIGN_WITH_GLYPHS
1035 while(swf
.firstTag
->prev
) swf
.firstTag
= swf
.firstTag
->prev
;
1037 swf_FontExtract(&swf
, id
, &font
);
1039 swf_SetTagPos(tag
, 3);
1040 while(tag
->pos
< tag
->len
) {
1041 printf("%sglyph %d) ", prefix
, num
);
1042 int nr
= swf_GetU8(tag
); // should be 2
1046 float v
= swf_GetF16(tag
);
1047 printf("%f ", v
*1024.0);
1050 for(s
=0;s
<nr
-1;s
++) {
1053 float v
= swf_GetF16(tag
);
1054 printf("+%f ", v
*1024.0);
1057 U8 xyflags
= swf_GetU8(tag
);
1058 printf("xy:%02x\n", xyflags
);
1060 #ifdef ALIGN_WITH_GLYPHS
1061 if(font
&& num
<font
->numchars
) {
1062 SHAPE2
* shape
= swf_ShapeToShape2(font
->glyph
[num
].shape
);
1063 SHAPELINE
*line
= shape
->lines
;
1065 if(line
->type
== moveTo
) {
1066 printf("%smoveTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
1067 } else if(line
->type
== lineTo
) {
1068 printf("%slineTo %.2f %.2f\n", prefix
, line
->x
/20.0, line
->y
/20.0);
1069 } else if(line
->type
== splineTo
) {
1070 printf("%ssplineTo (%.2f %.2f) %.2f %.2f\n", prefix
,
1071 line
->sx
/20.0, line
->sy
/20.0,
1072 line
->x
/20.0, line
->y
/20.0
1077 swf_Shape2Free(shape
);
1080 if(num
==font
->numchars
-1) break;
1087 void dumperror(const char* format
, ...)
1092 va_start(arglist
, format
);
1093 vsnprintf(buf
, sizeof(buf
)-1, format
, arglist
);
1097 printf("==== Error: %s ====\n", buf
);
1100 static char strbuf
[800];
1101 static int bufpos
=0;
1103 char* timestring(double f
)
1105 int hours
= (int)(f
/3600);
1106 int minutes
= (int)((f
-hours
*3600)/60);
1107 int seconds
= (int)((f
-hours
*3600-minutes
*60));
1108 int useconds
= (int)((f
-(int)f
)*1000+0.5);
1111 sprintf(&strbuf
[bufpos
], "%02d:%02d:%02d,%03d",hours
,minutes
,seconds
,useconds
);
1112 return &strbuf
[bufpos
];
1115 int main (int argc
,char ** argv
)
1119 struct stat statbuf
;
1123 char issprite
= 0; // are we inside a sprite definition?
1124 int spriteframe
= 0;
1126 char* spriteframelabel
= 0;
1127 char* framelabel
= 0;
1132 memset(idtab
,0,65536);
1134 processargs(argc
, argv
);
1138 fprintf(stderr
, "You must supply a filename.\n");
1142 f
= open(filename
,O_RDONLY
|O_BINARY
);
1146 sprintf(buffer
, "Couldn't open %.200s", filename
);
1152 char compressed
= (header
[0]=='C');
1153 char isflash
= (header
[0]=='F' && header
[1] == 'W' && header
[2] == 'S') ||
1154 (header
[0]=='C' && header
[1] == 'W' && header
[2] == 'S');
1157 int fl
=strlen(filename
);
1158 if(!isflash
&& fl
>3 && !strcmp(&filename
[fl
-4], ".abc")) {
1159 swf_ReadABCfile(filename
, &swf
);
1161 f
= open(filename
,O_RDONLY
|O_BINARY
);
1162 if FAILED(swf_ReadSWF(f
,&swf
))
1164 fprintf(stderr
, "%s is not a valid SWF file or contains errors.\n",filename
);
1171 if(statbuf
.st_size
!= swf
.fileSize
&& !compressed
)
1172 dumperror("Real Filesize (%d) doesn't match header Filesize (%d)",
1173 statbuf
.st_size
, swf
.fileSize
);
1174 filesize
= statbuf
.st_size
;
1179 //if(action && swf.fileVersion>=9) {
1180 // fprintf(stderr, "Actionscript parsing (-a) not yet supported for SWF versions>=9\n");
1184 xsize
= (swf
.movieSize
.xmax
-swf
.movieSize
.xmin
)/20;
1185 ysize
= (swf
.movieSize
.ymax
-swf
.movieSize
.ymin
)/20;
1189 printf("-X %d", xsize
);
1191 if((xy
&1) && (xy
&6))
1195 printf("-Y %d", ysize
);
1197 if((xy
&3) && (xy
&4))
1201 printf("-r %.2f", swf
.frameRate
/256.0);
1203 if((xy
&7) && (xy
&8))
1207 printf("-f %d", swf
.frameCount
);
1214 char*fileversions
[] = {"","1,0,0,0", "2,0,0,0","3,0,0,0","4,0,0,0",
1215 "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"};
1216 if(swf
.fileVersion
>10) {
1217 fprintf(stderr
, "Fileversion>10\n");
1222 printf("<object type=\"application/x-shockwave-flash\" data=\"%s\" width=\"%d\" height=\"%d\">\n"
1223 "<param name=\"movie\" value=\"%s\"/>\n"
1224 "<param name=\"play\" value=\"true\"/>\n"
1225 "<param name=\"loop\" value=\"false\"/>\n"
1226 "<param name=\"quality\" value=\"high\"/>\n"
1227 "<param name=\"loop\" value=\"false\"/>\n"
1228 "</object>\n\n", filename
, xsize
, ysize
, filename
);
1230 printf("<OBJECT CLASSID=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n"
1232 //" BGCOLOR=#ffffffff\n"?
1234 //http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,23,0?
1235 " CODEBASE=\"http://active.macromedia.com/flash5/cabs/swflash.cab#version=%s\">\n"
1236 " <PARAM NAME=\"MOVIE\" VALUE=\"%s\">\n"
1237 " <PARAM NAME=\"PLAY\" VALUE=\"true\">\n"
1238 " <PARAM NAME=\"LOOP\" VALUE=\"true\">\n"
1239 " <PARAM NAME=\"QUALITY\" VALUE=\"high\">\n"
1240 " <PARAM NAME=\"ALLOWSCRIPTACCESS\" VALUE=\"always\">\n"
1241 " <EMBED SRC=\"%s\" WIDTH=\"%d\" HEIGHT=\"%d\"\n" //bgcolor=#ffffff?
1242 " PLAY=\"true\" ALIGN=\"\" LOOP=\"true\" QUALITY=\"high\"\n"
1243 " TYPE=\"application/x-shockwave-flash\"\n"
1244 " ALLOWSCRIPTACCESS=\"always\"\n"
1245 " PLUGINSPAGE=\"http://get.adobe.com/flashplayer/\">\n"
1247 "</OBJECT>\n", xsize
, ysize
, fileversions
[swf
.fileVersion
],
1248 filename
, filename
, xsize
, ysize
);
1252 printf("[HEADER] File version: %d\n", swf
.fileVersion
);
1254 printf("[HEADER] File is zlib compressed.");
1255 if(filesize
&& swf
.fileSize
)
1256 printf(" Ratio: %02d%%\n", filesize
*100/(swf
.fileSize
));
1260 printf("[HEADER] File size: %d%s\n", swf
.fileSize
, swf
.compressed
?" (Depacked)":"");
1261 printf("[HEADER] Frame rate: %f\n",swf
.frameRate
/256.0);
1262 printf("[HEADER] Frame count: %d\n",swf
.frameCount
);
1263 printf("[HEADER] Movie width: %.2f",(swf
.movieSize
.xmax
-swf
.movieSize
.xmin
)/20.0);
1264 if(swf
.movieSize
.xmin
)
1265 printf(" (left offset: %.2f)\n", swf
.movieSize
.xmin
/20.0);
1268 printf("[HEADER] Movie height: %.2f",(swf
.movieSize
.ymax
-swf
.movieSize
.ymin
)/20.0);
1269 if(swf
.movieSize
.ymin
)
1270 printf(" (top offset: %.2f)\n", swf
.movieSize
.ymin
/20.0);
1278 swf_FontEnumerate(&swf
,&fontcallback1
, 0);
1279 fonts
= (SWFFONT
**)malloc(fontnum
*sizeof(SWFFONT
*));
1281 swf_FontEnumerate(&swf
,&fontcallback2
, 0);
1285 char*name
= swf_TagGetName(tag
);
1288 dumperror("Unknown tag:0x%03x", tag
->id
);
1293 name
= "UNKNOWN TAG";
1296 filepos
+= tag
->len
;
1297 printf("[%03x] %9d %9d %s%s", tag
->id
, tag
->len
, filepos
, prefix
, swf_TagGetName(tag
));
1299 printf("[%03x] %9d %s%s", tag
->id
, tag
->len
, prefix
, swf_TagGetName(tag
));
1302 if(tag
->id
== ST_PLACEOBJECT
) {
1303 printf(" places id %04d at depth %04x", swf_GetPlaceID(tag
), swf_GetDepth(tag
));
1304 if(swf_GetName(tag
))
1305 printf(" name \"%s\"",swf_GetName(tag
));
1307 else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
1314 printf(" id %04d",swf_GetPlaceID(tag
));
1318 printf(" at depth %04d", swf_GetDepth(tag
));
1320 if(tag
->id
== ST_PLACEOBJECT3
&& tag
->data
[1]&4)
1321 printf(" as bitmap");
1323 swf_SetTagPos(tag
, 0);
1324 if(tag
->data
[0]&64) {
1326 swf_GetPlaceObject(tag
, &po
);
1327 printf(" (clip to %04d)", po
.clipdepth
);
1328 swf_PlaceObjectFree(&po
);
1330 if(swf_GetName(tag
))
1331 printf(" name \"%s\"",swf_GetName(tag
));
1334 else if(tag
->id
== ST_REMOVEOBJECT
) {
1335 printf(" removes id %04d from depth %04d", swf_GetPlaceID(tag
), swf_GetDepth(tag
));
1337 else if(tag
->id
== ST_REMOVEOBJECT2
) {
1338 printf(" removes object from depth %04d", swf_GetDepth(tag
));
1340 else if(tag
->id
== ST_FREECHARACTER
) {
1341 printf(" frees object %04d", swf_GetPlaceID(tag
));
1343 else if(tag
->id
== ST_FILEATTRIBUTES
) {
1344 swf_SetTagPos(tag
, 0);
1345 U32 flags
= swf_GetU32(tag
);
1346 if(flags
&FILEATTRIBUTE_USENETWORK
) printf(" usenetwork");
1347 if(flags
&FILEATTRIBUTE_AS3
) printf(" as3");
1348 if(flags
&FILEATTRIBUTE_SYMBOLCLASS
) printf(" symbolclass");
1349 if(flags
&FILEATTRIBUTE_USEHARDWAREGPU
) printf(" hardware-gpu");
1350 if(flags
&FILEATTRIBUTE_USEACCELERATEDBLIT
) printf(" accelerated-blit");
1351 if(flags
&~(1|8|16|32|64))
1352 printf(" flags=%02x", flags
);
1354 else if(tag
->id
== ST_DOABC
) {
1355 swf_SetTagPos(tag
, 0);
1356 U32 flags
= swf_GetU32(tag
);
1357 char*s
= swf_GetString(tag
);
1359 printf(" flags=%08x", flags
);
1362 printf(" \"%s\"", s
);
1367 printf(" lazy load");
1369 swf_SetTagPos(tag
, 0);
1371 else if(tag
->id
== ST_STARTSOUND
) {
1374 id
= swf_GetU16(tag
);
1375 flags
= swf_GetU8(tag
);
1377 printf(" stops sound with id %04d", id
);
1379 printf(" starts sound with id %04d", id
);
1381 printf(" (if not already playing)");
1387 printf(" looping %d times", swf_GetU16(tag
));
1390 else if(tag
->id
== ST_FRAMELABEL
) {
1391 int l
= strlen((char*)tag
->data
);
1392 printf(" \"%s\"", tag
->data
);
1393 if((l
+1) < tag
->len
) {
1394 printf(" has %d extra bytes", tag
->len
-1-l
);
1395 if(tag
->len
- (l
+1) == 1 && tag
->data
[tag
->len
-1] == 1)
1396 printf(" (ANCHOR)");
1398 if((framelabel
&& !issprite
) ||
1399 (spriteframelabel
&& issprite
)) {
1400 dumperror("Frame %d has more than one label",
1401 issprite
?spriteframe
:mainframe
);
1403 if(issprite
) spriteframelabel
= (char*)tag
->data
;
1404 else framelabel
= (char*)tag
->data
;
1406 else if(tag
->id
== ST_SHOWFRAME
) {
1407 char*label
= issprite
?spriteframelabel
:framelabel
;
1408 int frame
= issprite
?spriteframe
:mainframe
;
1411 while(tag
->next
&& tag
->next
->id
== ST_SHOWFRAME
&& tag
->next
->len
== 0) {
1413 if(issprite
) spriteframe
++;
1419 printf(" %d (%s)", frame
+1, timestring(frame
*(256.0/(swf
.frameRate
+0.1))));
1421 printf(" %d-%d (%s-%s)", frame
+1, nframe
+1,
1422 timestring(frame
*(256.0/(swf
.frameRate
+0.1))),
1423 timestring(nframe
*(256.0/(swf
.frameRate
+0.1)))
1426 printf(" (label \"%s\")", label
);
1427 if(issprite
) {spriteframe
++; spriteframelabel
= 0;}
1428 if(!issprite
) {mainframe
++; framelabel
= 0;}
1430 else if(tag
->id
== ST_SETBACKGROUNDCOLOR
) {
1431 U8 r
= swf_GetU8(tag
);
1432 U8 g
= swf_GetU8(tag
);
1433 U8 b
= swf_GetU8(tag
);
1434 printf(" (%02x/%02x/%02x)",r
,g
,b
);
1436 else if(tag
->id
== ST_PROTECT
) {
1438 printf(" %s", swf_GetString(tag
));
1441 else if(tag
->id
== ST_DEFINEFONTALIGNZONES
) {
1442 handleFontAlign1(tag
);
1444 else if(tag
->id
== ST_CSMTEXTSETTINGS
) {
1445 U16 id
= swf_GetU16(tag
);
1446 U8 flags
= swf_GetU8(tag
);
1449 printf("flashtype,");
1451 switch(((flags
>>3)&7)) {
1452 case 0:printf("no grid,");break;
1453 case 1:printf("pixel grid,");break;
1454 case 2:printf("subpixel grid,");break;
1455 case 3:printf("unknown grid,");break;
1458 printf("unknown[%08x],", flags
);
1459 float thickness
= swf_GetFixed(tag
);
1460 float sharpness
= swf_GetFixed(tag
);
1461 printf("s=%.2f,t=%.2f)", thickness
, sharpness
);
1464 else if(swf_isDefiningTag(tag
)) {
1465 U16 id
= swf_GetDefineID(tag
);
1466 printf(" defines id %04d", id
);
1468 dumperror("Id %04d is defined more than once.", id
);
1471 else if(swf_isPseudoDefiningTag(tag
)) {
1472 U16 id
= swf_GetDefineID(tag
);
1473 printf(" adds information to id %04d", id
);
1475 dumperror("Id %04d is not yet defined.\n", id
);
1478 if(tag
->id
== ST_DEFINEBITSLOSSLESS
||
1479 tag
->id
== ST_DEFINEBITSLOSSLESS2
) {
1480 handleDefineBits(tag
);
1483 else if(tag
->id
== ST_DEFINESOUND
) {
1484 handleDefineSound(tag
);
1487 else if(tag
->id
== ST_VIDEOFRAME
) {
1488 handleVideoFrame(tag
, myprefix
);
1491 else if(tag
->id
== ST_DEFINEVIDEOSTREAM
) {
1492 handleVideoStream(tag
, myprefix
);
1495 else if(tag
->id
== ST_DEFINEEDITTEXT
) {
1496 handleEditText(tag
);
1499 else if(tag
->id
== ST_DEFINEMOVIE
) {
1500 U16 id
= swf_GetU16(tag
);
1501 char*s
= swf_GetString(tag
);
1502 printf(" URL: %s\n", s
);
1504 else if(tag
->id
== ST_DEFINETEXT
|| tag
->id
== ST_DEFINETEXT2
) {
1505 handleText(tag
, myprefix
);
1507 else if(tag
->id
== ST_DEFINESCALINGGRID
) {
1508 U16 id
= swf_GetU16(tag
);
1510 swf_GetRect(tag
, &r
);
1511 printf(" (%.2f,%.2f)-(%.2f,%.2f)\n", r
.xmin
/20.0, r
.ymin
/20.0, r
.xmax
/20.0, r
.ymax
/20.0);
1513 else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
1515 else if(tag
->id
== ST_NAMECHARACTER
|| tag
->id
==ST_DEFINEFONTNAME
) {
1517 printf(" \"%s\"\n", swf_GetString(tag
));
1523 if(bbox
&& swf_isDefiningTag(tag
) && tag
->id
!= ST_DEFINESPRITE
) {
1524 SRECT r
= swf_GetDefineBBox(tag
);
1525 printf(" %s bbox [%.2f, %.2f, %.2f, %.2f]\n", prefix
,
1532 sprintf(myprefix
, " %s", prefix
);
1534 if(tag
->id
== ST_DEFINESPRITE
) {
1535 sprintf(prefix
, " ");
1537 dumperror("Sprite definition inside a sprite definition");
1541 spriteframelabel
= 0;
1543 else if(tag
->id
== ST_END
) {
1546 spriteframelabel
= 0;
1548 dumperror("End Tag not empty");
1550 else if(tag
->id
== ST_IMPORTASSETS
|| tag
->id
== ST_IMPORTASSETS2
) {
1551 handleImportAssets(tag
, myprefix
, tag
->id
==ST_IMPORTASSETS2
?1:0);
1553 else if(tag
->id
== ST_EXPORTASSETS
|| tag
->id
== ST_SYMBOLCLASS
) {
1554 handleExportAssets(tag
, myprefix
);
1556 else if(tag
->id
== ST_DOACTION
&& action
) {
1558 actions
= swf_ActionGet(tag
);
1559 swf_DumpActions(actions
, myprefix
);
1561 else if((tag
->id
== ST_DOABC
|| tag
->id
== ST_RAWABC
) && action
) {
1562 void*abccode
= swf_ReadABC(tag
);
1563 swf_DumpABC(stdout
, abccode
, "");
1564 swf_FreeABC(abccode
);
1566 else if(tag
->id
== ST_DOINITACTION
&& action
) {
1568 swf_GetU16(tag
); // id
1569 actions
= swf_ActionGet(tag
);
1570 swf_DumpActions(actions
, myprefix
);
1572 else if(tag
->id
== ST_DEFINEBUTTON
) {
1574 dumpButton(tag
, myprefix
);
1577 dumpButtonActions(tag
, myprefix
);
1580 else if(swf_isFontTag(tag
) && showfonts
) {
1581 dumpFont(tag
, myprefix
);
1583 else if(tag
->id
== ST_DEFINEBUTTON2
) {
1585 dumpButton2Actions(tag
, myprefix
);
1588 else if(tag
->id
== ST_PLACEOBJECT
) {
1589 handlePlaceObject(tag
, myprefix
);
1591 else if(tag
->id
== ST_PLACEOBJECT2
|| tag
->id
== ST_PLACEOBJECT3
) {
1592 handlePlaceObject23(tag
, myprefix
);
1594 else if(tag
->id
== ST_DEFINEFONTALIGNZONES
) {
1595 handleFontAlign2(tag
, myprefix
);
1597 else if(tag
->id
== ST_DEFINEFONTNAME
) {
1598 swf_SetTagPos(tag
, 0);
1599 swf_GetU16(tag
); //id
1600 swf_GetString(tag
); //name
1601 char* copyright
= swf_GetString(tag
);
1602 printf("%s%s\n", myprefix
, copyright
);
1604 else if(tag
->id
== ST_DEFINESHAPE
||
1605 tag
->id
== ST_DEFINESHAPE2
||
1606 tag
->id
== ST_DEFINESHAPE3
||
1607 tag
->id
== ST_DEFINESHAPE4
) {
1609 handleShape(tag
, myprefix
);
1612 if(tag
->len
&& used
) {
1613 int num
= swf_GetNumUsedIDs(tag
);
1617 used
= (int*)malloc(sizeof(int)*num
);
1618 swf_GetUsedIDs(tag
, used
);
1619 printf("%s%suses IDs: ", indent
, prefix
);
1620 for(t
=0;t
<num
;t
++) {
1622 swf_SetTagPos(tag
, used
[t
]);
1623 id
= swf_GetU16(tag
);
1624 printf("%d%s", id
, t
<num
-1?", ":"");
1626 dumperror("Id %04d is not yet defined.\n", id
);
1633 if(tag
->id
== ST_FREECHARACTER
) {
1635 swf_SetTagPos(tag
, 0);
1636 id
= swf_GetU16(tag
);
1640 if(tag
->len
&& hex
) {
1641 hexdumpTag(tag
, prefix
);