public ICompressedImage Compress(IUncompressedImage image, IBlockCompressionFormat format) { if (!AreDimensionsMultipleOfFour(image)) { throw new InvalidOperationException("Only textures with dimensions that are multiples of " + $"{BlockFormat.Dimension} can be block compressed."); } Logger.Default.Log("Compressing BMP to DDS."); var dds = DDSImage.CreateEmpty(image.Width, image.Height, format); int numberOfVerticalBlocks = image.Height / BlockFormat.Dimension; int numberOfHorizontalBlocks = image.Width / BlockFormat.Dimension; int numberOfBlocks = numberOfVerticalBlocks * numberOfHorizontalBlocks; Parallel.For(0, numberOfBlocks, #if DEBUG RunInSingleThread, #endif (i) => { var blockIndex = PointUtility.FromRowMajor(i, numberOfHorizontalBlocks); var blockColors = image.GetBlockColors(blockIndex); var blockData = format.Compress(blockColors); dds.SetBlockData(blockIndex, blockData); }); Logger.Default.Log("Compression successful."); return(dds); }
public static ICompressedImage Compress(IUncompressedImage bitmap, IBlockCompressionFormat format) { using (Profiler.MeasureTime()) { return(new BlockCompressor().Compress(bitmap, format)); } }
private byte[] ReadSurfaceData(int width, int height, IBlockCompressionFormat format) { int pixelsInImage = width * height; int blocksInImage = pixelsInImage / BlockFormat.TexelCount; int mainImageSize = blocksInImage * format.BlockSize; return(_binaryReader.ReadBytes(mainImageSize)); }
private DDSImage(int width, int height, byte[] surfaceData, IBlockCompressionFormat compressionFormat) { Width = width; Height = height; _surfaceData = surfaceData; _compressionFormat = compressionFormat; }
/// <summary> /// Instantiates a <see cref="DDSImage"/> with an empty main surface data /// buffer reserved for the size of the specified dimensions. /// </summary> /// <param name="width">The pixel width of the image.</param> /// <param name="height">The pixel height of the image.</param> /// <param name="compressionFormat">The compression format for the image.</param> public static DDSImage CreateEmpty(int width, int height, IBlockCompressionFormat compressionFormat) { int numberOfPixels = width * height; int numberOfRequiredBlocks = numberOfPixels / BlockFormat.TexelCount; int bufferSize = numberOfRequiredBlocks * compressionFormat.BlockSize; return(new DDSImage(width, height, new byte[bufferSize], compressionFormat)); }
/// <summary> /// Creates a <see cref="ICompressedImage"/> mock of 3x2 blocks (48 texels) /// with a different set of arbitrary byte values in each block. /// </summary> /// <remarks> /// Block bytes: /// _____ _____ _____ /// | || || | /// | 0x1 || 0x2 || 0x3 | /// |_____||_____||_____| /// | || || | /// | 0x4 || 0x5 || 0x6 | /// |_____||_____||_____| /// </remarks> private static ICompressedImage CreateDDSImageMock(IBlockCompressionFormat format) { var blockBytes = new byte[] { 1, 2, 3, 4, 5, 6 }; const int blockSize = 8; const int numberOfBlocks = 6; var buffer = new byte[numberOfBlocks * blockSize]; for (int i = 0, bufferIndex = 0; i < blockBytes.Length; ++i, bufferIndex += blockSize) { for (int j = bufferIndex; j < blockSize + bufferIndex; ++j) { buffer[j] = blockBytes[i]; } } // Assert bytes have been set correctly // (for start and end byte value of each block only) Assert.AreEqual(1, buffer[0]); Assert.AreEqual(1, buffer[7]); Assert.AreEqual(2, buffer[8]); Assert.AreEqual(2, buffer[15]); Assert.AreEqual(3, buffer[16]); Assert.AreEqual(3, buffer[23]); Assert.AreEqual(4, buffer[24]); Assert.AreEqual(4, buffer[31]); Assert.AreEqual(5, buffer[32]); Assert.AreEqual(5, buffer[39]); Assert.AreEqual(6, buffer[40]); Assert.AreEqual(6, buffer[47]); const int width = 12; const int height = 8; return(DDSImage.CreateFromData(width, height, buffer, format)); }
/// <summary> /// Instantiates a <see cref="DDSImage"/> with the specified dimensions /// and raw main surface data. /// </summary> /// <param name="width">The pixel width of the image.</param> /// <param name="height">The pixel height of the image.</param> /// <param name="data">The main surface data of the DDS image.</param> /// <param name="compressionFormat">The compression format for the image.</param> public static DDSImage CreateFromData(int width, int height, byte[] data, IBlockCompressionFormat compressionFormat) { return(new DDSImage(width, height, data, compressionFormat)); }