private ImageData ReadV1() { if (8 == m_info.BPP) { var palette_data = new byte[0x400]; if (palette_data.Length != m_input.Read(palette_data, 0, palette_data.Length)) { throw new InvalidFormatException("Unexpected end of file"); } SetPalette(palette_data); } var packed = new byte[m_info.PackedSize]; if (packed.Length != m_input.Read(packed, 0, packed.Length)) { throw new InvalidFormatException("Unexpected end of file"); } for (int i = 0; i < packed.Length; ++i) { packed[i] ^= (byte)i; } using (var input = new MemoryStream(packed)) using (var reader = new LzssReader(input, packed.Length, m_info.UnpackedSize)) { reader.Unpack(); m_image_data = new byte[m_info.UnpackedSize]; // flip pixels vertically int dst = 0; for (int src = m_stride * ((int)m_info.Height - 1); src >= 0; src -= m_stride) { Buffer.BlockCopy(reader.Data, src, m_image_data, dst, m_stride); dst += m_stride; } } return(ImageData.Create(m_info, Format, Palette, m_image_data)); }
public override ImageData Read(Stream stream, ImageMetaData info) { var meta = (GrMetaData)info; using (var reader = new LzssReader(stream, (int)stream.Length, meta.UnpackedSize + 2)) { reader.Unpack(); if (32 != info.BPP) { using (var bmp = new MemoryStream(reader.Data)) return(base.Read(bmp, info)); } int stride = (int)info.Width * 4; var pixels = new byte[stride * info.Height]; int dst = 0; int offset = 0x36; for (int src = stride * ((int)info.Height - 1); src >= 0; src -= stride) { Buffer.BlockCopy(reader.Data, offset + src, pixels, dst, stride); dst += stride; } return(ImageData.Create(info, PixelFormats.Bgra32, null, pixels)); } }
static byte[] DecodeListBin(byte[] data) { var header = new byte[0x30]; DecodeDPD(data, 0, 0x30, header); int packed_size = LittleEndian.ToInt32(header, 0x0C); int unpacked_size = LittleEndian.ToInt32(header, 0x10); if (packed_size <= 0 || packed_size > data.Length - 0x30) { return(null); } if (Binary.AsciiEqual(header, 0, "DPDC")) { var decrypted = new byte[packed_size]; DecodeDPD(data, 0x30, packed_size, decrypted); return(decrypted); } if (Binary.AsciiEqual(header, 0, "SZLC")) // LZSS { using (var input = new MemoryStream(data, 0x30, packed_size)) using (var lzss = new LzssReader(input, packed_size, unpacked_size)) { lzss.Unpack(); return(lzss.Data); } } if (Binary.AsciiEqual(header, 0, "ELRC")) // RLE { var unpacked = new byte[unpacked_size]; int min_repeat = LittleEndian.ToInt32(header, 0x1C); DecodeRLE(data, 0x30, packed_size, unpacked, min_repeat); return(unpacked); } return(null); }
public override IImageDecoder OpenImage(ArcFile arc, Entry entry) { var id_str = arc.File.View.ReadString(entry.Offset, 2); if (id_str != "B1" && id_str != "D1" && id_str != "E1") { return(base.OpenImage(arc, entry)); } uint packed_size = arc.File.View.ReadUInt32(entry.Offset + 2); if (packed_size != entry.Size - 10) { return(base.OpenImage(arc, entry)); } uint unpacked_size = arc.File.View.ReadUInt32(entry.Offset + 6); using (var input = arc.File.CreateStream(entry.Offset + 10, packed_size)) using (var lzss = new LzssReader(input, (int)packed_size, (int)unpacked_size)) { lzss.Unpack(); var bmp = new BinMemoryStream(lzss.Data, entry.Name); return(new ImageFormatDecoder(bmp)); } }
public override ArcFile TryOpen(ArcView file) { if (!(file.View.AsciiEqual(0, "DataPack5") || file.View.AsciiEqual(0, "GsPack5") || file.View.AsciiEqual(0, "GsPack4"))) { return(null); } int version_minor = file.View.ReadUInt16(0x30); int version_major = file.View.ReadUInt16(0x32); uint index_size = file.View.ReadUInt32(0x34); int count = file.View.ReadInt32(0x3c); if (!IsSaneCount(count) || index_size > 0xffffff) { return(null); } uint is_encrypted = file.View.ReadUInt32(0x38); long data_offset = file.View.ReadUInt32(0x40); int index_offset = file.View.ReadInt32(0x44); int entry_size = version_major < 5 ? 0x48 : 0x68; int unpacked_size = count * entry_size; byte[] index; if (index_size != 0) { byte[] packed_index = file.View.ReadBytes(index_offset, index_size); if (index_size != packed_index.Length) { return(null); } if (0 != (is_encrypted & 1)) { for (int i = 0; i != packed_index.Length; ++i) { packed_index[i] ^= (byte)i; } } using (var stream = new MemoryStream(packed_index)) using (var reader = new LzssReader(stream, packed_index.Length, unpacked_size)) { reader.Unpack(); index = reader.Data; } } else { index = file.View.ReadBytes(index_offset, (uint)unpacked_size); } index_offset = 0; string default_type = ""; var arc_name = Path.GetFileNameWithoutExtension(file.Name); if (arc_name.StartsWith("image", StringComparison.OrdinalIgnoreCase)) { default_type = "image"; } else if (arc_name.StartsWith("voice", StringComparison.OrdinalIgnoreCase)) { default_type = "audio"; } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { string name = Binary.GetCString(index, index_offset, 0x40); if (0 != name.Length) { var entry = new Entry { Name = name, Type = default_type, Offset = data_offset + LittleEndian.ToUInt32(index, index_offset + 0x40), Size = LittleEndian.ToUInt32(index, index_offset + 0x44), }; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } index_offset += entry_size; } if (0 != (is_encrypted & 2)) { return(new GsPackArchive(file, this, dir)); } if (string.IsNullOrEmpty(default_type)) { foreach (var entry in dir) { uint signature = file.View.ReadUInt32(entry.Offset); var res = AutoEntry.DetectFileType(signature); entry.ChangeType(res); } } return(new ArcFile(file, this, dir)); }