summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/script.cc
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/libflash/script.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/script.cc1988
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
11static 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//
23inline U8 CInputScript::GetByte(void)
24{
25 return m_fileBuf[m_filePos++];
26}
27
28inline 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
35inline 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
49CInputScript::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
86CInputScript::~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
99U16 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
129void 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
139void 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
174void 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 */
224char *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
235void CInputScript::InitBits(void)
236{
237 // Reset the bit position and buffer.
238 m_bitPos = 0;
239 m_bitBuf = 0;
240}
241
242
243S32 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
260U32 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
289void CInputScript::ParseFreeCharacter()
290{
291 U32 tagid = (U32) GetWord();
292
293 tagid = tagid;
294
295 printf("tagFreeCharacter \ttagid %-5u\n", tagid);
296}
297
298
299void 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
327void 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
381void 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
398void 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
414void 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
432void 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
459void 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
504void 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
519void 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
538int
539CInputScript::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
636void 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
716void 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
744void 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
779void 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
797void 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
821void 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
844void 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
872void 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
906void CInputScript::ParseJPEGTables()
907{
908 Bitmap::readJpegTables(&m_fileBuf[m_filePos]);
909}
910
911
912ButtonRecord * 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
957ActionRecord * 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
1025void 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
1063void 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
1117void 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
1176memory_error:
1177 outOfMemory = 1;
1178 if (offsetTable) delete offsetTable;
1179 if (font) delete font;
1180 if (shapes) delete[] shapes;
1181}
1182
1183
1184void CInputScript::ParseDefineMorphShape()
1185{
1186 U32 tagid = (U32) GetWord();
1187
1188 tagid = tagid;
1189 printf("tagDefineMorphShape \ttagid %-5u\n", tagid);
1190}
1191
1192void 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
1254void 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
1354memory_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
1362TextRecord * 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
1427void 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
1466void 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
1503void 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
1577void 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
1592void 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
1607void CInputScript::ParseSoundStreamBlock()
1608{
1609 printf("tagSoundStreamBlock\n");
1610}
1611
1612void 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
1627void CInputScript::ParseNameCharacter()
1628{
1629 U32 tagid = (U32) GetWord();
1630 char *label = strdup(GetString());
1631
1632 nameCharacter(tagid, label);
1633}
1634
1635
1636void CInputScript::ParseFrameLabel()
1637{
1638 char *label = strdup(GetString());
1639 program->setCurrentFrameLabel(label);
1640}
1641
1642
1643void CInputScript::ParseDefineMouseTarget()
1644{
1645 printf("tagDefineMouseTarget\n");
1646}
1647
1648
1649void 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
1689void CInputScript::ParseUnknown(long code, long len)
1690{
1691 printf("Unknown Tag : %d - Length = %d\n", code, len);
1692}
1693
1694
1695void
1696CInputScript::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
1918int
1919CInputScript::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