Пример #1
0
        internal static WZObject ParseExtendedProperty(string name, WZBinaryReader r, WZObject parent, WZImage f,
                                                       bool encrypted)
        {
            string type = r.ReadWZStringBlock(encrypted);

            switch (type)
            {
            case "Property":
                r.Skip(2);
                return(new WZSubProperty(name, parent, r, f));

            case "Canvas":
                return(new WZCanvasProperty(name, parent, r, f));

            case "Shape2D#Vector2D":
                return(new WZPointProperty(name, parent, r, f));

            case "Shape2D#Convex2D":
                return(new WZConvexProperty(name, parent, r, f));

            case "Sound_DX8":
                return(new WZAudioProperty(name, parent, r, f));

            case "UOL":
                r.Skip(1);
                return(new WZLinkProperty(name, parent, r, f));

            default:
                return(WZUtil.Die <WZObject>($"Unknown ExtendedProperty type \"{type}\""));
            }
        }
Пример #2
0
 internal WZSubProperty(string name, WZObject parent, WZBinaryReader r, WZImage container)
     : base(name, parent, default(WZNothing), container, true, WZObjectType.SubProperty)
 {
     foreach (WZObject c in WZExtendedParser.ParsePropertyList(r, this, Image, Image._encrypted))
     {
         Add(c);
     }
 }
Пример #3
0
 internal WZDelayedProperty(string name, WZObject parent, WZImage container, WZBinaryReader r, bool children,
                            WZObjectType type)
     : base(name, parent, default(T), container, children, type)
 {
     _offset = r.Position;
     _parsed = Parse(r, true, out _value);
     _r      = r;
 }
Пример #4
0
        private static float ReadSingle(WZBinaryReader reader)
        {
            byte t = reader.ReadByte();

            return(t == 0x80
                ? reader.ReadSingle()
                : (t == 0 ? 0f : WZUtil.Die <float>("Unknown byte while reading WZSingleProperty.")));
        }
Пример #5
0
 internal WZImage(string name, WZObject parent, WZFile file, WZBinaryReader reader)
     : base(name, parent, file, true, WZObjectType.Image)
 {
     _r = reader;
     if ((file._flag & WZReadSelection.EagerParseImage) == WZReadSelection.EagerParseImage)
     {
         Parse();
     }
 }
Пример #6
0
        internal static List <WZObject> ParsePropertyList(WZBinaryReader r, WZObject parent, WZImage f, bool encrypted)
        {
            int             num = r.ReadWZInt();
            List <WZObject> ret = new List <WZObject>(num);

            for (int i = 0; i < num; ++i)
            {
                string name = r.ReadWZStringBlock(encrypted);
                byte   type = r.ReadByte();
                switch (type)
                {
                case 0:
                    ret.Add(new WZNullProperty(name, parent, f));
                    break;

                case 0x0B:
                case 2:
                    ret.Add(new WZUInt16Property(name, parent, r, f));
                    break;

                case 0x13:
                case 3:
                    ret.Add(new WZInt32Property(name, parent, r, f));
                    break;

                case 0x14:
                    ret.Add(new WZInt64Property(name, parent, r, f));
                    break;

                case 4:
                    ret.Add(new WZSingleProperty(name, parent, r, f));
                    break;

                case 5:
                    ret.Add(new WZDoubleProperty(name, parent, r, f));
                    break;

                case 8:
                    ret.Add(new WZStringProperty(name, parent, r, f));
                    break;

                case 9:
                    uint blockLen = r.ReadUInt32();
                    ret.Add(ParseExtendedProperty(name, r.Clone(), parent, f, encrypted));
                    r.Skip(blockLen);
                    break;

                default:
                    return
                        (WZUtil.Die <List <WZObject> >(
                             $"Unknown property type {type} at ParsePropertyList"));
                }
            }
            return(ret);
        }
Пример #7
0
        internal void CheckParsed()
        {
            if (_parsed)
            {
                return;
            }
            WZBinaryReader r = _r.Clone();

            r.Seek(_offset);
            Parse(r, false, out _value);
        }
