예제 #1
0
        public void TestFrequencyImg()
        {
            var rng = new UniformRNG(0);

            int[] bucket = new int[100];

            const int xExtent = 100;
            const int yExtent = 200;

            using (var file = File.OpenWrite(Path.Combine(RootDir, "rng_frequency.bmp")))
                using (var image = new Image <ImageSharp.PixelFormats.Rgb24>(xExtent, yExtent))
                {
                    for (int i = 0; i < 10000; ++i)
                    {
                        bucket[rng.Uniform(0, xExtent)]++;
                    }

                    for (int i = 0; i < xExtent; ++i)
                    {
                        for (int j = 0; j < bucket[i]; ++j)
                        {
                            image[i, yExtent - j] = new ImageSharp.PixelFormats.Rgb24(0xFF, 0x69, 0xB4);
                        }
                    }

                    image.SaveAsBmp(file);
                }
        }
예제 #2
0
        /// <inheritdoc/>
        public byte[] Decompress(byte[] blockData, int width, int height)
        {
            IBlock self = this;

            byte[] alpha  = new byte[8];
            var    colors = new ImageSharp.PixelFormats.Rgb24[4];

            return(Helper.InMemoryDecode <Dxt5>(blockData, width, height, (stream, data, streamIndex, dataIndex, stride) =>
            {
                streamIndex = Bc5.ExtractGradient(alpha, blockData, streamIndex);

                ulong alphaCodes = blockData[streamIndex++];
                alphaCodes |= (ulong)blockData[streamIndex++] << 8;
                alphaCodes |= (ulong)blockData[streamIndex++] << 16;
                alphaCodes |= (ulong)blockData[streamIndex++] << 24;
                alphaCodes |= (ulong)blockData[streamIndex++] << 32;
                alphaCodes |= (ulong)blockData[streamIndex++] << 40;

                // Colors are stored in a pair of 16 bits.
                ushort color0 = blockData[streamIndex++];
                color0 |= (ushort)(blockData[streamIndex++] << 8);

                ushort color1 = blockData[streamIndex++];
                color1 |= (ushort)(blockData[streamIndex++] << 8);

                // Extract R5G6B5.
                PixelUtils.ExtractR5G6B5(color0, ref colors[0]);
                PixelUtils.ExtractR5G6B5(color1, ref colors[1]);

                colors[2].R = (byte)(((2 * colors[0].R) + colors[1].R) / 3);
                colors[2].G = (byte)(((2 * colors[0].G) + colors[1].G) / 3);
                colors[2].B = (byte)(((2 * colors[0].B) + colors[1].B) / 3);

                colors[3].R = (byte)((colors[0].R + (2 * colors[1].R)) / 3);
                colors[3].G = (byte)((colors[0].G + (2 * colors[1].G)) / 3);
                colors[3].B = (byte)((colors[0].B + (2 * colors[1].B)) / 3);

                for (int alphaShift = 0; alphaShift < 48; alphaShift += 12)
                {
                    byte rowVal = blockData[streamIndex++];
                    for (int j = 0; j < 4; j++)
                    {
                        // 3 bits determine alpha index to use.
                        byte alphaIndex = (byte)((alphaCodes >> (alphaShift + (3 * j))) & 0x07);
                        ImageSharp.PixelFormats.Rgb24 col = colors[(rowVal >> (j * 2)) & 0x03];
                        data[dataIndex++] = col.R;
                        data[dataIndex++] = col.G;
                        data[dataIndex++] = col.B;
                        data[dataIndex++] = alpha[alphaIndex];
                    }

                    dataIndex += self.PixelDepthBytes * (stride - self.DivSize);
                }

                return streamIndex;
            }));
        }
