Beispiel #1
0
 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;
     }
 }
Beispiel #2
0
 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);
 }
Beispiel #3
0
 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;
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
            }
        }
Beispiel #6
0
 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);
 }
Beispiel #7
0
 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);
     }
 }
Beispiel #8
0
 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];
 }
Beispiel #9
0
 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);
 }
Beispiel #10
0
 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);
     }
 }
Beispiel #11
0
 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);
 }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
 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);
     }
 }
Beispiel #14
0
 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);
 }
Beispiel #15
0
 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);
     }
 }
Beispiel #16
0
        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);
                }
            }
        }
Beispiel #17
0
 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);
 }
Beispiel #18
0
 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();
 }
Beispiel #19
0
 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);
     }
 }
Beispiel #20
0
 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;
 }
Beispiel #21
0
 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();
     }
 }
Beispiel #22
0
 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]];
     }
 }
Beispiel #23
0
        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);
            }
        }
Beispiel #24
0
 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();
     }
 }