Exemplo n.º 1
0
        private static Color8888 DxtcRead3bColor(ushort data)
        {
            byte r = unchecked ((byte)(data & 0x1F));
            byte g = unchecked ((byte)((data & 0x7E0) >> 5));
            byte b = unchecked ((byte)((data & 0xF800) >> 11));

            Color8888 op = default;

            op.Red   = unchecked ((byte)(r << 3 | r >> 2));
            op.Green = unchecked ((byte)(g << 2 | g >> 3));
            op.Blue  = unchecked ((byte)(b << 3 | r >> 2));
            op.Alpha = 0xFF;
            return(op);
        }
Exemplo n.º 2
0
        private static Color8888 DxtcRead2bColor(BinaryReader reader)
        {
            byte data0 = reader.ReadByte();
            byte data1 = reader.ReadByte();

            byte r = unchecked ((byte)(data0 & 0x1F));
            byte g = unchecked ((byte)(((data0 & 0xE0) >> 5) | ((data1 & 0x7) << 3)));
            byte b = unchecked ((byte)((data1 & 0xF8) >> 3));

            Color8888 op = default;

            op.Red   = unchecked ((byte)(r << 3 | r >> 2));
            op.Green = unchecked ((byte)(g << 2 | g >> 3));
            op.Blue  = unchecked ((byte)(b << 3 | b >> 2));
            return(op);
        }