예제 #3
0
        public void TestIntNoiseImg()
        {
            var rng = new UniformRNG(0);

            const int xExtent = 100;
            const int yExtent = 100;

            using (var file = File.OpenWrite(Path.Combine(RootDir, "rng_int_noise.bmp")))
                using (var image = new Image <ImageSharp.PixelFormats.Rgb24>(xExtent, yExtent))
                {
                    for (int i = 0; i < xExtent; ++i)
                    {
                        for (int j = 0; j < yExtent; ++j)
                        {
                            var color = (byte)rng.Uniform(0, 255);
                            image[i, j] = new ImageSharp.PixelFormats.Rgb24(color, color, color);
                        }
                    }

                    image.SaveAsBmp(file);
                }
        }
예제 #4
0
        public void TestOctavedPerlinNoise3D()
        {
            const int xExtent = 100;
            const int yExtent = 100;

            using (var file = File.OpenWrite(Path.Combine(RootDir, "OctavedPerlinNoise3D.bmp")))
                using (var image = new Image <ImageSharp.PixelFormats.Rgb24>(xExtent, yExtent))
                {
                    var noise      = new OctavedNoise <PerlinNoise>(new PerlinNoise(100), 8, 0.25f);
                    var noiseValue = new float[xExtent, yExtent, 1];
                    noise.Noise(noiseValue, new Vector3(-10, 10, -10), new Vector3(0.1f, 0.1f, 0));
                    for (int x = 0; x < xExtent; x++)
                    {
                        for (int y = 0; y < yExtent; y++)
                        {
                            var color = (byte)(noiseValue[x, y, 0] * 255);
                            image[x, y] = new ImageSharp.PixelFormats.Rgb24(color, color, color);
                        }
                    }

                    image.SaveAsBmp(file);
                }
        }
예제 #5
0
        public byte[] Decompress(byte[] blockData, int width, int height)
        {
            IBlock self   = this;
            var    colors = new ImageSharp.PixelFormats.Rgb24[4];

            return(Helper.InMemoryDecode <Dxt1>(blockData, width, height, (byte[] stream, byte[] data, int streamIndex, int dataIndex, int stride) =>
            {
                ushort color0 = blockData[streamIndex++];
                color0 |= (ushort)(blockData[streamIndex++] << 8);

                ushort color1 = (blockData[streamIndex++]);
                color1 |= (ushort)(blockData[streamIndex++] << 8);

                // Extract R5G6B5 (in that order)
                colors[0].R = (byte)((color0 & 0x1f));
                colors[0].G = (byte)((color0 & 0x7E0) >> 5);
                colors[0].B = (byte)((color0 & 0xF800) >> 11);
                colors[0].R = (byte)(colors[0].R << 3 | colors[0].R >> 2);
                colors[0].G = (byte)(colors[0].G << 2 | colors[0].G >> 3);
                colors[0].B = (byte)(colors[0].B << 3 | colors[0].B >> 2);

                colors[1].R = (byte)((color1 & 0x1f));
                colors[1].G = (byte)((color1 & 0x7E0) >> 5);
                colors[1].B = (byte)((color1 & 0xF800) >> 11);
                colors[1].R = (byte)(colors[1].R << 3 | colors[1].R >> 2);
                colors[1].G = (byte)(colors[1].G << 2 | colors[1].G >> 3);
                colors[1].B = (byte)(colors[1].B << 3 | colors[1].B >> 2);

                // Used the two extracted colors to create two new colors that are
                // slightly different.
                if (color0 > color1)
                {
                    colors[2].R = (byte)((2 * colors[0].R + colors[1].R) / 3);
                    colors[2].G = (byte)((2 * colors[0].G + colors[1].G) / 3);
                    colors[2].B = (byte)((2 * colors[0].B + colors[1].B) / 3);

                    colors[3].R = (byte)((colors[0].R + 2 * colors[1].R) / 3);
                    colors[3].G = (byte)((colors[0].G + 2 * colors[1].G) / 3);
                    colors[3].B = (byte)((colors[0].B + 2 * colors[1].B) / 3);
                }
                else
                {
                    colors[2].R = (byte)((colors[0].R + colors[1].R) / 2);
                    colors[2].G = (byte)((colors[0].G + colors[1].G) / 2);
                    colors[2].B = (byte)((colors[0].B + colors[1].B) / 2);

                    colors[3].R = 0;
                    colors[3].G = 0;
                    colors[3].B = 0;
                }


                for (int i = 0; i < 4; i++)
                {
                    // Every 2 bit is a code [0-3] and represent what color the
                    // current pixel is

                    // Read in a byte and thus 4 colors
                    byte rowVal = blockData[streamIndex++];
                    for (int j = 0; j < 8; j += 2)
                    {
                        // Extract code by shifting the row byte so that we can
                        // AND it with 3 and get a value [0-3]
                        var col = colors[(rowVal >> j) & 0x03];
                        data[dataIndex++] = col.R;
                        data[dataIndex++] = col.G;
                        data[dataIndex++] = col.B;
                    }

                    // Jump down a row and start at the beginning of the row
                    dataIndex += self.PixelDepthBytes * (stride - self.DivSize);
                }

                return streamIndex;
            }));
        }
