Diffstat (limited to 'core/multimedia/opieplayer/libflash/script.cc') (more/less context) (ignore whitespace changes)
-rw-r--r-- | core/multimedia/opieplayer/libflash/script.cc | 1988 |
1 files changed, 1988 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/script.cc b/core/multimedia/opieplayer/libflash/script.cc new file mode 100644 index 0000000..db65819 --- a/dev/null +++ b/core/multimedia/opieplayer/libflash/script.cc | |||
@@ -0,0 +1,1988 @@ | |||
1 | #include "swf.h" | ||
2 | |||
3 | //////////////////////////////////////////////////////////// | ||
4 | // This file is derived from the 'buggy' SWF parser provided | ||
5 | // by Macromedia. | ||
6 | // | ||
7 | // Modifications : Olivier Debon <odebon@club-internet.fr> | ||
8 | // | ||
9 | |||
10 | #ifdef RCSID | ||
11 | static char *rcsid = "$Id$"; | ||
12 | #endif | ||
13 | |||
14 | #define printf(fmt,args...) | ||
15 | |||
16 | ////////////////////////////////////////////////////////////////////// | ||
17 | // Inline input script object methods. | ||
18 | ////////////////////////////////////////////////////////////////////// | ||
19 | |||
20 | // | ||
21 | // Inlines to parse a Flash file. | ||
22 | // | ||
23 | inline U8 CInputScript::GetByte(void) | ||
24 | { | ||
25 | return m_fileBuf[m_filePos++]; | ||
26 | } | ||
27 | |||
28 | inline U16 CInputScript::GetWord(void) | ||
29 | { | ||
30 | U8 * s = m_fileBuf + m_filePos; | ||
31 | m_filePos += 2; | ||
32 | return (U16) s[0] | ((U16) s[1] << 8); | ||
33 | } | ||
34 | |||
35 | inline U32 CInputScript::GetDWord(void) | ||
36 | { | ||
37 | U8 * s = m_fileBuf + m_filePos; | ||
38 | m_filePos += 4; | ||
39 | return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24); | ||
40 | } | ||
41 | |||
42 | |||
43 | |||
44 | |||
45 | ////////////////////////////////////////////////////////////////////// | ||
46 | // Input script object methods. | ||
47 | ////////////////////////////////////////////////////////////////////// | ||
48 | |||
49 | CInputScript::CInputScript(int level) | ||
50 | // Class constructor. | ||
51 | { | ||
52 | this->level = level; | ||
53 | |||
54 | // Initialize the input pointer. | ||
55 | m_fileBuf = NULL; | ||
56 | |||
57 | // Initialize the file information. | ||
58 | m_filePos = 0; | ||
59 | m_fileSize = 0; | ||
60 | m_fileVersion = 0; | ||
61 | |||
62 | // Initialize the bit position and buffer. | ||
63 | m_bitPos = 0; | ||
64 | m_bitBuf = 0; | ||
65 | |||
66 | // Initialize the output file. | ||
67 | m_outputFile = NULL; | ||
68 | |||
69 | // Set to true if we wish to dump all contents long form | ||
70 | m_dumpAll = false; | ||
71 | |||
72 | // if set to true will dump image guts (i.e. jpeg, zlib, etc. data) | ||
73 | m_dumpGuts = false; | ||
74 | |||
75 | needHeader = 1; | ||
76 | program = 0; | ||
77 | |||
78 | outOfMemory = 0; | ||
79 | |||
80 | next = NULL; | ||
81 | |||
82 | return; | ||
83 | } | ||
84 | |||
85 | |||
86 | CInputScript::~CInputScript(void) | ||
87 | // Class destructor. | ||
88 | { | ||
89 | // Free the buffer if it is there. | ||
90 | if (m_fileBuf) | ||
91 | { | ||
92 | delete program; | ||
93 | m_fileBuf = NULL; | ||
94 | m_fileSize = 0; | ||
95 | } | ||
96 | } | ||
97 | |||
98 | |||
99 | U16 CInputScript::GetTag(void) | ||
100 | { | ||
101 | // Save the start of the tag. | ||
102 | m_tagStart = m_filePos; | ||
103 | |||
104 | if (m_actualSize-m_filePos < 2) return notEnoughData; | ||
105 | |||
106 | // Get the combined code and length of the tag. | ||
107 | U16 code = GetWord(); | ||
108 | |||
109 | // The length is encoded in the tag. | ||
110 | U32 len = code & 0x3f; | ||
111 | |||
112 | // Remove the length from the code. | ||
113 | code = code >> 6; | ||
114 | |||
115 | // Determine if another long word must be read to get the length. | ||
116 | if (len == 0x3f) { | ||
117 | if (m_actualSize-m_filePos < 4) return notEnoughData; | ||
118 | len = (U32) GetDWord(); | ||
119 | } | ||
120 | |||
121 | // Determine the end position of the tag. | ||
122 | m_tagEnd = m_filePos + (U32) len; | ||
123 | m_tagLen = (U32) len; | ||
124 | |||
125 | return code; | ||
126 | } | ||
127 | |||
128 | |||
129 | void CInputScript::GetRect (Rect * r) | ||
130 | { | ||
131 | InitBits(); | ||
132 | int nBits = (int) GetBits(5); | ||
133 | r->xmin = GetSBits(nBits); | ||
134 | r->xmax = GetSBits(nBits); | ||
135 | r->ymin = GetSBits(nBits); | ||
136 | r->ymax = GetSBits(nBits); | ||
137 | } | ||
138 | |||
139 | void CInputScript::GetMatrix(Matrix* mat) | ||
140 | { | ||
141 | InitBits(); | ||
142 | |||
143 | // Scale terms | ||
144 | if (GetBits(1)) | ||
145 | { | ||
146 | int nBits = (int) GetBits(5); | ||
147 | mat->a = (float)(GetSBits(nBits))/(float)0x10000; | ||
148 | mat->d = (float)(GetSBits(nBits))/(float)0x10000; | ||
149 | } | ||
150 | else | ||
151 | { | ||
152 | mat->a = mat->d = 1.0; | ||
153 | } | ||
154 | |||
155 | // Rotate/skew terms | ||
156 | if (GetBits(1)) | ||
157 | { | ||
158 | int nBits = (int)GetBits(5); | ||
159 | mat->c = (float)(GetSBits(nBits))/(float)0x10000; | ||
160 | mat->b = (float)(GetSBits(nBits))/(float)0x10000; | ||
161 | } | ||
162 | else | ||
163 | { | ||
164 | mat->b = mat->c = 0.0; | ||
165 | } | ||
166 | |||
167 | // Translate terms | ||
168 | int nBits = (int) GetBits(5); | ||
169 | mat->tx = GetSBits(nBits); | ||
170 | mat->ty = GetSBits(nBits); | ||
171 | } | ||
172 | |||
173 | |||
174 | void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha) | ||
175 | { | ||
176 | int flags; | ||
177 | int nBits; | ||
178 | float aa; long ab; | ||
179 | float ra; long rb; | ||
180 | float ga; long gb; | ||
181 | float ba; long bb; | ||
182 | |||
183 | InitBits(); | ||
184 | |||
185 | flags = (int) GetBits(2); | ||
186 | nBits = (int) GetBits(4); | ||
187 | aa = 1.0; ab = 0; | ||
188 | if (flags & 1) | ||
189 | { | ||
190 | ra = (float) GetSBits(nBits)/256.0; | ||
191 | ga = (float) GetSBits(nBits)/256.0; | ||
192 | ba = (float) GetSBits(nBits)/256.0; | ||
193 | if (hasAlpha) aa = (float) GetSBits(nBits)/256.0; | ||
194 | } | ||
195 | else | ||
196 | { | ||
197 | ra = ga = ba = 1.0; | ||
198 | } | ||
199 | if (flags & 2) | ||
200 | { | ||
201 | rb = (S32) GetSBits(nBits); | ||
202 | gb = (S32) GetSBits(nBits); | ||
203 | bb = (S32) GetSBits(nBits); | ||
204 | if (hasAlpha) ab = (S32) GetSBits(nBits); | ||
205 | } | ||
206 | else | ||
207 | { | ||
208 | rb = gb = bb = 0; | ||
209 | } | ||
210 | if (cx) { | ||
211 | cx->aa = aa; | ||
212 | cx->ab = ab; | ||
213 | cx->ra = ra; | ||
214 | cx->rb = rb; | ||
215 | cx->ga = ga; | ||
216 | cx->gb = gb; | ||
217 | cx->ba = ba; | ||
218 | cx->bb = bb; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | |||
223 | /* XXX: should allocate string */ | ||
224 | char *CInputScript::GetString(void) | ||
225 | { | ||
226 | // Point to the string. | ||
227 | char *str = (char *) &m_fileBuf[m_filePos]; | ||
228 | |||
229 | // Skip over the string. | ||
230 | while (GetByte()); | ||
231 | |||
232 | return str; | ||
233 | } | ||
234 | |||
235 | void CInputScript::InitBits(void) | ||
236 | { | ||
237 | // Reset the bit position and buffer. | ||
238 | m_bitPos = 0; | ||
239 | m_bitBuf = 0; | ||
240 | } | ||
241 | |||
242 | |||
243 | S32 CInputScript::GetSBits (S32 n) | ||
244 | // Get n bits from the string with sign extension. | ||
245 | { | ||
246 | // Get the number as an unsigned value. | ||
247 | S32 v = (S32) GetBits(n); | ||
248 | |||
249 | // Is the number negative? | ||
250 | if (v & (1L << (n - 1))) | ||
251 | { | ||
252 | // Yes. Extend the sign. | ||
253 | v |= -1L << n; | ||
254 | } | ||
255 | |||
256 | return v; | ||
257 | } | ||
258 | |||
259 | |||
260 | U32 CInputScript::GetBits (S32 n) | ||
261 | // Get n bits from the stream. | ||
262 | { | ||
263 | U32 v = 0; | ||
264 | |||
265 | for (;;) | ||
266 | { | ||
267 | S32 s = n - m_bitPos; | ||
268 | if (s > 0) | ||
269 | { | ||
270 | // Consume the entire buffer | ||
271 | v |= m_bitBuf << s; | ||
272 | n -= m_bitPos; | ||
273 | |||
274 | // Get the next buffer | ||
275 | m_bitBuf = GetByte(); | ||
276 | m_bitPos = 8; | ||
277 | } | ||
278 | else | ||
279 | { | ||
280 | // Consume a portion of the buffer | ||
281 | v |= m_bitBuf >> -s; | ||
282 | m_bitPos -= n; | ||
283 | m_bitBuf &= 0xff >> (8 - m_bitPos);// mask off the consumed bits | ||
284 | return v; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 | void CInputScript::ParseFreeCharacter() | ||
290 | { | ||
291 | U32 tagid = (U32) GetWord(); | ||
292 | |||
293 | tagid = tagid; | ||
294 | |||
295 | printf("tagFreeCharacter \ttagid %-5u\n", tagid); | ||
296 | } | ||
297 | |||
298 | |||
299 | void CInputScript::ParsePlaceObject() | ||
300 | { | ||
301 | Control *ctrl; | ||
302 | |||
303 | ctrl = new Control; | ||
304 | if (ctrl == NULL) { | ||
305 | outOfMemory = 1; | ||
306 | return; | ||
307 | } | ||
308 | ctrl->type = ctrlPlaceObject; | ||
309 | ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter); | ||
310 | |||
311 | ctrl->character = getCharacter(GetWord()); | ||
312 | ctrl->depth = GetWord(); | ||
313 | |||
314 | GetMatrix(&(ctrl->matrix)); | ||
315 | |||
316 | if ( m_filePos < m_tagEnd ) | ||
317 | { | ||
318 | ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform); | ||
319 | |||
320 | GetCxform(&ctrl->cxform, false); | ||
321 | } | ||
322 | |||
323 | program->addControlInCurrentFrame(ctrl); | ||
324 | } | ||
325 | |||
326 | |||
327 | void CInputScript::ParsePlaceObject2() | ||
328 | { | ||
329 | Control *ctrl; | ||
330 | |||
331 | ctrl = new Control; | ||
332 | if (ctrl == NULL) { | ||
333 | outOfMemory = 1; | ||
334 | return; | ||
335 | } | ||
336 | ctrl->type = ctrlPlaceObject2; | ||
337 | |||
338 | ctrl->flags = (PlaceFlags)GetByte(); | ||
339 | ctrl->depth = GetWord(); | ||
340 | |||
341 | // Get the tag if specified. | ||
342 | if (ctrl->flags & placeHasCharacter) | ||
343 | { | ||
344 | ctrl->character = getCharacter(GetWord()); | ||
345 | } | ||
346 | |||
347 | // Get the matrix if specified. | ||
348 | if (ctrl->flags & placeHasMatrix) | ||
349 | { | ||
350 | GetMatrix(&(ctrl->matrix)); | ||
351 | } | ||
352 | |||
353 | // Get the color transform if specified. | ||
354 | if (ctrl->flags & placeHasColorXform) | ||
355 | { | ||
356 | GetCxform(&ctrl->cxform, true); | ||
357 | } | ||
358 | |||
359 | // Get the ratio if specified. | ||
360 | if (ctrl->flags & placeHasRatio) | ||
361 | { | ||
362 | ctrl->ratio = GetWord(); | ||
363 | } | ||
364 | |||
365 | // Get the ratio if specified. | ||
366 | if (ctrl->flags & placeHasName) | ||
367 | { | ||
368 | ctrl->name = strdup(GetString()); | ||
369 | } | ||
370 | |||
371 | // Get the clipdepth if specified. | ||
372 | if (ctrl->flags & placeHasClip) | ||
373 | { | ||
374 | ctrl->clipDepth = GetWord(); | ||
375 | } | ||
376 | |||
377 | program->addControlInCurrentFrame(ctrl); | ||
378 | } | ||
379 | |||
380 | |||
381 | void CInputScript::ParseRemoveObject() | ||
382 | { | ||
383 | Control *ctrl; | ||
384 | |||
385 | ctrl = new Control; | ||
386 | if (ctrl == NULL) { | ||
387 | outOfMemory = 1; | ||
388 | return; | ||
389 | } | ||
390 | ctrl->type = ctrlRemoveObject; | ||
391 | ctrl->character = getCharacter(GetWord()); | ||
392 | ctrl->depth = GetWord(); | ||
393 | |||
394 | program->addControlInCurrentFrame(ctrl); | ||
395 | } | ||
396 | |||
397 | |||
398 | void CInputScript::ParseRemoveObject2() | ||
399 | { | ||
400 | Control *ctrl; | ||
401 | |||
402 | ctrl = new Control; | ||
403 | if (ctrl == NULL) { | ||
404 | outOfMemory = 1; | ||
405 | return; | ||
406 | } | ||
407 | ctrl->type = ctrlRemoveObject2; | ||
408 | ctrl->depth = GetWord(); | ||
409 | |||
410 | program->addControlInCurrentFrame(ctrl); | ||
411 | } | ||
412 | |||
413 | |||
414 | void CInputScript::ParseSetBackgroundColor() | ||
415 | { | ||
416 | Control *ctrl; | ||
417 | |||
418 | ctrl = new Control; | ||
419 | if (ctrl == NULL) { | ||
420 | outOfMemory = 1; | ||
421 | return; | ||
422 | } | ||
423 | ctrl->type = ctrlBackgroundColor; | ||
424 | ctrl->color.red = GetByte(); | ||
425 | ctrl->color.green = GetByte(); | ||
426 | ctrl->color.blue = GetByte(); | ||
427 | |||
428 | program->addControlInCurrentFrame(ctrl); | ||
429 | } | ||
430 | |||
431 | |||
432 | void CInputScript::ParseDoAction() | ||
433 | { | ||
434 | Control *ctrl; | ||
435 | ActionRecord *ar; | ||
436 | |||
437 | ctrl = new Control; | ||
438 | if (ctrl == NULL) { | ||
439 | outOfMemory = 1; | ||
440 | return; | ||
441 | } | ||
442 | ctrl->type = ctrlDoAction; | ||
443 | |||
444 | do { | ||
445 | ar = ParseActionRecord(); | ||
446 | if (ar) { | ||
447 | ctrl->addActionRecord( ar ); | ||
448 | } | ||
449 | if (outOfMemory) { | ||
450 | return; | ||
451 | } | ||
452 | } while (ar); | ||
453 | |||
454 | program->addControlInCurrentFrame(ctrl); | ||
455 | |||
456 | } | ||
457 | |||
458 | |||
459 | void CInputScript::ParseStartSound() | ||
460 | { | ||
461 | Control *ctrl; | ||
462 | |||
463 | ctrl = new Control; | ||
464 | if (ctrl == NULL) { | ||
465 | outOfMemory = 1; | ||
466 | return; | ||
467 | } | ||
468 | ctrl->character = getCharacter(GetWord()); | ||
469 | ctrl->type = ctrlStartSound; | ||
470 | |||
471 | program->addControlInCurrentFrame(ctrl); | ||
472 | |||
473 | if (!m_dumpAll) | ||
474 | return; | ||
475 | |||
476 | U32 code = GetByte(); | ||
477 | |||
478 | printf("code %-3u", code); | ||
479 | |||
480 | if ( code & soundHasInPoint ) | ||
481 | printf(" inpoint %u ", GetDWord()); | ||
482 | if ( code & soundHasOutPoint ) | ||
483 | printf(" oupoint %u", GetDWord()); | ||
484 | if ( code & soundHasLoops ) | ||
485 | printf(" loops %u", GetWord()); | ||
486 | |||
487 | printf("\n"); | ||
488 | if ( code & soundHasEnvelope ) | ||
489 | { | ||
490 | int points = GetByte(); | ||
491 | |||
492 | for ( int i = 0; i < points; i++ ) | ||
493 | { | ||
494 | printf("\n"); | ||
495 | printf("mark44 %u", GetDWord()); | ||
496 | printf(" left chanel %u", GetWord()); | ||
497 | printf(" right chanel %u", GetWord()); | ||
498 | printf("\n"); | ||
499 | } | ||
500 | } | ||
501 | } | ||
502 | |||
503 | |||
504 | void CInputScript::ParseStopSound() | ||
505 | { | ||
506 | Control *ctrl; | ||
507 | |||
508 | ctrl = new Control; | ||
509 | if (ctrl == NULL) { | ||
510 | outOfMemory = 1; | ||
511 | return; | ||
512 | } | ||
513 | ctrl->type = ctrlStopSound; | ||
514 | |||
515 | program->addControlInCurrentFrame(ctrl); | ||
516 | } | ||
517 | |||
518 | |||
519 | void CInputScript::ParseShapeData(int getAlpha, int getStyles) | ||
520 | { | ||
521 | int shapeRecord = 0; | ||
522 | |||
523 | if (getStyles) { | ||
524 | // ShapeWithStyle | ||
525 | ParseFillStyle(getAlpha); | ||
526 | ParseLineStyle(getAlpha); | ||
527 | } | ||
528 | |||
529 | InitBits(); | ||
530 | m_nFillBits = (U16) GetBits(4); | ||
531 | m_nLineBits = (U16) GetBits(4); | ||
532 | |||
533 | do { | ||
534 | shapeRecord = ParseShapeRecord(getAlpha); | ||
535 | } while (shapeRecord); | ||
536 | } | ||
537 | |||
538 | int | ||
539 | CInputScript::ParseShapeRecord(long getAlpha) | ||
540 | { | ||
541 | // Determine if this is an edge. | ||
542 | BOOL isEdge = (BOOL) GetBits(1); | ||
543 | |||
544 | if (!isEdge) | ||
545 | { | ||
546 | // Handle a state change | ||
547 | U16 flags = (U16) GetBits(5); | ||
548 | |||
549 | // Are we at the end? | ||
550 | if (flags == 0) | ||
551 | { | ||
552 | // End of shape | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | // Process a move to. | ||
557 | if (flags & flagsMoveTo) | ||
558 | { | ||
559 | U16 nBits = (U16) GetBits(5); | ||
560 | GetSBits(nBits); | ||
561 | GetSBits(nBits); | ||
562 | } | ||
563 | |||
564 | // Get new fill info. | ||
565 | if (flags & flagsFill0) | ||
566 | { | ||
567 | GetBits(m_nFillBits); | ||
568 | } | ||
569 | if (flags & flagsFill1) | ||
570 | { | ||
571 | GetBits(m_nFillBits); | ||
572 | } | ||
573 | |||
574 | // Get new line info | ||
575 | if (flags & flagsLine) | ||
576 | { | ||
577 | GetBits(m_nLineBits); | ||
578 | } | ||
579 | |||
580 | // Check to get a new set of styles for a new shape layer. | ||
581 | if (flags & flagsNewStyles) | ||
582 | { | ||
583 | // Parse the style. | ||
584 | ParseFillStyle(getAlpha); | ||
585 | ParseLineStyle(getAlpha); | ||
586 | |||
587 | InitBits();// Bug ! | ||
588 | |||
589 | // Reset. | ||
590 | m_nFillBits = (U16) GetBits(4); | ||
591 | m_nLineBits = (U16) GetBits(4); | ||
592 | } | ||
593 | |||
594 | return flags & flagsEndShape ? 0 : 1; | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | if (GetBits(1)) | ||
599 | { | ||
600 | // Handle a line | ||
601 | U16 nBits = (U16) GetBits(4) + 2;// nBits is biased by 2 | ||
602 | |||
603 | // Save the deltas | ||
604 | if (GetBits(1)) | ||
605 | { | ||
606 | // Handle a general line. | ||
607 | GetSBits(nBits); | ||
608 | GetSBits(nBits); | ||
609 | } | ||
610 | else | ||
611 | { | ||
612 | // Handle a vert or horiz line. | ||
613 | GetBits(1); | ||
614 | GetSBits(nBits); | ||
615 | } | ||
616 | } | ||
617 | else | ||
618 | { | ||
619 | // Handle a curve | ||
620 | U16 nBits = (U16) GetBits(4) + 2;// nBits is biased by 2 | ||
621 | |||
622 | // Get the control | ||
623 | GetSBits(nBits); | ||
624 | GetSBits(nBits); | ||
625 | |||
626 | // Get the anchor | ||
627 | GetSBits(nBits); | ||
628 | GetSBits(nBits); | ||
629 | } | ||
630 | |||
631 | return 1; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | |||
636 | void CInputScript::ParseFillStyle(long getAlpha) | ||
637 | // | ||
638 | { | ||
639 | U16 i = 0; | ||
640 | FillType type; | ||
641 | Matrix matrix; | ||
642 | |||
643 | // Get the number of fills. | ||
644 | U16 nFills = GetByte(); | ||
645 | |||
646 | // Do we have a larger number? | ||
647 | if (nFills == 255) | ||
648 | { | ||
649 | // Get the larger number. | ||
650 | nFills = GetWord(); | ||
651 | } | ||
652 | |||
653 | // Get each of the fill style. | ||
654 | for (i = 0; i < nFills; i++) | ||
655 | { | ||
656 | U16 fillStyle = GetByte(); | ||
657 | |||
658 | type = (FillType) fillStyle; | ||
659 | |||
660 | printf("fillstyle: type=%d\n",defs[i].type); | ||
661 | if (fillStyle & 0x10) | ||
662 | { | ||
663 | U16 nbGradients; | ||
664 | |||
665 | type = (FillType) (fillStyle & 0x12); | ||
666 | |||
667 | // Get the gradient matrix. | ||
668 | GetMatrix(&matrix); | ||
669 | |||
670 | // Get the number of colors. | ||
671 | nbGradients = GetByte(); | ||
672 | |||
673 | // Get each of the colors. | ||
674 | for (U16 j = 0; j < nbGradients; j++) | ||
675 | { | ||
676 | GetByte(); | ||
677 | GetByte(); | ||
678 | GetByte(); | ||
679 | GetByte(); | ||
680 | if (getAlpha) { | ||
681 | GetByte(); | ||
682 | } | ||
683 | } | ||
684 | } | ||
685 | else if (fillStyle & 0x40) | ||
686 | { | ||
687 | type = (FillType) (fillStyle & 0x41); | ||
688 | |||
689 | // Get the bitmapId | ||
690 | GetWord(); | ||
691 | |||
692 | // Get the bitmap matrix. | ||
693 | GetMatrix(&matrix); | ||
694 | } | ||
695 | else | ||
696 | { | ||
697 | type = (FillType) 0; | ||
698 | |||
699 | // A solid color | ||
700 | GetByte(); | ||
701 | GetByte(); | ||
702 | GetByte(); | ||
703 | if (getAlpha) { | ||
704 | GetByte(); | ||
705 | } | ||
706 | |||
707 | printf("fillstyle: %x %x %x %x\n", | ||
708 | defs[i].color.red, | ||
709 | defs[i].color.green, | ||
710 | defs[i].color.blue, | ||
711 | defs[i].color.alpha); | ||
712 | } | ||
713 | } | ||
714 | } | ||
715 | |||
716 | void CInputScript::ParseLineStyle(long getAlpha) | ||
717 | { | ||
718 | long i; | ||
719 | |||
720 | // Get the number of lines. | ||
721 | U16 nLines = GetByte(); | ||
722 | |||
723 | // Do we have a larger number? | ||
724 | if (nLines == 255) | ||
725 | { | ||
726 | // Get the larger number. | ||
727 | nLines = GetWord(); | ||
728 | } | ||
729 | |||
730 | // Get each of the line styles. | ||
731 | for (i = 0; i < nLines; i++) | ||
732 | { | ||
733 | GetWord(); | ||
734 | GetByte(); | ||
735 | GetByte(); | ||
736 | GetByte(); | ||
737 | if (getAlpha) { | ||
738 | GetByte(); | ||
739 | } | ||
740 | } | ||
741 | } | ||
742 | |||
743 | |||
744 | void CInputScript::ParseDefineShape(int level) | ||
745 | { | ||
746 | Shape *shape; | ||
747 | Rect rect; | ||
748 | U32 tagid; | ||
749 | |||
750 | tagid = (U32) GetWord(); | ||
751 | shape = new Shape(tagid,level); | ||
752 | if (shape == NULL) { | ||
753 | outOfMemory = 1; | ||
754 | return; | ||
755 | } | ||
756 | shape->dict = this; | ||
757 | |||
758 | // Get the frame information. | ||
759 | GetRect(&rect); | ||
760 | |||
761 | shape->setBoundingBox(rect); | ||
762 | |||
763 | shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos); | ||
764 | if (shape->file_ptr == NULL) { | ||
765 | outOfMemory = 1; | ||
766 | delete shape; | ||
767 | return; | ||
768 | } | ||
769 | memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos); | ||
770 | |||
771 | shape->getStyles = 1; | ||
772 | shape->getAlpha = (level == 3); | ||
773 | |||
774 | ParseShapeData(level == 3, 1); | ||
775 | |||
776 | addCharacter(shape); | ||
777 | } | ||
778 | |||
779 | void CInputScript::S_DumpImageGuts() | ||
780 | { | ||
781 | #if 0 | ||
782 | U32 lfCount = 0; | ||
783 | printf("----- dumping image details -----"); | ||
784 | while (m_filePos < m_tagEnd) | ||
785 | { | ||
786 | if ((lfCount % 16) == 0) | ||
787 | { | ||
788 | fprintf(stdout, "\n"); | ||
789 | } | ||
790 | lfCount += 1; | ||
791 | fprintf(stdout, "%02x ", GetByte()); | ||
792 | } | ||
793 | fprintf(stdout, "\n"); | ||
794 | #endif | ||
795 | } | ||
796 | |||
797 | void CInputScript::ParseDefineBits() | ||
798 | { | ||
799 | Bitmap *bitmap; | ||
800 | U32 tagid = (U32) GetWord(); | ||
801 | int status; | ||
802 | |||
803 | bitmap = new Bitmap(tagid,1); | ||
804 | if (bitmap == NULL) { | ||
805 | outOfMemory = 1; | ||
806 | return; | ||
807 | } | ||
808 | |||
809 | status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]); | ||
810 | |||
811 | if (status < 0) { | ||
812 | fprintf(stderr,"Unable to read JPEG data\n"); | ||
813 | delete bitmap; | ||
814 | return; | ||
815 | } | ||
816 | |||
817 | addCharacter(bitmap); | ||
818 | } | ||
819 | |||
820 | |||
821 | void CInputScript::ParseDefineBitsJPEG2() | ||
822 | { | ||
823 | Bitmap *bitmap; | ||
824 | U32 tagid = (U32) GetWord(); | ||
825 | int status; | ||
826 | |||
827 | bitmap = new Bitmap(tagid,2); | ||
828 | if (bitmap == NULL) { | ||
829 | outOfMemory = 1; | ||
830 | return; | ||
831 | } | ||
832 | |||
833 | status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0); | ||
834 | |||
835 | if (status < 0) { | ||
836 | fprintf(stderr,"Unable to read JPEG data\n"); | ||
837 | delete bitmap; | ||
838 | return; | ||
839 | } | ||
840 | |||
841 | addCharacter(bitmap); | ||
842 | } | ||
843 | |||
844 | void CInputScript::ParseDefineBitsJPEG3() | ||
845 | { | ||
846 | Bitmap *bitmap; | ||
847 | U32 tagid = (U32) GetWord(); | ||
848 | int status; | ||
849 | long offset; | ||
850 | |||
851 | printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid); | ||
852 | |||
853 | bitmap = new Bitmap(tagid,3); | ||
854 | if (bitmap == NULL) { | ||
855 | outOfMemory = 1; | ||
856 | return; | ||
857 | } | ||
858 | |||
859 | offset = GetDWord();// Not in the specs !!!! | ||
860 | |||
861 | status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset); | ||
862 | if (status < 0) { | ||
863 | fprintf(stderr,"Unable to read JPEG data\n"); | ||
864 | delete bitmap; | ||
865 | return; | ||
866 | } | ||
867 | |||
868 | addCharacter(bitmap); | ||
869 | } | ||
870 | |||
871 | |||
872 | void CInputScript::ParseDefineBitsLossless(int level) | ||
873 | { | ||
874 | Bitmap *bitmap; | ||
875 | U32 tagid = (U32) GetWord(); | ||
876 | int status; | ||
877 | int tableSize; | ||
878 | |||
879 | bitmap = new Bitmap(tagid,0); | ||
880 | if (bitmap == NULL) { | ||
881 | outOfMemory = 1; | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | int format = GetByte(); | ||
886 | int width = GetWord(); | ||
887 | int height = GetWord(); | ||
888 | |||
889 | tableSize = 0; | ||
890 | |||
891 | if (format == 3) { | ||
892 | tableSize = GetByte(); | ||
893 | } | ||
894 | |||
895 | status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2); | ||
896 | |||
897 | if (status < 0) { | ||
898 | fprintf(stderr,"Unable to read ZLIB data\n"); | ||
899 | delete bitmap; | ||
900 | return; | ||
901 | } | ||
902 | |||
903 | addCharacter(bitmap); | ||
904 | } | ||
905 | |||
906 | void CInputScript::ParseJPEGTables() | ||
907 | { | ||
908 | Bitmap::readJpegTables(&m_fileBuf[m_filePos]); | ||
909 | } | ||
910 | |||
911 | |||
912 | ButtonRecord * CInputScript::ParseButtonRecord(long getCxform) | ||
913 | { | ||
914 | U16 state; | ||
915 | ButtonRecord *br; | ||
916 | long tagid; | ||
917 | Matrix matrix; | ||
918 | long layer; | ||
919 | Cxform *cxform; | ||
920 | |||
921 | state = (U16) GetByte(); | ||
922 | |||
923 | if (state == 0) return 0; | ||
924 | |||
925 | br = new ButtonRecord; | ||
926 | if (br == NULL) { | ||
927 | outOfMemory = 1; | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | tagid = GetWord(); | ||
932 | layer = GetWord(); | ||
933 | GetMatrix(&matrix); | ||
934 | |||
935 | if (br) { | ||
936 | br->state = (ButtonState) state; | ||
937 | br->character = getCharacter(tagid); | ||
938 | br->layer = layer; | ||
939 | br->cxform = 0; | ||
940 | br->buttonMatrix = matrix; | ||
941 | } | ||
942 | |||
943 | if (getCxform) { | ||
944 | cxform = new Cxform; | ||
945 | GetCxform(cxform, true); | ||
946 | if (br) { | ||
947 | br->cxform = cxform; | ||
948 | if (cxform == NULL) { | ||
949 | outOfMemory = 1; | ||
950 | } | ||
951 | } | ||
952 | } | ||
953 | |||
954 | return br; | ||
955 | } | ||
956 | |||
957 | ActionRecord * CInputScript::ParseActionRecord() | ||
958 | { | ||
959 | U8 action; | ||
960 | U16 length = 0; | ||
961 | char *url, *target, *label; | ||
962 | long frameIndex, skipCount; | ||
963 | ActionRecord *ar; | ||
964 | |||
965 | action = GetByte(); | ||
966 | if (action == 0) return 0; | ||
967 | |||
968 | ar = new ActionRecord; | ||
969 | if (ar == NULL) { | ||
970 | outOfMemory = 1; | ||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | ar->action = (Action)action; | ||
975 | |||
976 | if (action & 0x80) { | ||
977 | length = GetWord(); | ||
978 | } | ||
979 | |||
980 | switch (action) { | ||
981 | case ActionGotoFrame: | ||
982 | frameIndex = GetWord(); | ||
983 | if (ar) { | ||
984 | ar->frameIndex = frameIndex; | ||
985 | } | ||
986 | break; | ||
987 | case ActionGetURL: | ||
988 | url = GetString(); | ||
989 | target = GetString(); | ||
990 | if (ar) { | ||
991 | ar->url = strdup(url); | ||
992 | ar->target = strdup(target); | ||
993 | } | ||
994 | break; | ||
995 | case ActionWaitForFrame: | ||
996 | frameIndex = GetWord(); | ||
997 | skipCount = GetByte(); | ||
998 | if (ar) { | ||
999 | ar->frameIndex = frameIndex; | ||
1000 | ar->skipCount = skipCount; | ||
1001 | } | ||
1002 | break; | ||
1003 | case ActionSetTarget: | ||
1004 | target = strdup(GetString()); | ||
1005 | if (ar) { | ||
1006 | ar->target = target; | ||
1007 | } | ||
1008 | break; | ||
1009 | case ActionGoToLabel: | ||
1010 | label = GetString(); | ||
1011 | if (ar) { | ||
1012 | ar->frameLabel = strdup(label); | ||
1013 | } | ||
1014 | break; | ||
1015 | default: | ||
1016 | while (length--) { | ||
1017 | GetByte(); | ||
1018 | } | ||
1019 | break; | ||
1020 | } | ||
1021 | |||
1022 | return ar; | ||
1023 | } | ||
1024 | |||
1025 | void CInputScript::ParseDefineButton() | ||
1026 | { | ||
1027 | Button *button; | ||
1028 | ButtonRecord*buttonRecord; | ||
1029 | ActionRecord*actionRecord; | ||
1030 | |||
1031 | U32 tagid = (U32) GetWord(); | ||
1032 | |||
1033 | button = new Button(tagid); | ||
1034 | if (button == NULL) { | ||
1035 | outOfMemory = 1; | ||
1036 | return; | ||
1037 | } | ||
1038 | |||
1039 | do { | ||
1040 | buttonRecord = ParseButtonRecord(); | ||
1041 | if (buttonRecord) { | ||
1042 | button->addButtonRecord( buttonRecord ); | ||
1043 | } | ||
1044 | if (outOfMemory) { | ||
1045 | return; | ||
1046 | } | ||
1047 | } while (buttonRecord); | ||
1048 | |||
1049 | do { | ||
1050 | actionRecord = ParseActionRecord(); | ||
1051 | if (actionRecord) { | ||
1052 | button->addActionRecord( actionRecord ); | ||
1053 | } | ||
1054 | if (outOfMemory) { | ||
1055 | return; | ||
1056 | } | ||
1057 | } while (actionRecord); | ||
1058 | |||
1059 | addCharacter(button); | ||
1060 | } | ||
1061 | |||
1062 | |||
1063 | void CInputScript::ParseDefineButton2() | ||
1064 | { | ||
1065 | Button *button; | ||
1066 | ButtonRecord*buttonRecord; | ||
1067 | ActionRecord*actionRecord; | ||
1068 | U16 transition; | ||
1069 | U16 offset; | ||
1070 | U8 menu; | ||
1071 | |||
1072 | U32 tagid = (U32) GetWord(); | ||
1073 | |||
1074 | button = new Button(tagid); | ||
1075 | |||
1076 | if (button == NULL) { | ||
1077 | outOfMemory = 1; | ||
1078 | return; | ||
1079 | } | ||
1080 | |||
1081 | menu = GetByte(); | ||
1082 | |||
1083 | offset = GetWord(); | ||
1084 | |||
1085 | do { | ||
1086 | buttonRecord = ParseButtonRecord(true); | ||
1087 | if (buttonRecord) { | ||
1088 | button->addButtonRecord( buttonRecord ); | ||
1089 | } | ||
1090 | if (outOfMemory) { | ||
1091 | return; | ||
1092 | } | ||
1093 | } while (buttonRecord); | ||
1094 | |||
1095 | while (offset) { | ||
1096 | offset = GetWord(); | ||
1097 | |||
1098 | transition = GetWord(); | ||
1099 | |||
1100 | do { | ||
1101 | actionRecord = ParseActionRecord(); | ||
1102 | if (actionRecord) { | ||
1103 | button->addActionRecord( actionRecord ); | ||
1104 | } | ||
1105 | if (outOfMemory) { | ||
1106 | return; | ||
1107 | } | ||
1108 | } while (actionRecord); | ||
1109 | |||
1110 | button->addCondition( transition ); | ||
1111 | } | ||
1112 | |||
1113 | addCharacter(button); | ||
1114 | } | ||
1115 | |||
1116 | |||
1117 | void CInputScript::ParseDefineFont() | ||
1118 | { | ||
1119 | SwfFont*font = 0; | ||
1120 | U32 tagid = (U32) GetWord(); | ||
1121 | long start; | ||
1122 | long nb,n; | ||
1123 | long offset; | ||
1124 | long*offsetTable = 0; | ||
1125 | Shape*shapes = 0; | ||
1126 | |||
1127 | font = new SwfFont(tagid); | ||
1128 | if (font == NULL) { | ||
1129 | outOfMemory = 1; | ||
1130 | return; | ||
1131 | } | ||
1132 | start = m_filePos; | ||
1133 | |||
1134 | offset = GetWord(); | ||
1135 | nb = offset/2; | ||
1136 | offsetTable = new long[nb]; | ||
1137 | if (offsetTable == NULL) { | ||
1138 | goto memory_error; | ||
1139 | } | ||
1140 | offsetTable[0] = offset; | ||
1141 | |||
1142 | for(n=1; n<nb; n++) | ||
1143 | { | ||
1144 | offsetTable[n] = GetWord(); | ||
1145 | } | ||
1146 | |||
1147 | shapes = new Shape[nb]; | ||
1148 | if (shapes == NULL) { | ||
1149 | goto memory_error; | ||
1150 | } | ||
1151 | |||
1152 | for(n=0; n<nb; n++) | ||
1153 | { | ||
1154 | long here; | ||
1155 | |||
1156 | m_filePos = offsetTable[n]+start; | ||
1157 | |||
1158 | here = m_filePos; | ||
1159 | ParseShapeData(0, 0); | ||
1160 | |||
1161 | // Keep data for later parsing | ||
1162 | shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here); | ||
1163 | if (shapes[n].file_ptr == NULL) { | ||
1164 | goto memory_error; | ||
1165 | } | ||
1166 | memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here); | ||
1167 | } | ||
1168 | |||
1169 | font->setFontShapeTable(shapes,nb); | ||
1170 | |||
1171 | delete[] offsetTable; | ||
1172 | |||
1173 | addCharacter(font); | ||
1174 | return; | ||
1175 | |||
1176 | memory_error: | ||
1177 | outOfMemory = 1; | ||
1178 | if (offsetTable) delete offsetTable; | ||
1179 | if (font) delete font; | ||
1180 | if (shapes) delete[] shapes; | ||
1181 | } | ||
1182 | |||
1183 | |||
1184 | void CInputScript::ParseDefineMorphShape() | ||
1185 | { | ||
1186 | U32 tagid = (U32) GetWord(); | ||
1187 | |||
1188 | tagid = tagid; | ||
1189 | printf("tagDefineMorphShape \ttagid %-5u\n", tagid); | ||
1190 | } | ||
1191 | |||
1192 | void CInputScript::ParseDefineFontInfo() | ||
1193 | { | ||
1194 | SwfFont*font; | ||
1195 | U32 tagid = (U32) GetWord(); | ||
1196 | long nameLen; | ||
1197 | char*name; | ||
1198 | long n,nb; | ||
1199 | FontFlags flags; | ||
1200 | long*lut; | ||
1201 | |||
1202 | font = (SwfFont *)getCharacter(tagid); | ||
1203 | |||
1204 | if (font == NULL) { | ||
1205 | outOfMemory = 1; | ||
1206 | return; | ||
1207 | } | ||
1208 | |||
1209 | nameLen = GetByte(); | ||
1210 | name = new char[nameLen+1]; | ||
1211 | if (name == NULL) { | ||
1212 | outOfMemory = 1; | ||
1213 | return; | ||
1214 | } | ||
1215 | for(n=0; n < nameLen; n++) | ||
1216 | { | ||
1217 | name[n] = GetByte(); | ||
1218 | } | ||
1219 | name[n]=0; | ||
1220 | |||
1221 | font->setFontName(name); | ||
1222 | |||
1223 | delete name; | ||
1224 | |||
1225 | flags = (FontFlags)GetByte(); | ||
1226 | |||
1227 | font->setFontFlags(flags); | ||
1228 | |||
1229 | nb = font->getNbGlyphs(); | ||
1230 | |||
1231 | lut = new long[nb]; | ||
1232 | if (lut == NULL) { | ||
1233 | outOfMemory = 1; | ||
1234 | delete font; | ||
1235 | return; | ||
1236 | } | ||
1237 | |||
1238 | for(n=0; n < nb; n++) | ||
1239 | { | ||
1240 | if (flags & fontWideCodes) { | ||
1241 | lut[n] = GetWord(); | ||
1242 | } else { | ||
1243 | lut[n] = GetByte(); | ||
1244 | } | ||
1245 | } | ||
1246 | |||
1247 | font->setFontLookUpTable(lut); | ||
1248 | } | ||
1249 | |||
1250 | |||
1251 | |||
1252 | |||
1253 | |||
1254 | void CInputScript::ParseDefineFont2() | ||
1255 | { | ||
1256 | int n; | ||
1257 | U32 tagid = (U32) GetWord(); | ||
1258 | FontFlags flags; | ||
1259 | char *name; | ||
1260 | long nameLen; | ||
1261 | long fontGlyphCount; | ||
1262 | long *offsetTable = NULL; | ||
1263 | Shape *shapes = NULL; | ||
1264 | long start; | ||
1265 | SwfFont *font; | ||
1266 | long *lut = NULL; | ||
1267 | |||
1268 | font = new SwfFont(tagid); | ||
1269 | if (font == NULL) { | ||
1270 | goto memory_error; | ||
1271 | } | ||
1272 | |||
1273 | flags = (FontFlags)GetWord(); | ||
1274 | |||
1275 | font->setFontFlags(flags); | ||
1276 | |||
1277 | nameLen = GetByte(); | ||
1278 | name = new char[nameLen+1]; | ||
1279 | if (name == NULL) { | ||
1280 | goto memory_error; | ||
1281 | } | ||
1282 | for(n=0; n < nameLen; n++) | ||
1283 | { | ||
1284 | name[n] = GetByte(); | ||
1285 | } | ||
1286 | name[n]=0; | ||
1287 | |||
1288 | font->setFontName(name); | ||
1289 | |||
1290 | delete name; | ||
1291 | |||
1292 | fontGlyphCount = GetWord(); | ||
1293 | |||
1294 | start = m_filePos; | ||
1295 | |||
1296 | offsetTable = new long[fontGlyphCount]; | ||
1297 | if (offsetTable == NULL) { | ||
1298 | goto memory_error; | ||
1299 | } | ||
1300 | for (n=0; n<fontGlyphCount; n++) { | ||
1301 | if (flags & 8) { | ||
1302 | offsetTable[n] = GetDWord(); | ||
1303 | } else { | ||
1304 | offsetTable[n] = GetWord(); | ||
1305 | } | ||
1306 | } | ||
1307 | |||
1308 | shapes = new Shape[fontGlyphCount]; | ||
1309 | if (shapes == NULL) { | ||
1310 | goto memory_error; | ||
1311 | } | ||
1312 | |||
1313 | for (n=0; n<fontGlyphCount; n++) { | ||
1314 | long here; | ||
1315 | |||
1316 | m_filePos = offsetTable[n]+start; | ||
1317 | |||
1318 | here = m_filePos; | ||
1319 | ParseShapeData(0, 0); | ||
1320 | |||
1321 | // Keep data for later parsing | ||
1322 | shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here); | ||
1323 | if (shapes[n].file_ptr == NULL) { | ||
1324 | goto memory_error; | ||
1325 | } | ||
1326 | memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here); | ||
1327 | } | ||
1328 | |||
1329 | font->setFontShapeTable(shapes,fontGlyphCount); | ||
1330 | |||
1331 | lut = new long[fontGlyphCount]; | ||
1332 | if (lut == NULL) { | ||
1333 | goto memory_error; | ||
1334 | } | ||
1335 | |||
1336 | for(n=0; n < fontGlyphCount; n++) | ||
1337 | { | ||
1338 | if (flags & 4) { | ||
1339 | lut[n] = GetWord(); | ||
1340 | } else { | ||
1341 | lut[n] = GetByte(); | ||
1342 | } | ||
1343 | } | ||
1344 | |||
1345 | font->setFontLookUpTable(lut); | ||
1346 | |||
1347 | delete offsetTable; | ||
1348 | |||
1349 | addCharacter(font); | ||
1350 | |||
1351 | // This is an incomplete parsing | ||
1352 | return; | ||
1353 | |||
1354 | memory_error: | ||
1355 | outOfMemory = 1; | ||
1356 | if (font) delete font; | ||
1357 | if (offsetTable) delete offsetTable; | ||
1358 | if (lut) delete lut; | ||
1359 | if (shapes) delete[] shapes; | ||
1360 | } | ||
1361 | |||
1362 | TextRecord * CInputScript::ParseTextRecord(int hasAlpha) | ||
1363 | { | ||
1364 | TextRecord *tr; | ||
1365 | TextFlags flags; | ||
1366 | |||
1367 | flags = (TextFlags) GetByte(); | ||
1368 | if (flags == 0) return 0; | ||
1369 | |||
1370 | tr = new TextRecord; | ||
1371 | if (tr == NULL) { | ||
1372 | outOfMemory = 1; | ||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | tr->flags = flags; | ||
1377 | |||
1378 | if (flags & isTextControl) { | ||
1379 | if (flags & textHasFont) { | ||
1380 | long fontId; | ||
1381 | |||
1382 | fontId = GetWord(); | ||
1383 | tr->font = (SwfFont *)getCharacter(fontId); | ||
1384 | } | ||
1385 | if (flags & textHasColor) { | ||
1386 | tr->color.red = GetByte(); | ||
1387 | tr->color.green = GetByte(); | ||
1388 | tr->color.blue = GetByte(); | ||
1389 | if (hasAlpha) { | ||
1390 | tr->color.alpha = GetByte(); | ||
1391 | } else { | ||
1392 | tr->color.alpha = ALPHA_OPAQUE; | ||
1393 | } | ||
1394 | } | ||
1395 | if (flags & textHasXOffset) { | ||
1396 | tr->xOffset = GetWord(); | ||
1397 | } | ||
1398 | if (flags & textHasYOffset) { | ||
1399 | tr->yOffset = GetWord(); | ||
1400 | } | ||
1401 | if (flags & textHasFont) { | ||
1402 | tr->fontHeight = GetWord(); | ||
1403 | } | ||
1404 | tr->nbGlyphs = GetByte(); | ||
1405 | } else { | ||
1406 | tr->flags = (TextFlags)0; | ||
1407 | tr->nbGlyphs = (long)flags; | ||
1408 | } | ||
1409 | |||
1410 | tr->glyphs = new Glyph[ tr->nbGlyphs ]; | ||
1411 | if (tr->glyphs == NULL) { | ||
1412 | outOfMemory = 1; | ||
1413 | delete tr; | ||
1414 | return 0; | ||
1415 | } | ||
1416 | |||
1417 | InitBits(); | ||
1418 | for (int g = 0; g < tr->nbGlyphs; g++) | ||
1419 | { | ||
1420 | tr->glyphs[g].index = GetBits(m_nGlyphBits); | ||
1421 | tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits); | ||
1422 | } | ||
1423 | |||
1424 | return tr; | ||
1425 | } | ||
1426 | |||
1427 | void CInputScript::ParseDefineText(int hasAlpha) | ||
1428 | { | ||
1429 | Text *text; | ||
1430 | TextRecord*textRecord; | ||
1431 | Matrix m; | ||
1432 | Rect rect; | ||
1433 | U32 tagid = (U32) GetWord(); | ||
1434 | |||
1435 | text = new Text(tagid); | ||
1436 | if (text == NULL) { | ||
1437 | outOfMemory = 1; | ||
1438 | return; | ||
1439 | } | ||
1440 | |||
1441 | GetRect(&rect); | ||
1442 | text->setTextBoundary(rect); | ||
1443 | |||
1444 | GetMatrix(&m); | ||
1445 | text->setTextMatrix(m); | ||
1446 | |||
1447 | m_nGlyphBits = GetByte(); | ||
1448 | m_nAdvanceBits = GetByte(); | ||
1449 | |||
1450 | do { | ||
1451 | textRecord = ParseTextRecord(hasAlpha); | ||
1452 | if (textRecord) { | ||
1453 | text->addTextRecord( textRecord ); | ||
1454 | } | ||
1455 | if (outOfMemory) { | ||
1456 | delete text; | ||
1457 | return; | ||
1458 | } | ||
1459 | if (m_filePos >= m_tagEnd) break; | ||
1460 | } while (textRecord); | ||
1461 | |||
1462 | addCharacter(text); | ||
1463 | } | ||
1464 | |||
1465 | |||
1466 | void CInputScript::ParseDefineSound() | ||
1467 | { | ||
1468 | Sound *sound; | ||
1469 | U32 tagid = (U32) GetWord(); | ||
1470 | long nbSamples; | ||
1471 | long flags; | ||
1472 | char *buffer; | ||
1473 | |||
1474 | sound = new Sound(tagid); | ||
1475 | |||
1476 | flags = GetByte(); | ||
1477 | sound->setSoundFlags(flags); | ||
1478 | |||
1479 | nbSamples = GetDWord(); | ||
1480 | buffer = sound->setNbSamples(nbSamples); | ||
1481 | if (buffer == NULL) { | ||
1482 | outOfMemory = 1; | ||
1483 | delete sound; | ||
1484 | return; | ||
1485 | } | ||
1486 | |||
1487 | if (flags & soundIsADPCMCompressed) { | ||
1488 | Adpcm *adpcm; | ||
1489 | |||
1490 | adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo ); | ||
1491 | |||
1492 | adpcm->Decompress((short *)buffer, nbSamples); | ||
1493 | |||
1494 | delete adpcm; | ||
1495 | } else { | ||
1496 | memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5); | ||
1497 | } | ||
1498 | |||
1499 | addCharacter(sound); | ||
1500 | } | ||
1501 | |||
1502 | |||
1503 | void CInputScript::ParseDefineButtonSound() | ||
1504 | { | ||
1505 | U32 tagid = (U32) GetWord(); | ||
1506 | Button*button; | ||
1507 | |||
1508 | tagid = tagid; | ||
1509 | |||
1510 | printf("tagDefineButtonSound \ttagid %-5u\n", tagid); | ||
1511 | |||
1512 | button = (Button *)getCharacter(tagid); | ||
1513 | |||
1514 | if (button == 0) { | ||
1515 | printf("Couldn't find Button id %d\n", tagid); | ||
1516 | return; | ||
1517 | } | ||
1518 | |||
1519 | // step through for button states | ||
1520 | for (int i = 0; i < 4; i++) | ||
1521 | { | ||
1522 | Sound*sound; | ||
1523 | U32 soundTag = GetWord(); | ||
1524 | |||
1525 | sound = (Sound *)getCharacter(soundTag); | ||
1526 | |||
1527 | if (sound) { | ||
1528 | button->setButtonSound(sound,i); | ||
1529 | } else if (soundTag) { | ||
1530 | printf("Couldn't find Sound id %d\n", soundTag); | ||
1531 | } | ||
1532 | |||
1533 | switch (i) | ||
1534 | { | ||
1535 | case 0: | ||
1536 | printf("upState \ttagid %-5u\n", soundTag); | ||
1537 | break; | ||
1538 | case 1: | ||
1539 | printf("overState \ttagid %-5u\n", soundTag); | ||
1540 | break; | ||
1541 | case 2: | ||
1542 | printf("downState \ttagid %-5u\n", soundTag); | ||
1543 | break; | ||
1544 | } | ||
1545 | |||
1546 | if (soundTag) | ||
1547 | { | ||
1548 | U32 code = GetByte(); | ||
1549 | printf("sound code %u", code); | ||
1550 | |||
1551 | if ( code & soundHasInPoint ) | ||
1552 | printf(" inpoint %u", GetDWord()); | ||
1553 | if ( code & soundHasOutPoint ) | ||
1554 | printf(" outpoint %u", GetDWord()); | ||
1555 | if ( code & soundHasLoops ) | ||
1556 | printf(" loops %u", GetWord()); | ||
1557 | |||
1558 | printf("\n"); | ||
1559 | if ( code & soundHasEnvelope ) | ||
1560 | { | ||
1561 | int points = GetByte(); | ||
1562 | |||
1563 | for ( int p = 0; p < points; p++ ) | ||
1564 | { | ||
1565 | printf("\n"); | ||
1566 | printf("mark44 %u", GetDWord()); | ||
1567 | printf(" left chanel %u", GetWord()); | ||
1568 | printf(" right chanel %u", GetWord()); | ||
1569 | printf("\n"); | ||
1570 | } | ||
1571 | } | ||
1572 | } | ||
1573 | if (m_filePos == m_tagEnd) break; | ||
1574 | } | ||
1575 | } | ||
1576 | |||
1577 | void CInputScript::ParseSoundStreamHead() | ||
1578 | { | ||
1579 | int mixFormat = GetByte(); | ||
1580 | |||
1581 | // The stream settings | ||
1582 | int format = GetByte(); | ||
1583 | int nSamples = GetWord(); | ||
1584 | |||
1585 | mixFormat = mixFormat; | ||
1586 | format = format; | ||
1587 | nSamples = nSamples; | ||
1588 | |||
1589 | printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples); | ||
1590 | } | ||
1591 | |||
1592 | void CInputScript::ParseSoundStreamHead2() | ||
1593 | { | ||
1594 | int mixFormat = GetByte(); | ||
1595 | |||
1596 | // The stream settings | ||
1597 | int format = GetByte(); | ||
1598 | int nSamples = GetWord(); | ||
1599 | |||
1600 | mixFormat = mixFormat; | ||
1601 | format = format; | ||
1602 | nSamples = nSamples; | ||
1603 | |||
1604 | //printf("tagSoundStreamHead2 \tmixFormat %-3u format %-3u nSamples %-5u\n", mixFormat, format, nSamples); | ||
1605 | } | ||
1606 | |||
1607 | void CInputScript::ParseSoundStreamBlock() | ||
1608 | { | ||
1609 | printf("tagSoundStreamBlock\n"); | ||
1610 | } | ||
1611 | |||
1612 | void CInputScript::ParseDefineButtonCxform() | ||
1613 | { | ||
1614 | ButtonRecord *br; | ||
1615 | Button*button; | ||
1616 | U32 tagid = (U32) GetWord(); | ||
1617 | |||
1618 | button = (Button *)getCharacter(tagid); | ||
1619 | |||
1620 | for (br = button->getButtonRecords(); br; br = br->next) | ||
1621 | { | ||
1622 | br->cxform = new Cxform; | ||
1623 | GetCxform(br->cxform, false); | ||
1624 | } | ||
1625 | } | ||
1626 | |||
1627 | void CInputScript::ParseNameCharacter() | ||
1628 | { | ||
1629 | U32 tagid = (U32) GetWord(); | ||
1630 | char *label = strdup(GetString()); | ||
1631 | |||
1632 | nameCharacter(tagid, label); | ||
1633 | } | ||
1634 | |||
1635 | |||
1636 | void CInputScript::ParseFrameLabel() | ||
1637 | { | ||
1638 | char *label = strdup(GetString()); | ||
1639 | program->setCurrentFrameLabel(label); | ||
1640 | } | ||
1641 | |||
1642 | |||
1643 | void CInputScript::ParseDefineMouseTarget() | ||
1644 | { | ||
1645 | printf("tagDefineMouseTarget\n"); | ||
1646 | } | ||
1647 | |||
1648 | |||
1649 | void CInputScript::ParseDefineSprite() | ||
1650 | { | ||
1651 | Sprite *sprite; | ||
1652 | Program *prg; | ||
1653 | int status; | ||
1654 | |||
1655 | U32 tagid = (U32) GetWord(); | ||
1656 | U32 frameCount = (U32) GetWord(); | ||
1657 | |||
1658 | if (frameCount == 0) return; | ||
1659 | |||
1660 | printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount); | ||
1661 | |||
1662 | sprite = new Sprite(program->movie, tagid, frameCount); | ||
1663 | if (sprite == NULL) { | ||
1664 | outOfMemory = 1; | ||
1665 | return; | ||
1666 | } | ||
1667 | if (sprite->getProgram() == NULL) { | ||
1668 | delete sprite; | ||
1669 | outOfMemory = 1; | ||
1670 | return; | ||
1671 | } | ||
1672 | |||
1673 | prg = sprite->getProgram(); | ||
1674 | |||
1675 | // Set current program | ||
1676 | program = prg; | ||
1677 | |||
1678 | ParseTags(&status); | ||
1679 | |||
1680 | if (outOfMemory) { | ||
1681 | delete sprite; | ||
1682 | return; | ||
1683 | } | ||
1684 | |||
1685 | addCharacter(sprite); | ||
1686 | } | ||
1687 | |||
1688 | |||
1689 | void CInputScript::ParseUnknown(long code, long len) | ||
1690 | { | ||
1691 | printf("Unknown Tag : %d - Length = %d\n", code, len); | ||
1692 | } | ||
1693 | |||
1694 | |||
1695 | void | ||
1696 | CInputScript::ParseTags(int *status) | ||
1697 | // Parses the tags within the file. | ||
1698 | { | ||
1699 | |||
1700 | // Initialize the end of frame flag. | ||
1701 | BOOL atEnd = false; | ||
1702 | |||
1703 | // Loop through each tag. | ||
1704 | while (!atEnd) | ||
1705 | { | ||
1706 | U32 here; | ||
1707 | |||
1708 | // Get the current tag. | ||
1709 | U16 code = GetTag(); | ||
1710 | |||
1711 | if (code == notEnoughData) { | ||
1712 | m_filePos = m_tagStart; | ||
1713 | *status |= FLASH_PARSE_NEED_DATA; | ||
1714 | return; | ||
1715 | } | ||
1716 | |||
1717 | //printf("Code %d, tagLen %8u \n", code, m_tagLen); | ||
1718 | |||
1719 | here = m_filePos; | ||
1720 | |||
1721 | // Get the tag ending position. | ||
1722 | U32 tagEnd = m_tagEnd; | ||
1723 | |||
1724 | if (m_tagEnd > m_actualSize) { | ||
1725 | m_filePos = m_tagStart; | ||
1726 | *status |= FLASH_PARSE_NEED_DATA; | ||
1727 | return; | ||
1728 | } | ||
1729 | |||
1730 | switch (code) | ||
1731 | { | ||
1732 | case stagProtect: | ||
1733 | break; | ||
1734 | |||
1735 | case stagEnd: | ||
1736 | |||
1737 | // We reached the end of the file. | ||
1738 | atEnd = true; | ||
1739 | |||
1740 | printf("End of Movie\n"); | ||
1741 | |||
1742 | break; | ||
1743 | |||
1744 | case stagShowFrame: | ||
1745 | |||
1746 | // Validate frame | ||
1747 | program->validateLoadingFrame(); | ||
1748 | *status |= FLASH_PARSE_WAKEUP; | ||
1749 | |||
1750 | break; | ||
1751 | |||
1752 | case stagFreeCharacter: | ||
1753 | ParseFreeCharacter(); | ||
1754 | break; | ||
1755 | |||
1756 | case stagPlaceObject: | ||
1757 | ParsePlaceObject(); | ||
1758 | break; | ||
1759 | |||
1760 | case stagPlaceObject2: | ||
1761 | ParsePlaceObject2(); | ||
1762 | break; | ||
1763 | |||
1764 | case stagRemoveObject: | ||
1765 | ParseRemoveObject(); | ||
1766 | break; | ||
1767 | |||
1768 | case stagRemoveObject2: | ||
1769 | ParseRemoveObject2(); | ||
1770 | break; | ||
1771 | |||
1772 | case stagSetBackgroundColor: | ||
1773 | ParseSetBackgroundColor(); | ||
1774 | break; | ||
1775 | |||
1776 | case stagDoAction: | ||
1777 | ParseDoAction(); | ||
1778 | break; | ||
1779 | |||
1780 | case stagStartSound: | ||
1781 | ParseStartSound(); | ||
1782 | break; | ||
1783 | |||
1784 | case stagStopSound: | ||
1785 | ParseStopSound(); | ||
1786 | break; | ||
1787 | |||
1788 | case stagDefineShape: | ||
1789 | ParseDefineShape(1); | ||
1790 | break; | ||
1791 | |||
1792 | case stagDefineShape2: | ||
1793 | ParseDefineShape(2); | ||
1794 | break; | ||
1795 | |||
1796 | case stagDefineShape3: | ||
1797 | ParseDefineShape(3); | ||
1798 | break; | ||
1799 | |||
1800 | case stagDefineBits: | ||
1801 | ParseDefineBits(); | ||
1802 | break; | ||
1803 | |||
1804 | case stagDefineBitsJPEG2: | ||
1805 | ParseDefineBitsJPEG2(); | ||
1806 | break; | ||
1807 | |||
1808 | case stagDefineBitsJPEG3: | ||
1809 | ParseDefineBitsJPEG3(); | ||
1810 | break; | ||
1811 | |||
1812 | case stagDefineBitsLossless: | ||
1813 | ParseDefineBitsLossless(1); | ||
1814 | break; | ||
1815 | |||
1816 | case stagDefineBitsLossless2: | ||
1817 | ParseDefineBitsLossless(2); | ||
1818 | break; | ||
1819 | |||
1820 | case stagJPEGTables: | ||
1821 | ParseJPEGTables(); | ||
1822 | break; | ||
1823 | |||
1824 | case stagDefineButton: | ||
1825 | ParseDefineButton(); | ||
1826 | break; | ||
1827 | |||
1828 | case stagDefineButton2: | ||
1829 | ParseDefineButton2(); | ||
1830 | break; | ||
1831 | |||
1832 | case stagDefineFont: | ||
1833 | ParseDefineFont(); | ||
1834 | break; | ||
1835 | |||
1836 | case stagDefineMorphShape: | ||
1837 | ParseDefineMorphShape(); | ||
1838 | break; | ||
1839 | |||
1840 | case stagDefineFontInfo: | ||
1841 | ParseDefineFontInfo(); | ||
1842 | break; | ||
1843 | |||
1844 | case stagDefineText: | ||
1845 | ParseDefineText(0); | ||
1846 | break; | ||
1847 | |||
1848 | case stagDefineText2: | ||
1849 | ParseDefineText(1); | ||
1850 | break; | ||
1851 | |||
1852 | case stagDefineSound: | ||
1853 | ParseDefineSound(); | ||
1854 | break; | ||
1855 | |||
1856 | case stagDefineButtonSound: | ||
1857 | ParseDefineButtonSound(); | ||
1858 | break; | ||
1859 | |||
1860 | case stagSoundStreamHead: | ||
1861 | ParseSoundStreamHead(); | ||
1862 | break; | ||
1863 | |||
1864 | case stagSoundStreamHead2: | ||
1865 | ParseSoundStreamHead2(); | ||
1866 | break; | ||
1867 | |||
1868 | case stagSoundStreamBlock: | ||
1869 | ParseSoundStreamBlock(); | ||
1870 | break; | ||
1871 | |||
1872 | case stagDefineButtonCxform: | ||
1873 | ParseDefineButtonCxform(); | ||
1874 | break; | ||
1875 | |||
1876 | case stagDefineSprite: | ||
1877 | Program *save; | ||
1878 | |||
1879 | save = program; | ||
1880 | ParseDefineSprite(); | ||
1881 | program->rewindMovie(); | ||
1882 | program = save; | ||
1883 | break; | ||
1884 | |||
1885 | case stagNameCharacter: | ||
1886 | ParseNameCharacter(); | ||
1887 | break; | ||
1888 | |||
1889 | case stagFrameLabel: | ||
1890 | ParseFrameLabel(); | ||
1891 | break; | ||
1892 | |||
1893 | case stagDefineFont2: | ||
1894 | ParseDefineFont2(); | ||
1895 | break; | ||
1896 | |||
1897 | default: | ||
1898 | ParseUnknown(code, m_tagLen); | ||
1899 | break; | ||
1900 | } | ||
1901 | |||
1902 | //printf("Bytes read = %d\n", m_filePos-here); | ||
1903 | |||
1904 | // Increment the past the tag. | ||
1905 | m_filePos = tagEnd; | ||
1906 | |||
1907 | if (outOfMemory) { | ||
1908 | fprintf(stderr,"Flash: Out of memory\n"); | ||
1909 | *status |= FLASH_PARSE_OOM; | ||
1910 | return; | ||
1911 | } | ||
1912 | } | ||
1913 | |||
1914 | program->validateLoadingFrame(); | ||
1915 | *status |= FLASH_PARSE_EOM; | ||
1916 | } | ||
1917 | |||
1918 | int | ||
1919 | CInputScript::ParseData(FlashMovie *movie, char * data, long size) | ||
1920 | { | ||
1921 | int status = FLASH_PARSE_ERROR; | ||
1922 | |||
1923 | m_fileBuf = (unsigned char *)data; | ||
1924 | m_actualSize = size; | ||
1925 | |||
1926 | if (needHeader) { | ||
1927 | |||
1928 | // Do we have sufficient data to read the header ? | ||
1929 | if (size < 21) { | ||
1930 | return FLASH_PARSE_NEED_DATA;// No, need more data | ||
1931 | } | ||
1932 | |||
1933 | needHeader = 0;// Yes | ||
1934 | |||
1935 | U8 fileHdr[8]; | ||
1936 | |||
1937 | memcpy(fileHdr,data,8); | ||
1938 | |||
1939 | // Verify the header and get the file size. | ||
1940 | if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' ) | ||
1941 | { | ||
1942 | //fprintf(stderr, "Not a Flash File.\n"); | ||
1943 | return FLASH_PARSE_ERROR;// Error | ||
1944 | } | ||
1945 | else | ||
1946 | { | ||
1947 | // Get the file version. | ||
1948 | m_fileVersion = (U16) fileHdr[3]; | ||
1949 | } | ||
1950 | |||
1951 | // Get the file size. | ||
1952 | m_fileSize = (U32) fileHdr[4] | ||
1953 | | ((U32) fileHdr[5] << 8) | ||
1954 | | ((U32) fileHdr[6] << 16) | ||
1955 | | ((U32) fileHdr[7] << 24); | ||
1956 | |||
1957 | // Verify the minimum length of a Flash file. | ||
1958 | if (m_fileSize < 21) | ||
1959 | { | ||
1960 | //printf("ERROR: File size is too short\n"); | ||
1961 | return FLASH_PARSE_ERROR;// Error | ||
1962 | } | ||
1963 | |||
1964 | // Set the file position past the header and size information. | ||
1965 | m_filePos = 8; | ||
1966 | |||
1967 | // Get the frame information. | ||
1968 | GetRect(&frameRect); | ||
1969 | |||
1970 | frameRate = GetWord() >> 8; | ||
1971 | |||
1972 | frameCount = GetWord(); | ||
1973 | |||
1974 | program = new Program(movie, frameCount); | ||
1975 | |||
1976 | if (program == NULL || program->totalFrames == 0) { | ||
1977 | return FLASH_PARSE_ERROR; | ||
1978 | } | ||
1979 | |||
1980 | status |= FLASH_PARSE_START; | ||
1981 | } | ||
1982 | |||
1983 | ParseTags(&status); | ||
1984 | |||
1985 | return status; | ||
1986 | } | ||
1987 | |||
1988 | |||