use the dump function in swfaction.c.
[swftools.git] / src / swfdump.c
1 /* swfdump.c\r
2    Shows the structure of a swf file\r
3 \r
4    Part of the swftools package.\r
5    \r
6    Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>\r
7 \r
8    This file is distributed under the GPL, see file COPYING for details */\r
9 \r
10 #define HAVE_STAT\r
11 \r
12 #ifdef HAVE_SYS_STAT_H\r
13 #include <sys/stat.h>\r
14 #else\r
15 #undef HAVE_STAT\r
16 #endif\r
17 \r
18 #ifdef HAVE_SYS_TYPES_H\r
19 #include <sys/types.h>\r
20 #else\r
21 #undef HAVE_STAT\r
22 #endif\r
23 \r
24 #include <unistd.h>\r
25 #include <stdio.h>\r
26 #include <fcntl.h>\r
27 #include "../lib/rfxswf.h"\r
28 #include "../lib/args.h"\r
29 \r
30 char * filename = 0;\r
31 \r
32 /* idtab stores the ids which are defined in the file. This allows us\r
33    to detect errors in the file. (i.e. ids which are defined more than \r
34    once */\r
35 char idtab[65536];\r
36 int action = 0;\r
37 \r
38 struct options_t options[] =\r
39 {\r
40  {"a","action"},\r
41  {"v","verbose"},\r
42  {"V","version"},\r
43  {0,0}\r
44 };\r
45 \r
46 \r
47 int args_callback_option(char*name,char*val)\r
48 {\r
49     if(!strcmp(name, "V")) {\r
50         printf("swfdump - part of %s %s\n", PACKAGE, VERSION);\r
51         exit(0);\r
52     } \r
53     else if(name[0]=='a') {\r
54         action = 1;\r
55         return 0;\r
56     }\r
57     else {\r
58         printf("Unknown option: -%s\n", name);\r
59     }\r
60 \r
61     return 0;\r
62 }\r
63 int args_callback_longoption(char*name,char*val)\r
64 {\r
65     return args_long2shortoption(options, name, val);\r
66 }\r
67 void args_callback_usage(char*name)\r
68 {    \r
69     printf("Usage: %s [-a] file.swf\n", name);\r
70     printf("-h , --help\t\t\t Print help and exit\n");\r
71     printf("-a , --action\t\t\t Disassemble action tags\n");\r
72     printf("-V , --version\t\t\t Print program version and exit\n");\r
73 }\r
74 int args_callback_command(char*name,char*val)\r
75 {\r
76     if(filename) {\r
77         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",\r
78                  filename, name);\r
79     }\r
80     filename = name;\r
81     return 0;\r
82 }\r
83 \r
84 int main (int argc,char ** argv)\r
85\r
86     SWF swf;\r
87     TAG*tag;\r
88 #ifdef HAVE_STAT\r
89     struct stat statbuf;\r
90 #endif\r
91     int f;\r
92     char prefix[128];\r
93     prefix[0] = 0;\r
94     memset(idtab,0,65536);\r
95 \r
96     processargs(argc, argv);\r
97 \r
98     if(!filename)\r
99     {\r
100         fprintf(stderr, "You must supply a filename.\n");\r
101         return 1;\r
102     }\r
103 \r
104     f = open(filename,O_RDONLY);\r
105 \r
106     if (f<0)\r
107     { \r
108         perror("Couldn't open file: ");\r
109         exit(1);\r
110     }\r
111     if FAILED(ReadSWF(f,&swf))\r
112     { \r
113         fprintf(stderr, "%s is not a valid SWF file or contains errors.\n",filename);\r
114         close(f);\r
115         exit(1);\r
116     }\r
117 \r
118 #ifdef HAVE_STAT\r
119     fstat(f, &statbuf);\r
120     if(statbuf.st_size != swf.FileSize)\r
121         fprintf(stderr, "Error: Real Filesize (%d) doesn't match header Filesize (%d)",\r
122                 statbuf.st_size, swf.FileSize);\r
123 #endif\r
124 \r
125     close(f);\r
126 \r
127     printf("[HEADER]        File version: %d\n", swf.FileVersion);\r
128     printf("[HEADER]        File size: %ld\n", swf.FileSize);\r
129     printf("[HEADER]        Frame rate: %f\n",swf.FrameRate/256.0);\r
130     printf("[HEADER]        Frame count: %d\n",swf.FrameCount);\r
131     printf("[HEADER]        Movie width: %.3f\n",(swf.MovieSize.xmax-swf.MovieSize.xmin)/20.0);\r
132     printf("[HEADER]        Movie height: %.3f\n",(swf.MovieSize.ymax-swf.MovieSize.ymin)/20.0);\r
133 \r
134     tag = swf.FirstTag;\r
135 \r
136     while(tag) {\r
137         char*name = getTagName(tag);\r
138         if(!name) {\r
139             fprintf(stderr, "Error: Unknown tag:0x%03x\n", tag->id);\r
140             tag = tag->next;\r
141             continue;\r
142         }\r
143         printf("[%03x] %9ld %s%s", tag->id, tag->len, prefix, getTagName(tag));\r
144 \r
145         if(isDefiningTag(tag)) {\r
146             U16 id = GetDefineID(tag);\r
147             printf(" defines id %04x", id);\r
148             if(idtab[id])\r
149                 fprintf(stderr, "Error: Id %04x is defined more than once.\n", id);\r
150             idtab[id] = 1;\r
151         }\r
152         else if(tag->id == ST_PLACEOBJECT || \r
153                 tag->id == ST_PLACEOBJECT2) {\r
154             printf(" places id %04x at depth %04x", GetPlaceID(tag), GetDepth(tag));\r
155             if(GetName(tag))\r
156                 printf(" name \"%s\"",GetName(tag));\r
157         }\r
158         else if(tag->id == ST_REMOVEOBJECT) {\r
159             printf(" removes id %04x from depth %04x", GetPlaceID(tag), GetDepth(tag));\r
160         }\r
161         else if(tag->id == ST_REMOVEOBJECT2) {\r
162             printf(" removes object from depth %04x", GetDepth(tag));\r
163         }\r
164         \r
165         printf("\n");\r
166 \r
167         if(tag->id == ST_DEFINESPRITE) {\r
168             sprintf(prefix, "         ");\r
169         }\r
170         else if(tag->id == ST_END) {\r
171             *prefix = 0;\r
172         }\r
173         else if(tag->id == ST_DOACTION && action) {\r
174             char myprefix[128];\r
175             ActionTAG*actions;\r
176             sprintf(myprefix, "                %s", prefix);\r
177             \r
178             actions = GetActions(tag);\r
179 \r
180             DumpActions(actions, myprefix);\r
181         }\r
182         tag = tag->next;\r
183     }\r
184 \r
185     FreeTags(&swf);\r
186     return 0;\r
187 }\r
188 \r