Пример #8
0
        internal WZConvexProperty(string name, WZObject parent, WZBinaryReader r, WZImage container)
            : base(name, parent, default(WZNothing), container, true, WZObjectType.Convex)
        {
            int count = r.ReadWZInt();

            for (int i = 0; i < count; ++i)
            {
                Add(WZExtendedParser.ParseExtendedProperty(i.ToString(CultureInfo.InvariantCulture), r, this, Image,
                                                           Image._encrypted));
            }
        }
Пример #9
0
        private void Parse(WZBinaryReader wzbr, long offset)
        {
            wzbr.Seek(offset);
            int entryCount = wzbr.ReadWZInt();

            for (int i = 0; i < entryCount; ++i)
            {
                byte   type = wzbr.ReadByte();
                string name = null;
                switch (type)
                {
                case 2:
                    int x = wzbr.ReadInt32();
                    wzbr.PeekFor(() => {
                        wzbr.Seek(x + File._fstart);
                        type = wzbr.ReadByte();
                        name = wzbr.ReadWZString(File._encrypted);
                    });

                    break;

                case 3:
                case 4:
                    name = wzbr.ReadWZString(File._encrypted);
                    break;

                case 1:
                // wzbr.Skip(10);
                // continue;
                default:
                    WZUtil.Die($"Unknown object type {type} in WzDirectory.");
                    break;
                }
                if (name == null)
                {
                    WZUtil.Die("Failed to read WZDirectory entry name.");
                }
                int size = wzbr.ReadWZInt();
                wzbr.ReadWZInt();
                uint woffset = wzbr.ReadWZOffset(File._fstart);
                switch (type)
                {
                case 3:
                    Add(new WZDirectory(name, this, File, wzbr.Clone(), woffset));
                    break;

                case 4:
                    Add(new WZImage(name, this, File,
                                    File.GetSubstream(woffset, size)));
                    break;
                }
            }
        }
Пример #10
0
 internal override bool Parse(WZBinaryReader r, bool initial, out string result)
 {
     if (!initial || (File._flag & WZReadSelection.EagerParseStrings) == WZReadSelection.EagerParseStrings)
     {
         result = string.Intern(r.ReadWZStringBlock(Image._encrypted));
         return(true);
     }
     else
     {
         r.SkipWZStringBlock();
         result = null;
         return(false);
     }
 }
Пример #11
0
        internal override bool Parse(WZBinaryReader r, bool initial, out byte[] result)
        {
            r.Skip(1);
            int blockLen = r.ReadWZInt(); // sound data length

            Duration = r.ReadWZInt();     // sound duration
            r.Skip(1 + 16 + 16 + 2);      // Byte, Major type GUID, Sub type GUID, byte, byte

            Guid fmt = new Guid(r.ReadBytes(16));

            if (fmt == WaveFormatExGuid)
            {
                if (initial)
                {
                    r.Skip(r.ReadWZInt());
                }
                else
                {
                    _header = r.ReadBytes(r.ReadWZInt());
                    if (_header.Length != 18 + GetCbSize(_header))
                    {
                        _header = null; // TODO FIXME figure out what those gibberish headers are
                    }
                    // But in any case they don't affect our uses

                    //    File._aes.DecryptBytesAsciiKey(_header);
                    //if (_header.Length != 18 + GetCbSize(_header))
                    //    Debug.WriteLine("Failed to parse WAVEFORMATEX header at node {0}", Path);
                    //throw new WZException($"Failed to parse WAVEFORMATEX header at node {Path}");
                }
            }
            else if (fmt != NoHeaderGuid)
            {
                Debug.WriteLine("New format guid {0} @ {1}", fmt, Path);
            }

            if (!initial || (File._flag & WZReadSelection.EagerParseAudio) == WZReadSelection.EagerParseAudio)
            {
                result = r.ReadBytes(blockLen);
                return(true);
            }
            else
            {
                r.Skip(blockLen);
                result = null;
                return(false);
            }
        }
