internal List<Entry> ParseIndex(Stream input, int count, long base_offset, long max_offset) { using (var zstream = new ZLibStream (input, CompressionMode.Decompress)) using (var index = new BinaryReader (zstream)) { var dir = new List<Entry> (count); var name_buffer = new byte[0x20]; for (int i = 0; i < count; ++i) { uint offset = index.ReadUInt32(); uint size = index.ReadUInt32(); uint crc = index.ReadUInt32(); index.ReadInt32(); if (name_buffer.Length != index.Read (name_buffer, 0, name_buffer.Length)) return null; var name = Binary.GetCString (name_buffer, 0, 0x20); if (0 == name.Length) return null; var entry = FormatCatalog.Instance.Create<Entry> (name); entry.Offset = base_offset + offset; entry.Size = size; if (!entry.CheckPlacement (max_offset)) return null; dir.Add (entry); } return dir; } }
public override ImageMetaData ReadMetaData(Stream stream) { var header = new byte[8]; if (header.Length != stream.Read (header, 0, header.Length)) return null; using (var zstream = new ZLibStream (stream, CompressionMode.Decompress, true)) return base.ReadMetaData (zstream); }
public static MemoryStream Compress(Stream source) { var dest = new MemoryStream(); using (var zs = new ZLibStream (dest, CompressionMode.Compress, true)) { source.CopyTo (zs); } dest.Position = 0; return dest; }
public override ImageMetaData ReadMetaData(Stream stream) { int first = stream.ReadByte() ^ 0x21; if (first != 0x78) // doesn't look like zlib stream return null; stream.Position = 0; using (var input = new XoredStream (stream, 0x21, true)) using (var zstream = new ZLibStream (input, CompressionMode.Decompress)) return base.ReadMetaData (zstream); }
public override ImageData Read(Stream stream, ImageMetaData info) { var meta = (NgpMetaData)info; using (var input = new StreamRegion (stream, 0x104, meta.PackedSize, true)) using (var z = new ZLibStream (input, CompressionMode.Decompress)) { var pixels = new byte[meta.UnpackedSize]; if (pixels.Length != z.Read (pixels, 0, pixels.Length)) throw new EndOfStreamException(); PixelFormat format; if (32 == meta.BPP) format = PixelFormats.Bgra32; else if (24 == meta.BPP) format = PixelFormats.Bgr24; else if (8 == meta.BPP) format = PixelFormats.Gray8; else throw new System.NotSupportedException ("Not supported NGP image color depth"); return ImageData.Create (info, format, null, pixels); } }
public override ImageData Read(Stream stream, ImageMetaData info) { using (var input = new XoredStream (stream, 0x21, true)) using (var zstream = new ZLibStream (input, CompressionMode.Decompress)) return base.Read (zstream, info); }
void DeserializeScheme(Stream file) { using (var reader = new BinaryReader (file)) { var scheme_id = FormatCatalog.Instance.SchemeID; var header = reader.ReadChars (scheme_id.Length); if (!header.SequenceEqual (scheme_id)) throw new FormatException ("Invalid serialization file"); int version = reader.ReadInt32(); using (var zs = new ZLibStream (file, CompressionMode.Decompress)) FormatCatalog.Instance.DeserializeScheme (zs); } }
public Reader(Stream stream, QntMetaData info) { m_width = (int)info.Width; m_height = (int)info.Height; int w = (m_width + 1) & ~1; int h = (m_height + 1) & ~1; int rgb_size = h * w * 3; m_bpp = info.AlphaSize != 0 ? 4 : 3; m_input = new byte[rgb_size]; var alpha_pos = stream.Position + info.RGBSize; using (var zstream = new ZLibStream (stream, CompressionMode.Decompress, true)) if (rgb_size != zstream.Read (m_input, 0, rgb_size)) throw new InvalidFormatException ("Unexpected end of file"); if (info.AlphaSize != 0) { int alpha_size = w * m_height; m_alpha = new byte[alpha_size]; stream.Position = alpha_pos; using (var zstream = new ZLibStream (stream, CompressionMode.Decompress, true)) if (alpha_size != zstream.Read (m_alpha, 0, alpha_size)) throw new InvalidFormatException ("Unexpected end of file"); } m_output = new byte[info.Width*info.Height*m_bpp]; }
uint WriteImageEntry(PackedEntry entry, Stream input, Stream output) { var grp = s_grp_format.Value; if (null == grp) // probably never happens throw new FileFormatException ("GRP image encoder not available"); bool is_grp = grp.Signature == FormatCatalog.ReadSignature (input); input.Position = 0; var start = output.Position; using (var zstream = new ZLibStream (output, CompressionMode.Compress, CompressionLevel.Level9, true)) { if (is_grp) { input.CopyTo (zstream); } else { var image = ImageFormat.Read (input); if (null == image) throw new InvalidFormatException (string.Format (arcStrings.MsgInvalidImageFormat, entry.Name)); grp.Write (zstream, image); entry.UnpackedSize = (uint)zstream.TotalIn; } } return (uint)(output.Position - start); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var hzc = (HzcArchive)arc; using (var input = arc.File.CreateStream (0xC+hzc.ImageInfo.HeaderSize)) using (var z = new ZLibStream (input, CompressionMode.Decompress)) { uint frame_size = entry.Size - 0x12; var pixels = new byte[frame_size]; uint offset = 0; for (;;) { if (pixels.Length != z.Read (pixels, 0, pixels.Length)) break; if (offset >= entry.Offset) break; offset += frame_size; } if (4 == hzc.ImageInfo.Type) { for (int i = 0; i < pixels.Length; ++i) if (1 == pixels[i]) pixels[i] = 0xFF; } return TgaStream.Create (hzc.ImageInfo, pixels); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var data = arc.File.View.ReadBytes (entry.Offset, entry.Size); var cipher = new AzIsaacEncryption (entry.Size); cipher.Decrypt (data, 0, data.Length, 0); if (data.Length > 0x14 && Binary.AsciiEqual (data, 0, "ASB\0") && DecryptAsb (data)) { var header = new byte[0x10]; Buffer.BlockCopy (data, 0, header, 0, 0x10); Stream input = new MemoryStream (data, 0x10, data.Length-0x10); input = new ZLibStream (input, CompressionMode.Decompress); return new PrefixStream (header, input); } return new MemoryStream (data); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual (8, "AlicArch")) return null; if (!file.View.AsciiEqual (0x1C, "INFO")) return null; int version = file.View.ReadInt32 (0x10); long base_offset = file.View.ReadUInt32 (0x18); uint packed_size = file.View.ReadUInt32 (0x20); int unpacked_size = file.View.ReadInt32 (0x24); int count = file.View.ReadInt32 (0x28); if (!IsSaneCount (count)) return null; var dir = new List<Entry> (count); var name_buf = new byte[0x40]; using (var input = file.CreateStream (0x2C, packed_size)) using (var zstream = new ZLibStream (input, CompressionMode.Decompress)) using (var index = new BinaryReader (zstream)) { for (int i = 0; i < count; ++i) { int name_length = index.ReadInt32(); int index_step = index.ReadInt32(); if (name_length <= 0 || name_length > index_step || index_step > unpacked_size) return null; if (index_step > name_buf.Length) name_buf = new byte[index_step]; if (index_step != index.Read (name_buf, 0, index_step)) return null; var name = Encodings.cp932.GetString (name_buf, 0, name_length); var entry = FormatCatalog.Instance.Create<Entry> (name); index.ReadInt32(); index.ReadInt32(); if (version < 2) index.ReadInt32(); entry.Offset = index.ReadUInt32() + base_offset; entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); } }
public override void Write(Stream file, ImageData image) { using (var bmp = new MemoryStream()) { base.Write (bmp, image); using (var output = new BinaryWriter (file, Encoding.ASCII, true)) { output.Write (Signature); output.Write ((uint)bmp.Length); } bmp.Position = 0; using (var zstream = new ZLibStream (file, CompressionMode.Compress, CompressionLevel.Level9, true)) bmp.CopyTo (zstream); } }
public override ImageData Read(Stream stream, ImageMetaData info) { stream.Seek (8, SeekOrigin.Current); using (var zstream = new ZLibStream (stream, CompressionMode.Decompress, true)) return base.Read (zstream, info); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var packed_entry = entry as PackedEntry; var ypf = arc as YpfArchive; Stream input = arc.File.CreateStream (entry.Offset, entry.Size); if (null != packed_entry && packed_entry.IsPacked) input = new ZLibStream (input, CompressionMode.Decompress); uint unpacked_size = null == packed_entry ? entry.Size : packed_entry.UnpackedSize; if (null == ypf || 0 == ypf.ScriptKey || unpacked_size <= 0x20 || !entry.Name.EndsWith (".ybn", StringComparison.InvariantCultureIgnoreCase)) return input; using (input) { var data = new byte[unpacked_size]; input.Read (data, 0, data.Length); if (Binary.AsciiEqual (data, 0, "YSTB")) DecryptYstb (data, ypf.ScriptKey); return new MemoryStream (data); } }
public override void Create(Stream output, IEnumerable<Entry> list, ResourceOptions options, EntryCallback callback) { var ypf_options = GetOptions<YpfOptions> (options); if (null == ypf_options) throw new ArgumentException ("Invalid archive creation options", "options"); if (ypf_options.Key > 0xff) throw new InvalidEncryptionScheme (arcStrings.MsgCreationKeyRequired); if (0 == ypf_options.Version) throw new InvalidFormatException (arcStrings.MsgInvalidVersion); var scheme = new YpfScheme { SwapTable = GuessSwapTable (ypf_options.Version), Key = (byte)ypf_options.Key }; int callback_count = 0; var encoding = Encodings.cp932.WithFatalFallback(); ChecksumFunc Checksum = data => Crc32.Compute (data, 0, data.Length); uint data_offset = 0x20; var file_table = new List<YpfEntry>(); foreach (var entry in list) { try { string file_name = entry.Name; byte[] name_buf = encoding.GetBytes (file_name); if (name_buf.Length > 0xff) throw new InvalidFileName (entry.Name, arcStrings.MsgFileNameTooLong); uint hash = Checksum (name_buf); byte file_type = GetFileType (ypf_options.Version, file_name); for (int i = 0; i < name_buf.Length; ++i) name_buf[i] = (byte)(name_buf[i] ^ ypf_options.Key); file_table.Add (new YpfEntry { Name = file_name, IndexName = name_buf, NameHash = hash, FileType = file_type, IsPacked = 0 == file_type, }); data_offset += (uint)(0x17 + name_buf.Length); } catch (EncoderFallbackException X) { throw new InvalidFileName (entry.Name, arcStrings.MsgIllegalCharacters, X); } } file_table.Sort ((a, b) => a.NameHash.CompareTo (b.NameHash)); output.Position = data_offset; uint current_offset = data_offset; foreach (var entry in file_table) { if (null != callback) callback (callback_count++, entry, arcStrings.MsgAddingFile); entry.Offset = current_offset; using (var input = File.OpenRead (entry.Name)) { var file_size = input.Length; if (file_size > uint.MaxValue || current_offset + file_size > uint.MaxValue) throw new FileSizeException(); entry.UnpackedSize = (uint)file_size; using (var checked_stream = new CheckedStream (output, new Adler32())) { if (entry.IsPacked) { var start = output.Position; using (var zstream = new ZLibStream (checked_stream, CompressionMode.Compress, CompressionLevel.Level9, true)) { input.CopyTo (zstream); } entry.Size = (uint)(output.Position - start); } else { input.CopyTo (checked_stream); entry.Size = entry.UnpackedSize; } checked_stream.Flush(); entry.CheckSum = checked_stream.CheckSumValue; current_offset += entry.Size; } } } if (null != callback) callback (callback_count++, null, arcStrings.MsgWritingIndex); output.Position = 0; using (var writer = new BinaryWriter (output, encoding, true)) { writer.Write (Signature); writer.Write (ypf_options.Version); writer.Write (file_table.Count); writer.Write (data_offset); writer.BaseStream.Seek (0x20, SeekOrigin.Begin); foreach (var entry in file_table) { writer.Write (entry.NameHash); byte name_len = (byte)~Parser.DecryptLength (scheme.SwapTable, (byte)entry.IndexName.Length); writer.Write (name_len); writer.Write (entry.IndexName); writer.Write (entry.FileType); writer.Write (entry.IsPacked); writer.Write (entry.UnpackedSize); writer.Write (entry.Size); writer.Write ((uint)entry.Offset); writer.Write (entry.CheckSum); } } }
public override void Write(Stream file, ImageData image) { using (var output = new XoredStream (file, 0x21, true)) using (var zstream = new ZLibStream (output, CompressionMode.Compress, CompressionLevel.Level9)) base.Write (zstream, image); }
void UnpackZlib() { m_input.Position = 0x38; using (var z = new ZLibStream (m_input, CompressionMode.Decompress, true)) if (m_info.UnpackedSize1 != z.Read (m_output, 0, m_info.UnpackedSize1)) throw new EndOfStreamException(); m_input.Position = 0x38 + m_info.CompressedSize1; using (var z = new ZLibStream (m_input, CompressionMode.Decompress, true)) if (m_info.UnpackedSize2 != z.Read (m_output, m_info.UnpackedSize1, m_info.UnpackedSize2)) throw new EndOfStreamException(); }
uint ReadSysenvSeed(ArcView file, IEnumerable<Entry> dir, uint key) { var entry = dir.FirstOrDefault (e => e.Name.Equals ("sysenv.tbl", StringComparison.InvariantCultureIgnoreCase)); if (null == entry) return key; var data = file.View.ReadBytes (entry.Offset, entry.Size); if (data.Length <= 4) throw new InvalidFormatException ("Invalid sysenv.tbl size"); Decrypt (data, entry.Offset, key); uint adler32 = LittleEndian.ToUInt32 (data, 0); if (adler32 != Adler32.Compute (data, 4, data.Length-4)) throw new InvalidEncryptionScheme(); using (var input = new MemoryStream (data, 4, data.Length-4)) using (var sysenv_stream = new ZLibStream (input, CompressionMode.Decompress)) { var seed = new byte[0x10]; if (0x10 != sysenv_stream.Read (seed, 0, 0x10)) throw new InvalidFormatException ("Invalid sysenv.tbl size"); return EncryptionScheme.GenerateContentKey (seed); } }
public static MemoryStream DeCompress(Stream source) { var dest = new MemoryStream(); using (var zs = new ZLibStream (source, CompressionMode.Decompress, true)) { zs.CopyTo (dest); } dest.Position = 0; return dest; }
public override ImageData Read(Stream stream, ImageMetaData info) { var meta = (EencMetaData)info; meta.Info.FileName = info.FileName; Stream input = new StreamRegion (stream, 8, true); try { input = new EencStream (input, meta.Key); if (meta.Compressed) input = new ZLibStream (input, CompressionMode.Decompress); return meta.Format.Read (input, meta.Info); } finally { input.Dispose(); } }
void UnpackV0() { byte[] channel = new byte[m_width*m_height]; long start_pos = m_input.Position; for (int i = 0; i < 4; ++i) { if (0 == m_channel[StreamMap[i]]) continue; m_input.Position = start_pos + 4; // skip crc32 using (var input = new ZLibStream (m_input, CompressionMode.Decompress, true)) { int channel_size = input.Read (channel, 0, channel.Length); int dst = ChannelMap[i]; for (int j = 0; j < channel_size; ++j) { m_output[dst] = channel[j]; dst += 4; } } start_pos += m_channel[StreamMap[i]]; } }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32 (4); if (!IsSaneCount (count)) return null; uint index_size = file.View.ReadUInt32 (0xC); if (index_size < 2 || index_size > file.MaxOffset) return null; long base_offset = 0x118 + index_size; using (var mem = file.CreateStream (0x118, index_size)) using (var z = new ZLibStream (mem, CompressionMode.Decompress)) using (var index = new BinaryReader (z)) { var name_buffer = new byte[0x100]; var dir = new List<Entry> (count); for (int i = 0; i < count; ++i) { int name_length = index.ReadInt32(); if (name_length <= 0 || name_length > name_buffer.Length) return null; if (name_length != index.Read (name_buffer, 0, name_length)) return null; var name = Encodings.cp932.GetString (name_buffer, 0, name_length); var entry = FormatCatalog.Instance.Create<PackedEntry> (name); entry.Offset = index.ReadUInt32() + base_offset; uint size = index.ReadUInt32(); index.ReadUInt32(); uint flags = index.ReadUInt32(); uint packed_size = index.ReadUInt32(); entry.IsPacked = flags != 0 && packed_size != 0; if (entry.IsPacked) { entry.Size = packed_size; entry.UnpackedSize = size; } else { entry.Size = size; entry.UnpackedSize = size; } if (!entry.CheckPlacement (file.MaxOffset)) return null; dir.Add (entry); } return new ArcFile (file, this, dir); } }
public override ImageMetaData ReadMetaData(Stream stream) { var header = new byte[8]; if (8 != stream.Read (header, 0, 8)) return null; bool compressed = 'Z' == header[3]; uint key = LittleEndian.ToUInt32 (header, 4) ^ EencKey; Stream input = new StreamRegion (stream, 8, true); try { input = new EencStream (input, key); if (compressed) { input = new ZLibStream (input, CompressionMode.Decompress); input = new SeekableStream (input); } var format = FindFormat (input); if (null == format) return null; return new EencMetaData { Width = format.Item2.Width, Height = format.Item2.Height, BPP = format.Item2.BPP, Key = key, Info = format.Item2, Format = format.Item1, Compressed = compressed, }; } finally { input.Dispose(); } }