public Dune2ShpReader(Stream stream) { BinaryReader reader = new BinaryReader(stream); ImageCount = reader.ReadUInt16(); //Last offset is pointer to end of file. uint[] offsets = new uint[ImageCount + 1]; uint temp = reader.ReadUInt32(); //If fourth byte in file is non-zero, the offsets are two bytes each. bool twoByteOffsets = (temp & 0xFF0000) > 0; if (twoByteOffsets) { offsets[0] = ((temp & 0xFFFF0000) >> 16) + 2; //Offset does not account for image count bytes offsets[1] = (temp & 0xFFFF) + 2; } else { offsets[0] = temp + 2; } for (int i = twoByteOffsets ? 2 : 1; i < ImageCount + 1; i++) { offsets[i] = (twoByteOffsets ? reader.ReadUInt16() : reader.ReadUInt32()) + 2; } for (int i = 0; i < ImageCount; i++) { reader.BaseStream.Seek(offsets[i], SeekOrigin.Begin); Dune2ImageHeader header = new Dune2ImageHeader(reader); byte[] imgData = reader.ReadBytes(header.FileSize); header.Image = new byte[header.Height * header.Width]; //Decode image data if (header.Flags != Dune2ImageFlags.F2) { byte[] tempData = new byte[header.DataSize]; Format80.DecodeInto(imgData, tempData); Format2.DecodeInto(tempData, header.Image); } else { Format2.DecodeInto(imgData, header.Image); } //Lookup values in lookup table if (header.LookupTable != null) { for (int j = 0; j < header.Image.Length; j++) { header.Image[j] = header.LookupTable[header.Image[j]]; } } headers.Add(header); } }
public Frame(Stream s) { var flags = (FormatFlags)s.ReadUInt16(); s.Position += 1; var width = s.ReadUInt16(); var height = s.ReadUInt8(); Size = new Size(width, height); // Subtract header size var dataLeft = s.ReadUInt16() - 10; var dataSize = s.ReadUInt16(); byte[] table; if ((flags & FormatFlags.PaletteTable) != 0) { var n = (flags & FormatFlags.VariableLengthTable) != 0 ? s.ReadUInt8() : (byte)16; table = new byte[n]; for (var i = 0; i < n; i++) { table[i] = s.ReadUInt8(); } dataLeft -= n; } else { table = new byte[256]; for (var i = 0; i < 256; i++) { table[i] = (byte)i; } table[1] = 0x7f; table[2] = 0x7e; table[3] = 0x7d; table[4] = 0x7c; } Data = new byte[width * height]; // Decode image data var compressed = s.ReadBytes(dataLeft); if ((flags & FormatFlags.SkipFormat80) == 0) { var temp = new byte[dataSize]; Format80.DecodeInto(compressed, temp); compressed = temp; } Format2.DecodeInto(compressed, Data, 0); // Lookup values in lookup table for (var j = 0; j < Data.Length; j++) { Data[j] = table[Data[j]]; } }
public ShpTSReader(Stream stream) { stream.ReadUInt16(); var width = stream.ReadUInt16(); var height = stream.ReadUInt16(); var size = new Size(width, height); var frameCount = stream.ReadUInt16(); var frames = new FrameHeader[frameCount]; Frames = frames.AsReadOnly(); for (var i = 0; i < frames.Length; i++) { frames[i] = new FrameHeader(stream, size); } for (var i = 0; i < frameCount; i++) { var f = frames[i]; if (f.FileOffset == 0) { continue; } stream.Position = f.FileOffset; var frameSize = f.Size.Width * f.Size.Height; // Uncompressed if (f.Format == 1 || f.Format == 0) { f.Data = stream.ReadBytes(frameSize); } // Uncompressed scanlines else if (f.Format == 2) { f.Data = new byte[frameSize]; for (var j = 0; j < f.Size.Height; j++) { var length = stream.ReadUInt16() - 2; var offset = f.Size.Width * j; stream.ReadBytes(f.Data, offset, length); } } // RLE-zero compressed scanlines else if (f.Format == 3) { f.Data = new byte[frameSize]; for (var j = 0; j < f.Size.Height; j++) { var length = stream.ReadUInt16() - 2; var offset = f.Size.Width * j; Format2.DecodeInto(stream.ReadBytes(length), f.Data, offset); } } } }
public ShpTSReader(Stream stream) { stream.ReadUInt16(); var width = stream.ReadUInt16(); var height = stream.ReadUInt16(); var size = new Size(width, height); var frameCount = stream.ReadUInt16(); for (var i = 0; i < frameCount; i++) { frames.Add(new FrameHeader(stream, size)); } for (var i = 0; i < frameCount; i++) { var f = frames[i]; if (f.FileOffset == 0) { continue; } stream.Position = f.FileOffset; // Uncompressed if (f.Format == 1 || f.Format == 0) { f.Data = stream.ReadBytes(f.Size.Width * f.Size.Height); } // Uncompressed scanlines else if (f.Format == 2) { f.Data = new byte[f.Size.Width * f.Size.Height]; for (var j = 0; j < f.Size.Height; j++) { var length = stream.ReadUInt16() - 2; stream.Read(f.Data, f.Size.Width * j, length); } } // RLE-zero compressed scanlines else if (f.Format == 3) { f.Data = new byte[f.Size.Width * f.Size.Height]; for (var j = 0; j < f.Size.Height; j++) { var length = stream.ReadUInt16() - 2; Format2.DecodeInto(stream.ReadBytes(length), f.Data, j * f.Size.Width); } } } spriteFrames = Exts.Lazy(() => frames.Cast <ISpriteFrame>()); }