public override ImageData Read(IBinaryStream stream, ImageMetaData info) { var meta = (HizMetaData)info; var pixels = new byte[meta.UnpackedSize]; stream.Position = meta.DataOffset; using (var lzss = new LzssStream(stream.AsStream, LzssMode.Decompress, true)) { var channel = new byte[info.Width * info.Height]; for (int p = 0; p < 4; ++p) { if (channel.Length != lzss.Read(channel, 0, channel.Length)) { throw new InvalidFormatException("Unexpected end of file"); } int src = 0; for (int i = p; i < pixels.Length; i += 4) { pixels[i] = channel[src++]; } } return(ImageData.Create(info, PixelFormats.Bgra32, null, pixels)); } }
void UnpackV1() { m_input.Position = 0x18; using (var lzss = new LzssStream(m_input.AsStream, LzssMode.Decompress, true)) lzss.Read(m_output, 0, m_output.Length); for (int i = 3; i < m_output.Length; ++i) { m_output[i] += m_output[i - 3]; } var pixels = new byte[m_output.Length]; int src = 0; var z_order = GetZigzagBlock(); for (int y = 0; y < m_height; y += 8) { for (int x = 0; x < m_stride; x += 24) { int dst = x + y * m_stride; for (int i = 0; i < 64; ++i) { int pos = z_order[i]; pixels[dst + pos++] = m_output[src++]; pixels[dst + pos++] = m_output[src++]; pixels[dst + pos++] = m_output[src++]; } } } m_output = pixels; }
public override ImageMetaData ReadMetaData(IBinaryStream file) { using (var lzs = new LzssStream(file.AsStream, LzssMode.Decompress, true)) { if (lzs.ReadByte() != 'B' || lzs.ReadByte() != 'M') { return(null); } var bmp = new byte[0x26]; if (0x24 != lzs.Read(bmp, 2, 0x24)) { return(null); } int file_size = LittleEndian.ToInt32(bmp, 2); int width = LittleEndian.ToInt32(bmp, 0x12); int height = LittleEndian.ToInt32(bmp, 0x16); int bpp = LittleEndian.ToInt16(bmp, 0x1C); int image_size = LittleEndian.ToInt32(bmp, 0x22); if (0 == image_size) { image_size = width * height * (bpp / 8); } return(new GrMetaData { Width = (uint)width, Height = (uint)height, BPP = bpp, UnpackedSize = 24 == bpp ? file_size : (image_size + 0x36), }); } }
IBinaryStream OpenBitmap(IBinaryStream input) { input.Position = 0xA; var stream = new LzssStream(input.AsStream, LzssMode.Decompress, true); return(new BinaryStream(stream, input.Name)); }
public ImageData Unpack() { Stream input = new StreamRegion(m_input.AsStream, 0x18, m_info.PackedLength, true); if (m_info.IsEncrypted) { input = new InputCryptoStream(input, new SjTransform(m_info.Key)); } using (input = new LzssStream(input)) { var header = new byte[0x28]; input.Read(header, 0, header.Length); if (8 == m_info.BPP) { Palette = ImageFormat.ReadPalette(input); } input.Read(m_output, 0, m_output.Length); } if (m_info.AlphaLength > 0 && m_info.BPP == 8) { m_input.Position = 0x18 + m_info.PackedLength; var alpha = new byte[m_info.AlphaLength]; using (var lzss = new LzssStream(m_input.AsStream, LzssMode.Decompress, true)) lzss.Read(alpha, 0, alpha.Length); return(ApplyAlpha(alpha)); } return(ImageData.CreateFlipped(m_info, Format, Palette, m_output, Stride)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var pent = entry as PackedEntry; if (null == pent) { return(base.OpenEntry(arc, entry)); } if (!pent.IsPacked) { if (!arc.File.View.AsciiEqual(entry.Offset, "LZS\0")) { return(base.OpenEntry(arc, entry)); } pent.IsPacked = true; pent.UnpackedSize = arc.File.View.ReadUInt32(entry.Offset + 4); } var input = arc.File.CreateStream(entry.Offset + 8, entry.Size - 8); bool embedded_lzs = (input.Signature & ~0xF0u) == 0x535A4C0F; // 'LZS' var lzs = new LzssStream(input); if (embedded_lzs) { var header = new byte[8]; lzs.Read(header, 0, 8); pent.UnpackedSize = header.ToUInt32(4); lzs = new LzssStream(lzs); } return(lzs); }
public override ImageData Read(IBinaryStream stream, ImageMetaData info) { int stride = (int)info.Width * 3; var pixels = new byte[stride * (int)info.Height]; stream.Position = 0x24; using (var lz = new LzssStream(stream.AsStream, LzssMode.Decompress, true)) { if (pixels.Length != lz.Read(pixels, 0, pixels.Length)) { throw new InvalidFormatException(); } } int src = 0; for (int i = 3; i < stride; ++i) { pixels[i] += pixels[src++]; } src = 0; for (int i = stride; i < pixels.Length; ++i) { pixels[i] += pixels[src++]; } var meta = (MagMetaData)info; if (0 == meta.AlphaOffset) { return(ImageData.CreateFlipped(info, PixelFormats.Bgr24, null, pixels, stride)); } stream.Position = 0x24 + meta.AlphaOffset; var alpha = new byte[meta.BackWidth * meta.BackHeight]; using (var lz = new LzssStream(stream.AsStream, LzssMode.Decompress, true)) { if (alpha.Length != lz.Read(alpha, 0, alpha.Length)) { throw new InvalidFormatException(); } } int img_stride = (int)info.Width * 4; var img = new byte[img_stride * (int)info.Height]; int dst = 0; int alpha_y = meta.BackHeight - (meta.OffsetY + (int)meta.Height); for (int y = (int)meta.Height - 1; y >= 0; --y) { src = stride * y; int src_alpha = meta.BackWidth * (alpha_y + y) + meta.OffsetX; for (int i = 0; i < img_stride; i += 4) { img[dst++] = pixels[src++]; img[dst++] = pixels[src++]; img[dst++] = pixels[src++]; img[dst++] = alpha[src_alpha++]; } } return(ImageData.Create(info, PixelFormats.Bgra32, null, img, img_stride)); }
bool ReadV1(Stream input) { // NOTE CryptoStream will close an input stream using (var xored = new CryptoStream(input, new NotTransform(), CryptoStreamMode.Read)) using (var lzss = new LzssStream(xored)) lzss.Read(m_index, 0, m_index.Length); int index_offset = Array.IndexOf(m_index, (byte)0); if (-1 == index_offset || 0 == index_offset) { return(false); } Password = m_index.Take(index_offset++).ToArray(); long base_offset = 0x20 + m_packed_size; for (int i = 0; i < m_count; ++i) { var entry = new PackedEntry(); entry.Offset = LittleEndian.ToUInt32(m_index, index_offset) + base_offset; entry.Size = LittleEndian.ToUInt32(m_index, index_offset + 4); entry.UnpackedSize = LittleEndian.ToUInt32(m_index, index_offset + 8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.CheckPlacement(m_file.MaxOffset)) { return(false); } int name_len = LittleEndian.ToInt32(m_index, index_offset + 0xC); entry.Name = Encodings.cp932.GetString(m_index, index_offset + 0x18, name_len); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); m_dir.Value.Add(entry); index_offset += 0x18 + name_len; } return(true); }
public Stream UnpackStream() { var lzss = new LzssStream(new MemoryStream(m_input)); lzss.Config.FrameFill = 0x20; return(lzss); }
// Exile ~Blood Royal 2~ : flipped == true // Gakuen ~Nerawareta Chitai~ : flipped == false private ImageData ReadV3(bool flipped) { using (var lzs = new LzssStream(m_input, LzssMode.Decompress, true)) { if (8 == m_info.BPP) { var palette_data = new byte[0x400]; if (palette_data.Length != lzs.Read(palette_data, 0, palette_data.Length)) { throw new InvalidFormatException("Unexpected end of file"); } SetPalette(palette_data); } m_image_data = new byte[m_stride * (int)m_info.Height]; if (m_image_data.Length != lzs.Read(m_image_data, 0, m_image_data.Length)) { throw new InvalidFormatException(); } if (flipped) { return(ImageData.CreateFlipped(m_info, Format, Palette, m_image_data, m_stride)); } else { return(ImageData.Create(m_info, Format, Palette, m_image_data, m_stride)); } } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var snd_ent = (SdtEntry)entry; var header = arc.File.View.ReadBytes(entry.Offset, snd_ent.HeaderSize); using (var mem = new MemoryStream((int)snd_ent.HeaderSize + 0x18)) using (var fmt = new BinaryWriter(mem)) { uint total_size = snd_ent.Size + 0x18; fmt.Write(AudioFormat.Wav.Signature); fmt.Write(total_size); fmt.Write(0x45564157); // 'WAVE' fmt.Write(0x20746d66); // 'fmt ' fmt.Write(header.Length); fmt.Write(header, 0, header.Length); fmt.Write(0x61746164); // 'data' fmt.Write(snd_ent.UnpackedSize); fmt.Flush(); header = mem.ToArray(); } Stream input = arc.File.CreateStream(entry.Offset + snd_ent.HeaderSize, snd_ent.UnpackedSize); if (snd_ent.IsPacked) { input = new LzssStream(input); } return(new PrefixStream(header, input)); }
public override ImageData Read(Stream stream, ImageMetaData info) { stream.Position = 4; using (var lzss = new LzssStream(stream, LzssMode.Decompress, true)) using (var input = new SeekableStream(lzss)) return(base.Read(input, info)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var rent = entry as RepiEntry; if (null == rent || !rent.HasEncryptionKey) { return(arc.File.CreateStream(entry.Offset, entry.Size)); } var key = rent.CreateKey(); uint enc_length = Math.Min((uint)key.Length, entry.Size); byte[] encrypted = arc.File.View.ReadBytes(entry.Offset, enc_length); DecryptEntry(encrypted, key); Stream input; if (enc_length == entry.Size) { input = new BinMemoryStream(encrypted, entry.Name); } else { input = arc.File.CreateStream(entry.Offset + enc_length, entry.Size - enc_length); input = new PrefixStream(encrypted, input); } if (rent.IsPacked) { input = new LzssStream(input); } return(input); }
private ImageData ReadV1() { if (8 == m_info.BPP) { Palette = ImageFormat.ReadPalette(m_input); } 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 lzs = new LzssStream(input)) { m_image_data = new byte[m_info.UnpackedSize]; // flip pixels vertically for (int dst = m_stride * (m_info.iHeight - 1); dst >= 0; dst -= m_stride) { lzs.Read(m_image_data, dst, m_stride); } } return(ImageData.Create(m_info, Format, Palette, m_image_data, m_stride)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var header = arc.File.View.ReadBytes(entry.Offset, 25); if (header[0] < 'B' || header[0] > 'E' || header[1] != '1') { return(arc.File.CreateStream(entry.Offset, entry.Size)); } if ('E' == header[0]) { byte t = header[17]; header[17] = header[23]; header[23] = t; t = header[19]; header[19] = header[24]; header[24] = t; } int unpacked_size = header.ToInt32(6); var data = new byte[unpacked_size]; Stream input = arc.File.CreateStream(entry.Offset + header.Length, entry.Size - (uint)header.Length); input = new PrefixStream(header, input); input.Position = 10; using (input = new LzssStream(input)) input.Read(data, 0, unpacked_size); if (data.AsciiEqual("BPR01")) { return(new PackedStream <BprDecompressor> (Stream.Null, new BprDecompressor(data))); } else { return(new BinMemoryStream(data, entry.Name)); } }
IBinaryStream UnpackedStream(IBinaryStream input) { input.Position = 0xB; var unpacked = new LzssStream(input.AsStream, LzssMode.Decompress, true); return(new BinaryStream(unpacked, input.Name)); }
public override ImageData Read(IBinaryStream file, ImageMetaData info) { file.Position = 0x1B; int plane_size = info.iWidth * info.iHeight; var pixels = new byte[plane_size * 4]; using (var input = new LzssStream(file.AsStream, LzssMode.Decompress, true)) { var plane = new byte[plane_size]; int dst; for (int c = 0; c < 3; ++c) { input.Read(plane, 0, plane_size); dst = c; for (int src = 0; src < plane_size; ++src) { pixels[dst] = plane[src]; dst += 4; } } // alpha channel is inverted input.Read(plane, 0, plane_size); dst = 3; for (int src = 0; src < plane_size; ++src) { pixels[dst] = (byte)(0xFF - plane[src]); dst += 4; } } return(ImageData.CreateFlipped(info, PixelFormats.Bgra32, null, pixels, info.iWidth * 4)); }
public LzssOption(LzssStream lzss) { N = lzss.WindowSize; F = lzss.MaxMatchLength; THRESHOLD = lzss.MatchThresold; FILL = lzss.CharFiller; }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var larc = arc as LunaArchive; if (null == arc || !arc.File.View.AsciiEqual(entry.Offset, "LZSS")) { return(base.OpenEntry(arc, entry)); } uint unpacked_size = arc.File.View.ReadUInt32(entry.Offset + 4); Stream input = arc.File.CreateStream(entry.Offset + 8, entry.Size - 8); if (larc.Key != null) { var bf = new Blowfish(larc.Key); input = new InputCryptoStream(input, bf.CreateDecryptor()); return(new LimitStream(input, unpacked_size)); } else { var lz = new LzssStream(input); lz.Config.FrameInitPos = 0xFF0; return(lz); } }
List <Entry> ReadIndex(string ini_file, string arc_name) { if (null == LastAccessedIndex || !LastAccessedIndex.Item1.Equals(ini_file, StringComparison.InvariantCultureIgnoreCase)) { LastAccessedIndex = null; using (var ini = VFS.OpenView(ini_file)) { if (!ini.View.AsciiEqual(0, "S4IC") && !ini.View.AsciiEqual(0, "S3IC")) { return(null); } uint packed_size = ini.View.ReadUInt32(0x134); using (var packed = ini.CreateStream(0x138, packed_size)) using (var unpacked = new LzssStream(packed)) using (var index = new BinaryReader(unpacked)) { int arc_count = index.ReadInt32(); var name_buf = new byte[0x100]; var file_table = new Dictionary <string, List <Entry> > (arc_count, StringComparer.InvariantCultureIgnoreCase); var arc_list = new List <List <Entry> > (arc_count); for (int i = 0; i < arc_count; ++i) { index.Read(name_buf, 0, name_buf.Length); var file_list = new List <Entry>(); file_table.Add(Binary.GetCString(name_buf, 0, name_buf.Length), file_list); arc_list.Add(file_list); } int file_count = index.ReadInt32(); for (int i = 0; i < file_count; ++i) { index.Read(name_buf, 0, 0x40); int arc_id = index.ReadInt32(); if (arc_id < 0 || arc_id >= arc_list.Count) { return(null); } index.ReadInt32(); // file number uint offset = index.ReadUInt32(); uint size = index.ReadUInt32(); var name = Binary.GetCString(name_buf, 0, 0x40); if ("@" == name) { continue; } var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Offset = offset; entry.Size = size; arc_list[arc_id].Add(entry); } LastAccessedIndex = Tuple.Create(ini_file, file_table); } } } List <Entry> dir = null; LastAccessedIndex.Item2.TryGetValue(arc_name, out dir); return(dir); }
public byte[] Unpack(byte[] background = null) { if (0 == m_info.InnerWidth || 0 == m_info.InnerHeight) { return(background ?? CreateBackground()); } m_input.Position = m_info.DataOffset; int inner_stride = m_info.InnerWidth * m_pixel_size; var pixels = new byte[m_info.InnerHeight * inner_stride]; using (var lz = new LzssStream(m_input, LzssMode.Decompress, true)) { for (int pos = pixels.Length - inner_stride; pos >= 0; pos -= inner_stride) { if (inner_stride != lz.Read(pixels, pos, inner_stride)) { throw new InvalidFormatException(); } } } RestoreDelta(pixels, inner_stride); if (null == background && m_info.InnerWidth == m_info.Width && m_info.InnerHeight == m_info.Height) { return(pixels); } var image = background ?? CreateBackground(); int src = 0; int dst = m_info.OffsetY * Stride + m_info.OffsetX * m_pixel_size; Action blend_row; if (null == background) { blend_row = () => Buffer.BlockCopy(pixels, src, image, dst, inner_stride); } else { blend_row = () => { for (int x = 0; x < inner_stride; x += m_pixel_size) { if (0x00 != pixels[src + x] || 0xFF != pixels[src + x + 1] || 0x00 != pixels[src + x + 2]) { for (int i = 0; i < m_pixel_size; ++i) { image[dst + x + i] = pixels[src + x + i]; } } } }; } for (int y = 0; y < m_info.InnerHeight; ++y) { blend_row(); dst += Stride; src += inner_stride; } return(image); }
internal IBinaryStream DecompressStream(IBinaryStream stream) { stream.Position = 12; var input = new LzssStream(stream.AsStream, LzssMode.Decompress, true); input.Config.FrameFill = 0x20; return(new BinaryStream(input, stream.Name)); }
IBinaryStream OpenBitmapStream(IBinaryStream file, uint unpacked_size) { file.Position = 4; Stream input = new LzssStream(file.AsStream, LzssMode.Decompress, true); input = new LimitStream(input, unpacked_size); return(new BinaryStream(input, file.Name)); }
internal Stream OpenCrzStream(IBinaryStream file) { var lz = new LzssStream(file.AsStream, LzssMode.Decompress, true); lz.Config.FrameSize = 0x1000; lz.Config.FrameFill = 0x20; lz.Config.FrameInitPos = 0x1000 - 0x10; return(lz); }
bool ReadV0(Stream input) { long current_offset = 0x20 + m_packed_size; uint offset_table_size = (uint)m_count * 0x10; if (offset_table_size > m_file.View.Reserve(current_offset, offset_table_size)) { return(false); } using (var lzss = new LzssStream(input, LzssMode.Decompress, true)) if (m_index.Length != lzss.Read(m_index, 0, m_index.Length)) { return(false); } for (int i = 0; i < m_index.Length; ++i) { m_index[i] = (byte)(~m_index[i] - 5); } int index_offset = Array.IndexOf <byte> (m_index, 0); if (-1 == index_offset || 0 == index_offset) { return(false); } index_offset++; // Password = m_index.Take (index_offset++).ToArray(); for (int i = 0; i < m_count && index_offset < m_index.Length; ++i) { int name_end = Array.IndexOf <byte> (m_index, 0, index_offset); if (-1 == name_end) { name_end = m_index.Length; } if (index_offset == name_end) { return(false); } var entry = new PackedEntry(); entry.Offset = m_file.View.ReadUInt32(current_offset); entry.Size = m_file.View.ReadUInt32(current_offset + 4); entry.UnpackedSize = m_file.View.ReadUInt32(current_offset + 8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.CheckPlacement(m_file.MaxOffset)) { return(false); } entry.Name = Encodings.cp932.GetString(m_index, index_offset, name_end - index_offset); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); m_dir.Value.Add(entry); index_offset = name_end + 1; current_offset += 0x10; } return(true); }
void UnpackLzss(byte[] packed) { using (var mem = new MemoryStream(packed)) using (var lz = new LzssStream(mem)) if (m_output.Length != lz.Read(m_output, 0, m_output.Length)) { throw new EndOfStreamException(); } }
void ReadAlpha() { int alpha_stride = (m_width + 3) & ~3; Stream alpha_stream; if (m_info.AlphaSize == alpha_stride * m_height) { alpha_stream = new StreamRegion(m_input, m_input.Position, true); } else { alpha_stream = new LzssStream(m_input, LzssMode.Decompress, true); } using (alpha_stream) { int src_stride = Stride; int new_stride = m_width * 4; bool extend_alpha = 3 != m_info.Flags; var alpha_line = new byte[alpha_stride]; var pixels = new byte[new_stride * m_height]; for (int y = 0; y < m_height; ++y) { int src = y * src_stride; int dst = y * new_stride; if (alpha_line.Length != alpha_stream.Read(alpha_line, 0, alpha_line.Length)) { throw new EndOfStreamException(); } for (int x = 0; x < m_width; ++x) { if (8 == m_info.BPP) { var color = Palette.Colors[m_output[src++]]; pixels[dst++] = color.B; pixels[dst++] = color.G; pixels[dst++] = color.R; } else { pixels[dst++] = m_output[src++]; pixels[dst++] = m_output[src++]; pixels[dst++] = m_output[src++]; } int alpha = alpha_line[x]; if (extend_alpha) { alpha = alpha >= 0x10 ? 0xFF : alpha * 0x10; } pixels[dst++] = (byte)alpha; } } Stride = new_stride; Palette = null; m_output = pixels; } }
IBinaryStream OpenLzStream(IBinaryStream input) { input.Position = 0xE; var lz = new LzssStream(input.AsStream, LzssMode.Decompress, true); lz.Config.FrameSize = 0x1000; lz.Config.FrameFill = 0x20; lz.Config.FrameInitPos = 0x1000 - 0x10; return(new BinaryStream(lz, input.Name)); // XXX stream is unseekable }
public override ImageData Read(IBinaryStream file, ImageMetaData info) { file.Position = 0x10; using (var lzss = new LzssStream(file.AsStream, LzssMode.Decompress, true)) { var pixels = new byte[info.Width * info.Height]; lzss.Read(pixels, 0, pixels.Length); return(ImageData.CreateFlipped(info, PixelFormats.Gray8, null, pixels, (int)info.Width)); } }
Stream OpenLzStream(IBinaryStream input) { input.Position = 0xE; var lz = new LzssStream(input.AsStream, LzssMode.Decompress, true); lz.Config.FrameSize = 0x1000; lz.Config.FrameFill = 0x20; lz.Config.FrameInitPos = 0x1000 - 0x10; return(lz); }