Exemple #1
0
        private void Decode_COMPRESSED_DXT1()
        {
            var colors = new OutputPixel[4];

            for (int y = 0, ni = 0; y < _height; y += 4)
            {
                for (int x = 0; x < _width; x += 4, ni++)
                {
                    var block = ((Dxt1Block *)_inputByte)[ni];

                    colors[0] = Decode_RGBA_5650_Pixel(block.Color0)
                                .Transform((r, g, b, a) => OutputPixel.FromRgba(b, g, r, a));
                    colors[1] = Decode_RGBA_5650_Pixel(block.Color1)
                                .Transform((r, g, b, a) => OutputPixel.FromRgba(b, g, r, a));

                    if (block.Color0 > block.Color1)
                    {
                        colors[2] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                      (a, b) => (byte)(a * 2 / 3 + b * 1 / 3));
                        colors[3] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                      (a, b) => (byte)(a * 1 / 3 + b * 2 / 3));
                    }
                    else
                    {
                        colors[2] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                      (a, b) => (byte)(a * 1 / 2 + b * 1 / 2));
                        colors[3] = OutputPixel.FromRgba(0, 0, 0, 0);
                    }

                    var no = 0;
                    for (var y2 = 0; y2 < 4; y2++)
                    {
                        for (var x2 = 0; x2 < 4; x2++, no++)
                        {
                            var color = (block.ColorLookup >> (2 * no)) & 0x3;

                            var rx = x + x2;
                            var ry = y + y2;
                            var n  = ry * _width + rx;

                            _output[n] = colors[color];
                        }
                    }
                }
            }
        }
        /// <summary>
        /// DXT2 and DXT3 (collectively also known as Block Compression 2 or BC2) converts 16 input pixels
        /// (corresponding to a 4x4 pixel block) into 128 bits of output, consisting of 64 bits of alpha channel data
        /// (4 bits for each pixel) followed by 64 bits of color data, encoded the same way as DXT1 (with the exception
        /// that the 4 color version of the DXT1 algorithm is always used instead of deciding which version to use based
        /// on the relative values of  and ). In DXT2, the color data is interpreted as being premultiplied by alpha, in
        /// DXT3 it is interpreted as not having been premultiplied by alpha. Typically DXT2/3 are well suited to images
        /// with sharp alpha transitions, between translucent and opaque areas.
        /// </summary>
        private void Decode_COMPRESSED_DXT3()
        {
            var colors = new OutputPixel[4];

            var ni = 0;

            for (var y = 0; y < _height; y += 4)
            {
                for (var x = 0; x < _width; x += 4, ni++)
                {
                    var block = ((Dxt3Block *)_inputByte)[ni];
                    colors[0] = Decode_RGBA_5650_Pixel(block.Color0)
                                .Transform((r, g, b, a) => OutputPixel.FromRgba(b, g, r, a));
                    colors[1] = Decode_RGBA_5650_Pixel(block.Color1)
                                .Transform((r, g, b, a) => OutputPixel.FromRgba(b, g, r, a));
                    colors[2] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                  (a, b) => (byte)(((a * 2) / 3) + ((b * 1) / 3)));
                    colors[3] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                  (a, b) => (byte)(((a * 1) / 3) + ((b * 2) / 3)));

                    var no = 0;
                    for (var y2 = 0; y2 < 4; y2++)
                    {
                        for (var x2 = 0; x2 < 4; x2++, no++)
                        {
                            var alpha = (block.Alpha >> (4 * no)) & 0xF;
                            var color = (block.ColorLookup >> (2 * no)) & 0x3;

                            var rx = (x + x2);
                            var ry = (y + y2);
                            var n  = ry * _width + rx;

                            _output[n]   = colors[color];
                            _output[n].A = (byte)((alpha * 0xFF) / 0xF);
                        }
                    }
                }
            }
        }
Exemple #3
0
        private void Decode_COMPRESSED_DXT5()
        {
            //Console.Error.WriteLine("Not Implemented: Decode_COMPRESSED_DXT5");
            //throw new NotImplementedException();

            //_Decode_Unimplemented();

            var colors = new OutputPixel[4];

            var ni = 0;

            for (var y = 0; y < _height; y += 4)
            {
                for (var x = 0; x < _width; x += 4, ni++)
                {
                    var block = ((Dxt5Block *)_inputByte)[ni];
                    colors[0] = Decode_RGBA_5650_Pixel(block.Color0)
                                .Transform((r, g, b, a) => OutputPixel.FromRgba(b, g, r, a));
                    colors[1] = Decode_RGBA_5650_Pixel(block.Color1)
                                .Transform((r, g, b, a) => OutputPixel.FromRgba(b, g, r, a));
                    colors[2] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                  (a, b) => (byte)(a * 2 / 3 + b * 1 / 3));
                    colors[3] = OutputPixel.OperationPerComponent(colors[0], colors[1],
                                                                  (a, b) => (byte)(a * 1 / 3 + b * 2 / 3));

                    // Create Alpha Lookup
                    var alphaLookup = new byte[8];
                    var alphas      = (ushort)(block.Alpha >> 48);
                    var alpha0      = (byte)((alphas >> 0) & 0xFF);
                    var alpha1      = (byte)((alphas >> 8) & 0xFF);

                    alphaLookup[0] = alpha0;
                    alphaLookup[1] = alpha1;
                    if (alpha0 > alpha1)
                    {
                        alphaLookup[2] = (byte)((6 * alpha0 + alpha1) / 7);
                        alphaLookup[3] = (byte)((5 * alpha0 + 2 * alpha1) / 7);
                        alphaLookup[4] = (byte)((4 * alpha0 + 3 * alpha1) / 7);
                        alphaLookup[5] = (byte)((3 * alpha0 + 4 * alpha1) / 7);
                        alphaLookup[6] = (byte)((2 * alpha0 + 5 * alpha1) / 7);
                        alphaLookup[7] = (byte)((alpha0 + 6 * alpha1) / 7);
                    }
                    else
                    {
                        alphaLookup[2] = (byte)((4 * alpha0 + alpha1) / 5);
                        alphaLookup[3] = (byte)((3 * alpha0 + 2 * alpha1) / 5);
                        alphaLookup[4] = (byte)((2 * alpha0 + 3 * alpha1) / 5);
                        alphaLookup[5] = (byte)((alpha0 + 4 * alpha1) / 5);
                        alphaLookup[6] = (byte)0x00;
                        alphaLookup[7] = (byte)0xFF;
                    }

                    var no = 0;
                    for (var y2 = 0; y2 < 4; y2++)
                    {
                        for (var x2 = 0; x2 < 4; x2++, no++)
                        {
                            var alpha = alphaLookup[(block.Alpha >> (3 * no)) & 0x7];
                            var color = (block.ColorLookup >> (2 * no)) & 0x3;

                            var rx = x + x2;
                            var ry = y + y2;
                            var n  = ry * _width + rx;

                            _output[n]   = colors[color];
                            _output[n].A = alpha;
                        }
                    }
                }
            }
        }