Exemplo n.º 3
0
        public static void DecompressDXT1(BinaryReader sourceReader, Stream destination, DDSContainerParameters @params)
        {
            int  depth       = @params.BitMapDepth;
            int  width       = @params.Width;
            int  height      = @params.Height;
            int  bpp         = GetRGBABytesPerPixel(@params);
            int  bpc         = GetBytesPerColor(@params);
            int  bps         = width * bpp * bpc;
            long sizeOfPlane = bps * height;

            Color8888[] colors = new Color8888[4];

            long position = destination.Position;

            for (int z = 0; z < depth; z++)
            {
                // mirror Y
                for (int y = height - 1; y >= 0; y -= 4)
                {
                    for (int x = 0; x < width; x += 4)
                    {
                        ushort color0 = sourceReader.ReadUInt16();
                        ushort color1 = sourceReader.ReadUInt16();

                        uint bitMask0 = sourceReader.ReadUInt16();
                        uint bitMask1 = sourceReader.ReadUInt16();
                        uint bitMask  = (bitMask0 << 0) | (bitMask1 << 16);

                        colors[0] = DxtcRead3bColor(color0);
                        colors[1] = DxtcRead3bColor(color1);

                        if (color0 > color1)
                        {
                            // Four-color block: derive the other two colors.
                            // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
                            // These 2-bit codes correspond to the 2-bit fields
                            // stored in the 64-bit block.
                            colors[2].Blue  = unchecked ((byte)((2 * colors[0].Blue + colors[1].Blue + 1) / 3));
                            colors[2].Green = unchecked ((byte)((2 * colors[0].Green + colors[1].Green + 1) / 3));
                            colors[2].Red   = unchecked ((byte)((2 * colors[0].Red + colors[1].Red + 1) / 3));

                            colors[2].Alpha = 0xFF;
                            colors[3].Alpha = 0xFF;
                        }
                        else
                        {
                            // Three-color block: derive the other color.
                            // 00 = color_0,  01 = color_1,  10 = color_2,
                            // 11 = transparent.
                            // These 2-bit codes correspond to the 2-bit fields
                            // stored in the 64-bit block.
                            colors[2].Blue  = unchecked ((byte)((colors[0].Blue + colors[1].Blue) / 2));
                            colors[2].Green = unchecked ((byte)((colors[0].Green + colors[1].Green) / 2));
                            colors[2].Red   = unchecked ((byte)((colors[0].Red + colors[1].Red) / 2));

                            colors[2].Alpha = 0xFF;
                            colors[3].Alpha = 0x0;
                        }

                        colors[3].Blue  = unchecked ((byte)((colors[0].Blue + 2 * colors[1].Blue + 1) / 3));
                        colors[3].Green = unchecked ((byte)((colors[0].Green + 2 * colors[1].Green + 1) / 3));
                        colors[3].Red   = unchecked ((byte)((colors[0].Red + 2 * colors[1].Red + 1) / 3));

                        int bitIndex = 0;
                        for (int ly = 0; ly < 4; ly++)
                        {
                            for (int lx = 0; lx < 4; lx++, bitIndex++)
                            {
                                int       colorIndex = unchecked ((int)((bitMask & (3 << bitIndex * 2)) >> bitIndex * 2));
                                Color8888 color      = colors[colorIndex];
                                if ((x + lx) < width && (y - ly) < height && (y - ly) >= 0)
                                {
                                    // mirror Y
                                    long offset = z * sizeOfPlane + (y - ly) * bps + (x + lx) * bpp;
                                    destination.Position = position + offset;

                                    destination.WriteByte(color.Red);
                                    destination.WriteByte(color.Green);
                                    destination.WriteByte(color.Blue);
                                    destination.WriteByte(color.Alpha);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        public static void DecompressDXT5(BinaryReader sourceReader, Stream destination, DDSContainerParameters @params)
        {
            int  depth       = @params.BitMapDepth;
            int  width       = @params.Width;
            int  height      = @params.Height;
            int  bpp         = GetRGBABytesPerPixel(@params);
            int  bpc         = GetBytesPerColor(@params);
            int  bps         = width * bpp * bpc;
            long sizeOfPlane = bps * height;

            Color8888[] colors    = new Color8888[4];
            ushort[]    alphas    = new ushort[8];
            byte[]      alphaMask = new byte[6];

            long position = destination.Position;

            for (int z = 0; z < depth; z++)
            {
                // mirror Y
                for (int y = height - 1; y >= 0; y -= 4)
                {
                    for (int x = 0; x < width; x += 4)
                    {
                        ushort alpha = sourceReader.ReadUInt16();
                        alphas[0] = unchecked ((byte)(alpha >> 0));
                        alphas[1] = unchecked ((byte)(alpha >> 8));

                        ushort alphaMask0 = sourceReader.ReadUInt16();
                        ushort alphaMask1 = sourceReader.ReadUInt16();
                        ushort alphaMask2 = sourceReader.ReadUInt16();
                        alphaMask[0] = unchecked ((byte)(alphaMask0 >> 0));
                        alphaMask[1] = unchecked ((byte)(alphaMask0 >> 8));
                        alphaMask[2] = unchecked ((byte)(alphaMask1 >> 0));
                        alphaMask[3] = unchecked ((byte)(alphaMask1 >> 8));
                        alphaMask[4] = unchecked ((byte)(alphaMask2 >> 0));
                        alphaMask[5] = unchecked ((byte)(alphaMask2 >> 8));

                        colors[0] = DxtcRead2bColor(sourceReader);
                        colors[1] = DxtcRead2bColor(sourceReader);

                        uint bitMask0 = sourceReader.ReadUInt16();
                        uint bitMask1 = sourceReader.ReadUInt16();
                        uint bitMask  = (bitMask0 << 0) | (bitMask1 << 16);

                        // Four-color block: derive the other two colors.
                        // 00 = color_0, 01 = color_1, 10 = color_2, 11	= color_3
                        // These 2-bit codes correspond to the 2-bit fields
                        // stored in the 64-bit block.
                        colors[2].Blue  = unchecked ((byte)((2 * colors[0].Blue + colors[1].Blue + 1) / 3));
                        colors[2].Green = unchecked ((byte)((2 * colors[0].Green + colors[1].Green + 1) / 3));
                        colors[2].Red   = unchecked ((byte)((2 * colors[0].Red + colors[1].Red + 1) / 3));

                        colors[3].Blue  = unchecked ((byte)((colors[0].Blue + 2 * colors[1].Blue + 1) / 3));
                        colors[3].Green = unchecked ((byte)((colors[0].Green + 2 * colors[1].Green + 1) / 3));
                        colors[3].Red   = unchecked ((byte)((colors[0].Red + 2 * colors[1].Red + 1) / 3));

                        int bitIndex = 0;
                        for (int ly = 0; ly < 4; ly++)
                        {
                            for (int lx = 0; lx < 4; lx++, bitIndex++)
                            {
                                int       colorIndex = (int)((bitMask & (0x03 << bitIndex * 2)) >> bitIndex * 2);
                                Color8888 col        = colors[colorIndex];
                                // only put pixels out < width or height
                                if ((x + lx) < width && (y - ly) < height && (y - ly) >= 0)
                                {
                                    // mirror Y
                                    long offset = z * sizeOfPlane + (y - ly) * bps + (x + lx) * bpp;
                                    destination.Position = position + offset;

                                    destination.WriteByte(col.Red);
                                    destination.WriteByte(col.Green);
                                    destination.WriteByte(col.Blue);
                                }
                            }
                        }

                        // 8-alpha or 6-alpha block?
                        if (alphas[0] > alphas[1])
                        {
                            // 8-alpha block:  derive the other six alphas.
                            // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
                            alphas[2] = unchecked ((ushort)((6 * alphas[0] + 1 * alphas[1] + 3) / 7));                            // bit code 010
                            alphas[3] = unchecked ((ushort)((5 * alphas[0] + 2 * alphas[1] + 3) / 7));                            // bit code 011
                            alphas[4] = unchecked ((ushort)((4 * alphas[0] + 3 * alphas[1] + 3) / 7));                            // bit code 100
                            alphas[5] = unchecked ((ushort)((3 * alphas[0] + 4 * alphas[1] + 3) / 7));                            // bit code 101
                            alphas[6] = unchecked ((ushort)((2 * alphas[0] + 5 * alphas[1] + 3) / 7));                            // bit code 110
                            alphas[7] = unchecked ((ushort)((1 * alphas[0] + 6 * alphas[1] + 3) / 7));                            // bit code 111
                        }
                        else
                        {
                            // 6-alpha block.
                            // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated.
                            alphas[2] = unchecked ((ushort)((4 * alphas[0] + 1 * alphas[1] + 2) / 5)); // Bit code 010
                            alphas[3] = unchecked ((ushort)((3 * alphas[0] + 2 * alphas[1] + 2) / 5)); // Bit code 011
                            alphas[4] = unchecked ((ushort)((2 * alphas[0] + 3 * alphas[1] + 2) / 5)); // Bit code 100
                            alphas[5] = unchecked ((ushort)((1 * alphas[0] + 4 * alphas[1] + 2) / 5)); // Bit code 101
                            alphas[6] = 0x00;                                                          // Bit code 110
                            alphas[7] = 0xFF;                                                          // Bit code 111
                        }

                        // Note: Have to separate the next two loops,
                        // it operates on a 6-byte system.

                        // First three bytes
                        //uint bits = (uint)(alphamask[0]);
                        uint bits = unchecked ((uint)((alphaMask[0]) | (alphaMask[1] << 8) | (alphaMask[2] << 16)));
                        for (int ly = 0; ly < 2; ly++)
                        {
                            for (int lx = 0; lx < 4; lx++, bits >>= 3)
                            {
                                // only put pixels out < width or height
                                if ((x + lx) < width && (y - ly) < height && (y - ly) >= 0)
                                {
                                    byte alphaValue = unchecked ((byte)alphas[bits & 0x07]);
                                    // mirror Y
                                    long offset = z * sizeOfPlane + (y - ly) * bps + (x + lx) * bpp + 3;
                                    destination.Position = position + offset;
                                    destination.WriteByte(alphaValue);
                                }
                            }
                        }

                        // Last three bytes
                        //bits = (uint)(alphamask[3]);
                        bits = unchecked ((uint)((alphaMask[3]) | (alphaMask[4] << 8) | (alphaMask[5] << 16)));
                        for (int ly = 2; ly < 4; ly++)
                        {
                            for (int lx = 0; lx < 4; lx++, bits >>= 3)
                            {
                                // only put pixels out < width or height
                                if ((x + lx) < width && (y - ly) < height && (y - ly) >= 0)
                                {
                                    byte alphaValue = unchecked ((byte)alphas[bits & 0x07]);
                                    // mirror Y
                                    long offset = z * sizeOfPlane + (y - ly) * bps + (x + lx) * bpp + 3;
                                    destination.Position = position + offset;
                                    destination.WriteByte(alphaValue);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        public static void DecompressDXT3(Stream destination, Stream source, DDSConvertParameters @params)
        {
            int  depth       = @params.BitMapDepth;
            int  width       = @params.Width;
            int  height      = @params.Height;
            int  bpp         = GetRGBABytesPerPixel(@params);
            int  bpc         = GetBytesPerColor(@params);
            int  bps         = width * bpp * bpc;
            long sizeOfPlane = bps * height;

            Color8888[] colors = new Color8888[4];
            byte[]      alphas = new byte[16];

            long position = destination.Position;

            using (BinaryReader reader = new BinaryReader(source, Encoding.UTF8, true))
            {
                for (int z = 0; z < depth; z++)
                {
                    // mirror Y
                    for (int y = height - 1; y >= 0; y -= 4)
                    {
                        for (int x = 0; x < width; x += 4)
                        {
                            for (int i = 0; i < 4; ++i)
                            {
                                ushort alpha = reader.ReadUInt16();
                                alphas[i * 4 + 0] = (byte)(((alpha >> 0) & 0xF) * 0x11);
                                alphas[i * 4 + 1] = (byte)(((alpha >> 4) & 0xF) * 0x11);
                                alphas[i * 4 + 2] = (byte)(((alpha >> 8) & 0xF) * 0x11);
                                alphas[i * 4 + 3] = (byte)(((alpha >> 12) & 0xF) * 0x11);
                            }

                            ushort color0  = reader.ReadUInt16();
                            ushort color1  = reader.ReadUInt16();
                            uint   bitMask = reader.ReadUInt32();

                            colors[0] = DxtcRead3bColor(color0);
                            colors[1] = DxtcRead3bColor(color1);

                            if (color0 > color1)
                            {
                                // Four-color block: derive the other two colors.
                                // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3
                                // These 2-bit codes correspond to the 2-bit fields
                                // stored in the 64-bit block.
                                colors[2].Blue  = unchecked ((byte)((2 * colors[0].Blue + colors[1].Blue + 1) / 3));
                                colors[2].Green = unchecked ((byte)((2 * colors[0].Green + colors[1].Green + 1) / 3));
                                colors[2].Red   = unchecked ((byte)((2 * colors[0].Red + colors[1].Red + 1) / 3));
                            }
                            else
                            {
                                // Three-color block: derive the other color.
                                // 00 = color_0,  01 = color_1,  10 = color_2,
                                // 11 = transparent.
                                // These 2-bit codes correspond to the 2-bit fields
                                // stored in the 64-bit block.
                                colors[2].Blue  = unchecked ((byte)((colors[0].Blue + colors[1].Blue) / 2));
                                colors[2].Green = unchecked ((byte)((colors[0].Green + colors[1].Green) / 2));
                                colors[2].Red   = unchecked ((byte)((colors[0].Red + colors[1].Red) / 2));
                            }

                            colors[3].Blue  = unchecked ((byte)((colors[0].Blue + 2 * colors[1].Blue + 1) / 3));
                            colors[3].Green = unchecked ((byte)((colors[0].Green + 2 * colors[1].Green + 1) / 3));
                            colors[3].Red   = unchecked ((byte)((colors[0].Red + 2 * colors[1].Red + 1) / 3));

                            int bitIndex = 0;
                            for (int ly = 0; ly < 4; ly++)
                            {
                                for (int lx = 0; lx < 4; lx++, bitIndex++)
                                {
                                    int       colorIndex = unchecked ((int)((bitMask & (3 << bitIndex * 2)) >> bitIndex * 2));
                                    Color8888 color      = colors[colorIndex];
                                    color.Alpha = alphas[bitIndex];
                                    if ((x + lx) < width && (y - ly) < height && (y - ly) >= 0)
                                    {
                                        // mirror Y
                                        long offset = z * sizeOfPlane + (y - ly) * bps + (x + lx) * bpp;
                                        destination.Position = position + offset;

                                        destination.WriteByte(color.Red);
                                        destination.WriteByte(color.Green);
                                        destination.WriteByte(color.Blue);
                                        destination.WriteByte(color.Alpha);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }