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); } }
/// <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; })); }
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); } }
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); } }
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; })); }
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; })); }
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; })); }