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!"); } } }