private byte[] EncodeString(string value, out bool unicode) { unicode = value.Any(x => x >= 0x80); byte[] bytes; var encoding = unicode ? Encoding.Unicode : Encoding.ASCII; bytes = encoding.GetBytes(value); WzEncryption.ApplyCrypto(bytes); bytes = bytes.ApplyStringXor(unicode); return(bytes); }
private static string DecodeStringUnicode(this BinaryReader reader, sbyte len) { int actualLen = len; if (len == 127) { actualLen = reader.ReadInt32(); } actualLen *= 2; var bytes = reader.ReadBytes(actualLen).ApplyStringXor(true); WzEncryption.TryDecryptString(bytes, null); return(Encoding.Unicode.GetString(bytes)); }
private static string DecodeStringASCII(this BinaryReader reader, sbyte len) { int actualLen; if (len == -128) { actualLen = reader.ReadInt32(); } else { actualLen = -len; } var bytes = reader.ReadBytes(actualLen).ApplyStringXor(false); WzEncryption.TryDecryptString(bytes, y => !y.Any(x => x < 0x20 && x != '\n' && x != '\r' && x != '\t')); return(Encoding.ASCII.GetString(Encoding.Convert(Encoding.UTF8, Encoding.ASCII, bytes))); }
public override void Read(BinaryReader reader) { // dont care Debug.Assert(reader.ReadByte() == 0); // just zero if (reader.ReadByte() != 0) { // Initialize prop base.Read(reader); } else { base._objects = new Dictionary <string, object>(); } Width = reader.ReadCompressedInt(); Debug.Assert(Width < 0x10000); Height = reader.ReadCompressedInt(); Debug.Assert(Height < 0x10000); PixFormat = (WzPixFormat)reader.ReadCompressedInt(); Debug.Assert( PixFormat == WzPixFormat.A4R4G4B4 || PixFormat == WzPixFormat.A8R8G8B8 || PixFormat == WzPixFormat.R5G6B5 || PixFormat == WzPixFormat.DXT3 || PixFormat == WzPixFormat.DXT5 ); MagLevel = reader.ReadCompressedInt(); Debug.Assert(MagLevel >= 0); // Zeroes for (var i = 0; i < 4; i++) { Debug.Assert(reader.ReadCompressedInt() == 0); } var dataSize = reader.ReadInt32(); Debug.Assert(reader.ReadByte() == 0); // just zero using (var outputStream = new MemoryStream(ExpectedDataSize)) using (var inputStream = new MemoryStream(dataSize)) { var isPlainZlibStream = reader.ReadByte() == 0x78; reader.BaseStream.Position -= 1; var blob = new byte[Math.Min(0x2000, dataSize)]; if (WzEncryption.HasCurrentCrypto && !isPlainZlibStream) { // Need to skip 1 for (var i = 1; i < dataSize;) { var blobSize = reader.ReadInt32(); i += 4; Array.Resize(ref blob, blobSize); reader.Read(blob, 0, blobSize); WzEncryption.TryDecryptImage(blob); inputStream.Write(blob, 0, blobSize); i += blobSize; } } else { for (var i = 0; i < dataSize;) { var blobSize = Math.Min(blob.Length, dataSize - i); reader.Read(blob, 0, blobSize); inputStream.Write(blob, 0, blobSize); i += blobSize; } } inputStream.Position = 2; using (var deflate = new DeflateStream(inputStream, CompressionMode.Decompress)) { deflate.CopyTo(outputStream); } var uncompressedSize = outputStream.Length; outputStream.Position = 0; Bitmap output = null; byte[] arr; switch (PixFormat) { case WzPixFormat.A4R4G4B4: arr = ARGB16toARGB32(outputStream, uncompressedSize); break; case WzPixFormat.DXT5: case WzPixFormat.DXT3: arr = DXTDecoder.Decode( TileWidth, TileHeight, outputStream.ToArray(), PixFormat == WzPixFormat.DXT3 ? DXTDecoder.CompressionType.DXT3 : DXTDecoder.CompressionType.DXT5 ); break; default: arr = outputStream.ToArray(); break; } PixelFormat format; switch (PixFormat) { case WzPixFormat.R5G6B5: format = PixelFormat.Format16bppRgb565; break; case WzPixFormat.A4R4G4B4: case WzPixFormat.A8R8G8B8: default: format = PixelFormat.Format32bppArgb; break; } output = new Bitmap(TileWidth, TileHeight, format); var rect = new Rectangle(0, 0, output.Width, output.Height); var bmpData = output.LockBits(rect, ImageLockMode.ReadWrite, output.PixelFormat); // Apply MipMap stuff var arrRowLength = rect.Width * Image.GetPixelFormatSize(output.PixelFormat) / 8; var ptr = bmpData.Scan0; for (var i = 0; i < rect.Height; i++) { Marshal.Copy(arr, i * arrRowLength, ptr, arrRowLength); ptr += bmpData.Stride; } output.UnlockBits(bmpData); Tile = output; } }