Пример #12
0
        private void Parse(WZBinaryReader wzbr, long offset)
        {
            wzbr.Seek(offset);
            int entryCount = wzbr.ReadWZInt();
            for (int i = 0; i < entryCount; ++i) {
                byte type = wzbr.ReadByte();
                string name = null;
                switch (type) {
                    case 2:
                        int x = wzbr.ReadInt32();
                        wzbr.PeekFor(() => {
                            wzbr.Seek(x + File._fstart);
                            type = wzbr.ReadByte();
                            name = wzbr.ReadWZString(File._encrypted);
                        });

                        break;
                    case 3:
                    case 4:
                        name = wzbr.ReadWZString(File._encrypted);
                        break;
                    case 1:
                    // wzbr.Skip(10);
                    // continue;
                    default:
                        WZUtil.Die($"Unknown object type {type} in WzDirectory.");
                        break;
                }
                if (name == null) {
                    WZUtil.Die("Failed to read WZDirectory entry name.");
                }
                int size = wzbr.ReadWZInt();
                wzbr.ReadWZInt();
                uint woffset = wzbr.ReadWZOffset(File._fstart);
                switch (type) {
                    case 3:
                        Add(new WZDirectory(name, this, File, wzbr.Clone(), woffset));
                        break;
                    case 4:
                        Add(new WZImage(name, this, File,
                            File.GetSubstream(woffset, size)));
                        break;
                }
            }
        }
Пример #13
0
 internal WZDoubleProperty(string name, WZObject parent, WZBinaryReader reader, WZImage container)
     : base(name, parent, reader.ReadDouble(), container, false, WZObjectType.Double)
 {
 }
Пример #14
0
 internal WZStringProperty(string name, WZObject parent, WZBinaryReader reader, WZImage container)
     : base(name, parent, container, reader, false, WZObjectType.String)
 {
 }
Пример #15
0
 internal WZSingleProperty(string name, WZObject parent, WZBinaryReader reader, WZImage container)
     : base(name, parent, ReadSingle(reader), container, false, WZObjectType.Single)
 {
 }
Пример #16
0
        private static unsafe Bitmap ParsePNG(int width, int height, int format1, int scale, byte[] data)
        {
            byte[] dec;
            using (MemoryStream @in = new MemoryStream(data, 0, data.Length)) {
                dec = WZBinaryReader.Inflate(@in);
            }
            int decLen = dec.Length;

            width  >>= scale;
            height >>= scale;
            switch (format1)
            {
            case 0x001: {
                if (decLen != width * height * 2)
                {
                    Debug.WriteLine("Warning; dec.Length != 2wh; ARGB4444");
                }
                Bitmap     ret = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                BitmapData bd  = ret.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly,
                                              PixelFormat.Format32bppArgb);
                try
                {
                    fixed(byte *t = dec)
                    {
                        byte *u = t, s = (byte *)bd.Scan0;

                        for (int i = 0; i < decLen; i++)
                        {
                            *s++ = (byte)((*u & 0x0F) * 0x11);
                            *s++ = (byte)(((*u++ & 0xF0) >> 4) * 0x11);
                        }
                    }
                } finally {
                    ret.UnlockBits(bd);
                }
                return(ret);
            }

            case 0x002:
                if (decLen != width * height * 4)
                {
                    Debug.WriteLine("Warning; dec.Length != 4wh; 32BPP");
                }
                return(BitmapFromBytes(width, height, PixelFormat.Format32bppArgb, dec));

            case 0x201:
                if (decLen != width * height * 2)
                {
                    Debug.WriteLine("Warning; dec.Length != 2wh; 16BPP");
                }
                return(BitmapFromBytes(width, height, PixelFormat.Format16bppRgb565, dec));

            case 0x402: {
                Bitmap     ret = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                BitmapData bd  = ret.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly,
                                              PixelFormat.Format32bppArgb);
                try
                {
                    fixed(byte *decP = dec)
                    {
                        UnDXT.DecompressImage((byte *)bd.Scan0, width, height, decP, UnDXT.kDxt3);
                    }
                } finally {
                    ret.UnlockBits(bd);
                }
                return(ret);
            }

            default:
                Debug.WriteLine("Unknown bitmap type format1:{0} scale:{1}", format1, scale);
                return(null);
            }
        }
