fix crashes reported by Debian Cylab Mayhem Team
[swftools.git] / src / swfstrings.c
blob27494b421a6020f9c2d3f921041146faddbe4359
1 /* swfstrings.c
2 Scans a swf file for strings
4 Part of the swftools package.
6 Copyright (c) 2000,2001 Rainer Böhme <rfxswf@reflex-studio.de>
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 <stdio.h>
23 #include <fcntl.h>
24 #include "../lib/rfxswf.h"
25 #include "../lib/args.h"
26 #include "../lib/utf8.h"
28 static char * filename = 0;
29 static char showfonts = 0;
30 static int x=0,y=0,w=0,h=0;
32 static struct options_t options[] = {
33 {"f", "fonts"},
34 {"x", "xpos"},
35 {"y", "ypos"},
36 {"W", "width"},
37 {"H", "height"},
38 {"V", "version"},
39 {0,0}
42 int args_callback_option(char*name,char*val)
44 if(!strcmp(name, "V")) {
45 printf("swfstrings - part of %s %s\n", PACKAGE, VERSION);
46 exit(0);
47 } else if(!strcmp(name, "x")) {
48 x = atoi(val);
49 return 1;
50 } else if(!strcmp(name, "y")) {
51 y = atoi(val);
52 return 1;
53 } else if(!strcmp(name, "W")) {
54 w = atoi(val);
55 return 1;
56 } else if(!strcmp(name, "H")) {
57 h = atoi(val);
58 return 1;
59 } else if(!strcmp(name, "f")) {
60 showfonts = 1;
61 return 0;
62 } else if(!strcmp(name, "V")) {
63 printf("swfstrings - part of %s %s\n", PACKAGE, VERSION);
64 exit(0);
65 } else {
66 fprintf(stderr, "Unknown option: -%s\n", name);
67 exit(1);
69 return 0;
71 int args_callback_longoption(char*name,char*val)
73 return args_long2shortoption(options, name, val);
75 void args_callback_usage(char *name)
77 printf("\n");
78 printf("Usage: %s [options] file.swf\n", name);
79 printf("\n");
80 printf("-f , --fonts Print out font information for each text block\n");
81 printf("-x , --xpos <x> Set bounding box x coordinate\n");
82 printf("-y , --ypos <y> Set bounding box y coordinate\n");
83 printf("-W , --width <width> Set bounding box width\n");
84 printf("-H , --height <height> Set bounding box height\n");
85 printf("-V , --version Print version information and exit\n");
86 printf("\n");
88 int args_callback_command(char*name,char*val)
90 if(filename) {
91 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
92 filename, name);
94 filename = name;
95 return 0;
98 static SWF swf;
99 static int fontnum = 0;
100 static SWFFONT**fonts = 0;
102 void fontcallback1(void*self, U16 id,U8 * name)
103 { fontnum++;
106 void fontcallback2(void*self, U16 id,U8 * name)
108 swf_FontExtract(&swf,id,&fonts[fontnum]);
109 fontnum++;
113 void textcallback(void*self, int*glyphs, int*advance, int nr, int fontid, int fontsize, int startx, int starty, RGBA*color)
115 SWFFONT*font = 0;
116 int t;
117 for(t=0;t<fontnum;t++)
119 if(fonts[t]->id == fontid) {
120 font = fonts[t];
121 break;
125 if(showfonts) {
126 if(font)
127 printf("#<font %d \"%s\"%s%s>\n", fontid, font->name, swf_FontIsBold(font)?" bold":"",swf_FontIsItalic(font)?" italic":"");
128 printf("#<color #%02x%02x%02x%02x>\n", color->r, color->g, color->b, color->a);
129 printf("#<size %d>\n", fontsize);
132 for(t=0;t<nr;t++)
134 int xx = startx + advance[t];
135 int yy = starty;
136 MATRIX*m = (MATRIX*)self;
138 SPOINT p = {xx,yy};
139 p = swf_TurnPoint(p, m);
140 xx = p.x / 20;
141 yy = p.y / 20;
143 if(x|y|w|h) {
144 if(xx < x || yy < y || xx > x+w || yy > y+h) {
145 /* outside of bounding box */
146 ///printf("(%d+%d,%d) -> (%d,%d)\n", startx, advance[t]/20, starty, xx, yy);
147 if(t==nr-1) return;
148 else continue;
152 unsigned int a;
153 int advance = 0;
154 if(font) {
155 if(glyphs[t]<0 || glyphs[t] >= font->numchars /*glyph is not in range*/
156 || !font->glyph2ascii /* font has ascii<->glyph mapping */
157 ) a = glyphs[t];
158 else {
159 if(font->glyph2ascii[glyphs[t]])
160 a = font->glyph2ascii[glyphs[t]];
161 else
162 a = glyphs[t];
164 } else {
165 a = glyphs[t];
168 if(a>=32) {
169 char* utf8 = getUTF8(a);
170 printf("%s", utf8);
171 } else {
172 printf("\\x%x", (int)a);
175 printf("\n");
178 void fontcallback(void*self,U16 id,U8 * name)
179 { SWFFONT* font;
180 TAG* t;
182 swf_FontExtract(&swf,id,&font);
184 t = swf.firstTag;
186 swf_FontFree(font);
189 TAG**id2tag = 0;
191 int main (int argc,char ** argv)
193 int f;
194 processargs(argc, argv);
195 if(!filename)
196 exit(0);
198 f = open(filename,O_RDONLY|O_BINARY);
199 if (f<0 || swf_ReadSWF(f,&swf)<0) {
200 fprintf(stderr,"%s is not a valid SWF file or contains errors.\n",filename);
201 if(f>=0) close(f);
202 exit(-1);
204 close(f);
206 if(x|y|w|h) {
207 if(!w) w = (swf.movieSize.xmax - swf.movieSize.xmin) / 20;
208 if(!h) h = (swf.movieSize.ymax - swf.movieSize.ymin) / 20;
211 id2tag = rfx_calloc(sizeof(TAG)*65536);
213 fontnum = 0;
214 swf_FontEnumerate(&swf,&fontcallback1, 0);
215 fonts = (SWFFONT**)malloc(fontnum*sizeof(SWFFONT*));
216 fontnum = 0;
217 swf_FontEnumerate(&swf,&fontcallback2, 0);
219 TAG*tag = swf.firstTag;
220 while (tag)
222 if(swf_isTextTag(tag)) {
223 id2tag[swf_GetDefineID(tag)] = tag;
224 } else if(swf_isPlaceTag(tag)) {
225 SWFPLACEOBJECT po;
226 swf_SetTagPos(tag, 0);
227 swf_GetPlaceObject(tag, &po);
228 if(!po.move && id2tag[po.id]) {
229 TAG*text = id2tag[po.id];
230 swf_SetTagPos(text, 0);
231 swf_GetU16(text);
232 swf_GetRect(text, NULL);
233 swf_ResetReadBits(text);
234 MATRIX m,tm;
235 swf_GetMatrix(text, &tm);
236 swf_MatrixJoin(&m, &po.matrix, &tm);
237 swf_ParseDefineText(text, textcallback, &m);
240 tag = tag->next;
243 swf_FreeTags(&swf);
244 return 0;