summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/libflash/script.cc
Side-by-side diff
Diffstat (limited to 'core/multimedia/opieplayer/libflash/script.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libflash/script.cc1988
1 files changed, 1988 insertions, 0 deletions
diff --git a/core/multimedia/opieplayer/libflash/script.cc b/core/multimedia/opieplayer/libflash/script.cc
new file mode 100644
index 0000000..db65819
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/script.cc
@@ -0,0 +1,1988 @@
+#include "swf.h"
+
+////////////////////////////////////////////////////////////
+// This file is derived from the 'buggy' SWF parser provided
+// by Macromedia.
+//
+// Modifications : Olivier Debon <odebon@club-internet.fr>
+//
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define printf(fmt,args...)
+
+//////////////////////////////////////////////////////////////////////
+// Inline input script object methods.
+//////////////////////////////////////////////////////////////////////
+
+//
+// Inlines to parse a Flash file.
+//
+inline U8 CInputScript::GetByte(void)
+{
+ return m_fileBuf[m_filePos++];
+}
+
+inline U16 CInputScript::GetWord(void)
+{
+ U8 * s = m_fileBuf + m_filePos;
+ m_filePos += 2;
+ return (U16) s[0] | ((U16) s[1] << 8);
+}
+
+inline U32 CInputScript::GetDWord(void)
+{
+ U8 * s = m_fileBuf + m_filePos;
+ m_filePos += 4;
+ return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24);
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////
+// Input script object methods.
+//////////////////////////////////////////////////////////////////////
+
+CInputScript::CInputScript(int level)
+// Class constructor.
+{
+ this->level = level;
+
+ // Initialize the input pointer.
+ m_fileBuf = NULL;
+
+ // Initialize the file information.
+ m_filePos = 0;
+ m_fileSize = 0;
+ m_fileVersion = 0;
+
+ // Initialize the bit position and buffer.
+ m_bitPos = 0;
+ m_bitBuf = 0;
+
+ // Initialize the output file.
+ m_outputFile = NULL;
+
+ // Set to true if we wish to dump all contents long form
+ m_dumpAll = false;
+
+ // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
+ m_dumpGuts = false;
+
+ needHeader = 1;
+ program = 0;
+
+ outOfMemory = 0;
+
+ next = NULL;
+
+ return;
+}
+
+
+CInputScript::~CInputScript(void)
+// Class destructor.
+{
+ // Free the buffer if it is there.
+ if (m_fileBuf)
+ {
+ delete program;
+ m_fileBuf = NULL;
+ m_fileSize = 0;
+ }
+}
+
+
+U16 CInputScript::GetTag(void)
+{
+ // Save the start of the tag.
+ m_tagStart = m_filePos;
+
+ if (m_actualSize-m_filePos < 2) return notEnoughData;
+
+ // Get the combined code and length of the tag.
+ U16 code = GetWord();
+
+ // The length is encoded in the tag.
+ U32 len = code & 0x3f;
+
+ // Remove the length from the code.
+ code = code >> 6;
+
+ // Determine if another long word must be read to get the length.
+ if (len == 0x3f) {
+ if (m_actualSize-m_filePos < 4) return notEnoughData;
+ len = (U32) GetDWord();
+ }
+
+ // Determine the end position of the tag.
+ m_tagEnd = m_filePos + (U32) len;
+ m_tagLen = (U32) len;
+
+ return code;
+}
+
+
+void CInputScript::GetRect (Rect * r)
+{
+ InitBits();
+ int nBits = (int) GetBits(5);
+ r->xmin = GetSBits(nBits);
+ r->xmax = GetSBits(nBits);
+ r->ymin = GetSBits(nBits);
+ r->ymax = GetSBits(nBits);
+}
+
+void CInputScript::GetMatrix(Matrix* mat)
+{
+ InitBits();
+
+ // Scale terms
+ if (GetBits(1))
+ {
+ int nBits = (int) GetBits(5);
+ mat->a = (float)(GetSBits(nBits))/(float)0x10000;
+ mat->d = (float)(GetSBits(nBits))/(float)0x10000;
+ }
+ else
+ {
+ mat->a = mat->d = 1.0;
+ }
+
+ // Rotate/skew terms
+ if (GetBits(1))
+ {
+ int nBits = (int)GetBits(5);
+ mat->c = (float)(GetSBits(nBits))/(float)0x10000;
+ mat->b = (float)(GetSBits(nBits))/(float)0x10000;
+ }
+ else
+ {
+ mat->b = mat->c = 0.0;
+ }
+
+ // Translate terms
+ int nBits = (int) GetBits(5);
+ mat->tx = GetSBits(nBits);
+ mat->ty = GetSBits(nBits);
+}
+
+
+void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha)
+{
+ int flags;
+ int nBits;
+ float aa; long ab;
+ float ra; long rb;
+ float ga; long gb;
+ float ba; long bb;
+
+ InitBits();
+
+ flags = (int) GetBits(2);
+ nBits = (int) GetBits(4);
+ aa = 1.0; ab = 0;
+ if (flags & 1)
+ {
+ ra = (float) GetSBits(nBits)/256.0;
+ ga = (float) GetSBits(nBits)/256.0;
+ ba = (float) GetSBits(nBits)/256.0;
+ if (hasAlpha) aa = (float) GetSBits(nBits)/256.0;
+ }
+ else
+ {
+ ra = ga = ba = 1.0;
+ }
+ if (flags & 2)
+ {
+ rb = (S32) GetSBits(nBits);
+ gb = (S32) GetSBits(nBits);
+ bb = (S32) GetSBits(nBits);
+ if (hasAlpha) ab = (S32) GetSBits(nBits);
+ }
+ else
+ {
+ rb = gb = bb = 0;
+ }
+ if (cx) {
+ cx->aa = aa;
+ cx->ab = ab;
+ cx->ra = ra;
+ cx->rb = rb;
+ cx->ga = ga;
+ cx->gb = gb;
+ cx->ba = ba;
+ cx->bb = bb;
+ }
+}
+
+
+/* XXX: should allocate string */
+char *CInputScript::GetString(void)
+{
+ // Point to the string.
+ char *str = (char *) &m_fileBuf[m_filePos];
+
+ // Skip over the string.
+ while (GetByte());
+
+ return str;
+}
+
+void CInputScript::InitBits(void)
+{
+ // Reset the bit position and buffer.
+ m_bitPos = 0;
+ m_bitBuf = 0;
+}
+
+
+S32 CInputScript::GetSBits (S32 n)
+// Get n bits from the string with sign extension.
+{
+ // Get the number as an unsigned value.
+ S32 v = (S32) GetBits(n);
+
+ // Is the number negative?
+ if (v & (1L << (n - 1)))
+ {
+ // Yes. Extend the sign.
+ v |= -1L << n;
+ }
+
+ return v;
+}
+
+
+U32 CInputScript::GetBits (S32 n)
+// Get n bits from the stream.
+{
+ U32 v = 0;
+
+ for (;;)
+ {
+ S32 s = n - m_bitPos;
+ if (s > 0)
+ {
+ // Consume the entire buffer
+ v |= m_bitBuf << s;
+ n -= m_bitPos;
+
+ // Get the next buffer
+ m_bitBuf = GetByte();
+ m_bitPos = 8;
+ }
+ else
+ {
+ // Consume a portion of the buffer
+ v |= m_bitBuf >> -s;
+ m_bitPos -= n;
+ m_bitBuf &= 0xff >> (8 - m_bitPos); // mask off the consumed bits
+ return v;
+ }
+ }
+}
+
+void CInputScript::ParseFreeCharacter()
+{
+ U32 tagid = (U32) GetWord();
+
+ tagid = tagid;
+
+ printf("tagFreeCharacter \ttagid %-5u\n", tagid);
+}
+
+
+void CInputScript::ParsePlaceObject()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlPlaceObject;
+ ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter);
+
+ ctrl->character = getCharacter(GetWord());
+ ctrl->depth = GetWord();
+
+ GetMatrix(&(ctrl->matrix));
+
+ if ( m_filePos < m_tagEnd )
+ {
+ ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform);
+
+ GetCxform(&ctrl->cxform, false);
+ }
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParsePlaceObject2()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlPlaceObject2;
+
+ ctrl->flags = (PlaceFlags)GetByte();
+ ctrl->depth = GetWord();
+
+ // Get the tag if specified.
+ if (ctrl->flags & placeHasCharacter)
+ {
+ ctrl->character = getCharacter(GetWord());
+ }
+
+ // Get the matrix if specified.
+ if (ctrl->flags & placeHasMatrix)
+ {
+ GetMatrix(&(ctrl->matrix));
+ }
+
+ // Get the color transform if specified.
+ if (ctrl->flags & placeHasColorXform)
+ {
+ GetCxform(&ctrl->cxform, true);
+ }
+
+ // Get the ratio if specified.
+ if (ctrl->flags & placeHasRatio)
+ {
+ ctrl->ratio = GetWord();
+ }
+
+ // Get the ratio if specified.
+ if (ctrl->flags & placeHasName)
+ {
+ ctrl->name = strdup(GetString());
+ }
+
+ // Get the clipdepth if specified.
+ if (ctrl->flags & placeHasClip)
+ {
+ ctrl->clipDepth = GetWord();
+ }
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseRemoveObject()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlRemoveObject;
+ ctrl->character = getCharacter(GetWord());
+ ctrl->depth = GetWord();
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseRemoveObject2()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlRemoveObject2;
+ ctrl->depth = GetWord();
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseSetBackgroundColor()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlBackgroundColor;
+ ctrl->color.red = GetByte();
+ ctrl->color.green = GetByte();
+ ctrl->color.blue = GetByte();
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseDoAction()
+{
+ Control *ctrl;
+ ActionRecord *ar;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlDoAction;
+
+ do {
+ ar = ParseActionRecord();
+ if (ar) {
+ ctrl->addActionRecord( ar );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (ar);
+
+ program->addControlInCurrentFrame(ctrl);
+
+}
+
+
+void CInputScript::ParseStartSound()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->character = getCharacter(GetWord());
+ ctrl->type = ctrlStartSound;
+
+ program->addControlInCurrentFrame(ctrl);
+
+ if (!m_dumpAll)
+ return;
+
+ U32 code = GetByte();
+
+ printf("code %-3u", code);
+
+ if ( code & soundHasInPoint )
+ printf(" inpoint %u ", GetDWord());
+ if ( code & soundHasOutPoint )
+ printf(" oupoint %u", GetDWord());
+ if ( code & soundHasLoops )
+ printf(" loops %u", GetWord());
+
+ printf("\n");
+ if ( code & soundHasEnvelope )
+ {
+ int points = GetByte();
+
+ for ( int i = 0; i < points; i++ )
+ {
+ printf("\n");
+ printf("mark44 %u", GetDWord());
+ printf(" left chanel %u", GetWord());
+ printf(" right chanel %u", GetWord());
+ printf("\n");
+ }
+ }
+}
+
+
+void CInputScript::ParseStopSound()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlStopSound;
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseShapeData(int getAlpha, int getStyles)
+{
+ int shapeRecord = 0;
+
+ if (getStyles) {
+ // ShapeWithStyle
+ ParseFillStyle(getAlpha);
+ ParseLineStyle(getAlpha);
+ }
+
+ InitBits();
+ m_nFillBits = (U16) GetBits(4);
+ m_nLineBits = (U16) GetBits(4);
+
+ do {
+ shapeRecord = ParseShapeRecord(getAlpha);
+ } while (shapeRecord);
+}
+
+int
+CInputScript::ParseShapeRecord(long getAlpha)
+{
+ // Determine if this is an edge.
+ BOOL isEdge = (BOOL) GetBits(1);
+
+ if (!isEdge)
+ {
+ // Handle a state change
+ U16 flags = (U16) GetBits(5);
+
+ // Are we at the end?
+ if (flags == 0)
+ {
+ // End of shape
+ return 0;
+ }
+
+ // Process a move to.
+ if (flags & flagsMoveTo)
+ {
+ U16 nBits = (U16) GetBits(5);
+ GetSBits(nBits);
+ GetSBits(nBits);
+ }
+
+ // Get new fill info.
+ if (flags & flagsFill0)
+ {
+ GetBits(m_nFillBits);
+ }
+ if (flags & flagsFill1)
+ {
+ GetBits(m_nFillBits);
+ }
+
+ // Get new line info
+ if (flags & flagsLine)
+ {
+ GetBits(m_nLineBits);
+ }
+
+ // Check to get a new set of styles for a new shape layer.
+ if (flags & flagsNewStyles)
+ {
+ // Parse the style.
+ ParseFillStyle(getAlpha);
+ ParseLineStyle(getAlpha);
+
+ InitBits(); // Bug !
+
+ // Reset.
+ m_nFillBits = (U16) GetBits(4);
+ m_nLineBits = (U16) GetBits(4);
+ }
+
+ return flags & flagsEndShape ? 0 : 1;
+ }
+ else
+ {
+ if (GetBits(1))
+ {
+ // Handle a line
+ U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2
+
+ // Save the deltas
+ if (GetBits(1))
+ {
+ // Handle a general line.
+ GetSBits(nBits);
+ GetSBits(nBits);
+ }
+ else
+ {
+ // Handle a vert or horiz line.
+ GetBits(1);
+ GetSBits(nBits);
+ }
+ }
+ else
+ {
+ // Handle a curve
+ U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2
+
+ // Get the control
+ GetSBits(nBits);
+ GetSBits(nBits);
+
+ // Get the anchor
+ GetSBits(nBits);
+ GetSBits(nBits);
+ }
+
+ return 1;
+ }
+}
+
+
+void CInputScript::ParseFillStyle(long getAlpha)
+ //
+{
+ U16 i = 0;
+ FillType type;
+ Matrix matrix;
+
+ // Get the number of fills.
+ U16 nFills = GetByte();
+
+ // Do we have a larger number?
+ if (nFills == 255)
+ {
+ // Get the larger number.
+ nFills = GetWord();
+ }
+
+ // Get each of the fill style.
+ for (i = 0; i < nFills; i++)
+ {
+ U16 fillStyle = GetByte();
+
+ type = (FillType) fillStyle;
+
+ printf("fillstyle: type=%d\n",defs[i].type);
+ if (fillStyle & 0x10)
+ {
+ U16 nbGradients;
+
+ type = (FillType) (fillStyle & 0x12);
+
+ // Get the gradient matrix.
+ GetMatrix(&matrix);
+
+ // Get the number of colors.
+ nbGradients = GetByte();
+
+ // Get each of the colors.
+ for (U16 j = 0; j < nbGradients; j++)
+ {
+ GetByte();
+ GetByte();
+ GetByte();
+ GetByte();
+ if (getAlpha) {
+ GetByte();
+ }
+ }
+ }
+ else if (fillStyle & 0x40)
+ {
+ type = (FillType) (fillStyle & 0x41);
+
+ // Get the bitmapId
+ GetWord();
+
+ // Get the bitmap matrix.
+ GetMatrix(&matrix);
+ }
+ else
+ {
+ type = (FillType) 0;
+
+ // A solid color
+ GetByte();
+ GetByte();
+ GetByte();
+ if (getAlpha) {
+ GetByte();
+ }
+
+ printf("fillstyle: %x %x %x %x\n",
+ defs[i].color.red,
+ defs[i].color.green,
+ defs[i].color.blue,
+ defs[i].color.alpha);
+ }
+ }
+}
+
+void CInputScript::ParseLineStyle(long getAlpha)
+{
+ long i;
+
+ // Get the number of lines.
+ U16 nLines = GetByte();
+
+ // Do we have a larger number?
+ if (nLines == 255)
+ {
+ // Get the larger number.
+ nLines = GetWord();
+ }
+
+ // Get each of the line styles.
+ for (i = 0; i < nLines; i++)
+ {
+ GetWord();
+ GetByte();
+ GetByte();
+ GetByte();
+ if (getAlpha) {
+ GetByte();
+ }
+ }
+}
+
+
+void CInputScript::ParseDefineShape(int level)
+{
+ Shape *shape;
+ Rect rect;
+ U32 tagid;
+
+ tagid = (U32) GetWord();
+ shape = new Shape(tagid,level);
+ if (shape == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ shape->dict = this;
+
+ // Get the frame information.
+ GetRect(&rect);
+
+ shape->setBoundingBox(rect);
+
+ shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos);
+ if (shape->file_ptr == NULL) {
+ outOfMemory = 1;
+ delete shape;
+ return;
+ }
+ memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos);
+
+ shape->getStyles = 1;
+ shape->getAlpha = (level == 3);
+
+ ParseShapeData(level == 3, 1);
+
+ addCharacter(shape);
+}
+
+void CInputScript::S_DumpImageGuts()
+{
+#if 0
+ U32 lfCount = 0;
+ printf("----- dumping image details -----");
+ while (m_filePos < m_tagEnd)
+ {
+ if ((lfCount % 16) == 0)
+ {
+ fprintf(stdout, "\n");
+ }
+ lfCount += 1;
+ fprintf(stdout, "%02x ", GetByte());
+ }
+ fprintf(stdout, "\n");
+#endif
+}
+
+void CInputScript::ParseDefineBits()
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+
+ bitmap = new Bitmap(tagid,1);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]);
+
+ if (status < 0) {
+ fprintf(stderr,"Unable to read JPEG data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+
+void CInputScript::ParseDefineBitsJPEG2()
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+
+ bitmap = new Bitmap(tagid,2);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0);
+
+ if (status < 0) {
+ fprintf(stderr,"Unable to read JPEG data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+void CInputScript::ParseDefineBitsJPEG3()
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+ long offset;
+
+ printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid);
+
+ bitmap = new Bitmap(tagid,3);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ offset = GetDWord(); // Not in the specs !!!!
+
+ status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset);
+ if (status < 0) {
+ fprintf(stderr,"Unable to read JPEG data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+
+void CInputScript::ParseDefineBitsLossless(int level)
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+ int tableSize;
+
+ bitmap = new Bitmap(tagid,0);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ int format = GetByte();
+ int width = GetWord();
+ int height = GetWord();
+
+ tableSize = 0;
+
+ if (format == 3) {
+ tableSize = GetByte();
+ }
+
+ status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2);
+
+ if (status < 0) {
+ fprintf(stderr,"Unable to read ZLIB data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+void CInputScript::ParseJPEGTables()
+{
+ Bitmap::readJpegTables(&m_fileBuf[m_filePos]);
+}
+
+
+ButtonRecord * CInputScript::ParseButtonRecord(long getCxform)
+{
+ U16 state;
+ ButtonRecord *br;
+ long tagid;
+ Matrix matrix;
+ long layer;
+ Cxform *cxform;
+
+ state = (U16) GetByte();
+
+ if (state == 0) return 0;
+
+ br = new ButtonRecord;
+ if (br == NULL) {
+ outOfMemory = 1;
+ return 0;
+ }
+
+ tagid = GetWord();
+ layer = GetWord();
+ GetMatrix(&matrix);
+
+ if (br) {
+ br->state = (ButtonState) state;
+ br->character = getCharacter(tagid);
+ br->layer = layer;
+ br->cxform = 0;
+ br->buttonMatrix = matrix;
+ }
+
+ if (getCxform) {
+ cxform = new Cxform;
+ GetCxform(cxform, true);
+ if (br) {
+ br->cxform = cxform;
+ if (cxform == NULL) {
+ outOfMemory = 1;
+ }
+ }
+ }
+
+ return br;
+}
+
+ActionRecord * CInputScript::ParseActionRecord()
+{
+ U8 action;
+ U16 length = 0;
+ char *url, *target, *label;
+ long frameIndex, skipCount;
+ ActionRecord *ar;
+
+ action = GetByte();
+ if (action == 0) return 0;
+
+ ar = new ActionRecord;
+ if (ar == NULL) {
+ outOfMemory = 1;
+ return 0;
+ }
+
+ ar->action = (Action)action;
+
+ if (action & 0x80) {
+ length = GetWord();
+ }
+
+ switch (action) {
+ case ActionGotoFrame:
+ frameIndex = GetWord();
+ if (ar) {
+ ar->frameIndex = frameIndex;
+ }
+ break;
+ case ActionGetURL:
+ url = GetString();
+ target = GetString();
+ if (ar) {
+ ar->url = strdup(url);
+ ar->target = strdup(target);
+ }
+ break;
+ case ActionWaitForFrame:
+ frameIndex = GetWord();
+ skipCount = GetByte();
+ if (ar) {
+ ar->frameIndex = frameIndex;
+ ar->skipCount = skipCount;
+ }
+ break;
+ case ActionSetTarget:
+ target = strdup(GetString());
+ if (ar) {
+ ar->target = target;
+ }
+ break;
+ case ActionGoToLabel:
+ label = GetString();
+ if (ar) {
+ ar->frameLabel = strdup(label);
+ }
+ break;
+ default:
+ while (length--) {
+ GetByte();
+ }
+ break;
+ }
+
+ return ar;
+}
+
+void CInputScript::ParseDefineButton()
+{
+ Button *button;
+ ButtonRecord *buttonRecord;
+ ActionRecord *actionRecord;
+
+ U32 tagid = (U32) GetWord();
+
+ button = new Button(tagid);
+ if (button == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ do {
+ buttonRecord = ParseButtonRecord();
+ if (buttonRecord) {
+ button->addButtonRecord( buttonRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (buttonRecord);
+
+ do {
+ actionRecord = ParseActionRecord();
+ if (actionRecord) {
+ button->addActionRecord( actionRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (actionRecord);
+
+ addCharacter(button);
+}
+
+
+void CInputScript::ParseDefineButton2()
+{
+ Button *button;
+ ButtonRecord *buttonRecord;
+ ActionRecord *actionRecord;
+ U16 transition;
+ U16 offset;
+ U8 menu;
+
+ U32 tagid = (U32) GetWord();
+
+ button = new Button(tagid);
+
+ if (button == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ menu = GetByte();
+
+ offset = GetWord();
+
+ do {
+ buttonRecord = ParseButtonRecord(true);
+ if (buttonRecord) {
+ button->addButtonRecord( buttonRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (buttonRecord);
+
+ while (offset) {
+ offset = GetWord();
+
+ transition = GetWord();
+
+ do {
+ actionRecord = ParseActionRecord();
+ if (actionRecord) {
+ button->addActionRecord( actionRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (actionRecord);
+
+ button->addCondition( transition );
+ }
+
+ addCharacter(button);
+}
+
+
+void CInputScript::ParseDefineFont()
+{
+ SwfFont *font = 0;
+ U32 tagid = (U32) GetWord();
+ long start;
+ long nb,n;
+ long offset;
+ long *offsetTable = 0;
+ Shape *shapes = 0;
+
+ font = new SwfFont(tagid);
+ if (font == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ start = m_filePos;
+
+ offset = GetWord();
+ nb = offset/2;
+ offsetTable = new long[nb];
+ if (offsetTable == NULL) {
+ goto memory_error;
+ }
+ offsetTable[0] = offset;
+
+ for(n=1; n<nb; n++)
+ {
+ offsetTable[n] = GetWord();
+ }
+
+ shapes = new Shape[nb];
+ if (shapes == NULL) {
+ goto memory_error;
+ }
+
+ for(n=0; n<nb; n++)
+ {
+ long here;
+
+ m_filePos = offsetTable[n]+start;
+
+ here = m_filePos;
+ ParseShapeData(0, 0);
+
+ // Keep data for later parsing
+ shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
+ if (shapes[n].file_ptr == NULL) {
+ goto memory_error;
+ }
+ memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
+ }
+
+ font->setFontShapeTable(shapes,nb);
+
+ delete[] offsetTable;
+
+ addCharacter(font);
+ return;
+
+memory_error:
+ outOfMemory = 1;
+ if (offsetTable) delete offsetTable;
+ if (font) delete font;
+ if (shapes) delete[] shapes;
+}
+
+
+void CInputScript::ParseDefineMorphShape()
+{
+ U32 tagid = (U32) GetWord();
+
+ tagid = tagid;
+ printf("tagDefineMorphShape \ttagid %-5u\n", tagid);
+}
+
+void CInputScript::ParseDefineFontInfo()
+{
+ SwfFont *font;
+ U32 tagid = (U32) GetWord();
+ long nameLen;
+ char *name;
+ long n,nb;
+ FontFlags flags;
+ long *lut;
+
+ font = (SwfFont *)getCharacter(tagid);
+
+ if (font == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ nameLen = GetByte();
+ name = new char[nameLen+1];
+ if (name == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ for(n=0; n < nameLen; n++)
+ {
+ name[n] = GetByte();
+ }
+ name[n]=0;
+
+ font->setFontName(name);
+
+ delete name;
+
+ flags = (FontFlags)GetByte();
+
+ font->setFontFlags(flags);
+
+ nb = font->getNbGlyphs();
+
+ lut = new long[nb];
+ if (lut == NULL) {
+ outOfMemory = 1;
+ delete font;
+ return;
+ }
+
+ for(n=0; n < nb; n++)
+ {
+ if (flags & fontWideCodes) {
+ lut[n] = GetWord();
+ } else {
+ lut[n] = GetByte();
+ }
+ }
+
+ font->setFontLookUpTable(lut);
+}
+
+
+
+
+
+void CInputScript::ParseDefineFont2()
+{
+ int n;
+ U32 tagid = (U32) GetWord();
+ FontFlags flags;
+ char *name;
+ long nameLen;
+ long fontGlyphCount;
+ long *offsetTable = NULL;
+ Shape *shapes = NULL;
+ long start;
+ SwfFont *font;
+ long *lut = NULL;
+
+ font = new SwfFont(tagid);
+ if (font == NULL) {
+ goto memory_error;
+ }
+
+ flags = (FontFlags)GetWord();
+
+ font->setFontFlags(flags);
+
+ nameLen = GetByte();
+ name = new char[nameLen+1];
+ if (name == NULL) {
+ goto memory_error;
+ }
+ for(n=0; n < nameLen; n++)
+ {
+ name[n] = GetByte();
+ }
+ name[n]=0;
+
+ font->setFontName(name);
+
+ delete name;
+
+ fontGlyphCount = GetWord();
+
+ start = m_filePos;
+
+ offsetTable = new long[fontGlyphCount];
+ if (offsetTable == NULL) {
+ goto memory_error;
+ }
+ for (n=0; n<fontGlyphCount; n++) {
+ if (flags & 8) {
+ offsetTable[n] = GetDWord();
+ } else {
+ offsetTable[n] = GetWord();
+ }
+ }
+
+ shapes = new Shape[fontGlyphCount];
+ if (shapes == NULL) {
+ goto memory_error;
+ }
+
+ for (n=0; n<fontGlyphCount; n++) {
+ long here;
+
+ m_filePos = offsetTable[n]+start;
+
+ here = m_filePos;
+ ParseShapeData(0, 0);
+
+ // Keep data for later parsing
+ shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
+ if (shapes[n].file_ptr == NULL) {
+ goto memory_error;
+ }
+ memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
+ }
+
+ font->setFontShapeTable(shapes,fontGlyphCount);
+
+ lut = new long[fontGlyphCount];
+ if (lut == NULL) {
+ goto memory_error;
+ }
+
+ for(n=0; n < fontGlyphCount; n++)
+ {
+ if (flags & 4) {
+ lut[n] = GetWord();
+ } else {
+ lut[n] = GetByte();
+ }
+ }
+
+ font->setFontLookUpTable(lut);
+
+ delete offsetTable;
+
+ addCharacter(font);
+
+ // This is an incomplete parsing
+ return;
+
+memory_error:
+ outOfMemory = 1;
+ if (font) delete font;
+ if (offsetTable) delete offsetTable;
+ if (lut) delete lut;
+ if (shapes) delete[] shapes;
+}
+
+TextRecord * CInputScript::ParseTextRecord(int hasAlpha)
+{
+ TextRecord *tr;
+ TextFlags flags;
+
+ flags = (TextFlags) GetByte();
+ if (flags == 0) return 0;
+
+ tr = new TextRecord;
+ if (tr == NULL) {
+ outOfMemory = 1;
+ return 0;
+ }
+
+ tr->flags = flags;
+
+ if (flags & isTextControl) {
+ if (flags & textHasFont) {
+ long fontId;
+
+ fontId = GetWord();
+ tr->font = (SwfFont *)getCharacter(fontId);
+ }
+ if (flags & textHasColor) {
+ tr->color.red = GetByte();
+ tr->color.green = GetByte();
+ tr->color.blue = GetByte();
+ if (hasAlpha) {
+ tr->color.alpha = GetByte();
+ } else {
+ tr->color.alpha = ALPHA_OPAQUE;
+ }
+ }
+ if (flags & textHasXOffset) {
+ tr->xOffset = GetWord();
+ }
+ if (flags & textHasYOffset) {
+ tr->yOffset = GetWord();
+ }
+ if (flags & textHasFont) {
+ tr->fontHeight = GetWord();
+ }
+ tr->nbGlyphs = GetByte();
+ } else {
+ tr->flags = (TextFlags)0;
+ tr->nbGlyphs = (long)flags;
+ }
+
+ tr->glyphs = new Glyph[ tr->nbGlyphs ];
+ if (tr->glyphs == NULL) {
+ outOfMemory = 1;
+ delete tr;
+ return 0;
+ }
+
+ InitBits();
+ for (int g = 0; g < tr->nbGlyphs; g++)
+ {
+ tr->glyphs[g].index = GetBits(m_nGlyphBits);
+ tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits);
+ }
+
+ return tr;
+}
+
+void CInputScript::ParseDefineText(int hasAlpha)
+{
+ Text *text;
+ TextRecord *textRecord;
+ Matrix m;
+ Rect rect;
+ U32 tagid = (U32) GetWord();
+
+ text = new Text(tagid);
+ if (text == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ GetRect(&rect);
+ text->setTextBoundary(rect);
+
+ GetMatrix(&m);
+ text->setTextMatrix(m);
+
+ m_nGlyphBits = GetByte();
+ m_nAdvanceBits = GetByte();
+
+ do {
+ textRecord = ParseTextRecord(hasAlpha);
+ if (textRecord) {
+ text->addTextRecord( textRecord );
+ }
+ if (outOfMemory) {
+ delete text;
+ return;
+ }
+ if (m_filePos >= m_tagEnd) break;
+ } while (textRecord);
+
+ addCharacter(text);
+}
+
+
+void CInputScript::ParseDefineSound()
+{
+ Sound *sound;
+ U32 tagid = (U32) GetWord();
+ long nbSamples;
+ long flags;
+ char *buffer;
+
+ sound = new Sound(tagid);
+
+ flags = GetByte();
+ sound->setSoundFlags(flags);
+
+ nbSamples = GetDWord();
+ buffer = sound->setNbSamples(nbSamples);
+ if (buffer == NULL) {
+ outOfMemory = 1;
+ delete sound;
+ return;
+ }
+
+ if (flags & soundIsADPCMCompressed) {
+ Adpcm *adpcm;
+
+ adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo );
+
+ adpcm->Decompress((short *)buffer, nbSamples);
+
+ delete adpcm;
+ } else {
+ memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5);
+ }
+
+ addCharacter(sound);
+}
+
+
+void CInputScript::ParseDefineButtonSound()
+{
+ U32 tagid = (U32) GetWord();
+ Button *button;
+
+ tagid = tagid;
+
+ printf("tagDefineButtonSound \ttagid %-5u\n", tagid);
+
+ button = (Button *)getCharacter(tagid);
+
+ if (button == 0) {
+ printf(" Couldn't find Button id %d\n", tagid);
+ return;
+ }
+
+ // step through for button states
+ for (int i = 0; i < 4; i++)
+ {
+ Sound *sound;
+ U32 soundTag = GetWord();
+
+ sound = (Sound *)getCharacter(soundTag);
+
+ if (sound) {
+ button->setButtonSound(sound,i);
+ } else if (soundTag) {
+ printf(" Couldn't find Sound id %d\n", soundTag);
+ }
+
+ switch (i)
+ {
+ case 0:
+ printf("upState \ttagid %-5u\n", soundTag);
+ break;
+ case 1:
+ printf("overState \ttagid %-5u\n", soundTag);
+ break;
+ case 2:
+ printf("downState \ttagid %-5u\n", soundTag);
+ break;
+ }
+
+ if (soundTag)
+ {
+ U32 code = GetByte();
+ printf("sound code %u", code);
+
+ if ( code & soundHasInPoint )
+ printf(" inpoint %u", GetDWord());
+ if ( code & soundHasOutPoint )
+ printf(" outpoint %u", GetDWord());
+ if ( code & soundHasLoops )
+ printf(" loops %u", GetWord());
+
+ printf("\n");
+ if ( code & soundHasEnvelope )
+ {
+ int points = GetByte();
+
+ for ( int p = 0; p < points; p++ )
+ {
+ printf("\n");
+ printf("mark44 %u", GetDWord());
+ printf(" left chanel %u", GetWord());
+ printf(" right chanel %u", GetWord());
+ printf("\n");
+ }
+ }
+ }
+ if (m_filePos == m_tagEnd) break;
+ }
+}
+
+void CInputScript::ParseSoundStreamHead()
+{
+ int mixFormat = GetByte();
+
+ // The stream settings
+ int format = GetByte();
+ int nSamples = GetWord();
+
+ mixFormat = mixFormat;
+ format = format;
+ nSamples = nSamples;
+
+ printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples);
+}
+
+void CInputScript::ParseSoundStreamHead2()
+{
+ int mixFormat = GetByte();
+
+ // The stream settings
+ int format = GetByte();
+ int nSamples = GetWord();
+
+ mixFormat = mixFormat;
+ format = format;
+ nSamples = nSamples;
+
+ //printf("tagSoundStreamHead2 \tmixFormat %-3u format %-3u nSamples %-5u\n", mixFormat, format, nSamples);
+}
+
+void CInputScript::ParseSoundStreamBlock()
+{
+ printf("tagSoundStreamBlock\n");
+}
+
+void CInputScript::ParseDefineButtonCxform()
+{
+ ButtonRecord *br;
+ Button *button;
+ U32 tagid = (U32) GetWord();
+
+ button = (Button *)getCharacter(tagid);
+
+ for (br = button->getButtonRecords(); br; br = br->next)
+ {
+ br->cxform = new Cxform;
+ GetCxform(br->cxform, false);
+ }
+}
+
+void CInputScript::ParseNameCharacter()
+{
+ U32 tagid = (U32) GetWord();
+ char *label = strdup(GetString());
+
+ nameCharacter(tagid, label);
+}
+
+
+void CInputScript::ParseFrameLabel()
+{
+ char *label = strdup(GetString());
+ program->setCurrentFrameLabel(label);
+}
+
+
+void CInputScript::ParseDefineMouseTarget()
+{
+ printf("tagDefineMouseTarget\n");
+}
+
+
+void CInputScript::ParseDefineSprite()
+{
+ Sprite *sprite;
+ Program *prg;
+ int status;
+
+ U32 tagid = (U32) GetWord();
+ U32 frameCount = (U32) GetWord();
+
+ if (frameCount == 0) return;
+
+ printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount);
+
+ sprite = new Sprite(program->movie, tagid, frameCount);
+ if (sprite == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ if (sprite->getProgram() == NULL) {
+ delete sprite;
+ outOfMemory = 1;
+ return;
+ }
+
+ prg = sprite->getProgram();
+
+ // Set current program
+ program = prg;
+
+ ParseTags(&status);
+
+ if (outOfMemory) {
+ delete sprite;
+ return;
+ }
+
+ addCharacter(sprite);
+}
+
+
+void CInputScript::ParseUnknown(long code, long len)
+{
+ printf("Unknown Tag : %d - Length = %d\n", code, len);
+}
+
+
+void
+CInputScript::ParseTags(int *status)
+ // Parses the tags within the file.
+{
+
+ // Initialize the end of frame flag.
+ BOOL atEnd = false;
+
+ // Loop through each tag.
+ while (!atEnd)
+ {
+ U32 here;
+
+ // Get the current tag.
+ U16 code = GetTag();
+
+ if (code == notEnoughData) {
+ m_filePos = m_tagStart;
+ *status |= FLASH_PARSE_NEED_DATA;
+ return;
+ }
+
+ //printf("Code %d, tagLen %8u \n", code, m_tagLen);
+
+ here = m_filePos;
+
+ // Get the tag ending position.
+ U32 tagEnd = m_tagEnd;
+
+ if (m_tagEnd > m_actualSize) {
+ m_filePos = m_tagStart;
+ *status |= FLASH_PARSE_NEED_DATA;
+ return;
+ }
+
+ switch (code)
+ {
+ case stagProtect:
+ break;
+
+ case stagEnd:
+
+ // We reached the end of the file.
+ atEnd = true;
+
+ printf("End of Movie\n");
+
+ break;
+
+ case stagShowFrame:
+
+ // Validate frame
+ program->validateLoadingFrame();
+ *status |= FLASH_PARSE_WAKEUP;
+
+ break;
+
+ case stagFreeCharacter:
+ ParseFreeCharacter();
+ break;
+
+ case stagPlaceObject:
+ ParsePlaceObject();
+ break;
+
+ case stagPlaceObject2:
+ ParsePlaceObject2();
+ break;
+
+ case stagRemoveObject:
+ ParseRemoveObject();
+ break;
+
+ case stagRemoveObject2:
+ ParseRemoveObject2();
+ break;
+
+ case stagSetBackgroundColor:
+ ParseSetBackgroundColor();
+ break;
+
+ case stagDoAction:
+ ParseDoAction();
+ break;
+
+ case stagStartSound:
+ ParseStartSound();
+ break;
+
+ case stagStopSound:
+ ParseStopSound();
+ break;
+
+ case stagDefineShape:
+ ParseDefineShape(1);
+ break;
+
+ case stagDefineShape2:
+ ParseDefineShape(2);
+ break;
+
+ case stagDefineShape3:
+ ParseDefineShape(3);
+ break;
+
+ case stagDefineBits:
+ ParseDefineBits();
+ break;
+
+ case stagDefineBitsJPEG2:
+ ParseDefineBitsJPEG2();
+ break;
+
+ case stagDefineBitsJPEG3:
+ ParseDefineBitsJPEG3();
+ break;
+
+ case stagDefineBitsLossless:
+ ParseDefineBitsLossless(1);
+ break;
+
+ case stagDefineBitsLossless2:
+ ParseDefineBitsLossless(2);
+ break;
+
+ case stagJPEGTables:
+ ParseJPEGTables();
+ break;
+
+ case stagDefineButton:
+ ParseDefineButton();
+ break;
+
+ case stagDefineButton2:
+ ParseDefineButton2();
+ break;
+
+ case stagDefineFont:
+ ParseDefineFont();
+ break;
+
+ case stagDefineMorphShape:
+ ParseDefineMorphShape();
+ break;
+
+ case stagDefineFontInfo:
+ ParseDefineFontInfo();
+ break;
+
+ case stagDefineText:
+ ParseDefineText(0);
+ break;
+
+ case stagDefineText2:
+ ParseDefineText(1);
+ break;
+
+ case stagDefineSound:
+ ParseDefineSound();
+ break;
+
+ case stagDefineButtonSound:
+ ParseDefineButtonSound();
+ break;
+
+ case stagSoundStreamHead:
+ ParseSoundStreamHead();
+ break;
+
+ case stagSoundStreamHead2:
+ ParseSoundStreamHead2();
+ break;
+
+ case stagSoundStreamBlock:
+ ParseSoundStreamBlock();
+ break;
+
+ case stagDefineButtonCxform:
+ ParseDefineButtonCxform();
+ break;
+
+ case stagDefineSprite:
+ Program *save;
+
+ save = program;
+ ParseDefineSprite();
+ program->rewindMovie();
+ program = save;
+ break;
+
+ case stagNameCharacter:
+ ParseNameCharacter();
+ break;
+
+ case stagFrameLabel:
+ ParseFrameLabel();
+ break;
+
+ case stagDefineFont2:
+ ParseDefineFont2();
+ break;
+
+ default:
+ ParseUnknown(code, m_tagLen);
+ break;
+ }
+
+ //printf("Bytes read = %d\n", m_filePos-here);
+
+ // Increment the past the tag.
+ m_filePos = tagEnd;
+
+ if (outOfMemory) {
+ fprintf(stderr,"Flash: Out of memory\n");
+ *status |= FLASH_PARSE_OOM;
+ return;
+ }
+ }
+
+ program->validateLoadingFrame();
+ *status |= FLASH_PARSE_EOM;
+}
+
+int
+CInputScript::ParseData(FlashMovie *movie, char * data, long size)
+{
+ int status = FLASH_PARSE_ERROR;
+
+ m_fileBuf = (unsigned char *)data;
+ m_actualSize = size;
+
+ if (needHeader) {
+
+ // Do we have sufficient data to read the header ?
+ if (size < 21) {
+ return FLASH_PARSE_NEED_DATA; // No, need more data
+ }
+
+ needHeader = 0; // Yes
+
+ U8 fileHdr[8];
+
+ memcpy(fileHdr,data,8);
+
+ // Verify the header and get the file size.
+ if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' )
+ {
+ //fprintf(stderr, "Not a Flash File.\n");
+ return FLASH_PARSE_ERROR; // Error
+ }
+ else
+ {
+ // Get the file version.
+ m_fileVersion = (U16) fileHdr[3];
+ }
+
+ // Get the file size.
+ m_fileSize = (U32) fileHdr[4]
+ | ((U32) fileHdr[5] << 8)
+ | ((U32) fileHdr[6] << 16)
+ | ((U32) fileHdr[7] << 24);
+
+ // Verify the minimum length of a Flash file.
+ if (m_fileSize < 21)
+ {
+ //printf("ERROR: File size is too short\n");
+ return FLASH_PARSE_ERROR; // Error
+ }
+
+ // Set the file position past the header and size information.
+ m_filePos = 8;
+
+ // Get the frame information.
+ GetRect(&frameRect);
+
+ frameRate = GetWord() >> 8;
+
+ frameCount = GetWord();
+
+ program = new Program(movie, frameCount);
+
+ if (program == NULL || program->totalFrames == 0) {
+ return FLASH_PARSE_ERROR;
+ }
+
+ status |= FLASH_PARSE_START;
+ }
+
+ ParseTags(&status);
+
+ return status;
+}
+
+