예제 #6
0
        public byte[] Decompress(byte[] blockData, int width, int height)
        {
            IBlock self   = this;
            var    alpha  = new byte[8];
            var    colors = new ImageSharp.PixelFormats.Rgb24[4];

            return(Helper.InMemoryDecode <Dxt5>(blockData, width, height, (byte[] stream, byte[] data, int streamIndex, int dataIndex, int stride) =>
            {
                streamIndex = Bc5.ExtractGradient(alpha, blockData, streamIndex);

                ulong alphaCodes = blockData[streamIndex++];
                alphaCodes |= ((ulong)blockData[streamIndex++] << 8);
                alphaCodes |= ((ulong)blockData[streamIndex++] << 16);
                alphaCodes |= ((ulong)blockData[streamIndex++] << 24);
                alphaCodes |= ((ulong)blockData[streamIndex++] << 32);
                alphaCodes |= ((ulong)blockData[streamIndex++] << 40);

                // Colors are stored in a pair of 16 bits
                ushort color0 = blockData[streamIndex++];
                color0 |= (ushort)(blockData[streamIndex++] << 8);

                ushort color1 = (blockData[streamIndex++]);
                color1 |= (ushort)(blockData[streamIndex++] << 8);

                // Extract R5G6B5 (in that order)
                colors[0].R = (byte)((color0 & 0x1f));
                colors[0].G = (byte)((color0 & 0x7E0) >> 5);
                colors[0].B = (byte)((color0 & 0xF800) >> 11);
                colors[0].R = (byte)(colors[0].R << 3 | colors[0].R >> 2);
                colors[0].G = (byte)(colors[0].G << 2 | colors[0].G >> 3);
                colors[0].B = (byte)(colors[0].B << 3 | colors[0].B >> 2);

                colors[1].R = (byte)((color1 & 0x1f));
                colors[1].G = (byte)((color1 & 0x7E0) >> 5);
                colors[1].B = (byte)((color1 & 0xF800) >> 11);
                colors[1].R = (byte)(colors[1].R << 3 | colors[1].R >> 2);
                colors[1].G = (byte)(colors[1].G << 2 | colors[1].G >> 3);
                colors[1].B = (byte)(colors[1].B << 3 | colors[1].B >> 2);

                colors[2].R = (byte)((2 * colors[0].R + colors[1].R) / 3);
                colors[2].G = (byte)((2 * colors[0].G + colors[1].G) / 3);
                colors[2].B = (byte)((2 * colors[0].B + colors[1].B) / 3);

                colors[3].R = (byte)((colors[0].R + 2 * colors[1].R) / 3);
                colors[3].G = (byte)((colors[0].G + 2 * colors[1].G) / 3);
                colors[3].B = (byte)((colors[0].B + 2 * colors[1].B) / 3);

                for (int alphaShift = 0; alphaShift < 48; alphaShift += 12)
                {
                    byte rowVal = blockData[streamIndex++];
                    for (int j = 0; j < 4; j++)
                    {
                        // 3 bits determine alpha index to use
                        byte alphaIndex = (byte)((alphaCodes >> (alphaShift + 3 * j)) & 0x07);
                        var col = colors[((rowVal >> (j * 2)) & 0x03)];
                        data[dataIndex++] = col.R;
                        data[dataIndex++] = col.G;
                        data[dataIndex++] = col.B;
                        data[dataIndex++] = alpha[alphaIndex];
                    }
                    dataIndex += self.PixelDepthBytes * (stride - self.DivSize);
                }

                return streamIndex;
            }));
        }
