예제 #1
0
        IarImage CombineLayers(IarImage layers, IarArchive iarc)
        {
            layers.Info.Stride = (int)layers.Info.Width * 4;
            layers.Info.BPP    = 32;
            var pixels = new byte[layers.Info.Stride * (int)layers.Info.Height];
            var output = new IarImage(layers.Info, pixels);

            using (var input = new BinMemoryStream(layers.Data))
            {
                int offset_x = 0, offset_y = 0;
                var dir = (List <Entry>)iarc.Dir;
                while (input.Position < input.Length)
                {
                    int cmd = input.ReadUInt8();
                    switch (cmd)
                    {
                    case 0x21:
                        offset_x += input.ReadInt16();
                        offset_y += input.ReadInt16();
                        break;

                    case 0x00:
                    case 0x20:
                    {
                        int index = input.ReadInt32();
                        if (index < 0 || index >= dir.Count)
                        {
                            throw new InvalidFormatException("Invalid image layer index");
                        }
                        var layer = new IarImage(iarc, dir[index]);
                        layer.Info.OffsetX -= offset_x;
                        layer.Info.OffsetY -= offset_y;
                        if (0x20 == cmd)
                        {
                            output.ApplyMask(layer);
                        }
                        else
                        {
                            output.Blend(layer);
                        }
                    }
                    break;

                    default:
                        Trace.WriteLine(string.Format("Unknown layer type 0x{0:X2}", cmd), "IAR");
                        break;
                    }
                }
                return(output);
            }
        }
예제 #2
0
파일: Asset.cs 프로젝트: zxc120/GARbro
        void LoadBlob(AssetReader reader)
        {
            int count        = reader.ReadInt32();
            int buffer_bytes = reader.ReadInt32();
            var node_data    = reader.ReadBytes(24 * count);

            m_data = reader.ReadBytes(buffer_bytes);

            var parents = new Stack <TypeTree>();

            parents.Push(this);
            using (var buf = new BinMemoryStream(node_data))
            {
                for (int i = 0; i < count; ++i)
                {
                    int      version = buf.ReadInt16();
                    int      depth   = buf.ReadUInt8();
                    TypeTree current;
                    if (0 == depth)
                    {
                        current = this;
                    }
                    else
                    {
                        while (parents.Count > depth)
                        {
                            parents.Pop();
                        }
                        current = new TypeTree(m_format);
                        parents.Peek().Children.Add(current);
                        parents.Push(current);
                    }
                    current.Version = version;
                    current.IsArray = buf.ReadUInt8() != 0;
                    current.Type    = GetString(buf.ReadInt32());
                    current.Name    = GetString(buf.ReadInt32());
                    current.Size    = buf.ReadInt32();
                    current.Index   = buf.ReadUInt32();
                    current.Flags   = buf.ReadInt32();
                }
            }
        }
예제 #3
0
파일: ImageG00.cs 프로젝트: zxc120/GARbro
        void UnpackV2()
        {
            Format = PixelFormats.Bgra32;
            int tile_count = m_input.ReadInt32();
            var tiles      = new List <Tile> (tile_count);

            for (int i = 0; i < tile_count; ++i)
            {
                var tile = new Tile();
                tile.X = m_input.ReadInt32();
                tile.Y = m_input.ReadInt32();
                tiles.Add(tile);
                m_input.Seek(0x10, SeekOrigin.Current);
            }
            using (var input = new BinMemoryStream(LzDecompress(m_input, 2, 1)))
            {
                if (input.ReadInt32() != tile_count)
                {
                    throw new InvalidFormatException();
                }
                int dst_stride = m_width * 4;
                m_output = new byte[m_height * dst_stride];
                for (int i = 0; i < tile_count; ++i)
                {
                    tiles[i].Offset = input.ReadUInt32();
                    tiles[i].Length = input.ReadInt32();
                }
                var tile = tiles.First(t => t.Length != 0);

                input.Position = tile.Offset;
                int tile_type = input.ReadUInt16();
                int count     = input.ReadUInt16();
                if (tile_type != 1)
                {
                    throw new InvalidFormatException();
                }
                input.Seek(0x70, SeekOrigin.Current);
                for (int i = 0; i < count; ++i)
                {
                    int tile_x = input.ReadUInt16();
                    int tile_y = input.ReadUInt16();
                    input.ReadInt16();
                    int tile_width  = input.ReadUInt16();
                    int tile_height = input.ReadUInt16();
                    input.Seek(0x52, SeekOrigin.Current);

                    tile_x += tile.X;
                    tile_y += tile.Y;
                    if (tile_x + tile_width > m_width || tile_y + tile_height > m_height)
                    {
                        throw new InvalidFormatException();
                    }
                    int dst         = tile_y * dst_stride + tile_x * 4;
                    int tile_stride = tile_width * 4;
                    for (int row = 0; row < tile_height; ++row)
                    {
                        input.Read(m_output, dst, tile_stride);
                        dst += dst_stride;
                    }
                }
            }
        }