new function isPseudoDefiningTag.
[swftools.git] / lib / modules / swftools.c
1 /* swftools.c
2
3    Math and matrix functions, misc tools
4
5    Extension module for the rfxswf library.
6    Part of the swftools package.
7
8    Copyright (c) 2000, 2001 Rainer Böhme <rfxswf@reflex-studio.de>
9  
10    This file is distributed under the GPL, see file COPYING for details 
11
12 */
13
14 // Matrix & Math tools for SWF files
15
16 #define S64 long long
17 SFIXED RFXSWF_SP(SFIXED a1,SFIXED a2,SFIXED b1,SFIXED b2)
18 { S64 a;
19   a = (S64)a1*(S64)b1+(S64)a2*(S64)b2;
20   return (SFIXED)(a>>16);
21 }
22 SFIXED RFXSWF_QFIX(int zaehler,int nenner) // bildet Quotient von zwei INTs in SFIXED
23 { S64 z = zaehler<<16;
24   S64 a = z/(S64)nenner;
25   return (SFIXED)a;
26 }
27 #undef S64
28
29 MATRIX * swf_MatrixJoin(MATRIX * d,MATRIX * s1,MATRIX * s2)
30 {        
31   if (!d) return NULL;
32   if (!s1) return (s2)?(MATRIX *)memcpy(d,s2,sizeof(MATRIX)):NULL;
33   if (!s2) return (MATRIX *)memcpy(d,s1,sizeof(MATRIX));
34   
35   d->tx = s1->tx + s2->tx;
36   d->ty = s1->ty + s2->ty;
37   
38   d->sx = RFXSWF_SP(s1->sx,s1->r1,s2->sx,s2->r0);
39   d->sy = RFXSWF_SP(s1->r0,s1->sy,s2->r1,s2->sy);
40   d->r0 = RFXSWF_SP(s1->r0,s1->sy,s2->sx,s2->r0);
41   d->r1 = RFXSWF_SP(s1->sx,s1->r1,s2->r1,s2->sy);
42
43   //DumpMatrix(NULL,d);
44   
45   return d;
46 }
47
48 MATRIX * swf_MatrixMapTriangle(MATRIX * m,int dx,int dy,int x0,int y0,
49                                int x1,int y1,int x2,int y2)
50 { int dx1 = x1 - x0;
51   int dy1 = y1 - y0;
52   int dx2 = x2 - x0;
53   int dy2 = y2 - y0;
54   
55   if (!m) return NULL;
56   if ((!dx)||(!dy)) return NULL; // check DIV by zero
57
58   m->tx = x0;
59   m->ty = y0;
60   m->sx = RFXSWF_QFIX(dx1,dx);
61   m->sy = RFXSWF_QFIX(dy2,dy);
62   m->r0 = RFXSWF_QFIX(dy1,dx);
63   m->r1 = RFXSWF_QFIX(dx2,dy);
64   
65   return m;
66 }
67
68 U16 swf_GetDefineID(TAG * t)
69 // up to SWF 4.0
70 { U32 oldTagPos;
71   U16 id = 0;
72
73   oldTagPos = swf_GetTagPos(t);
74   swf_SetTagPos(t,0);
75
76   switch (swf_GetTagID(t))
77   { case ST_DEFINESHAPE:
78     case ST_DEFINESHAPE2:
79     case ST_DEFINESHAPE3:
80     case ST_DEFINEMORPHSHAPE:
81     case ST_DEFINEEDITTEXT:
82     case ST_DEFINEBITS:
83     case ST_DEFINEBITSJPEG2:
84     case ST_DEFINEBITSJPEG3:
85     case ST_DEFINEBITSLOSSLESS:
86     case ST_DEFINEBITSLOSSLESS2:
87     case ST_DEFINEBUTTON:
88     case ST_DEFINEBUTTON2:
89     case ST_DEFINEBUTTONCXFORM:
90     case ST_DEFINEBUTTONSOUND:
91     case ST_DEFINEFONT:
92     case ST_DEFINEFONT2:
93     case ST_DEFINEFONTINFO: //psedodefine
94     case ST_DEFINETEXT:
95     case ST_DEFINETEXT2:
96     case ST_DEFINESOUND:
97     case ST_DEFINESPRITE:
98       id = swf_GetU16(t);
99       break;
100   }
101
102   swf_SetTagPos(t,oldTagPos);
103
104   return id;
105 }
106
107 U16 swf_GetPlaceID(TAG * t)
108 // up to SWF 4.0
109 { U32 oldTagPos;
110   U16 id = 0;
111
112   oldTagPos = swf_GetTagPos(t);
113   swf_SetTagPos(t,0);
114
115   switch (swf_GetTagID(t))
116   { case ST_PLACEOBJECT:
117     case ST_REMOVEOBJECT:
118     case ST_STARTSOUND:
119       id = swf_GetU16(t);
120       break;
121
122     case ST_PLACEOBJECT2:
123     { U8 flags = swf_GetU8(t);
124       U16 d = swf_GetU16(t);
125       id = (flags&PF_CHAR)?swf_GetU16(t):id;
126     } break;
127
128   }
129
130   swf_SetTagPos(t,oldTagPos);
131
132   return id;
133 }
134
135 static int swf_definingtagids[] =
136 {ST_DEFINESHAPE,
137  ST_DEFINESHAPE2,
138  ST_DEFINESHAPE3,
139  ST_DEFINEMORPHSHAPE,
140  ST_DEFINEFONT,
141  ST_DEFINEFONT2,
142  ST_DEFINETEXT,
143  ST_DEFINETEXT2,
144  ST_DEFINEEDITTEXT,
145  ST_DEFINEBITS,
146  ST_DEFINEBITSJPEG2,
147  ST_DEFINEBITSJPEG3,
148  ST_DEFINEBITSLOSSLESS,
149  ST_DEFINEBITSLOSSLESS2,
150  ST_DEFINEMOVIE,
151  ST_DEFINESPRITE,
152  ST_DEFINEBUTTON,
153  ST_DEFINEBUTTON2,
154  ST_DEFINESOUND,
155  -1
156 };
157
158 // tags which may be used inside a sprite definition
159 static int swf_spritetagids[] =
160 {ST_SHOWFRAME,
161  ST_PLACEOBJECT,
162  ST_PLACEOBJECT2,
163  ST_REMOVEOBJECT,
164  ST_REMOVEOBJECT2, //?
165  ST_DOACTION,
166  ST_STARTSOUND,
167  ST_FRAMELABEL,
168  ST_SOUNDSTREAMHEAD,
169  ST_SOUNDSTREAMHEAD2,
170  ST_SOUNDSTREAMBLOCK,
171  ST_END,
172  -1
173 };
174
175 static int swf_pseudodefiningtagids[] = 
176 {
177  ST_DEFINEFONTINFO,
178  -1
179 };
180
181 U8 swf_isAllowedSpriteTag(TAG * tag)
182 {
183     int id = tag->id;
184     int t=0;
185     while(swf_spritetagids[t]>=0)
186     {
187         if(swf_spritetagids[t] == id) 
188             return 1;
189         t++;
190     }
191     return 0; 
192 }
193
194 U8 swf_isDefiningTag(TAG * tag)
195 {
196     int id = tag->id;
197     int t=0;
198     while(swf_definingtagids[t]>=0)
199     {
200         if(swf_definingtagids[t] == id) 
201             return 1;
202         t++;
203     }
204     return 0; 
205 }
206
207 U8 swf_isPseudoDefiningTag(TAG * tag)
208 {
209     int id = tag->id;
210     int t=0;
211     while(swf_pseudodefiningtagids[t]>=0)
212     {
213         if(swf_pseudodefiningtagids[t] == id) 
214             return 1;
215         t++;
216     }
217     return 0; 
218 }
219
220 U16 swf_GetDepth(TAG * t)
221 // up to SWF 4.0
222
223   U16 depth = 0;
224   U32 oldTagPos;
225   oldTagPos = swf_GetTagPos(t);
226   swf_SetTagPos(t,0);
227
228   switch (swf_GetTagID(t))
229   { case ST_PLACEOBJECT:
230     case ST_REMOVEOBJECT:
231       swf_GetU16(t); //id
232       depth = swf_GetU16(t);
233       break;
234     case ST_REMOVEOBJECT2:
235       depth = swf_GetU16(t);
236       break;
237     case ST_PLACEOBJECT2:
238     { U8 flags = swf_GetU8(t);
239       depth = swf_GetU16(t);
240     } break;
241   }
242   swf_SetTagPos(t,oldTagPos);
243   return depth;
244 }
245
246 char* swf_GetName(TAG * t)
247 {
248     char* name = 0;
249     U32 oldTagPos;
250     MATRIX m;
251     CXFORM c;
252     oldTagPos = swf_GetTagPos(t);
253     swf_SetTagPos(t,0);
254     switch(swf_GetTagID(t))
255     {
256         case ST_FRAMELABEL:
257             name = &t->data[swf_GetTagPos(t)];
258         break;
259         case ST_PLACEOBJECT2: {   
260             U8 flags = swf_GetU8(t);
261             swf_GetU16(t); //depth;
262             if(flags&PF_CHAR) 
263               swf_GetU16(t); //id
264             if(flags&PF_MATRIX)
265               swf_GetMatrix(t, &m);
266             if(flags&PF_CXFORM)
267               swf_GetCXForm(t, &c, 1);
268             if(flags&PF_RATIO)
269               swf_GetU16(t);
270             if(flags&PF_NAME) {
271               swf_ResetReadBits(t);
272               name = &t->data[swf_GetTagPos(t)];
273             }
274         }
275         break;
276     }
277     swf_SetTagPos(t,oldTagPos);
278     return name;
279 }
280