📄 script.cc
字号:
#include "swf.h"////////////////////////////////////////////////////////////// This file is derived from the 'buggy' SWF parser provided// by Macromedia.//// Modifications : Olivier Debon <odebon@club-internet.fr>// #ifdef RCSIDstatic char *rcsid = "$Id: script.cc,v 1.1 2003/09/08 19:41:59 jasonk Exp $";#endif#ifndef NDEBUG#define printf(fmt, args...)#endif//////////////////////////////////////////////////////////////////////// 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);}intCInputScript::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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -