📄 script.cpp
字号:
#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: script.cc,v 1.8 1999/09/10 06:01:21 ode Exp $";
#endif
//#define printf(fmt,args...)
extern int __cdecl printf (
const char *format,
...
);
//////////////////////////////////////////////////////////////////////
// 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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -