public static IEnumerable <Image> ParseImagesFromSwfFile(Stream stream) { using (stream) { using var reader = new BittableBinaryReader(stream); var header = Encoding.ASCII.GetString(reader.ReadBytes(3)); if (header == "ZWS") { throw new InvalidOperationException($"Unspported file type '{header}'."); } else if (header != "CWS" && header != "FWS") { throw new InvalidDataException("Not a valid SWF file."); } var versionNumber = reader.ReadByte(); var fileLength = reader.ReadInt32(); //This is the uncompressed length, so won't match file size for CWF if (header == "CWS") { //CWS Files are compressed with Zlib reader.ReadBytes(2); //Skip the zlib header, since DeflateStream won't process it correctly using var compressedReader = new BittableBinaryReader(new DeflateStream(reader.BaseStream, CompressionMode.Decompress)); return(ReadHeaderAndImages(compressedReader)); } return(ReadHeaderAndImages(reader)); } }
private static List <SwfTag> ReadTags(BittableBinaryReader reader) { var tags = new List <SwfTag>(); do { tags.Add(ReadTag(reader)); } while (tags[tags.Count - 1].Code != SwfTagCode.End); return(tags); }
private static void ReadRect(BittableBinaryReader reader) { //This is the "twip" sized boundaries of the SWF int length = reader.ReadBits(5); //Bit length of bounds _ = reader.ReadBits(length); //xMin _ = reader.ReadBits(length); //xMax _ = reader.ReadBits(length); //yMin _ = reader.ReadBits(length); //yMax }
private static IEnumerable <Image> ReadHeaderAndImages(BittableBinaryReader reader) { ReadRect(reader); var framerate = reader.ReadInt16(); var frameCount = reader.ReadInt16(); var tags = ReadTags(reader); return(tags.Where(t => IMAGE_CODES.Contains(t.Code)).Select(t => HandleImageTag(t))); }
private static SwfTag ReadTag(BittableBinaryReader reader) { uint tagCodeAndLength = reader.ReadUInt16(); uint code = (tagCodeAndLength & 0b1111_1111_1100_0000) >> 6; //upper 10 bits are code uint length = tagCodeAndLength & 0b0011_1111; //lower 6 bits are length if (length == 0b0011_1111) { //If all length bits are set, this is a large block and uses a UInt to signal size length = reader.ReadUInt32(); } var data = reader.ReadBytes((int)length); //This cast isn't safe, probably should check this return(new SwfTag() { Code = (SwfTagCode)code, Data = data }); }