public ShpD2Frame(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]]; } }
private static void Decode(Stream stream, ShpOffset[] offsets, int width, int height, byte[][] frames, byte[] src, ref int recdepth) { if (recdepth > frames.Length) { throw new NotImplementedException("Format 40/20 frames contain infinite loop!"); } for (uint i = 0; i < frames.Length; i++) { byte[] frame = new byte[width * height]; byte[] refframe = null; ShpOffset curoff = offsets[i + 0]; ShpOffset nxtoff = offsets[i + 1]; int srclen = (int)(nxtoff.Offset - curoff.Offset); stream.Read(src, 0, srclen); switch (curoff.OffsetFormat) { // Format 20 case 0x20: refframe = frames[i - 1]; goto do_format40; // Format 40 case 0x40: int j = Array.FindIndex(offsets, o => o.Offset == curoff.Ref); if (j < 0) { throw new IndexOutOfRangeException("Invalid frame reference!"); } refframe = frames[j]; do_format40: if (refframe == null) { recdepth++; Decode(stream, offsets, width, height, frames, src, ref recdepth); recdepth--; } Format40.Decode(src, srclen, frame, refframe); break; // Format 80 case 0x80: Format80.Decode(src, 0, frame, 0, srclen); break; // Invalid format default: throw new NotImplementedException("Invalid format!"); } frames[i] = frame; } }
static MemoryStream ReadPackedSection(IniSection mapPackSection) { StringBuilder sb = new StringBuilder(); for (int i = 1; ; i++) { string line = mapPackSection.GetValue(i.ToString(), null); if (line == null) { break; } sb.Append(line.Trim()); } byte[] data = Convert.FromBase64String(sb.ToString()); List <byte[]> chunks = new List <byte[]>(); BinaryReader reader = new BinaryReader(new MemoryStream(data)); try { while (true) { uint length = reader.ReadUInt32() & 0xdfffffff; byte[] dest = new byte[8192]; byte[] src = reader.ReadBytes((int)length); /*int actualLength =*/ Format80.DecodeInto(src, dest); chunks.Add(dest); } } catch (EndOfStreamException) { } MemoryStream ms = new MemoryStream(); foreach (byte[] chunk in chunks) { ms.Write(chunk, 0, chunk.Length); } ms.Position = 0; return(ms); }
void Decompress(ImageHeader h) { // No extra work is required for empty frames if (h.Size.Width == 0 || h.Size.Height == 0) { return; } if (recurseDepth > imageCount) { throw new InvalidDataException("Format20/40 headers contain infinite loop"); } switch (h.Format) { case Format.Format20: case Format.Format40: { if (h.RefImage.Data == null) { ++recurseDepth; Decompress(h.RefImage); --recurseDepth; } h.Data = CopyImageData(h.RefImage.Data); Format40.DecodeInto(shpBytes, h.Data, (int)(h.FileOffset - shpBytesFileOffset)); break; } case Format.Format80: { var imageBytes = new byte[Size.Width * Size.Height]; Format80.DecodeInto(shpBytes, imageBytes, (int)(h.FileOffset - shpBytesFileOffset)); h.Data = imageBytes; break; } default: throw new InvalidDataException(); } }
public static byte[] ReadAsBytes(Stream stream, out Palette palette) { CpsHeader header = stream.ReadStruct <CpsHeader>(); int src_size = header.file_size - Helpers.SizeOf <CpsHeader>() + 2; if ((header.flags & FLAG_PALETTE) == FLAG_PALETTE) { palette = new Palette(stream, 2); src_size -= 768; } else { palette = null; } byte[] src = stream.ReadBytes(src_size); byte[] dst = new byte[header.image_size]; Format80.Decode(src, 0, dst, 0, src.Length); return(dst); }
public static void Write(Stream s, Size size, IEnumerable <byte[]> frames) { var compressedFrames = frames.Select(f => Format80.Encode(f)).ToList(); // note: end-of-file and all-zeroes headers var dataOffset = 14 + (compressedFrames.Count + 2) * 8; using (var bw = new BinaryWriter(s)) { bw.Write((ushort)compressedFrames.Count); bw.Write((ushort)0); bw.Write((ushort)0); bw.Write((ushort)size.Width); bw.Write((ushort)size.Height); bw.Write((uint)0); foreach (var f in compressedFrames) { var ih = new ImageHeader { Format = Format.Format80, FileOffset = (uint)dataOffset }; dataOffset += f.Length; ih.WriteTo(bw); } var eof = new ImageHeader { FileOffset = (uint)dataOffset }; eof.WriteTo(bw); var allZeroes = new ImageHeader { }; allZeroes.WriteTo(bw); foreach (var f in compressedFrames) { bw.Write(f); } } }
public static void Write(Stream s, int width, int height, IEnumerable <byte[]> frames) { var compressedFrames = frames.Select(f => Format80.Encode(f)).ToArray(); // note: end-of-file and all-zeroes headers var dataOffset = 14 + (compressedFrames.Length + 2) * ImageHeader.SizeOnDisk; using (var bw = new BinaryWriter(s)) { bw.Write((ushort)compressedFrames.Length); bw.Write((ushort)0); // unused bw.Write((ushort)0); // unused bw.Write((ushort)width); bw.Write((ushort)height); bw.Write((uint)0); // unused foreach (var f in compressedFrames) { var ih = new ImageHeader { Format = Format.Format80, Offset = (uint)dataOffset }; dataOffset += f.Length; ih.WriteTo(bw); } var eof = new ImageHeader { Offset = (uint)dataOffset }; eof.WriteTo(bw); var allZeroes = new ImageHeader { }; allZeroes.WriteTo(bw); foreach (var f in compressedFrames) { bw.Write(f); } } }
private void UnpackSection(string section, byte[] buffer, int ofs, int len) { if (!config.Contains(section)) { throw new Exception("[{0}] missing".F(section)); } var sb = string.Join(string.Empty, config.Enumerate(section).Select(x => x.Value)); var bin = Convert.FromBase64String(sb); using (var br = new BinaryReader(new MemoryStream(bin))) { var max = ofs + len; while (ofs < max) { var cmpsz = br.ReadUInt16(); // compressed size var ucmpsz = br.ReadUInt16(); // uncompressed size var chunk = br.ReadBytes(cmpsz); Format80.Decode(chunk, 0, buffer, ofs, cmpsz); ofs += ucmpsz; } } }