00001 #include "swf.h"
00002
00004
00005
00006
00007
00008
00009
00010 #ifdef RCSID
00011 static char *rcsid = "$Id: script.cc,v 1.1.1.1 2002/01/25 22:14:59 kergoth Exp $";
00012 #endif
00013
00014 #define printf(fmt,args...)
00015
00017
00019
00020
00021
00022
00023 inline U8 CInputScript::GetByte(void)
00024 {
00025 return m_fileBuf[m_filePos++];
00026 }
00027
00028 inline U16 CInputScript::GetWord(void)
00029 {
00030 U8 * s = m_fileBuf + m_filePos;
00031 m_filePos += 2;
00032 return (U16) s[0] | ((U16) s[1] << 8);
00033 }
00034
00035 inline U32 CInputScript::GetDWord(void)
00036 {
00037 U8 * s = m_fileBuf + m_filePos;
00038 m_filePos += 4;
00039 return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24);
00040 }
00041
00042
00043
00044
00046
00048
00049 CInputScript::CInputScript(int level)
00050
00051 {
00052 this->level = level;
00053
00054
00055 m_fileBuf = NULL;
00056
00057
00058 m_filePos = 0;
00059 m_fileSize = 0;
00060 m_fileVersion = 0;
00061
00062
00063 m_bitPos = 0;
00064 m_bitBuf = 0;
00065
00066
00067 m_outputFile = NULL;
00068
00069
00070 m_dumpAll = false;
00071
00072
00073 m_dumpGuts = false;
00074
00075 needHeader = 1;
00076 program = 0;
00077
00078 outOfMemory = 0;
00079
00080 next = NULL;
00081
00082 return;
00083 }
00084
00085
00086 CInputScript::~CInputScript(void)
00087
00088 {
00089
00090 if (m_fileBuf)
00091 {
00092 delete program;
00093 m_fileBuf = NULL;
00094 m_fileSize = 0;
00095 }
00096 }
00097
00098
00099 U16 CInputScript::GetTag(void)
00100 {
00101
00102 m_tagStart = m_filePos;
00103
00104 if (m_actualSize-m_filePos < 2) return notEnoughData;
00105
00106
00107 U16 code = GetWord();
00108
00109
00110 U32 len = code & 0x3f;
00111
00112
00113 code = code >> 6;
00114
00115
00116 if (len == 0x3f) {
00117 if (m_actualSize-m_filePos < 4) return notEnoughData;
00118 len = (U32) GetDWord();
00119 }
00120
00121
00122 m_tagEnd = m_filePos + (U32) len;
00123 m_tagLen = (U32) len;
00124
00125 return code;
00126 }
00127
00128
00129 void CInputScript::GetRect (Rect * r)
00130 {
00131 InitBits();
00132 int nBits = (int) GetBits(5);
00133 r->xmin = GetSBits(nBits);
00134 r->xmax = GetSBits(nBits);
00135 r->ymin = GetSBits(nBits);
00136 r->ymax = GetSBits(nBits);
00137 }
00138
00139 void CInputScript::GetMatrix(Matrix* mat)
00140 {
00141 InitBits();
00142
00143
00144 if (GetBits(1))
00145 {
00146 int nBits = (int) GetBits(5);
00147 mat->a = (float)(GetSBits(nBits))/(float)0x10000;
00148 mat->d = (float)(GetSBits(nBits))/(float)0x10000;
00149 }
00150 else
00151 {
00152 mat->a = mat->d = 1.0;
00153 }
00154
00155
00156 if (GetBits(1))
00157 {
00158 int nBits = (int)GetBits(5);
00159 mat->c = (float)(GetSBits(nBits))/(float)0x10000;
00160 mat->b = (float)(GetSBits(nBits))/(float)0x10000;
00161 }
00162 else
00163 {
00164 mat->b = mat->c = 0.0;
00165 }
00166
00167
00168 int nBits = (int) GetBits(5);
00169 mat->tx = GetSBits(nBits);
00170 mat->ty = GetSBits(nBits);
00171 }
00172
00173
00174 void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha)
00175 {
00176 int flags;
00177 int nBits;
00178 float aa; long ab;
00179 float ra; long rb;
00180 float ga; long gb;
00181 float ba; long bb;
00182
00183 InitBits();
00184
00185 flags = (int) GetBits(2);
00186 nBits = (int) GetBits(4);
00187 aa = 1.0; ab = 0;
00188 if (flags & 1)
00189 {
00190 ra = (float) GetSBits(nBits)/256.0;
00191 ga = (float) GetSBits(nBits)/256.0;
00192 ba = (float) GetSBits(nBits)/256.0;
00193 if (hasAlpha) aa = (float) GetSBits(nBits)/256.0;
00194 }
00195 else
00196 {
00197 ra = ga = ba = 1.0;
00198 }
00199 if (flags & 2)
00200 {
00201 rb = (S32) GetSBits(nBits);
00202 gb = (S32) GetSBits(nBits);
00203 bb = (S32) GetSBits(nBits);
00204 if (hasAlpha) ab = (S32) GetSBits(nBits);
00205 }
00206 else
00207 {
00208 rb = gb = bb = 0;
00209 }
00210 if (cx) {
00211 cx->aa = aa;
00212 cx->ab = ab;
00213 cx->ra = ra;
00214 cx->rb = rb;
00215 cx->ga = ga;
00216 cx->gb = gb;
00217 cx->ba = ba;
00218 cx->bb = bb;
00219 }
00220 }
00221
00222
00223
00224 char *CInputScript::GetString(void)
00225 {
00226
00227 char *str = (char *) &m_fileBuf[m_filePos];
00228
00229
00230 while (GetByte());
00231
00232 return str;
00233 }
00234
00235 void CInputScript::InitBits(void)
00236 {
00237
00238 m_bitPos = 0;
00239 m_bitBuf = 0;
00240 }
00241
00242
00243 S32 CInputScript::GetSBits (S32 n)
00244
00245 {
00246
00247 S32 v = (S32) GetBits(n);
00248
00249
00250 if (v & (1L << (n - 1)))
00251 {
00252
00253 v |= -1L << n;
00254 }
00255
00256 return v;
00257 }
00258
00259
00260 U32 CInputScript::GetBits (S32 n)
00261
00262 {
00263 U32 v = 0;
00264
00265 for (;;)
00266 {
00267 S32 s = n - m_bitPos;
00268 if (s > 0)
00269 {
00270
00271 v |= m_bitBuf << s;
00272 n -= m_bitPos;
00273
00274
00275 m_bitBuf = GetByte();
00276 m_bitPos = 8;
00277 }
00278 else
00279 {
00280
00281 v |= m_bitBuf >> -s;
00282 m_bitPos -= n;
00283 m_bitBuf &= 0xff >> (8 - m_bitPos);
00284 return v;
00285 }
00286 }
00287 }
00288
00289 void CInputScript::ParseFreeCharacter()
00290 {
00291 U32 tagid = (U32) GetWord();
00292
00293 tagid = tagid;
00294
00295 printf("tagFreeCharacter \ttagid %-5u\n", tagid);
00296 }
00297
00298
00299 void CInputScript::ParsePlaceObject()
00300 {
00301 Control *ctrl;
00302
00303 ctrl = new Control;
00304 if (ctrl == NULL) {
00305 outOfMemory = 1;
00306 return;
00307 }
00308 ctrl->type = ctrlPlaceObject;
00309 ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter);
00310
00311 ctrl->character = getCharacter(GetWord());
00312 ctrl->depth = GetWord();
00313
00314 GetMatrix(&(ctrl->matrix));
00315
00316 if ( m_filePos < m_tagEnd )
00317 {
00318 ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform);
00319
00320 GetCxform(&ctrl->cxform, false);
00321 }
00322
00323 program->addControlInCurrentFrame(ctrl);
00324 }
00325
00326
00327 void CInputScript::ParsePlaceObject2()
00328 {
00329 Control *ctrl;
00330
00331 ctrl = new Control;
00332 if (ctrl == NULL) {
00333 outOfMemory = 1;
00334 return;
00335 }
00336 ctrl->type = ctrlPlaceObject2;
00337
00338 ctrl->flags = (PlaceFlags)GetByte();
00339 ctrl->depth = GetWord();
00340
00341
00342 if (ctrl->flags & placeHasCharacter)
00343 {
00344 ctrl->character = getCharacter(GetWord());
00345 }
00346
00347
00348 if (ctrl->flags & placeHasMatrix)
00349 {
00350 GetMatrix(&(ctrl->matrix));
00351 }
00352
00353
00354 if (ctrl->flags & placeHasColorXform)
00355 {
00356 GetCxform(&ctrl->cxform, true);
00357 }
00358
00359
00360 if (ctrl->flags & placeHasRatio)
00361 {
00362 ctrl->ratio = GetWord();
00363 }
00364
00365
00366 if (ctrl->flags & placeHasName)
00367 {
00368 ctrl->name = strdup(GetString());
00369 }
00370
00371
00372 if (ctrl->flags & placeHasClip)
00373 {
00374 ctrl->clipDepth = GetWord();
00375 }
00376
00377 program->addControlInCurrentFrame(ctrl);
00378 }
00379
00380
00381 void CInputScript::ParseRemoveObject()
00382 {
00383 Control *ctrl;
00384
00385 ctrl = new Control;
00386 if (ctrl == NULL) {
00387 outOfMemory = 1;
00388 return;
00389 }
00390 ctrl->type = ctrlRemoveObject;
00391 ctrl->character = getCharacter(GetWord());
00392 ctrl->depth = GetWord();
00393
00394 program->addControlInCurrentFrame(ctrl);
00395 }
00396
00397
00398 void CInputScript::ParseRemoveObject2()
00399 {
00400 Control *ctrl;
00401
00402 ctrl = new Control;
00403 if (ctrl == NULL) {
00404 outOfMemory = 1;
00405 return;
00406 }
00407 ctrl->type = ctrlRemoveObject2;
00408 ctrl->depth = GetWord();
00409
00410 program->addControlInCurrentFrame(ctrl);
00411 }
00412
00413
00414 void CInputScript::ParseSetBackgroundColor()
00415 {
00416 Control *ctrl;
00417
00418 ctrl = new Control;
00419 if (ctrl == NULL) {
00420 outOfMemory = 1;
00421 return;
00422 }
00423 ctrl->type = ctrlBackgroundColor;
00424 ctrl->color.red = GetByte();
00425 ctrl->color.green = GetByte();
00426 ctrl->color.blue = GetByte();
00427
00428 program->addControlInCurrentFrame(ctrl);
00429 }
00430
00431
00432 void CInputScript::ParseDoAction()
00433 {
00434 Control *ctrl;
00435 ActionRecord *ar;
00436
00437 ctrl = new Control;
00438 if (ctrl == NULL) {
00439 outOfMemory = 1;
00440 return;
00441 }
00442 ctrl->type = ctrlDoAction;
00443
00444 do {
00445 ar = ParseActionRecord();
00446 if (ar) {
00447 ctrl->addActionRecord( ar );
00448 }
00449 if (outOfMemory) {
00450 return;
00451 }
00452 } while (ar);
00453
00454 program->addControlInCurrentFrame(ctrl);
00455
00456 }
00457
00458
00459 void CInputScript::ParseStartSound()
00460 {
00461 Control *ctrl;
00462
00463 ctrl = new Control;
00464 if (ctrl == NULL) {
00465 outOfMemory = 1;
00466 return;
00467 }
00468 ctrl->character = getCharacter(GetWord());
00469 ctrl->type = ctrlStartSound;
00470
00471 program->addControlInCurrentFrame(ctrl);
00472
00473 if (!m_dumpAll)
00474 return;
00475
00476 U32 code = GetByte();
00477
00478 printf("code %-3u", code);
00479
00480 if ( code & soundHasInPoint )
00481 printf(" inpoint %u ", GetDWord());
00482 if ( code & soundHasOutPoint )
00483 printf(" oupoint %u", GetDWord());
00484 if ( code & soundHasLoops )
00485 printf(" loops %u", GetWord());
00486
00487 printf("\n");
00488 if ( code & soundHasEnvelope )
00489 {
00490 int points = GetByte();
00491
00492 for ( int i = 0; i < points; i++ )
00493 {
00494 printf("\n");
00495 printf("mark44 %u", GetDWord());
00496 printf(" left chanel %u", GetWord());
00497 printf(" right chanel %u", GetWord());
00498 printf("\n");
00499 }
00500 }
00501 }
00502
00503
00504 void CInputScript::ParseStopSound()
00505 {
00506 Control *ctrl;
00507
00508 ctrl = new Control;
00509 if (ctrl == NULL) {
00510 outOfMemory = 1;
00511 return;
00512 }
00513 ctrl->type = ctrlStopSound;
00514
00515 program->addControlInCurrentFrame(ctrl);
00516 }
00517
00518
00519 void CInputScript::ParseShapeData(int getAlpha, int getStyles)
00520 {
00521 int shapeRecord = 0;
00522
00523 if (getStyles) {
00524
00525 ParseFillStyle(getAlpha);
00526 ParseLineStyle(getAlpha);
00527 }
00528
00529 InitBits();
00530 m_nFillBits = (U16) GetBits(4);
00531 m_nLineBits = (U16) GetBits(4);
00532
00533 do {
00534 shapeRecord = ParseShapeRecord(getAlpha);
00535 } while (shapeRecord);
00536 }
00537
00538 int
00539 CInputScript::ParseShapeRecord(long getAlpha)
00540 {
00541
00542 BOOL isEdge = (BOOL) GetBits(1);
00543
00544 if (!isEdge)
00545 {
00546
00547 U16 flags = (U16) GetBits(5);
00548
00549
00550 if (flags == 0)
00551 {
00552
00553 return 0;
00554 }
00555
00556
00557 if (flags & flagsMoveTo)
00558 {
00559 U16 nBits = (U16) GetBits(5);
00560 GetSBits(nBits);
00561 GetSBits(nBits);
00562 }
00563
00564
00565 if (flags & flagsFill0)
00566 {
00567 GetBits(m_nFillBits);
00568 }
00569 if (flags & flagsFill1)
00570 {
00571 GetBits(m_nFillBits);
00572 }
00573
00574
00575 if (flags & flagsLine)
00576 {
00577 GetBits(m_nLineBits);
00578 }
00579
00580
00581 if (flags & flagsNewStyles)
00582 {
00583
00584 ParseFillStyle(getAlpha);
00585 ParseLineStyle(getAlpha);
00586
00587 InitBits();
00588
00589
00590 m_nFillBits = (U16) GetBits(4);
00591 m_nLineBits = (U16) GetBits(4);
00592 }
00593
00594 return flags & flagsEndShape ? 0 : 1;
00595 }
00596 else
00597 {
00598 if (GetBits(1))
00599 {
00600
00601 U16 nBits = (U16) GetBits(4) + 2;
00602
00603
00604 if (GetBits(1))
00605 {
00606
00607 GetSBits(nBits);
00608 GetSBits(nBits);
00609 }
00610 else
00611 {
00612
00613 GetBits(1);
00614 GetSBits(nBits);
00615 }
00616 }
00617 else
00618 {
00619
00620 U16 nBits = (U16) GetBits(4) + 2;
00621
00622
00623 GetSBits(nBits);
00624 GetSBits(nBits);
00625
00626
00627 GetSBits(nBits);
00628 GetSBits(nBits);
00629 }
00630
00631 return 1;
00632 }
00633 }
00634
00635
00636 void CInputScript::ParseFillStyle(long getAlpha)
00637
00638 {
00639 U16 i = 0;
00640 FillType type;
00641 Matrix matrix;
00642
00643
00644 U16 nFills = GetByte();
00645
00646
00647 if (nFills == 255)
00648 {
00649
00650 nFills = GetWord();
00651 }
00652
00653
00654 for (i = 0; i < nFills; i++)
00655 {
00656 U16 fillStyle = GetByte();
00657
00658 type = (FillType) fillStyle;
00659
00660 printf("fillstyle: type=%d\n",defs[i].type);
00661 if (fillStyle & 0x10)
00662 {
00663 U16 nbGradients;
00664
00665 type = (FillType) (fillStyle & 0x12);
00666
00667
00668 GetMatrix(&matrix);
00669
00670
00671 nbGradients = GetByte();
00672
00673
00674 for (U16 j = 0; j < nbGradients; j++)
00675 {
00676 GetByte();
00677 GetByte();
00678 GetByte();
00679 GetByte();
00680 if (getAlpha) {
00681 GetByte();
00682 }
00683 }
00684 }
00685 else if (fillStyle & 0x40)
00686 {
00687 type = (FillType) (fillStyle & 0x41);
00688
00689
00690 GetWord();
00691
00692
00693 GetMatrix(&matrix);
00694 }
00695 else
00696 {
00697 type = (FillType) 0;
00698
00699
00700 GetByte();
00701 GetByte();
00702 GetByte();
00703 if (getAlpha) {
00704 GetByte();
00705 }
00706
00707 printf("fillstyle: %x %x %x %x\n",
00708 defs[i].color.red,
00709 defs[i].color.green,
00710 defs[i].color.blue,
00711 defs[i].color.alpha);
00712 }
00713 }
00714 }
00715
00716 void CInputScript::ParseLineStyle(long getAlpha)
00717 {
00718 long i;
00719
00720
00721 U16 nLines = GetByte();
00722
00723
00724 if (nLines == 255)
00725 {
00726
00727 nLines = GetWord();
00728 }
00729
00730
00731 for (i = 0; i < nLines; i++)
00732 {
00733 GetWord();
00734 GetByte();
00735 GetByte();
00736 GetByte();
00737 if (getAlpha) {
00738 GetByte();
00739 }
00740 }
00741 }
00742
00743
00744 void CInputScript::ParseDefineShape(int level)
00745 {
00746 Shape *shape;
00747 Rect rect;
00748 U32 tagid;
00749
00750 tagid = (U32) GetWord();
00751 shape = new Shape(tagid,level);
00752 if (shape == NULL) {
00753 outOfMemory = 1;
00754 return;
00755 }
00756 shape->dict = this;
00757
00758
00759 GetRect(&rect);
00760
00761 shape->setBoundingBox(rect);
00762
00763 shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos);
00764 if (shape->file_ptr == NULL) {
00765 outOfMemory = 1;
00766 delete shape;
00767 return;
00768 }
00769 memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos);
00770
00771 shape->getStyles = 1;
00772 shape->getAlpha = (level == 3);
00773
00774 ParseShapeData(level == 3, 1);
00775
00776 addCharacter(shape);
00777 }
00778
00779 void CInputScript::S_DumpImageGuts()
00780 {
00781 #if 0
00782 U32 lfCount = 0;
00783 printf("----- dumping image details -----");
00784 while (m_filePos < m_tagEnd)
00785 {
00786 if ((lfCount % 16) == 0)
00787 {
00788 fprintf(stdout, "\n");
00789 }
00790 lfCount += 1;
00791 fprintf(stdout, "%02x ", GetByte());
00792 }
00793 fprintf(stdout, "\n");
00794 #endif
00795 }
00796
00797 void CInputScript::ParseDefineBits()
00798 {
00799 Bitmap *bitmap;
00800 U32 tagid = (U32) GetWord();
00801 int status;
00802
00803 bitmap = new Bitmap(tagid,1);
00804 if (bitmap == NULL) {
00805 outOfMemory = 1;
00806 return;
00807 }
00808
00809 status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]);
00810
00811 if (status < 0) {
00812 fprintf(stderr,"Unable to read JPEG data\n");
00813 delete bitmap;
00814 return;
00815 }
00816
00817 addCharacter(bitmap);
00818 }
00819
00820
00821 void CInputScript::ParseDefineBitsJPEG2()
00822 {
00823 Bitmap *bitmap;
00824 U32 tagid = (U32) GetWord();
00825 int status;
00826
00827 bitmap = new Bitmap(tagid,2);
00828 if (bitmap == NULL) {
00829 outOfMemory = 1;
00830 return;
00831 }
00832
00833 status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0);
00834
00835 if (status < 0) {
00836 fprintf(stderr,"Unable to read JPEG data\n");
00837 delete bitmap;
00838 return;
00839 }
00840
00841 addCharacter(bitmap);
00842 }
00843
00844 void CInputScript::ParseDefineBitsJPEG3()
00845 {
00846 Bitmap *bitmap;
00847 U32 tagid = (U32) GetWord();
00848 int status;
00849 long offset;
00850
00851 printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid);
00852
00853 bitmap = new Bitmap(tagid,3);
00854 if (bitmap == NULL) {
00855 outOfMemory = 1;
00856 return;
00857 }
00858
00859 offset = GetDWord();
00860
00861 status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset);
00862 if (status < 0) {
00863 fprintf(stderr,"Unable to read JPEG data\n");
00864 delete bitmap;
00865 return;
00866 }
00867
00868 addCharacter(bitmap);
00869 }
00870
00871
00872 void CInputScript::ParseDefineBitsLossless(int level)
00873 {
00874 Bitmap *bitmap;
00875 U32 tagid = (U32) GetWord();
00876 int status;
00877 int tableSize;
00878
00879 bitmap = new Bitmap(tagid,0);
00880 if (bitmap == NULL) {
00881 outOfMemory = 1;
00882 return;
00883 }
00884
00885 int format = GetByte();
00886 int width = GetWord();
00887 int height = GetWord();
00888
00889 tableSize = 0;
00890
00891 if (format == 3) {
00892 tableSize = GetByte();
00893 }
00894
00895 status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2);
00896
00897 if (status < 0) {
00898 fprintf(stderr,"Unable to read ZLIB data\n");
00899 delete bitmap;
00900 return;
00901 }
00902
00903 addCharacter(bitmap);
00904 }
00905
00906 void CInputScript::ParseJPEGTables()
00907 {
00908 Bitmap::readJpegTables(&m_fileBuf[m_filePos]);
00909 }
00910
00911
00912 ButtonRecord * CInputScript::ParseButtonRecord(long getCxform)
00913 {
00914 U16 state;
00915 ButtonRecord *br;
00916 long tagid;
00917 Matrix matrix;
00918 long layer;
00919 Cxform *cxform;
00920
00921 state = (U16) GetByte();
00922
00923 if (state == 0) return 0;
00924
00925 br = new ButtonRecord;
00926 if (br == NULL) {
00927 outOfMemory = 1;
00928 return 0;
00929 }
00930
00931 tagid = GetWord();
00932 layer = GetWord();
00933 GetMatrix(&matrix);
00934
00935 if (br) {
00936 br->state = (ButtonState) state;
00937 br->character = getCharacter(tagid);
00938 br->layer = layer;
00939 br->cxform = 0;
00940 br->buttonMatrix = matrix;
00941 }
00942
00943 if (getCxform) {
00944 cxform = new Cxform;
00945 GetCxform(cxform, true);
00946 if (br) {
00947 br->cxform = cxform;
00948 if (cxform == NULL) {
00949 outOfMemory = 1;
00950 }
00951 }
00952 }
00953
00954 return br;
00955 }
00956
00957 ActionRecord * CInputScript::ParseActionRecord()
00958 {
00959 U8 action;
00960 U16 length = 0;
00961 char *url, *target, *label;
00962 long frameIndex, skipCount;
00963 ActionRecord *ar;
00964
00965 action = GetByte();
00966 if (action == 0) return 0;
00967
00968 ar = new ActionRecord;
00969 if (ar == NULL) {
00970 outOfMemory = 1;
00971 return 0;
00972 }
00973
00974 ar->action = (Action)action;
00975
00976 if (action & 0x80) {
00977 length = GetWord();
00978 }
00979
00980 switch (action) {
00981 case ActionGotoFrame:
00982 frameIndex = GetWord();
00983 if (ar) {
00984 ar->frameIndex = frameIndex;
00985 }
00986 break;
00987 case ActionGetURL:
00988 url = GetString();
00989 target = GetString();
00990 if (ar) {
00991 ar->url = strdup(url);
00992 ar->target = strdup(target);
00993 }
00994 break;
00995 case ActionWaitForFrame:
00996 frameIndex = GetWord();
00997 skipCount = GetByte();
00998 if (ar) {
00999 ar->frameIndex = frameIndex;
01000 ar->skipCount = skipCount;
01001 }
01002 break;
01003 case ActionSetTarget:
01004 target = strdup(GetString());
01005 if (ar) {
01006 ar->target = target;
01007 }
01008 break;
01009 case ActionGoToLabel:
01010 label = GetString();
01011 if (ar) {
01012 ar->frameLabel = strdup(label);
01013 }
01014 break;
01015 default:
01016 while (length--) {
01017 GetByte();
01018 }
01019 break;
01020 }
01021
01022 return ar;
01023 }
01024
01025 void CInputScript::ParseDefineButton()
01026 {
01027 Button *button;
01028 ButtonRecord *buttonRecord;
01029 ActionRecord *actionRecord;
01030
01031 U32 tagid = (U32) GetWord();
01032
01033 button = new Button(tagid);
01034 if (button == NULL) {
01035 outOfMemory = 1;
01036 return;
01037 }
01038
01039 do {
01040 buttonRecord = ParseButtonRecord();
01041 if (buttonRecord) {
01042 button->addButtonRecord( buttonRecord );
01043 }
01044 if (outOfMemory) {
01045 return;
01046 }
01047 } while (buttonRecord);
01048
01049 do {
01050 actionRecord = ParseActionRecord();
01051 if (actionRecord) {
01052 button->addActionRecord( actionRecord );
01053 }
01054 if (outOfMemory) {
01055 return;
01056 }
01057 } while (actionRecord);
01058
01059 addCharacter(button);
01060 }
01061
01062
01063 void CInputScript::ParseDefineButton2()
01064 {
01065 Button *button;
01066 ButtonRecord *buttonRecord;
01067 ActionRecord *actionRecord;
01068 U16 transition;
01069 U16 offset;
01070 U8 menu;
01071
01072 U32 tagid = (U32) GetWord();
01073
01074 button = new Button(tagid);
01075
01076 if (button == NULL) {
01077 outOfMemory = 1;
01078 return;
01079 }
01080
01081 menu = GetByte();
01082
01083 offset = GetWord();
01084
01085 do {
01086 buttonRecord = ParseButtonRecord(true);
01087 if (buttonRecord) {
01088 button->addButtonRecord( buttonRecord );
01089 }
01090 if (outOfMemory) {
01091 return;
01092 }
01093 } while (buttonRecord);
01094
01095 while (offset) {
01096 offset = GetWord();
01097
01098 transition = GetWord();
01099
01100 do {
01101 actionRecord = ParseActionRecord();
01102 if (actionRecord) {
01103 button->addActionRecord( actionRecord );
01104 }
01105 if (outOfMemory) {
01106 return;
01107 }
01108 } while (actionRecord);
01109
01110 button->addCondition( transition );
01111 }
01112
01113 addCharacter(button);
01114 }
01115
01116
01117 void CInputScript::ParseDefineFont()
01118 {
01119 SwfFont *font = 0;
01120 U32 tagid = (U32) GetWord();
01121 long start;
01122 long nb,n;
01123 long offset;
01124 long *offsetTable = 0;
01125 Shape *shapes = 0;
01126
01127 font = new SwfFont(tagid);
01128 if (font == NULL) {
01129 outOfMemory = 1;
01130 return;
01131 }
01132 start = m_filePos;
01133
01134 offset = GetWord();
01135 nb = offset/2;
01136 offsetTable = new long[nb];
01137 if (offsetTable == NULL) {
01138 goto memory_error;
01139 }
01140 offsetTable[0] = offset;
01141
01142 for(n=1; n<nb; n++)
01143 {
01144 offsetTable[n] = GetWord();
01145 }
01146
01147 shapes = new Shape[nb];
01148 if (shapes == NULL) {
01149 goto memory_error;
01150 }
01151
01152 for(n=0; n<nb; n++)
01153 {
01154 long here;
01155
01156 m_filePos = offsetTable[n]+start;
01157
01158 here = m_filePos;
01159 ParseShapeData(0, 0);
01160
01161
01162 shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
01163 if (shapes[n].file_ptr == NULL) {
01164 goto memory_error;
01165 }
01166 memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
01167 }
01168
01169 font->setFontShapeTable(shapes,nb);
01170
01171 delete[] offsetTable;
01172
01173 addCharacter(font);
01174 return;
01175
01176 memory_error:
01177 outOfMemory = 1;
01178 if (offsetTable) delete offsetTable;
01179 if (font) delete font;
01180 if (shapes) delete[] shapes;
01181 }
01182
01183
01184 void CInputScript::ParseDefineMorphShape()
01185 {
01186 U32 tagid = (U32) GetWord();
01187
01188 tagid = tagid;
01189 printf("tagDefineMorphShape \ttagid %-5u\n", tagid);
01190 }
01191
01192 void CInputScript::ParseDefineFontInfo()
01193 {
01194 SwfFont *font;
01195 U32 tagid = (U32) GetWord();
01196 long nameLen;
01197 char *name;
01198 long n,nb;
01199 FontFlags flags;
01200 long *lut;
01201
01202 font = (SwfFont *)getCharacter(tagid);
01203
01204 if (font == NULL) {
01205 outOfMemory = 1;
01206 return;
01207 }
01208
01209 nameLen = GetByte();
01210 name = new char[nameLen+1];
01211 if (name == NULL) {
01212 outOfMemory = 1;
01213 return;
01214 }
01215 for(n=0; n < nameLen; n++)
01216 {
01217 name[n] = GetByte();
01218 }
01219 name[n]=0;
01220
01221 font->setFontName(name);
01222
01223 delete name;
01224
01225 flags = (FontFlags)GetByte();
01226
01227 font->setFontFlags(flags);
01228
01229 nb = font->getNbGlyphs();
01230
01231 lut = new long[nb];
01232 if (lut == NULL) {
01233 outOfMemory = 1;
01234 delete font;
01235 return;
01236 }
01237
01238 for(n=0; n < nb; n++)
01239 {
01240 if (flags & fontWideCodes) {
01241 lut[n] = GetWord();
01242 } else {
01243 lut[n] = GetByte();
01244 }
01245 }
01246
01247 font->setFontLookUpTable(lut);
01248 }
01249
01250
01251
01252
01253
01254 void CInputScript::ParseDefineFont2()
01255 {
01256 int n;
01257 U32 tagid = (U32) GetWord();
01258 FontFlags flags;
01259 char *name;
01260 long nameLen;
01261 long fontGlyphCount;
01262 long *offsetTable = NULL;
01263 Shape *shapes = NULL;
01264 long start;
01265 SwfFont *font;
01266 long *lut = NULL;
01267
01268 font = new SwfFont(tagid);
01269 if (font == NULL) {
01270 goto memory_error;
01271 }
01272
01273 flags = (FontFlags)GetWord();
01274
01275 font->setFontFlags(flags);
01276
01277 nameLen = GetByte();
01278 name = new char[nameLen+1];
01279 if (name == NULL) {
01280 goto memory_error;
01281 }
01282 for(n=0; n < nameLen; n++)
01283 {
01284 name[n] = GetByte();
01285 }
01286 name[n]=0;
01287
01288 font->setFontName(name);
01289
01290 delete name;
01291
01292 fontGlyphCount = GetWord();
01293
01294 start = m_filePos;
01295
01296 offsetTable = new long[fontGlyphCount];
01297 if (offsetTable == NULL) {
01298 goto memory_error;
01299 }
01300 for (n=0; n<fontGlyphCount; n++) {
01301 if (flags & 8) {
01302 offsetTable[n] = GetDWord();
01303 } else {
01304 offsetTable[n] = GetWord();
01305 }
01306 }
01307
01308 shapes = new Shape[fontGlyphCount];
01309 if (shapes == NULL) {
01310 goto memory_error;
01311 }
01312
01313 for (n=0; n<fontGlyphCount; n++) {
01314 long here;
01315
01316 m_filePos = offsetTable[n]+start;
01317
01318 here = m_filePos;
01319 ParseShapeData(0, 0);
01320
01321
01322 shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
01323 if (shapes[n].file_ptr == NULL) {
01324 goto memory_error;
01325 }
01326 memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
01327 }
01328
01329 font->setFontShapeTable(shapes,fontGlyphCount);
01330
01331 lut = new long[fontGlyphCount];
01332 if (lut == NULL) {
01333 goto memory_error;
01334 }
01335
01336 for(n=0; n < fontGlyphCount; n++)
01337 {
01338 if (flags & 4) {
01339 lut[n] = GetWord();
01340 } else {
01341 lut[n] = GetByte();
01342 }
01343 }
01344
01345 font->setFontLookUpTable(lut);
01346
01347 delete offsetTable;
01348
01349 addCharacter(font);
01350
01351
01352 return;
01353
01354 memory_error:
01355 outOfMemory = 1;
01356 if (font) delete font;
01357 if (offsetTable) delete offsetTable;
01358 if (lut) delete lut;
01359 if (shapes) delete[] shapes;
01360 }
01361
01362 TextRecord * CInputScript::ParseTextRecord(int hasAlpha)
01363 {
01364 TextRecord *tr;
01365 TextFlags flags;
01366
01367 flags = (TextFlags) GetByte();
01368 if (flags == 0) return 0;
01369
01370 tr = new TextRecord;
01371 if (tr == NULL) {
01372 outOfMemory = 1;
01373 return 0;
01374 }
01375
01376 tr->flags = flags;
01377
01378 if (flags & isTextControl) {
01379 if (flags & textHasFont) {
01380 long fontId;
01381
01382 fontId = GetWord();
01383 tr->font = (SwfFont *)getCharacter(fontId);
01384 }
01385 if (flags & textHasColor) {
01386 tr->color.red = GetByte();
01387 tr->color.green = GetByte();
01388 tr->color.blue = GetByte();
01389 if (hasAlpha) {
01390 tr->color.alpha = GetByte();
01391 } else {
01392 tr->color.alpha = ALPHA_OPAQUE;
01393 }
01394 }
01395 if (flags & textHasXOffset) {
01396 tr->xOffset = GetWord();
01397 }
01398 if (flags & textHasYOffset) {
01399 tr->yOffset = GetWord();
01400 }
01401 if (flags & textHasFont) {
01402 tr->fontHeight = GetWord();
01403 }
01404 tr->nbGlyphs = GetByte();
01405 } else {
01406 tr->flags = (TextFlags)0;
01407 tr->nbGlyphs = (long)flags;
01408 }
01409
01410 tr->glyphs = new Glyph[ tr->nbGlyphs ];
01411 if (tr->glyphs == NULL) {
01412 outOfMemory = 1;
01413 delete tr;
01414 return 0;
01415 }
01416
01417 InitBits();
01418 for (int g = 0; g < tr->nbGlyphs; g++)
01419 {
01420 tr->glyphs[g].index = GetBits(m_nGlyphBits);
01421 tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits);
01422 }
01423
01424 return tr;
01425 }
01426
01427 void CInputScript::ParseDefineText(int hasAlpha)
01428 {
01429 Text *text;
01430 TextRecord *textRecord;
01431 Matrix m;
01432 Rect rect;
01433 U32 tagid = (U32) GetWord();
01434
01435 text = new Text(tagid);
01436 if (text == NULL) {
01437 outOfMemory = 1;
01438 return;
01439 }
01440
01441 GetRect(&rect);
01442 text->setTextBoundary(rect);
01443
01444 GetMatrix(&m);
01445 text->setTextMatrix(m);
01446
01447 m_nGlyphBits = GetByte();
01448 m_nAdvanceBits = GetByte();
01449
01450 do {
01451 textRecord = ParseTextRecord(hasAlpha);
01452 if (textRecord) {
01453 text->addTextRecord( textRecord );
01454 }
01455 if (outOfMemory) {
01456 delete text;
01457 return;
01458 }
01459 if (m_filePos >= m_tagEnd) break;
01460 } while (textRecord);
01461
01462 addCharacter(text);
01463 }
01464
01465
01466 void CInputScript::ParseDefineSound()
01467 {
01468 Sound *sound;
01469 U32 tagid = (U32) GetWord();
01470 long nbSamples;
01471 long flags;
01472 char *buffer;
01473
01474 sound = new Sound(tagid);
01475
01476 flags = GetByte();
01477 sound->setSoundFlags(flags);
01478
01479 nbSamples = GetDWord();
01480 buffer = sound->setNbSamples(nbSamples);
01481 if (buffer == NULL) {
01482 outOfMemory = 1;
01483 delete sound;
01484 return;
01485 }
01486
01487 if (flags & soundIsADPCMCompressed) {
01488 Adpcm *adpcm;
01489
01490 adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo );
01491
01492 adpcm->Decompress((short *)buffer, nbSamples);
01493
01494 delete adpcm;
01495 } else {
01496 memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5);
01497 }
01498
01499 addCharacter(sound);
01500 }
01501
01502
01503 void CInputScript::ParseDefineButtonSound()
01504 {
01505 U32 tagid = (U32) GetWord();
01506 Button *button;
01507
01508 tagid = tagid;
01509
01510 printf("tagDefineButtonSound \ttagid %-5u\n", tagid);
01511
01512 button = (Button *)getCharacter(tagid);
01513
01514 if (button == 0) {
01515 printf(" Couldn't find Button id %d\n", tagid);
01516 return;
01517 }
01518
01519
01520 for (int i = 0; i < 4; i++)
01521 {
01522 Sound *sound;
01523 U32 soundTag = GetWord();
01524
01525 sound = (Sound *)getCharacter(soundTag);
01526
01527 if (sound) {
01528 button->setButtonSound(sound,i);
01529 } else if (soundTag) {
01530 printf(" Couldn't find Sound id %d\n", soundTag);
01531 }
01532
01533 switch (i)
01534 {
01535 case 0:
01536 printf("upState \ttagid %-5u\n", soundTag);
01537 break;
01538 case 1:
01539 printf("overState \ttagid %-5u\n", soundTag);
01540 break;
01541 case 2:
01542 printf("downState \ttagid %-5u\n", soundTag);
01543 break;
01544 }
01545
01546 if (soundTag)
01547 {
01548 U32 code = GetByte();
01549 printf("sound code %u", code);
01550
01551 if ( code & soundHasInPoint )
01552 printf(" inpoint %u", GetDWord());
01553 if ( code & soundHasOutPoint )
01554 printf(" outpoint %u", GetDWord());
01555 if ( code & soundHasLoops )
01556 printf(" loops %u", GetWord());
01557
01558 printf("\n");
01559 if ( code & soundHasEnvelope )
01560 {
01561 int points = GetByte();
01562
01563 for ( int p = 0; p < points; p++ )
01564 {
01565 printf("\n");
01566 printf("mark44 %u", GetDWord());
01567 printf(" left chanel %u", GetWord());
01568 printf(" right chanel %u", GetWord());
01569 printf("\n");
01570 }
01571 }
01572 }
01573 if (m_filePos == m_tagEnd) break;
01574 }
01575 }
01576
01577 void CInputScript::ParseSoundStreamHead()
01578 {
01579 int mixFormat = GetByte();
01580
01581
01582 int format = GetByte();
01583 int nSamples = GetWord();
01584
01585 mixFormat = mixFormat;
01586 format = format;
01587 nSamples = nSamples;
01588
01589 printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples);
01590 }
01591
01592 void CInputScript::ParseSoundStreamHead2()
01593 {
01594 int mixFormat = GetByte();
01595
01596
01597 int format = GetByte();
01598 int nSamples = GetWord();
01599
01600 mixFormat = mixFormat;
01601 format = format;
01602 nSamples = nSamples;
01603
01604
01605 }
01606
01607 void CInputScript::ParseSoundStreamBlock()
01608 {
01609 printf("tagSoundStreamBlock\n");
01610 }
01611
01612 void CInputScript::ParseDefineButtonCxform()
01613 {
01614 ButtonRecord *br;
01615 Button *button;
01616 U32 tagid = (U32) GetWord();
01617
01618 button = (Button *)getCharacter(tagid);
01619
01620 for (br = button->getButtonRecords(); br; br = br->next)
01621 {
01622 br->cxform = new Cxform;
01623 GetCxform(br->cxform, false);
01624 }
01625 }
01626
01627 void CInputScript::ParseNameCharacter()
01628 {
01629 U32 tagid = (U32) GetWord();
01630 char *label = strdup(GetString());
01631
01632 nameCharacter(tagid, label);
01633 }
01634
01635
01636 void CInputScript::ParseFrameLabel()
01637 {
01638 char *label = strdup(GetString());
01639 program->setCurrentFrameLabel(label);
01640 }
01641
01642
01643 void CInputScript::ParseDefineMouseTarget()
01644 {
01645 printf("tagDefineMouseTarget\n");
01646 }
01647
01648
01649 void CInputScript::ParseDefineSprite()
01650 {
01651 Sprite *sprite;
01652 Program *prg;
01653 int status;
01654
01655 U32 tagid = (U32) GetWord();
01656 U32 frameCount = (U32) GetWord();
01657
01658 if (frameCount == 0) return;
01659
01660 printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount);
01661
01662 sprite = new Sprite(program->movie, tagid, frameCount);
01663 if (sprite == NULL) {
01664 outOfMemory = 1;
01665 return;
01666 }
01667 if (sprite->getProgram() == NULL) {
01668 delete sprite;
01669 outOfMemory = 1;
01670 return;
01671 }
01672
01673 prg = sprite->getProgram();
01674
01675
01676 program = prg;
01677
01678 ParseTags(&status);
01679
01680 if (outOfMemory) {
01681 delete sprite;
01682 return;
01683 }
01684
01685 addCharacter(sprite);
01686 }
01687
01688
01689 void CInputScript::ParseUnknown(long code, long len)
01690 {
01691 printf("Unknown Tag : %d - Length = %d\n", code, len);
01692 }
01693
01694
01695 void
01696 CInputScript::ParseTags(int *status)
01697
01698 {
01699
01700
01701 BOOL atEnd = false;
01702
01703
01704 while (!atEnd)
01705 {
01706 U32 here;
01707
01708
01709 U16 code = GetTag();
01710
01711 if (code == notEnoughData) {
01712 m_filePos = m_tagStart;
01713 *status |= FLASH_PARSE_NEED_DATA;
01714 return;
01715 }
01716
01717
01718
01719 here = m_filePos;
01720
01721
01722 U32 tagEnd = m_tagEnd;
01723
01724 if (m_tagEnd > m_actualSize) {
01725 m_filePos = m_tagStart;
01726 *status |= FLASH_PARSE_NEED_DATA;
01727 return;
01728 }
01729
01730 switch (code)
01731 {
01732 case stagProtect:
01733 break;
01734
01735 case stagEnd:
01736
01737
01738 atEnd = true;
01739
01740 printf("End of Movie\n");
01741
01742 break;
01743
01744 case stagShowFrame:
01745
01746
01747 program->validateLoadingFrame();
01748 *status |= FLASH_PARSE_WAKEUP;
01749
01750 break;
01751
01752 case stagFreeCharacter:
01753 ParseFreeCharacter();
01754 break;
01755
01756 case stagPlaceObject:
01757 ParsePlaceObject();
01758 break;
01759
01760 case stagPlaceObject2:
01761 ParsePlaceObject2();
01762 break;
01763
01764 case stagRemoveObject:
01765 ParseRemoveObject();
01766 break;
01767
01768 case stagRemoveObject2:
01769 ParseRemoveObject2();
01770 break;
01771
01772 case stagSetBackgroundColor:
01773 ParseSetBackgroundColor();
01774 break;
01775
01776 case stagDoAction:
01777 ParseDoAction();
01778 break;
01779
01780 case stagStartSound:
01781 ParseStartSound();
01782 break;
01783
01784 case stagStopSound:
01785 ParseStopSound();
01786 break;
01787
01788 case stagDefineShape:
01789 ParseDefineShape(1);
01790 break;
01791
01792 case stagDefineShape2:
01793 ParseDefineShape(2);
01794 break;
01795
01796 case stagDefineShape3:
01797 ParseDefineShape(3);
01798 break;
01799
01800 case stagDefineBits:
01801 ParseDefineBits();
01802 break;
01803
01804 case stagDefineBitsJPEG2:
01805 ParseDefineBitsJPEG2();
01806 break;
01807
01808 case stagDefineBitsJPEG3:
01809 ParseDefineBitsJPEG3();
01810 break;
01811
01812 case stagDefineBitsLossless:
01813 ParseDefineBitsLossless(1);
01814 break;
01815
01816 case stagDefineBitsLossless2:
01817 ParseDefineBitsLossless(2);
01818 break;
01819
01820 case stagJPEGTables:
01821 ParseJPEGTables();
01822 break;
01823
01824 case stagDefineButton:
01825 ParseDefineButton();
01826 break;
01827
01828 case stagDefineButton2:
01829 ParseDefineButton2();
01830 break;
01831
01832 case stagDefineFont:
01833 ParseDefineFont();
01834 break;
01835
01836 case stagDefineMorphShape:
01837 ParseDefineMorphShape();
01838 break;
01839
01840 case stagDefineFontInfo:
01841 ParseDefineFontInfo();
01842 break;
01843
01844 case stagDefineText:
01845 ParseDefineText(0);
01846 break;
01847
01848 case stagDefineText2:
01849 ParseDefineText(1);
01850 break;
01851
01852 case stagDefineSound:
01853 ParseDefineSound();
01854 break;
01855
01856 case stagDefineButtonSound:
01857 ParseDefineButtonSound();
01858 break;
01859
01860 case stagSoundStreamHead:
01861 ParseSoundStreamHead();
01862 break;
01863
01864 case stagSoundStreamHead2:
01865 ParseSoundStreamHead2();
01866 break;
01867
01868 case stagSoundStreamBlock:
01869 ParseSoundStreamBlock();
01870 break;
01871
01872 case stagDefineButtonCxform:
01873 ParseDefineButtonCxform();
01874 break;
01875
01876 case stagDefineSprite:
01877 Program *save;
01878
01879 save = program;
01880 ParseDefineSprite();
01881 program->rewindMovie();
01882 program = save;
01883 break;
01884
01885 case stagNameCharacter:
01886 ParseNameCharacter();
01887 break;
01888
01889 case stagFrameLabel:
01890 ParseFrameLabel();
01891 break;
01892
01893 case stagDefineFont2:
01894 ParseDefineFont2();
01895 break;
01896
01897 default:
01898 ParseUnknown(code, m_tagLen);
01899 break;
01900 }
01901
01902
01903
01904
01905 m_filePos = tagEnd;
01906
01907 if (outOfMemory) {
01908 fprintf(stderr,"Flash: Out of memory\n");
01909 *status |= FLASH_PARSE_OOM;
01910 return;
01911 }
01912 }
01913
01914 program->validateLoadingFrame();
01915 *status |= FLASH_PARSE_EOM;
01916 }
01917
01918 int
01919 CInputScript::ParseData(FlashMovie *movie, char * data, long size)
01920 {
01921 int status = FLASH_PARSE_ERROR;
01922
01923 m_fileBuf = (unsigned char *)data;
01924 m_actualSize = size;
01925
01926 if (needHeader) {
01927
01928
01929 if (size < 21) {
01930 return FLASH_PARSE_NEED_DATA;
01931 }
01932
01933 needHeader = 0;
01934
01935 U8 fileHdr[8];
01936
01937 memcpy(fileHdr,data,8);
01938
01939
01940 if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' )
01941 {
01942
01943 return FLASH_PARSE_ERROR;
01944 }
01945 else
01946 {
01947
01948 m_fileVersion = (U16) fileHdr[3];
01949 }
01950
01951
01952 m_fileSize = (U32) fileHdr[4]
01953 | ((U32) fileHdr[5] << 8)
01954 | ((U32) fileHdr[6] << 16)
01955 | ((U32) fileHdr[7] << 24);
01956
01957
01958 if (m_fileSize < 21)
01959 {
01960
01961 return FLASH_PARSE_ERROR;
01962 }
01963
01964
01965 m_filePos = 8;
01966
01967
01968 GetRect(&frameRect);
01969
01970 frameRate = GetWord() >> 8;
01971
01972 frameCount = GetWord();
01973
01974 program = new Program(movie, frameCount);
01975
01976 if (program == NULL || program->totalFrames == 0) {
01977 return FLASH_PARSE_ERROR;
01978 }
01979
01980 status |= FLASH_PARSE_START;
01981 }
01982
01983 ParseTags(&status);
01984
01985 return status;
01986 }
01987
01988