예제 #7
0
        public byte[] Decompress(byte[] blockData, int width, int height)
        {
            IBlock self   = this;
            var    colors = new ImageSharp.PixelFormats.Rgb24[4];

            return(Helper.InMemoryDecode <Dxt3>(blockData, width, height, (byte[] stream, byte[] data, int streamIndex, int dataIndex, int stride) =>
            {
                /*
                 * Strategy for decompression:
                 * -We're going to decode both alpha and color at the same time
                 * to save on space and time as we don't have to allocate an array
                 * to store values for later use.
                 */

                // Remember where the alpha data is stored so we can decode simultaneously
                int alphaPtr = streamIndex;

                // Jump ahead to the color data
                streamIndex += 8;

                // Colors are stored in a pair of 16 bits
                ushort color0 = blockData[streamIndex++];
                color0 |= (ushort)(blockData[streamIndex++] << 8);

                ushort color1 = (blockData[streamIndex++]);
                color1 |= (ushort)(blockData[streamIndex++] << 8);

                // Extract R5G6B5 (in that order)
                colors[0].R = (byte)((color0 & 0x1f));
                colors[0].G = (byte)((color0 & 0x7E0) >> 5);
                colors[0].B = (byte)((color0 & 0xF800) >> 11);
                colors[0].R = (byte)(colors[0].R << 3 | colors[0].R >> 2);
                colors[0].G = (byte)(colors[0].G << 2 | colors[0].G >> 3);
                colors[0].B = (byte)(colors[0].B << 3 | colors[0].B >> 2);

                colors[1].R = (byte)((color1 & 0x1f));
                colors[1].G = (byte)((color1 & 0x7E0) >> 5);
                colors[1].B = (byte)((color1 & 0xF800) >> 11);
                colors[1].R = (byte)(colors[1].R << 3 | colors[1].R >> 2);
                colors[1].G = (byte)(colors[1].G << 2 | colors[1].G >> 3);
                colors[1].B = (byte)(colors[1].B << 3 | colors[1].B >> 2);

                // Used the two extracted colors to create two new colors
                // that are slightly different.
                colors[2].R = (byte)((2 * colors[0].R + colors[1].R) / 3);
                colors[2].G = (byte)((2 * colors[0].G + colors[1].G) / 3);
                colors[2].B = (byte)((2 * colors[0].B + colors[1].B) / 3);

                colors[3].R = (byte)((colors[0].R + 2 * colors[1].R) / 3);
                colors[3].G = (byte)((colors[0].G + 2 * colors[1].G) / 3);
                colors[3].B = (byte)((colors[0].B + 2 * colors[1].B) / 3);

                for (int i = 0; i < 4; i++)
                {
                    byte rowVal = blockData[streamIndex++];

                    // Each row of rgb values have 4 alpha values that  are
                    // encoded in 4 bits
                    ushort rowAlpha = blockData[alphaPtr++];
                    rowAlpha |= (ushort)(blockData[alphaPtr++] << 8);

                    for (int j = 0; j < 8; j += 2)
                    {
                        byte currentAlpha = (byte)((rowAlpha >> (j * 2)) & 0x0f);
                        currentAlpha |= (byte)(currentAlpha << 4);
                        var col = colors[((rowVal >> j) & 0x03)];
                        data[dataIndex++] = col.R;
                        data[dataIndex++] = col.G;
                        data[dataIndex++] = col.B;
                        data[dataIndex++] = currentAlpha;
                    }
                    dataIndex += self.PixelDepthBytes * (stride - self.DivSize);
                }

                return streamIndex;
            }));
        }