Пример #1
0
        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)));
        }
Пример #4
0
        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;
                }
        }