Files
unity-flash-tools/Assets/FlashTools/Scripts/Internal/Editor/FlashAnimSwfUtils.cs
2016-03-09 03:34:24 +06:00

400 lines
9.6 KiB
C#

using UnityEngine;
using System.IO;
using System.Text;
namespace FlashTools.Internal {
class SwfStreamReader {
struct BitContext {
public byte CachedByte;
public byte BitIndex;
}
BitContext _bitContext;
BinaryReader _reader;
long Length {
get { return _reader.BaseStream.Length; }
}
long Position {
get { return _reader.BaseStream.Position; }
}
long BytesLeft {
get { return Length - Position; }
}
public SwfStreamReader(string path) {
_reader = new BinaryReader(File.OpenRead(path));
}
public SwfStreamReader(Stream stream) {
_reader = new BinaryReader(stream);
}
public BinaryReader Reader {
get { return _reader; }
}
public bool ReadBit() {
var bitIndex = _bitContext.BitIndex & 0x07;
if ( bitIndex == 0 ) {
_bitContext.CachedByte = Reader.ReadByte();
}
++_bitContext.BitIndex;
return ((_bitContext.CachedByte << bitIndex) & 0x80) != 0;
}
public int ReadSignedBits(uint count) {
if ( count == 0 ) {
return 0;
}
bool sign = ReadBit();
var res = sign ? uint.MaxValue : 0;
--count;
for ( var i = 0; i < count; ++i ) {
var bit = ReadBit();
res = (res << 1 | (bit ? 1u : 0u));
}
return (int)res;
}
public uint ReadUnsignedBits(uint count) {
if ( count == 0 ) {
return 0;
}
uint res = 0;
for ( var i = 0; i < count; ++i ) {
var bit = ReadBit();
res = (res << 1 | (bit ? 1u : 0u));
}
return res;
}
public void AlignToByte() {
_bitContext.BitIndex = 0;
_bitContext.CachedByte = 0;
}
public string ReadString() {
var data_stream = new MemoryStream();
byte bt = 1;
while ( bt > 0 ) {
bt = _reader.ReadByte();
if ( bt > 0 ) {
data_stream.WriteByte(bt);
}
}
return Encoding.UTF8.GetString(data_stream.ToArray());
}
public float ReadFixedPoint8() {
return Reader.ReadInt16() / 256.0f;
}
public float ReadFixedPoint16(uint bits) {
var value = ReadSignedBits(bits);
return value / 65536.0f;
}
public uint ReadEncodedU32() {
AlignToByte();
uint val = 0;
var bt = _reader.ReadByte();
val |= bt & 0x7fu;
if ((bt & 0x80) == 0) return val;
bt = _reader.ReadByte();
val |= (bt & 0x7fu) << 7;
if ((bt & 0x80) == 0) return val;
bt = _reader.ReadByte();
val |= (bt & 0x7fu) << 14;
if ((bt & 0x80) == 0) return val;
bt = _reader.ReadByte();
val |= (bt & 0x7fu) << 21;
if ((bt & 0x80) == 0) return val;
bt = _reader.ReadByte();
val |= (bt & 0x7fu) << 28;
return val;
}
public byte[] ReadRest() {
return Reader.ReadBytes((int)BytesLeft);
}
public bool IsEOF {
get { return Position == Length; }
}
}
enum SwfBlendMode : byte {
Normal = 0,
Normal1 = 1,
Layer = 2,
Multiply = 3,
Screen = 4,
Lighten = 5,
Darken = 6,
Difference = 7,
Add = 8,
Subtract = 9,
Invert = 10,
Alpha = 11,
Erase = 12,
Overlay = 13,
Hardlight = 14
}
struct SwfHeader {
public string Format;
public byte Version;
public uint FileLength;
public SwfRect FrameSize;
public float FrameRate;
public ushort FrameCount;
public static SwfHeader Read(SwfStreamReader reader) {
var header = new SwfHeader();
header.Format = new string(reader.Reader.ReadChars(3));
header.Version = reader.Reader.ReadByte();
header.FileLength = reader.Reader.ReadUInt32();
header.FrameSize = SwfRect.Read(reader);
header.FrameRate = reader.ReadFixedPoint8();
header.FrameCount = reader.Reader.ReadUInt16();
return header;
}
public override string ToString() {
return string.Format(
"Format: {0}, Version: {1}, FileLength: {2}, FrameSize: {3}, FrameRate: {4}, FrameCount: {5}",
Format, Version, FileLength, FrameSize, FrameRate, FrameCount);
}
}
struct SceneOffsetData {
public uint Offset;
public string Name;
}
struct FrameLabelData {
public uint Number;
public string Label;
}
struct SwfRGB {
public byte Red;
public byte Green;
public byte Blue;
public static SwfRGB Read(SwfStreamReader reader) {
var rgb = new SwfRGB();
rgb.Red = reader.Reader.ReadByte();
rgb.Green = reader.Reader.ReadByte();
rgb.Blue = reader.Reader.ReadByte();
return rgb;
}
public override string ToString() {
return string.Format(
"R: {0}, G: {1}, B: {2}",
Red, Green, Blue);
}
}
struct SwfRGBA {
public byte Red;
public byte Green;
public byte Blue;
public byte Alpha;
public static SwfRGBA Read(SwfStreamReader reader) {
var rgba = new SwfRGBA();
rgba.Red = reader.Reader.ReadByte();
rgba.Green = reader.Reader.ReadByte();
rgba.Blue = reader.Reader.ReadByte();
rgba.Alpha = reader.Reader.ReadByte();
return rgba;
}
public override string ToString() {
return string.Format(
"R: {0}, G: {1}, B: {2}, A: {3}",
Red, Green, Blue, Alpha);
}
}
struct SwfRect {
public float XMin;
public float XMax;
public float YMin;
public float YMax;
public static SwfRect Read(SwfStreamReader reader) {
var rect = new SwfRect();
var bits = reader.ReadUnsignedBits(5);
rect.XMin = reader.ReadSignedBits(bits) / 20.0f;
rect.XMax = reader.ReadSignedBits(bits) / 20.0f;
rect.YMin = reader.ReadSignedBits(bits) / 20.0f;
rect.YMax = reader.ReadSignedBits(bits) / 20.0f;
reader.AlignToByte();
return rect;
}
public override string ToString() {
return string.Format(
"XMin: {0}, XMax: {1}, YMin: {2}, YMax: {3}",
XMin, XMax, YMin, YMax);
}
}
struct SwfMatrix {
public float ScaleX;
public float ScaleY;
public float RotateSkew0;
public float RotateSkew1;
public int TranslateX;
public int TranslateY;
public static SwfMatrix Identity {
get {
return new SwfMatrix {
ScaleX = 1,
ScaleY = 1,
RotateSkew0 = 0,
RotateSkew1 = 0,
TranslateX = 0,
TranslateY = 0
};
}
}
public static SwfMatrix Read(SwfStreamReader reader) {
var matrix = SwfMatrix.Identity;
var has_scale = reader.ReadBit();
if ( has_scale ) {
var bits = (byte)reader.ReadUnsignedBits(5);
matrix.ScaleX = reader.ReadFixedPoint16(bits);
matrix.ScaleY = reader.ReadFixedPoint16(bits);
}
var has_rotate = reader.ReadBit();
if ( has_rotate ) {
var bits = (byte)reader.ReadUnsignedBits(5);
matrix.RotateSkew0 = reader.ReadFixedPoint16(bits);
matrix.RotateSkew1 = reader.ReadFixedPoint16(bits);
}
var translate_bits = (byte)reader.ReadUnsignedBits(5);
matrix.TranslateX = reader.ReadSignedBits(translate_bits);
matrix.TranslateY = reader.ReadSignedBits(translate_bits);
reader.AlignToByte();
return matrix;
}
public override string ToString() {
return string.Format(
"ScaleX: {0}, ScaleY: {1}, RotateSkew0: {2}, RotateSkew1: {3}, TranslateX: {4}, TranslateY: {5}",
ScaleX, ScaleY, RotateSkew0, RotateSkew1, TranslateX, TranslateY);
}
}
struct SwfColorTransformRGB {
public short RMul;
public short GMul;
public short BMul;
public bool HasMul;
public short RAdd;
public short GAdd;
public short BAdd;
public bool HasAdd;
public static SwfColorTransformRGB Read(SwfStreamReader reader) {
SwfColorTransformRGB transform;
var has_add = reader.ReadBit();
var has_mul = reader.ReadBit();
var bits = reader.ReadUnsignedBits(4);
if ( has_mul ) {
transform.RMul = (short)reader.ReadSignedBits(bits);
transform.GMul = (short)reader.ReadSignedBits(bits);
transform.BMul = (short)reader.ReadSignedBits(bits);
transform.HasMul = true;
} else {
transform.RMul = 1;
transform.GMul = 1;
transform.BMul = 1;
transform.HasMul = false;
}
if ( has_add ) {
transform.RAdd = (short)reader.ReadSignedBits(bits);
transform.GAdd = (short)reader.ReadSignedBits(bits);
transform.BAdd = (short)reader.ReadSignedBits(bits);
transform.HasAdd = true;
} else {
transform.RAdd = 0;
transform.GAdd = 0;
transform.BAdd = 0;
transform.HasAdd = false;
}
reader.AlignToByte();
return transform;
}
}
struct SwfColorTransformRGBA {
public short RMul;
public short GMul;
public short BMul;
public short AMul;
public bool HasMul;
public short RAdd;
public short GAdd;
public short BAdd;
public short AAdd;
public bool HasAdd;
public static SwfColorTransformRGBA Read(SwfStreamReader reader) {
SwfColorTransformRGBA transform;
var has_add = reader.ReadBit();
var has_mul = reader.ReadBit();
var bits = reader.ReadUnsignedBits(4);
if ( has_mul ) {
transform.RMul = (short)reader.ReadSignedBits(bits);
transform.GMul = (short)reader.ReadSignedBits(bits);
transform.BMul = (short)reader.ReadSignedBits(bits);
transform.AMul = (short)reader.ReadSignedBits(bits);
transform.HasMul = true;
} else {
transform.RMul = 1;
transform.GMul = 1;
transform.BMul = 1;
transform.AMul = 1;
transform.HasMul = false;
}
if ( has_add ) {
transform.RAdd = (short)reader.ReadSignedBits(bits);
transform.GAdd = (short)reader.ReadSignedBits(bits);
transform.BAdd = (short)reader.ReadSignedBits(bits);
transform.AAdd = (short)reader.ReadSignedBits(bits);
transform.HasAdd = true;
} else {
transform.RAdd = 0;
transform.GAdd = 0;
transform.BAdd = 0;
transform.AAdd = 0;
transform.HasAdd = false;
}
reader.AlignToByte();
return transform;
}
}
struct SwfClipActions {
public static SwfClipActions Read(SwfStreamReader reader) {
throw new UnityException("implme!");
}
}
struct SwfSurfaceFilters {
public static SwfSurfaceFilters Read(SwfStreamReader reader) {
throw new UnityException("implme!");
}
}
}