home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 19 / Amiga Plus Leser CD 19.iso / Tools / Freeware / Swf_Player / Lib / script.cc < prev    next >
Encoding:
C/C++ Source or Header  |  2002-11-17  |  35.3 KB  |  1,987 lines

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