Пример #17
0
 internal WZUInt16Property(string name, WZObject parent, WZBinaryReader reader, WZImage container)
     : base(name, parent, reader.ReadUInt16(), container, false, WZObjectType.UInt16)
 {
 }
Пример #18
0
 internal WZInt64Property(string name, WZObject parent, WZBinaryReader reader, WZImage container)
     : base(name, parent, reader.ReadWZLong(), container, false, WZObjectType.Int64)
 {
 }
Пример #19
0
 internal WZPointProperty(string name, WZObject parent, WZBinaryReader wzbr, WZImage container)
     : base(name, parent, new Point(wzbr.ReadWZInt(), wzbr.ReadWZInt()), container, false, WZObjectType.Point)
 {
 }
Пример #20
0
 internal WZLinkProperty(string name, WZObject parent, WZBinaryReader reader, WZImage container)
     : base(
         name, parent, string.Intern(reader.ReadWZStringBlock(container._encrypted)), container, false,
         WZObjectType.Link)
 {
 }
Пример #21
0
 internal WZCanvasProperty(string name, WZObject parent, WZBinaryReader br, WZImage container)
     : base(name, parent, container, br, true, WZObjectType.Canvas)
 {
 }
Пример #22
0
        internal override bool Parse(WZBinaryReader br, bool initial, out Bitmap result)
        {
            bool skip  = (File._flag & WZReadSelection.NeverParseCanvas) == WZReadSelection.NeverParseCanvas,
                 eager = (File._flag & WZReadSelection.EagerParseCanvas) == WZReadSelection.EagerParseCanvas;

            if (initial)
            {
                if (skip && eager)
                {
                    result = null;
                    return(WZUtil.Die <bool>("Both NeverParseCanvas and EagerParseCanvas are set."));
                }
                br.Skip(1);
                if (br.ReadByte() == 1)
                {
                    br.Skip(2);
                    List <WZObject> l = WZExtendedParser.ParsePropertyList(br, this, Image, Image._encrypted);
                    if (ChildCount == 0)
                    {
                        l.ForEach(Add);
                    }
                }
                _afterChildren = br.Position;
            }
            else
            {
                br.Position = _afterChildren;
            }
            int width   = br.ReadWZInt(); // width
            int height  = br.ReadWZInt(); // height
            int format1 = br.ReadWZInt(); // format 1
            int scale   = br.ReadByte();  // format 2

            br.Skip(4);
            int blockLen = br.ReadInt32();

            if ((initial || skip) && !eager)
            {
                br.Skip(blockLen); // block Len & png data
                result = null;
                return(skip);
            }
            else
            {
                br.Skip(1);
                byte[] header = br.ReadBytes(2);
                // FLG bit 5 indicates the presence of a preset dictionary
                // seems like MS doesn't use that?
                if ((header[1] & 0x20) != 0)
                {
                    Debug.WriteLine("Warning; zlib with preset dictionary");
                    result = null;
                    br.Skip(blockLen - 3);
                    return(true);
                }
                // zlib header: CMF (byte), FLG (byte)
                byte[] pngData = br.ReadBytes(blockLen - 3);
                result = ParsePNG(width, height, format1, scale,
                                  // CMF least significant bits 0 to 3 are compression method. only 8 is valid
                                  (header[0] & 0xF) != 8 ||
                                  // CMF << 8 | FLG i.e. header read as a big-endian short is a multiple of 31
                                  (header[0] << 8 | header[1]) % 31 != 0
                        ? DecryptPNG(pngData)
                        : pngData);
                return(true);
            }
        }
Пример #23
0
 internal abstract bool Parse(WZBinaryReader r, bool initial, out T result);
Пример #24
0
 internal WZDirectory(string name, WZObject parent, WZFile file, WZBinaryReader wzbr, long offset)
     : base(name, parent, file, true, WZObjectType.Directory)
 {
     Parse(wzbr, offset);
 }
Пример #25
0
 internal WZDirectory(string name, WZObject parent, WZFile file, WZBinaryReader wzbr, long offset)
     : base(name, parent, file, true, WZObjectType.Directory)
 {
     Parse(wzbr, offset);
 }