From d29691e0ee18356e0902244f85031ce8cdd90668 Mon Sep 17 00:00:00 2001 From: Valeriy Mironov Date: Sun, 13 May 2018 08:21:37 +0300 Subject: [PATCH] Started work on Cor .res decompression --- Resources/Compression.cs | 88 ++++++++++++++++++++++++++++++++++++++ Resources/Resources.csproj | 1 + WatchFace/Program.cs | 6 ++- 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 Resources/Compression.cs diff --git a/Resources/Compression.cs b/Resources/Compression.cs new file mode 100644 index 0000000..02faa20 --- /dev/null +++ b/Resources/Compression.cs @@ -0,0 +1,88 @@ +using NLog; +using System; +using System.IO; + +namespace Resources +{ + public class Compression + { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + class Header + { + public const int Size = 9; + + public byte[] Buffer; + public byte Flags => Buffer[0]; + public uint CompressedLength => BitConverter.ToUInt32(Buffer, 1); + public uint DecompressedLength => BitConverter.ToUInt32(Buffer, 5); + public bool IsCompressed => (Flags & 1) > 0; + public int LengthSize => (Flags & 2) > 0 ? 4 : 1; + + public static Header Read(BinaryReader reader) + { + var buffer = new byte[Size]; + reader.Read(buffer, 0, buffer.Length); + return new Header { Buffer = buffer }; + } + } + + private readonly Stream _stream; + private readonly BinaryReader _reader; + private readonly long _streamSize; + + public Compression(Stream stream) + { + _stream = stream; + _reader = new BinaryReader(stream); + _streamSize = stream.Length; + } + + public Stream Decompress() + { + var output = new MemoryStream(); + var buffer = new byte[5120]; + + var offset = (uint)0; + + while (true) + { + var header = Header.Read(_reader); + + if (header.DecompressedLength == 4096) + { + Logger.Debug("Compression block header read at offset 0x{0:X}", offset); + Logger.Debug("Flags 0x{0:X}, Compressed {1}, Decompressed {2}, LengthSize {3}", + header.Flags, header.CompressedLength, header.DecompressedLength, header.LengthSize); + + _reader.Read(buffer, 0, (int)header.CompressedLength - 9); + offset += header.CompressedLength; + + + if (header.IsCompressed) + { + // Here should be decompression + + } + else + output.Write(buffer, 0, (int)header.CompressedLength); + } + else + { + var latestBlock = _streamSize - offset; + Logger.Debug("Latest block read at offset 0x{0:X}, size: {1}", offset, latestBlock); + + _reader.Read(buffer, 0, (int)(latestBlock - Header.Size)); + + output.Write(header.Buffer, 0, Header.Size); + output.Write(buffer, 0, (int)(latestBlock - Header.Size)); + break; + } + } + + output.Seek(0, SeekOrigin.Begin); + return output; + } + + } +} diff --git a/Resources/Resources.csproj b/Resources/Resources.csproj index bc6ff7d..8d09397 100644 --- a/Resources/Resources.csproj +++ b/Resources/Resources.csproj @@ -48,6 +48,7 @@ + diff --git a/WatchFace/Program.cs b/WatchFace/Program.cs index 1847788..024530e 100644 --- a/WatchFace/Program.cs +++ b/WatchFace/Program.cs @@ -72,6 +72,9 @@ namespace WatchFace case ".bin": UnpackWatchFace(inputFileName); break; + case ".res": + UnpackResources(inputFileName); + break; case ".json": PackWatchFace(inputFileName); break; @@ -205,7 +208,8 @@ namespace WatchFace FileDescriptor resDescriptor; using (var stream = File.OpenRead(inputFileName)) { - resDescriptor = FileReader.Read(stream); + var decompressedStream = new Compression(stream).Decompress(); + resDescriptor = FileReader.Read(decompressedStream); } ExportResConfig(resDescriptor, Path.Combine(outputDirectory, "header.json"));