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