Пример #1
0
        void UnpackBlock_4_9(PxBlock block_info)
        {
            var  output    = NewBlock(block_info);
            int  dst       = 0;
            bool has_alpha = true;

            for (;;)
            {
                int code = m_input.ReadInt32();
                if (-1 == code)
                {
                    break;
                }
                if (0 != (code & 0x180000))
                {
                    has_alpha = !has_alpha;
                }
                dst += (code & 0x1FF) * MaxBlockSize;
                dst += code >> 21;

                int count = (code >> 9) & 0x3FF;
                for (int i = 0; i < count; ++i)
                {
                    byte alpha     = (byte)(has_alpha ? (m_input.ReadUInt8() << 1) - 1 : 0xFF);
                    int  color_idx = m_input.ReadByte();
                    if (dst < output.Length)
                    {
                        var color = Palette.Colors[color_idx];
                        output[dst] = (uint)(color.B | color.G << 8 | color.R << 16 | alpha << 24);
                    }
                    dst++;
                }
            }
            PutBlock(block_info);
        }
Пример #2
0
        void UnpackBlock_7(PxBlock block)
        {
            m_stride       = 4 * block.Width;
            m_output       = new byte[m_stride * block.Height];
            Format         = PixelFormats.Bgra32;
            m_info.OffsetX = block.X;
            m_info.OffsetY = block.Y;
            int dst       = 0;
            var color_map = ImageFormat.ReadColorMap(m_input.AsStream, 0x100, PaletteFormat.BgrA);

            for (int y = 0; y < block.Height; ++y)
            {
                for (int x = 0; x < block.Width; ++x)
                {
                    int idx = m_input.ReadUInt8();
                    var c   = color_map[idx];
                    m_output[dst++] = c.B;
                    m_output[dst++] = c.G;
                    m_output[dst++] = c.R;
                    if (c.A != 0)
                    {
                        m_output[dst++] = (byte)((c.A << 1 | c.R >> 7) + 0xFF);
                    }
                    else
                    {
                        m_output[dst++] = 0xFF;
                    }
                }
            }
        }
Пример #3
0
        uint[] NewBlock(PxBlock block_info)
        {
            var block = m_block.Value;

            Array.Clear(block, 0, MaxBlockSize * block_info.Height);
            return(block);
        }
Пример #4
0
        void ReadBlock(uint offset)
        {
            m_input.Position = offset;
            var px = new PxBlock();

            px.Width         = m_input.ReadInt32();
            px.Height        = m_input.ReadInt32();
            px.X             = m_input.ReadInt32();
            px.Y             = m_input.ReadInt32();
            px.Type          = m_input.ReadUInt16();
            px.Bits          = m_input.ReadUInt16();
            m_input.Position = offset + 0x20;
            switch (px.Type)
            {
            case 0:
                Palette = ImageFormat.ReadPalette(m_input.AsStream, (int)px.Width);
                break;

            case 1:
                switch (px.Bits)
                {
                case 8:     UnpackBlock_1_8(px); break;

                case 0x20:  UnpackBlock_1_20(px); break;
                }
                break;

            case 4:
                switch (px.Bits)
                {
                case 8:     UnpackBlock_4_8(px); break;

                case 9:     UnpackBlock_4_9(px); break;

                case 0x20:  UnpackBlock_4_20(px); break;

                case 0x30:  UnpackBlock_4_30(px); break;
                }
                break;

            case 7:
                UnpackBlock_7(px);
                break;

            default:
                throw new InvalidFormatException();
            }
        }
Пример #5
0
        void PutBlock(PxBlock block_info)
        {
            var block    = m_block.Value;
            int left     = Math.Max(0, block_info.X);
            int top      = Math.Max(0, block_info.Y);
            int right    = Math.Min(block_info.X + block_info.Width, (int)m_info.Width);
            int bottom   = Math.Min(block_info.Y + block_info.Height, (int)m_info.Height);
            int dst_row  = top * m_stride + left * 4;
            int row_size = (right - left) * 4;

            for (int y = top; y < bottom; ++y)
            {
                int src = (left - block_info.X) + (y - block_info.Y) * MaxBlockSize;
                Buffer.BlockCopy(block, src * 4, m_output, dst_row, row_size);
                dst_row += m_stride;
            }
        }
Пример #6
0
        void UnpackBlock_4_30(PxBlock block_info)
        {
            var output = NewBlock(block_info);
            int dst    = 0;

            for (;;)
            {
                int next = m_input.ReadInt32();
                if (-1 == next)
                {
                    break;
                }
                if (0 != (next & 0xFF000000))
                {
                    continue;
                }
                dst += next / 4;
                m_input.ReadInt32();

                int count = m_input.ReadInt32();
                for (int i = 0; i < count; ++i)
                {
                    uint color = m_input.ReadUInt32();
                    m_input.ReadInt16();
                    if (dst < output.Length)
                    {
                        if (0 != (color & 0xFF000000))
                        {
                            uint alpha = ((color >> 23) + 0xFF) << 24;
                            output[dst] = (color & 0xFFFFFF) | alpha;
                        }
                        else
                        {
                            output[dst] = 0;
                        }
                    }
                    dst++;
                }
            }
            PutBlock(block_info);
        }
Пример #7
0
        void UnpackBlock_1_20(PxBlock block)
        {
            int dst = 0;

            for (int y = 0; y < block.Height; ++y)
            {
                for (int x = 0; x < block.Width; ++x)
                {
                    m_input.Read(m_output, dst, 4);
                    if (0 != m_output[dst + 3])
                    {
                        byte alpha = (byte)((m_output[dst + 3] << 1 | m_output[dst + 2] >> 7) + 0xFF);
                        m_output[dst + 3] = alpha;
                    }
                    else
                    {
                        m_output[dst + 3] = 0xFF;
                    }
                    dst += 4;
                }
            }
        }
Пример #8
0
        void UnpackBlock_4_20(PxBlock block_info)
        {
            var block = NewBlock(block_info);
            int dst   = 0;
            int next;

            while ((next = m_input.ReadInt32()) != -1)
            {
                if (next < 0 || next > 0xFFFFFF)
                {
                    continue;
                }
                dst += next / 4;
                m_input.ReadInt32();

                int count = m_input.ReadInt32();
                while (count-- > 0)
                {
                    uint color = m_input.ReadUInt32();
                    if (dst < block.Length)
                    {
                        if (0 != (color & 0xFF000000))
                        {
                            uint alpha = ((color >> 23) + 0xFF) << 24;
                            block[dst] = (color & 0xFFFFFFu) | alpha;
                        }
                        else
                        {
                            block[dst] = color | 0xFF000000u;
                        }
                    }
                    ++dst;
                }
            }
            PutBlock(block_info);
        }
Пример #9
0
 void UnpackBlock_4_8(PxBlock block)
 {
     throw new NotImplementedException();
 }
Пример #10
0
 void UnpackBlock_1_8(PxBlock block)
 {
     m_input.Read(m_output, 0, (int)m_info.Width * (int)m_info.Height);
 }