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