added -a option
[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 \r
37 struct options_t options[] =\r
38 {\r
39  {"v","verbose"},\r
40  {"V","version"},\r
41  {0,0}\r
42 };\r
43 \r
44 \r
45 int args_callback_option(char*name,char*val)\r
46 {\r
47     if(!strcmp(name, "V")) {\r
48         printf("swfdump - part of %s %s\n", PACKAGE, VERSION);\r
49         exit(0);\r
50     }\r
51 }\r
52 int args_callback_longoption(char*name,char*val)\r
53 {\r
54     return args_long2shortoption(options, name, val);\r
55 }\r
56 void args_callback_usage(char*name)\r
57 {    \r
58     printf("Usage: %s file.swf\n", name);\r
59 }\r
60 int args_callback_command(char*name,char*val)\r
61 {\r
62     if(filename) {\r
63         fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",\r
64                  filename, name);\r
65     }\r
66     filename = name;\r
67     return 0;\r
68 }\r
69   \r
70 int main (int argc,char ** argv)\r
71\r
72     SWF swf;\r
73     TAG*tag;\r
74 #ifdef HAVE_STAT\r
75     struct stat statbuf;\r
76 #endif\r
77     int f;\r
78     char prefix[128];\r
79     prefix[0] = 0;\r
80     memset(idtab,0,65536);\r
81 \r
82     processargs(argc, argv);\r
83 \r
84     f = open(filename,O_RDONLY);\r
85 \r
86     if (f<0)\r
87     { \r
88         perror("Couldn't open file: ");\r
89         exit(1);\r
90     }\r
91     if FAILED(ReadSWF(f,&swf))\r
92     { \r
93         fprintf(stderr,"%s is not a valid SWF file or contains errors.\n",filename);\r
94         close(f);\r
95         exit(1);\r
96     }\r
97 \r
98 #ifdef HAVE_STAT\r
99     fstat(f, &statbuf);\r
100     if(statbuf.st_size != swf.FileSize)\r
101         fprintf(stderr, "Error: Real Filesize (%d) doesn't match header Filesize (%d)",\r
102                 statbuf.st_size, swf.FileSize);\r
103 #endif\r
104 \r
105     close(f);\r
106 \r
107     printf("[HEADER]        File version: %d\n", swf.FileVersion);\r
108     printf("[HEADER]        File size: %d\n", swf.FileSize);\r
109     printf("[HEADER]        Frame rate: %f\n",swf.FrameRate/256.0);\r
110     printf("[HEADER]        Frame count: %d\n",swf.FrameCount);\r
111     printf("[HEADER]        Movie width: %.3f\n",(swf.MovieSize.xmax-swf.MovieSize.xmin)/20.0);\r
112     printf("[HEADER]        Movie height: %.3f\n",(swf.MovieSize.ymax-swf.MovieSize.ymin)/20.0);\r
113 \r
114     tag = swf.FirstTag;\r
115 \r
116     while(tag) {\r
117         printf("[%03x] %9d %s%s", tag->id, tag->len, prefix, getTagName(tag));\r
118         if(isDefiningTag(tag)) {\r
119             U16 id = GetDefineID(tag);\r
120             printf(" defines id %04x", id);\r
121             if(idtab[id])\r
122                 fprintf(stderr, "Error: Id %04x is defined more than once.\n", id);\r
123             idtab[id] = 1;\r
124         }\r
125         else if(tag->id == ST_PLACEOBJECT || \r
126                 tag->id == ST_PLACEOBJECT2) {\r
127             printf(" places id %04x at depth %04x", GetPlaceID(tag), GetDepth(tag));\r
128             if(GetName(tag))\r
129                 printf(" name \"%s\"",GetName(tag));\r
130         }\r
131         else if(tag->id == ST_REMOVEOBJECT) {\r
132             printf(" removes id %04x from depth %04x", GetPlaceID(tag), GetDepth(tag));\r
133         }\r
134         else if(tag->id == ST_REMOVEOBJECT2) {\r
135             printf(" removes object from depth %04x", GetDepth(tag));\r
136         }\r
137         \r
138         printf("\n");\r
139 \r
140         if(tag->id == ST_DEFINESPRITE)\r
141         {\r
142             sprintf(prefix, "         ");\r
143         }\r
144         if(tag->id == ST_END) \r
145         {\r
146             sprintf(prefix, "");\r
147         }\r
148         tag = tag->next;\r
149     }\r
150 \r
151     FreeTags(&swf);\r
152     return 0;\r
153 }\r
154 \r