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