コード例 #1
0
        public void UnpackAlpha(int offset)
        {
            using (var input = new BinMemoryStream(this.Input, offset, Input.Length - offset))
            {
                if (1 != input.ReadInt32())
                {
                    return;
                }
                int dst = 3;
                int ctl = 1 << 1;
                while (dst < Output.Length)
                {
                    ctl >>= 1;
                    if (1 == ctl)
                    {
                        ctl = input.ReadUInt8() | 0x100;
                    }

                    if (0 != (ctl & 1))
                    {
                        int v = input.ReadUInt16();
                        int x = v & 0x3F;
                        if (x > 0x1F)
                        {
                            x |= -0x40;
                        }
                        int y = (v >> 6) & 7;
                        if (y != 0)
                        {
                            y |= -8;
                        }
                        int count = ((v >> 9) & 0x7F) + 3;

                        int src = dst + (x + y * Width) * 4;
                        if (src < 0 || src >= dst)
                        {
                            return;
                        }

                        for (int i = 0; i < count; ++i)
                        {
                            Output[dst] = Output[src];
                            src        += 4;
                            dst        += 4;
                        }
                    }
                    else
                    {
                        Output[dst] = input.ReadUInt8();
                        dst        += 4;
                    }
                }
                HasAlpha = true;
            }
        }
コード例 #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
        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);
            }
        }
コード例 #4
0
        public byte[] Unpack()
        {
            m_input.Position = 0x20;
            if (m_info.HasPalette)
            {
                Palette = ImageFormat.ReadPalette(m_input.AsStream, 0x100, PaletteFormat.Bgr);
            }

            var buffer = ReadChunks();

            using (var input = new BinMemoryStream(buffer))
            {
                int g_pos         = m_info.iWidth;
                int b_pos         = m_info.iWidth * 2;
                int a_pos         = m_info.iWidth * 3;
                var scanline      = new byte[m_info.ScanLineSize * 2];
                var unpack_buffer = new byte[scanline.Length];
                int dst           = 0;
                for (int y = 0; y < m_info.iHeight; ++y)
                {
                    int  packed_size = Binary.BigEndian(input.ReadInt24() << 8);
                    byte flags       = input.ReadUInt8();
                    if (packed_size > scanline.Length)
                    {
                        break;
                    }
                    input.Read(scanline, 0, packed_size);
                    if ((flags & 4) != 0) // LZSS compression
                    {
                        packed_size = PckOpener.LzssUnpack(scanline, packed_size, unpack_buffer);
                        var swap = scanline;
                        scanline      = unpack_buffer;
                        unpack_buffer = swap;
                    }
                    if ((flags & 2) != 0) // RLE compression
                    {
                        packed_size = RleUnpack(scanline, packed_size, unpack_buffer);
                        var swap = scanline;
                        scanline      = unpack_buffer;
                        unpack_buffer = swap;
                    }
                    if ((flags & 1) != 0)
                    {
                        RestoreScanline(scanline, packed_size);
                    }
                    switch (m_info.BPP)
                    {
                    case 24:
                    {
                        int src_r = 0;
                        int src_g = g_pos;
                        int src_b = b_pos;
                        int src_a = a_pos;
                        for (int x = 0; x < m_info.iWidth; ++x)
                        {
                            m_output[dst++] = scanline[src_b++];
                            m_output[dst++] = scanline[src_g++];
                            m_output[dst++] = scanline[src_r++];
                            if (m_info.HasAlpha)
                            {
                                m_output[dst++] = scanline[src_a++];
                            }
                        }
                        break;
                    }

                    default:
                        throw new NotImplementedException("Not supported LAG color depth.");
                    }
                }
            }
            return(m_output);
        }