📄 swftophp.c
字号:
/* $Id: swftophp.c,v 1.7 2003/12/14 10:07:14 whamann Exp $ *//* convert everything to objects, resolve dependencies, etc.. */#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <math.h>#include "blocktypes.h"#include "action.h"#include "read.h"#include "decompile.h"#include "swftophp.h"#ifndef M_PI #define M_PI 3.14159265358979f#endifvoid skipBytes(FILE *f, int length);char *blockName(int);static m_version = {0};void decompileAction(FILE *f, int length, int indent){ if(m_version >= 5) decompile5Action(f, length, indent); else if(m_version > 3) decompile4Action(f, length, indent); else while(--length >= 0) readUInt8(f);}void readMatrix(FILE *f, struct Matrix *s){ int nBits; byteAlign(); if(readBits(f, 1)) /* has scale */ { nBits = readBits(f, 5); s->xScale = (float)readSBits(f, nBits)/0x10000; s->yScale = (float)readSBits(f, nBits)/0x10000; } else s->xScale = s->yScale = 1.0; if(readBits(f, 1)) /* has rotate */ { nBits = readBits(f, 5); s->rot0 = (float)readSBits(f, nBits)/0x10000; s->rot1 = (float)readSBits(f, nBits)/0x10000; } else s->rot0 = s->rot1 = 0; nBits = readBits(f, 5); s->x = readSBits(f, nBits); s->y = readSBits(f, nBits);}void readCXForm(FILE *f, struct CXForm *s, boolean hasAlpha){ int hasAdd, hasMult, nBits; byteAlign(); hasAdd = readBits(f, 1); hasMult = readBits(f, 1); nBits = readBits(f, 4); if(hasMult) { s->rMult = readSBits(f, nBits); s->gMult = readSBits(f, nBits); s->bMult = readSBits(f, nBits); if(hasAlpha) s->aMult = readSBits(f, nBits); else s->aMult = 0x100; } else { s->aMult = 0x100; s->rMult = 0x100; s->gMult = 0x100; s->bMult = 0x100; } if(hasAdd) { s->rAdd = readSBits(f, nBits); s->gAdd = readSBits(f, nBits); s->bAdd = readSBits(f, nBits); if(hasAlpha) s->aAdd = readSBits(f, nBits); else s->aAdd = 0; } else { s->aAdd = 0; s->rAdd = 0; s->gAdd = 0; s->bAdd = 0; }}void readRect(FILE *f, struct Rect *s){ int nBits; byteAlign(); nBits = readBits(f, 5); s->xMin = readSBits(f, nBits); s->xMax = readSBits(f, nBits); s->yMin = readSBits(f, nBits); s->yMax = readSBits(f, nBits);}void readRGB(FILE *f, struct RGBA *s){ s->r = readUInt8(f); s->g = readUInt8(f); s->b = readUInt8(f); s->a = 0xff;}void readRGBA(FILE *f, struct RGBA *s){ s->r = readUInt8(f); s->g = readUInt8(f); s->b = readUInt8(f); s->a = readUInt8(f);}void printRGBA(struct RGBA *s){ printf("0x%02x, 0x%02x, 0x%02x", s->r, s->g, s->b); if(s->a != 0xff) printf(", 0x%02x", s->a);}void readGradient(FILE *f, struct Gradient *s, Blocktype shapeType){ int i; int numGrads = readUInt8(f); s->nGradients = numGrads; s->colors = malloc(sizeof(struct RGBA)*numGrads); s->ratio = malloc(sizeof(int)*numGrads); for(i=0; i<numGrads; ++i) { s->ratio[i] = readUInt8(f); if(shapeType==DEFINESHAPE3) readRGBA(f, &(s->colors[i])); else readRGB(f, &(s->colors[i])); }}void printGradient(struct Gradient *g){ int i; printf("\t$g = new SWFGradient();\n"); for(i=0; i<g->nGradients; ++i) { printf("\t$g->addEntry(%f, ", g->ratio[i]/255.0); printRGBA(&(g->colors[i])); printf(");\n"); }}void readLineStyleArray(FILE *f, struct Shape *shape, int isMorph){ struct LineStyles *s; struct LineStyle *l; int count, i; int start = shape->lines.nLines; shape->lineOffset = start; count = readUInt8(f); if(count==255) count = readUInt16(f); s = &(shape->lines); s->nLines += count; s->line = realloc(s->line, s->nLines * sizeof(struct LineStyle)); for(i=0; i<count; ++i) { l = &(s->line[start+i]); l->width = readUInt16(f); if(isMorph) l->width2 = readUInt16(f); if(shape->shapeType == DEFINESHAPE3) readRGBA(f, &(l->color)); else readRGB(f, &(l->color)); if(isMorph) readRGBA(f, &(l->color2)); }}void readFillStyle(FILE *f, struct FillStyle *s, Blocktype shapeType, int isMorph){ int type; type = readUInt8(f); s->type = type; if(type==0) /* solid fill */ { if(shapeType==DEFINESHAPE3) readRGBA(f, &(s->fill.color)); else readRGB(f, &(s->fill.color)); if(isMorph) readRGBA(f, &(s->fill2.color)); } else if(type==0x10 || type==0x12) { /* linear (0x10) or radial (0x10) gradient */ readMatrix(f, &(s->matrix)); if(isMorph) readMatrix(f, &(s->matrix2)); readGradient(f, &(s->fill.gradient), shapeType); } else if(type==0x40 || type==0x41) { /* tiled bitmap (0x40) or clipped bitmap (0x41) fill */ s->fill.bitmap = readUInt16(f); readMatrix(f, &(s->matrix)); if(isMorph) readMatrix(f, &(s->matrix2)); } else error("Unknown fill type: %i\n", type);}void printTransform(struct Matrix *m, char ch, int num, int always){ float a = m->xScale, b = m->rot0, c = m->rot1, d = m->yScale; float angle; float xScale = sqrt(a*a+c*c); float yScale = (a*d-b*c)/xScale; float skew = (a*b+c*d)/(a*a+c*c); if(a==0) { if(c<0) angle = -90; else angle = 90; } else { angle = atan(c/a)*180/M_PI; if(a<0) { if(angle < 0) angle += 180; else angle -= 180; } }#define TOLERANCE 0.02 if(skew < -TOLERANCE || skew > TOLERANCE) printf("\t$%c%i->skewXTo(%f);\n", ch, num, skew); if(xScale > 1.0-TOLERANCE && xScale < 1.0+TOLERANCE) xScale = 1.0; if(yScale > 1.0-TOLERANCE && yScale < 1.0+TOLERANCE) yScale = 1.0; if((xScale != 1.0) || (yScale != 1.0) || always) { if(xScale == yScale) printf("\t$%c%i->scaleTo(%f);\n", ch, num, xScale); else printf("\t$%c%i->scaleTo(%f, %f);\n", ch, num, xScale, yScale); } if(angle < -TOLERANCE || angle > TOLERANCE) printf("\t$%c%i->rotateTo(%f);\n", ch, num, angle); if(m->x != 0 || m->y != 0) printf("\t$%c%i->moveTo(%i, %i);\n", ch, num, m->x, m->y);}void printFillStyle(struct FillStyle *s, int id, int num, int isMorph){ switch(s->type) { case 0: return; case 0x10: printGradient(&(s->fill.gradient)); printf("\t$f%i = $s%i->addFill($g, SWFFILL_LINEAR_GRADIENT);\n", num, id); break; case 0x12: printGradient(&(s->fill.gradient)); printf("\t$f%i = $s%i->addFill($g, SWFFILL_RADIAL_GRADIENT);\n", num, id); break; case 0x40: printf("\t$f%i = $s%i->addFill($b%i, SWFFILL_TILED_BITMAP);\n", num, id, s->fill.bitmap); break; case 0x41: printf("\t$f%i = $s%i->addFill($b%i, SWFFILL_CLIPPED_BITMAP);\n", num, id, s->fill.bitmap); break; default: error("Unknown fill type: 0x%02x!", s->type); } if(isMorph) { if(s->type == 0x40 || s->type == 0x41) printTransform(&(s->matrix2), 'f', num, 0); } else printTransform(&(s->matrix), 'f', num, 0);}void readFillStyleArray(FILE *f, struct Shape *shape, int isMorph){ struct FillStyles *s; int count, i, start; start = shape->fills.nFills; shape->fillOffset = start; count = readUInt8(f); if(count==255) count = readUInt16(f); s = &(shape->fills); s->nFills += count; s->fill = realloc(s->fill, s->nFills * sizeof(struct FillStyle)); for(i=0; i<count; ++i) readFillStyle(f, &(s->fill[start+i]), shape->shapeType, isMorph);}int readShapeRec(FILE *f, struct Shape *shape){ struct ShapeRecord *s; int type; shape->shapes.shape = realloc(shape->shapes.shape, (shape->shapes.nShapes+1) * sizeof(struct ShapeRecord)); s = &(shape->shapes.shape[shape->shapes.nShapes]); ++shape->shapes.nShapes; type = readBits(f, 1); if(type==0) /* state change */ { int newStyles = readBits(f, 1); int lineStyle = readBits(f, 1); int fillStyle1 = readBits(f, 1); int fillStyle0 = readBits(f, 1); int moveTo = readBits(f, 1); if(newStyles==0 && lineStyle==0 && fillStyle1==0 && fillStyle0==0 && moveTo==0) { s->type = SHAPERECORD_END; return 0; } s->type = SHAPERECORD_STATECHANGE; if(moveTo==1) { int moveBits = readBits(f, 5); s->data.change.movetox = readSBits(f, moveBits); s->data.change.movetoy = readSBits(f, moveBits); } else { s->data.change.movetox = 0; s->data.change.movetoy = 0; } if(fillStyle0==1) { int num = readBits(f, shape->fillBits); s->data.change.fill0 = (num==0) ? 0 : num + shape->fillOffset; } else s->data.change.fill0 = -1; if(fillStyle1==1) { int num = readBits(f, shape->fillBits); s->data.change.fill1 = (num==0) ? 0 : num + shape->fillOffset; } else s->data.change.fill1 = -1; if(lineStyle==1) { int num = readBits(f, shape->lineBits); s->data.change.line = (num==0) ? 0 : num + shape->lineOffset; } else s->data.change.line = -1; if(newStyles==1) { readFillStyleArray(f, shape, 0); readLineStyleArray(f, shape, 0); shape->fillBits = readBits(f, 4); shape->lineBits = readBits(f, 4); } } else /* it's an edge record */ { int straight = readBits(f, 1); int numBits = readBits(f, 4)+2; if(straight==1) { s->type = SHAPERECORD_LINE; if(readBits(f, 1)) /* general line */ { s->data.line.x = readSBits(f, numBits); s->data.line.y = readSBits(f, numBits); } else if(readBits(f, 1)) /* vert = 1 */ { s->data.line.x = 0; s->data.line.y = readSBits(f, numBits); } else { s->data.line.x = readSBits(f, numBits); s->data.line.y = 0; } } else { s->type = SHAPERECORD_CURVE; s->data.curve.controlx = readSBits(f, numBits); s->data.curve.controly = readSBits(f, numBits); s->data.curve.anchorx = readSBits(f, numBits); s->data.curve.anchory = readSBits(f, numBits); } } return 1;}void printFillChange(int id, struct Shape *shape, int fillNum, int side){ if(fillNum == 0) printf("\t$s%i->set%sFill(0);\n", id, side==0 ? "Left" : "Right"); else if(shape->fills.fill[fillNum-1].type == 0) { printf("\t$s%i->set%sFill(", id, side==0 ? "Left" : "Right"); printRGBA(&(shape->fills.fill[fillNum-1].fill.color)); printf(");\n"); } else printf("\t$s%i->set%sFill($f%i);\n", id, side==0 ? "Left" : "Right", fillNum);}void printShapeRec(struct Shape *shape, struct ShapeRecord *s, int id){ switch(s->type) { case SHAPERECORD_END: return; case SHAPERECORD_STATECHANGE: if(s->data.change.movetox != 0 || s->data.change.movetoy != 0) printf("\t$s%i->movePenTo(%i, %i);\n", id, s->data.change.movetox, s->data.change.movetoy); if(s->data.change.fill0 != -1) printFillChange(id, shape, s->data.change.fill0, 0); if(s->data.change.fill1 != -1) printFillChange(id, shape, s->data.change.fill1, 1); if(s->data.change.line != -1) { if(s->data.change.line == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -