From 22c09a45c1c3ffe54154ab2c54b45336fdff15ae Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Sun, 10 Jan 2021 16:43:50 +0100 Subject: [PATCH 1/9] Remove code duplications in BcDecoder; Add more detailed summary to public methods in BcDecoder and BcEncoder; --- BCnEnc.Net/Decoder/BcDecoder.cs | 816 +++++------ .../Decoder/Options/DecoderInputOptions.cs | 13 + .../Decoder/Options/DecoderOutputOptions.cs | 11 + BCnEnc.Net/Encoder/BcEncoder.cs | 1270 ++++++++--------- .../Encoder/Options/EncoderInputOptions.cs | 11 + BCnEnc.Net/Encoder/Options/EncoderOptions.cs | 13 + .../Encoder/Options/EncoderOutputOptions.cs | 45 + BCnEnc.Net/Shared/CompressionFormat.cs | 134 +- 8 files changed, 1169 insertions(+), 1144 deletions(-) create mode 100644 BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs create mode 100644 BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs create mode 100644 BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs create mode 100644 BCnEnc.Net/Encoder/Options/EncoderOptions.cs create mode 100644 BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs diff --git a/BCnEnc.Net/Decoder/BcDecoder.cs b/BCnEnc.Net/Decoder/BcDecoder.cs index d768a85..cff60dd 100644 --- a/BCnEnc.Net/Decoder/BcDecoder.cs +++ b/BCnEnc.Net/Decoder/BcDecoder.cs @@ -1,445 +1,397 @@ using System; using System.IO; using System.Text; +using BCnEncoder.Decoder.Options; using BCnEncoder.Shared; using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; namespace BCnEncoder.Decoder { - public class DecoderInputOptions { - /// - /// The DDS file format doesn't seem to have a standard for indicating whether a BC1 texture - /// includes 1bit of alpha. This option will assume that all Bc1 textures contain alpha. - /// If this option is false, but the dds header includes a DDPF_ALPHAPIXELS flag, alpha will be included. - /// Default is true. - /// - public bool ddsBc1ExpectAlpha = true; - } - - public class DecoderOutputOptions { - /// - /// If true, when decoding from a format that only includes a red channel, - /// output pixels will have all colors set to the same value (greyscale). Default is true. - /// - public bool redAsLuminance = true; - } - - /// + /// /// Decodes compressed files into Rgba format. /// public class BcDecoder - { - public DecoderOutputOptions OutputOptions { get; set; } = new DecoderOutputOptions(); - public DecoderInputOptions InputOptions { get; set; } = new DecoderInputOptions(); - - private bool IsSupportedRawFormat(GlInternalFormat format) - { - switch (format) - { - case GlInternalFormat.GL_R8: - case GlInternalFormat.GL_RG8: - case GlInternalFormat.GL_RGB8: - case GlInternalFormat.GL_RGBA8: - return true; - default: - return false; - } - } - - private bool IsSupportedRawFormat(DXGI_FORMAT format) - { - switch (format) - { - case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: - return true; - default: - return false; - } - } - - private IBcBlockDecoder GetDecoder(GlInternalFormat format) - { - switch (format) - { - case GlInternalFormat.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return new Bc1NoAlphaDecoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return new Bc1ADecoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return new Bc2Decoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return new Bc3Decoder(); - case GlInternalFormat.GL_COMPRESSED_RED_RGTC1_EXT: - return new Bc4Decoder(OutputOptions.redAsLuminance); - case GlInternalFormat.GL_COMPRESSED_RED_GREEN_RGTC2_EXT: - return new Bc5Decoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - return new Bc7Decoder(); - // TODO: Not sure what to do with SRGB input. - case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - return new Bc7Decoder(); - default: - return null; - } - } - - private IBcBlockDecoder GetDecoder(DXGI_FORMAT format, DdsHeader header) - { - switch (format) - { - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS: - if ((header.ddsPixelFormat.dwFlags & PixelFormatFlags.DDPF_ALPHAPIXELS) != 0) { - return new Bc1ADecoder(); - } - else if(InputOptions.ddsBc1ExpectAlpha){ - return new Bc1ADecoder(); - } - else { - return new Bc1NoAlphaDecoder(); - } - - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS: - return new Bc2Decoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS: - return new Bc3Decoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS: - return new Bc4Decoder(OutputOptions.redAsLuminance); - case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS: - return new Bc5Decoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS: - return new Bc7Decoder(); - default: - return null; - } - } - - private IRawDecoder GetRawDecoder(GlInternalFormat format) - { - switch (format) - { - case GlInternalFormat.GL_R8: - return new RawRDecoder(OutputOptions.redAsLuminance); - case GlInternalFormat.GL_RG8: - return new RawRGDecoder(); - case GlInternalFormat.GL_RGB8: - return new RawRGBDecoder(); - case GlInternalFormat.GL_RGBA8: - return new RawRGBADecoder(); - default: - return null; - } - } - - private IRawDecoder GetRawDecoder(DXGI_FORMAT format) - { - switch (format) - { - case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: - return new RawRDecoder(OutputOptions.redAsLuminance); - case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: - return new RawRGDecoder(); - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: - return new RawRGBADecoder(); - default: - return null; - } - } - - /// - /// Read a Ktx or a Dds file from a stream and decode it. - /// - public Image Decode(Stream inputStream) { - var position = inputStream.Position; - try { - if (inputStream is FileStream fs) { - var extension = Path.GetExtension(fs.Name).ToLower(); - if (extension == ".ktx") { - KtxFile file = KtxFile.Load(inputStream); - return Decode(file); - } - else if (extension == ".dds") { - DdsFile file = DdsFile.Load(inputStream); - return Decode(file); - } - } - - bool isDDS = false; - using (var br = new BinaryReader(inputStream, Encoding.UTF8, true)) { - var magic = br.ReadUInt32(); - if (magic == 0x20534444U) { - isDDS = true; - } - } - - inputStream.Seek(position, SeekOrigin.Begin); - - if (isDDS) { - DdsFile dds = DdsFile.Load(inputStream); - return Decode(dds); - } - else { - KtxFile ktx = KtxFile.Load(inputStream); - return Decode(ktx); - } - } - catch (Exception) { - inputStream.Seek(position, SeekOrigin.Begin); - throw; - } - } - - /// - /// Read a Ktx or a Dds file from a stream and decode it. - /// - public Image[] DecodeAllMipMaps(Stream inputStream) { - var position = inputStream.Position; - try { - if (inputStream is FileStream fs) { - var extension = Path.GetExtension(fs.Name).ToLower(); - if (extension == ".ktx") { - KtxFile file = KtxFile.Load(inputStream); - return DecodeAllMipMaps(file); - } - else if (extension == ".dds") { - DdsFile file = DdsFile.Load(inputStream); - return DecodeAllMipMaps(file); - } - } - - bool isDDS = false; - using (var br = new BinaryReader(inputStream, Encoding.UTF8, true)) { - var magic = br.ReadUInt32(); - if (magic == 0x20534444U) { - isDDS = true; - } - } - - inputStream.Seek(position, SeekOrigin.Begin); - - if (isDDS) { - DdsFile dds = DdsFile.Load(inputStream); - return DecodeAllMipMaps(dds); - } - else { - KtxFile ktx = KtxFile.Load(inputStream); - return DecodeAllMipMaps(ktx); - } - } - catch (Exception) { - inputStream.Seek(position, SeekOrigin.Begin); - throw; - } - } - - /// - /// Read a KtxFile and decode it. - /// - public Image Decode(KtxFile file) - { - if (IsSupportedRawFormat(file.Header.GlInternalFormat)) { - var decoder = GetRawDecoder(file.Header.GlInternalFormat); - var data = file.MipMaps[0].Faces[0].Data; - var pixelWidth = file.MipMaps[0].Width; - var pixelHeight = file.MipMaps[0].Height; - - var image = new Image((int)pixelWidth, (int)pixelHeight); - var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); - if (!image.TryGetSinglePixelSpan(out var pixels)) { - throw new Exception("Cannot get pixel span."); - } - - output.CopyTo(pixels); - return image; - } - else { - var decoder = GetDecoder(file.Header.GlInternalFormat); - if (decoder == null) - { - throw new NotSupportedException($"This format is not supported: {file.Header.GlInternalFormat}"); - } - - var data = file.MipMaps[0].Faces[0].Data; - var pixelWidth = file.MipMaps[0].Width; - var pixelHeight = file.MipMaps[0].Height; - - var blocks = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight, out var blockWidth, out var blockHeight); - - return ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, - (int)pixelWidth, (int)pixelHeight); - } - } - - /// - /// Read a KtxFile and decode it. - /// - public Image[] DecodeAllMipMaps(KtxFile file) - { - if (IsSupportedRawFormat(file.Header.GlInternalFormat)) { - var decoder = GetRawDecoder(file.Header.GlInternalFormat); - var images = new Image[file.MipMaps.Count]; - - for (int mip = 0; mip < file.MipMaps.Count; mip++) { - var data = file.MipMaps[mip].Faces[0].Data; - var pixelWidth = file.MipMaps[mip].Width; - var pixelHeight = file.MipMaps[mip].Height; - - var image = new Image((int)pixelWidth, (int)pixelHeight); - var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); - if (!image.TryGetSinglePixelSpan(out var pixels)) { - throw new Exception("Cannot get pixel span."); - } - - output.CopyTo(pixels); - images[mip] = image; - } - - return images; - } - else { - var decoder = GetDecoder(file.Header.GlInternalFormat); - if (decoder == null) - { - throw new NotSupportedException($"This format is not supported: {file.Header.GlInternalFormat}"); - } - var images = new Image[file.MipMaps.Count]; - - for (int mip = 0; mip < file.MipMaps.Count; mip++) { - - var data = file.MipMaps[mip].Faces[0].Data; - var pixelWidth = file.MipMaps[mip].Width; - var pixelHeight = file.MipMaps[mip].Height; - - var blocks = decoder.Decode(data, (int) pixelWidth, (int) pixelHeight, out var blockWidth, - out var blockHeight); - - var image = ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, - (int)pixelWidth, (int)pixelHeight); - images[mip] = image; - } - return images; - } - } - - /// - /// Read a DdsFile and decode it - /// - public Image Decode(DdsFile file) - { - if (IsSupportedRawFormat(file.Header.ddsPixelFormat.DxgiFormat)) { - var decoder = GetRawDecoder(file.Header.ddsPixelFormat.DxgiFormat); - var data = file.Faces[0].MipMaps[0].Data; - var pixelWidth = file.Faces[0].Width; - var pixelHeight = file.Faces[0].Height; - - var image = new Image((int)pixelWidth, (int)pixelHeight); - var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); - if (!image.TryGetSinglePixelSpan(out var pixels)) { - throw new Exception("Cannot get pixel span."); - } - - output.CopyTo(pixels); - return image; - } - else { - DXGI_FORMAT format = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN; - if (file.Header.ddsPixelFormat.IsDxt10Format) { - format = file.Dxt10Header.dxgiFormat; - } - else { - format = file.Header.ddsPixelFormat.DxgiFormat; - } - IBcBlockDecoder decoder = GetDecoder(format, file.Header); - - if (decoder == null) - { - throw new NotSupportedException($"This format is not supported: {format}"); - } - - var data = file.Faces[0].MipMaps[0].Data; - var pixelWidth = file.Faces[0].Width; - var pixelHeight = file.Faces[0].Height; - - var blocks = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight, out var blockWidth, out var blockHeight); - - return ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, - (int)pixelWidth, (int)pixelHeight); - } - } - - /// - /// Read a DdsFile and decode it - /// - public Image[] DecodeAllMipMaps(DdsFile file) - { - if (IsSupportedRawFormat(file.Header.ddsPixelFormat.DxgiFormat)) { - var decoder = GetRawDecoder(file.Header.ddsPixelFormat.DxgiFormat); - - var images = new Image[file.Header.dwMipMapCount]; - - for (int mip = 0; mip < file.Header.dwMipMapCount; mip++) { - var data = file.Faces[0].MipMaps[mip].Data; - var pixelWidth = file.Faces[0].MipMaps[mip].Width; - var pixelHeight = file.Faces[0].MipMaps[mip].Height; - - var image = new Image((int) pixelWidth, (int) pixelHeight); - var output = decoder.Decode(data, (int) pixelWidth, (int) pixelHeight); - if (!image.TryGetSinglePixelSpan(out var pixels)) { - throw new Exception("Cannot get pixel span."); - } - - output.CopyTo(pixels); - images[mip] = image; - } - return images; - } - else { - DXGI_FORMAT format = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN; - if (file.Header.ddsPixelFormat.IsDxt10Format) { - format = file.Dxt10Header.dxgiFormat; - } - else { - format = file.Header.ddsPixelFormat.DxgiFormat; - } - IBcBlockDecoder decoder = GetDecoder(format, file.Header); - - if (decoder == null) - { - throw new NotSupportedException($"This format is not supported: {format}"); - } - var images = new Image[file.Header.dwMipMapCount]; - - for (int mip = 0; mip < file.Header.dwMipMapCount; mip++) { - var data = file.Faces[0].MipMaps[mip].Data; - var pixelWidth = file.Faces[0].MipMaps[mip].Width; - var pixelHeight = file.Faces[0].MipMaps[mip].Height; - - var blocks = decoder.Decode(data, (int) pixelWidth, (int) pixelHeight, out var blockWidth, - out var blockHeight); - - var image = ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, - (int)pixelWidth, (int)pixelHeight); - - images[mip] = image; - } - - return images; - } - } - } + { + /// + /// The input options of the decoder. + /// + public DecoderInputOptions InputOptions { get; } = new DecoderInputOptions(); + + /// + /// The output options of the decoder. + /// + public DecoderOutputOptions OutputOptions { get; } = new DecoderOutputOptions(); + + /// + /// Read a Ktx or a Dds file from a stream and decode it. + /// + /// The stream containing a Ktx or Dds file. + /// The decoded Rgba32 image. + public Image Decode(Stream inputStream) + { + return Decode(inputStream, false)[0]; + } + + /// + /// Read a Ktx or a Dds file from a stream and decode it. + /// + /// The stream containing a Ktx or Dds file. + /// An array of decoded Rgba32 images. + public Image[] DecodeAllMipMaps(Stream inputStream) + { + return Decode(inputStream, true); + } + + /// + /// Read a Ktx file and decode it. + /// + /// The loaded Ktx file. + /// The decoded Rgba32 image. + public Image Decode(KtxFile file) + { + return Decode(file, false)[0]; + } + + /// + /// Read a Ktx file and decode it. + /// + /// The loaded Ktx file. + /// An array of decoded Rgba32 images. + public Image[] DecodeAllMipMaps(KtxFile file) + { + return Decode(file, true); + } + + /// + /// Read a Dds file and decode it. + /// + /// The loaded Dds file. + /// The decoded Rgba32 image. + public Image Decode(DdsFile file) + { + return Decode(file, false)[0]; + } + + /// + /// Read a Dds file and decode it. + /// + /// The loaded Dds file. + /// An array of decoded Rgba32 images. + public Image[] DecodeAllMipMaps(DdsFile file) + { + return Decode(file, true); + } + + /// + /// Load a KTX or DDS file from a stream and extract either the main image or all mip maps. + /// + /// The input stream to decode. + /// If all mip maps or only the main image should be decoded. + /// An array of decoded Rgba32 images. + private Image[] Decode(Stream inputStream, bool allMipMaps) + { + var position = inputStream.Position; + try + { + // Detect if file is a KTX or DDS by file extension + if (inputStream is FileStream fs) + { + var extension = Path.GetExtension(fs.Name).ToLower(); + switch (extension) + { + case ".dds": + var ddsFile = DdsFile.Load(inputStream); + return Decode(ddsFile, allMipMaps); + + case ".file": + var ktxFile = KtxFile.Load(inputStream); + return Decode(ktxFile, allMipMaps); + } + } + + // Otherwise detect KTX or DDS by content of the stream + bool isDds; + using (var br = new BinaryReader(inputStream, Encoding.UTF8, true)) + { + var magic = br.ReadUInt32(); + isDds = magic == 0x20534444U; + } + + inputStream.Seek(position, SeekOrigin.Begin); + + if (isDds) + { + var dds = DdsFile.Load(inputStream); + return Decode(dds, allMipMaps); + } + + var ktx = KtxFile.Load(inputStream); + return Decode(ktx, allMipMaps); + } + catch (Exception) + { + inputStream.Seek(position, SeekOrigin.Begin); + throw; + } + } + + /// + /// Load a KTX file and extract either the main image or all mip maps. + /// + /// The Ktx file to decode. + /// If all mip maps or only the main image should be decoded. + /// An array of decoded Rgba32 images. + private Image[] Decode(KtxFile file, bool allMipMaps) + { + var images = new Image[file.MipMaps.Count]; + + if (IsSupportedRawFormat(file.Header.GlInternalFormat)) + { + var decoder = GetRawDecoder(file.Header.GlInternalFormat); + + var mipMaps = allMipMaps ? file.MipMaps.Count : 1; + for (var mip = 0; mip < mipMaps; mip++) + { + var data = file.MipMaps[mip].Faces[0].Data; + var pixelWidth = file.MipMaps[mip].Width; + var pixelHeight = file.MipMaps[mip].Height; + + var image = new Image((int)pixelWidth, (int)pixelHeight); + var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); + if (!image.TryGetSinglePixelSpan(out var pixels)) + throw new Exception("Cannot get pixel span."); + + output.CopyTo(pixels); + images[mip] = image; + } + } + else + { + var decoder = GetDecoder(file.Header.GlInternalFormat); + if (decoder == null) + throw new NotSupportedException($"This format is not supported: {file.Header.GlInternalFormat}"); + + var mipMaps = allMipMaps ? file.MipMaps.Count : 1; + for (var mip = 0; mip < mipMaps; mip++) + { + var data = file.MipMaps[mip].Faces[0].Data; + var pixelWidth = file.MipMaps[mip].Width; + var pixelHeight = file.MipMaps[mip].Height; + + var blocks = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight, out var blockWidth, out var blockHeight); + + images[mip] = ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, (int)pixelWidth, (int)pixelHeight); + } + } + + return images; + } + + /// + /// Load a DDS file and extract either the main image or all mip maps. + /// + /// The Dds file to decode. + /// If all mip maps or only the main image should be decoded. + /// An array of decoded Rgba32 images. + private Image[] Decode(DdsFile file, bool allMipMaps) + { + var images = new Image[file.Header.dwMipMapCount]; + + if (IsSupportedRawFormat(file.Header.ddsPixelFormat.DxgiFormat)) + { + var decoder = GetRawDecoder(file.Header.ddsPixelFormat.DxgiFormat); + + var mipMaps = allMipMaps ? file.Header.dwMipMapCount : 1; + for (var mip = 0; mip < mipMaps; mip++) + { + var data = file.Faces[0].MipMaps[mip].Data; + var pixelWidth = file.Faces[0].MipMaps[mip].Width; + var pixelHeight = file.Faces[0].MipMaps[mip].Height; + + var image = new Image((int)pixelWidth, (int)pixelHeight); + var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); + if (!image.TryGetSinglePixelSpan(out var pixels)) + throw new Exception("Cannot get pixel span."); + + output.CopyTo(pixels); + images[mip] = image; + } + } + else + { + var format = file.Header.ddsPixelFormat.IsDxt10Format ? + file.Dxt10Header.dxgiFormat : + file.Header.ddsPixelFormat.DxgiFormat; + var decoder = GetDecoder(format, file.Header); + + if (decoder == null) + throw new NotSupportedException($"This format is not supported: {format}"); + + for (var mip = 0; mip < file.Header.dwMipMapCount; mip++) + { + var data = file.Faces[0].MipMaps[mip].Data; + var pixelWidth = file.Faces[0].MipMaps[mip].Width; + var pixelHeight = file.Faces[0].MipMaps[mip].Height; + + var blocks = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight, out var blockWidth, + out var blockHeight); + + var image = ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, + (int)pixelWidth, (int)pixelHeight); + + images[mip] = image; + } + } + + return images; + } + + private bool IsSupportedRawFormat(GlInternalFormat format) + { + switch (format) + { + case GlInternalFormat.GL_R8: + case GlInternalFormat.GL_RG8: + case GlInternalFormat.GL_RGB8: + case GlInternalFormat.GL_RGBA8: + return true; + + default: + return false; + } + } + + private bool IsSupportedRawFormat(DXGI_FORMAT format) + { + switch (format) + { + case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: + return true; + + default: + return false; + } + } + + private IBcBlockDecoder GetDecoder(GlInternalFormat format) + { + switch (format) + { + case GlInternalFormat.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + return new Bc1NoAlphaDecoder(); + + case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return new Bc1ADecoder(); + + case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + return new Bc2Decoder(); + + case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return new Bc3Decoder(); + + case GlInternalFormat.GL_COMPRESSED_RED_RGTC1_EXT: + return new Bc4Decoder(OutputOptions.redAsLuminance); + + case GlInternalFormat.GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + return new Bc5Decoder(); + + case GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + return new Bc7Decoder(); + + // TODO: Not sure what to do with SRGB input. + case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + return new Bc7Decoder(); + + default: + return null; + } + } + + private IBcBlockDecoder GetDecoder(DXGI_FORMAT format, DdsHeader header) + { + switch (format) + { + case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS: + if ((header.ddsPixelFormat.dwFlags & PixelFormatFlags.DDPF_ALPHAPIXELS) != 0) + return new Bc1ADecoder(); + + if (InputOptions.ddsBc1ExpectAlpha) + return new Bc1ADecoder(); + + return new Bc1NoAlphaDecoder(); + + case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS: + return new Bc2Decoder(); + + case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS: + return new Bc3Decoder(); + + case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS: + return new Bc4Decoder(OutputOptions.redAsLuminance); + + case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS: + return new Bc5Decoder(); + + case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB: + case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS: + return new Bc7Decoder(); + + default: + return null; + } + } + + private IRawDecoder GetRawDecoder(GlInternalFormat format) + { + switch (format) + { + case GlInternalFormat.GL_R8: + return new RawRDecoder(OutputOptions.redAsLuminance); + + case GlInternalFormat.GL_RG8: + return new RawRGDecoder(); + + case GlInternalFormat.GL_RGB8: + return new RawRGBDecoder(); + + case GlInternalFormat.GL_RGBA8: + return new RawRGBADecoder(); + + default: + return null; + } + } + + private IRawDecoder GetRawDecoder(DXGI_FORMAT format) + { + switch (format) + { + case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: + return new RawRDecoder(OutputOptions.redAsLuminance); + + case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: + return new RawRGDecoder(); + + case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: + return new RawRGBADecoder(); + + default: + return null; + } + } + } } diff --git a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs new file mode 100644 index 0000000..9529ab4 --- /dev/null +++ b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs @@ -0,0 +1,13 @@ +namespace BCnEncoder.Decoder.Options +{ + public class DecoderInputOptions + { + /// + /// The DDS file format doesn't seem to have a standard for indicating whether a BC1 texture + /// includes 1bit of alpha. This option will assume that all Bc1 textures contain alpha. + /// If this option is false, but the dds header includes a DDPF_ALPHAPIXELS flag, alpha will be included. + /// Default is true. + /// + public bool ddsBc1ExpectAlpha = true; + } +} diff --git a/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs new file mode 100644 index 0000000..a0a8299 --- /dev/null +++ b/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs @@ -0,0 +1,11 @@ +namespace BCnEncoder.Decoder.Options +{ + public class DecoderOutputOptions + { + /// + /// If true, when decoding from a format that only includes a red channel, + /// output pixels will have all colors set to the same value (greyscale). Default is true. + /// + public bool redAsLuminance = true; + } +} diff --git a/BCnEnc.Net/Encoder/BcEncoder.cs b/BCnEnc.Net/Encoder/BcEncoder.cs index 3424d55..6446af2 100644 --- a/BCnEnc.Net/Encoder/BcEncoder.cs +++ b/BCnEnc.Net/Encoder/BcEncoder.cs @@ -3,659 +3,637 @@ using System.Diagnostics; using System.IO; using BCnEncoder.Encoder.Bc7; +using BCnEncoder.Encoder.Options; using BCnEncoder.Shared; using SixLabors.ImageSharp; -using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; namespace BCnEncoder.Encoder { - public class EncoderInputOptions - { - /// - /// If true, when encoding to a format that only includes a red channel, - /// use the pixel luminance instead of just the red channel. Default is false. - /// - public bool luminanceAsRed = false; - } - - public class EncoderOutputOptions - { - /// - /// Whether to generate mipMaps. Default is true. - /// - public bool generateMipMaps = true; - /// - /// The maximum number of mipmap levels to generate. -1 or 0 is unbounded. - /// Default is -1. - /// - public int maxMipMapLevel = -1; - /// - /// The compression format to use. Default is BC1. - /// - public CompressionFormat format = CompressionFormat.BC1; - /// - /// The quality of the compression. Use either fast or balanced for testing. - /// Fast can be used for near real-time encoding for most algorithms. - /// Use bestQuality when needed. Default is balanced. - /// - public CompressionQuality quality = CompressionQuality.Balanced; - /// - /// The output file format of the data. Either Ktx or Dds. - /// Default is Ktx. - /// - public OutputFileFormat fileFormat = OutputFileFormat.Ktx; - /// - /// The DDS file format doesn't seem to have a standard for indicating whether a BC1 texture - /// includes 1bit of alpha. This option will write DDPF_ALPHAPIXELS flag to the header - /// to indicate the presence of an alpha channel. Some programs read and write this flag, - /// but some programs don't like it and get confused. Your mileage may vary. - /// Default is false. - /// - public bool ddsBc1WriteAlphaFlag = false; - } - - public class EncoderOptions { - /// - /// Whether the blocks should be encoded in parallel. This can be much faster than single-threaded encoding, - /// but is slow if multiple textures are being processed at the same time. - /// When a debugger is attached, the encoder defaults to single-threaded operation to ease debugging. - /// Default is true. - /// - public bool multiThreaded = true; - } - - /// + /// /// Handles all encoding of images into compressed or uncompressed formats. For decoding, /// public class BcEncoder - { - public EncoderInputOptions InputOptions { get; set; } = new EncoderInputOptions(); - public EncoderOutputOptions OutputOptions { get; set; } = new EncoderOutputOptions(); - public EncoderOptions Options { get; set; } = new EncoderOptions(); - - public BcEncoder() { } - public BcEncoder(CompressionFormat format) - { - OutputOptions.format = format; - } - - private IBcBlockEncoder GetEncoder(CompressionFormat format) - { - switch (format) - { - case CompressionFormat.BC1: - return new Bc1BlockEncoder(); - case CompressionFormat.BC1WithAlpha: - return new Bc1AlphaBlockEncoder(); - case CompressionFormat.BC2: - return new Bc2BlockEncoder(); - case CompressionFormat.BC3: - return new Bc3BlockEncoder(); - case CompressionFormat.BC4: - return new Bc4BlockEncoder(InputOptions.luminanceAsRed); - case CompressionFormat.BC5: - return new Bc5BlockEncoder(); - case CompressionFormat.BC7: - return new Bc7Encoder(); - default: - return null; - } - } - - private IRawEncoder GetRawEncoder(CompressionFormat format) - { - switch (format) - { - case CompressionFormat.R: - return new RawLuminanceEncoder(InputOptions.luminanceAsRed); - case CompressionFormat.RG: - return new RawRGEncoder(); - case CompressionFormat.RGB: - return new RawRGBEncoder(); - case CompressionFormat.RGBA: - return new RawRGBAEncoder(); - default: - throw new ArgumentOutOfRangeException(nameof(format), format, null); - } - } - - /// - /// Encodes all mipmap levels into a ktx or a dds file and writes it to the output stream. - /// - public void Encode(Image inputImage, Stream outputStream) - { - if (OutputOptions.fileFormat == OutputFileFormat.Ktx) - { - KtxFile output = EncodeToKtx(inputImage); - output.Write(outputStream); - } - else if (OutputOptions.fileFormat == OutputFileFormat.Dds) - { - DdsFile output = EncodeToDds(inputImage); - output.Write(outputStream); - } - } - - /// - /// Encodes all mipmap levels into a Ktx file. - /// - public KtxFile EncodeToKtx(Image inputImage) - { - KtxFile output; - IBcBlockEncoder compressedEncoder = null; - IRawEncoder uncompressedEncoder = null; - if (OutputOptions.format.IsCompressedFormat()) - { - compressedEncoder = GetEncoder(OutputOptions.format); - if (compressedEncoder == null) - { - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); - } - output = new KtxFile( - KtxHeader.InitializeCompressed(inputImage.Width, inputImage.Height, - compressedEncoder.GetInternalFormat(), - compressedEncoder.GetBaseInternalFormat())); - } - else - { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); - output = new KtxFile( - KtxHeader.InitializeUncompressed(inputImage.Width, inputImage.Height, - uncompressedEncoder.GetGlType(), - uncompressedEncoder.GetGlFormat(), - uncompressedEncoder.GetGlTypeSize(), - uncompressedEncoder.GetInternalFormat(), - uncompressedEncoder.GetBaseInternalFormat())); - - } - - uint numMipMaps = (uint)OutputOptions.maxMipMapLevel; - if (!OutputOptions.generateMipMaps) - { - numMipMaps = 1; - } - - var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); - - for (int i = 0; i < numMipMaps; i++) - { - byte[] encoded = null; - if (OutputOptions.format.IsCompressedFormat()) - { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[i].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, - !Debugger.IsAttached && Options.multiThreaded); - } - else - { - if (!mipChain[i].TryGetSinglePixelSpan(out var mipPixels)) { - throw new Exception("Cannot get pixel span."); - } - encoded = uncompressedEncoder.Encode(mipPixels); - } - - output.MipMaps.Add(new KtxMipmap((uint)encoded.Length, - (uint)inputImage.Width, - (uint)inputImage.Height, 1)); - output.MipMaps[i].Faces[0] = new KtxMipFace(encoded, - (uint)inputImage.Width, - (uint)inputImage.Height); - } - - foreach (var image in mipChain) - { - image.Dispose(); - } - - output.Header.NumberOfFaces = 1; - output.Header.NumberOfMipmapLevels = numMipMaps; - - return output; - } - - /// - /// Encodes all mipmap levels into a Ktx file. - /// - public DdsFile EncodeToDds(Image inputImage) - { - DdsFile output; - IBcBlockEncoder compressedEncoder = null; - IRawEncoder uncompressedEncoder = null; - if (OutputOptions.format.IsCompressedFormat()) - { - compressedEncoder = GetEncoder(OutputOptions.format); - if (compressedEncoder == null) - { - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); - } - - var (ddsHeader, dxt10Header) = DdsHeader.InitializeCompressed(inputImage.Width, inputImage.Height, - compressedEncoder.GetDxgiFormat()); - output = new DdsFile(ddsHeader, dxt10Header); - - if (OutputOptions.ddsBc1WriteAlphaFlag && - OutputOptions.format == CompressionFormat.BC1WithAlpha) - { - output.Header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DDPF_ALPHAPIXELS; - } - } - else - { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); - var ddsHeader = DdsHeader.InitializeUncompressed(inputImage.Width, inputImage.Height, - uncompressedEncoder.GetDxgiFormat()); - output = new DdsFile(ddsHeader); - } - - uint numMipMaps = (uint)OutputOptions.maxMipMapLevel; - if (!OutputOptions.generateMipMaps) - { - numMipMaps = 1; - } - - var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); - - for (int mip = 0; mip < numMipMaps; mip++) - { - byte[] encoded = null; - if (OutputOptions.format.IsCompressedFormat()) - { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, - !Debugger.IsAttached && Options.multiThreaded); - } - else - { - if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) { - throw new Exception("Cannot get pixel span."); - } - encoded = uncompressedEncoder.Encode(mipPixels); - } - - if (mip == 0) - { - output.Faces.Add(new DdsFace((uint)inputImage.Width, (uint)inputImage.Height, - (uint)encoded.Length, (int)numMipMaps)); - } - - output.Faces[0].MipMaps[mip] = new DdsMipMap(encoded, - (uint)inputImage.Width, - (uint)inputImage.Height); - } - - foreach (var image in mipChain) - { - image.Dispose(); - } - - output.Header.dwMipMapCount = numMipMaps; - if (numMipMaps > 1) - { - output.Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX | HeaderCaps.DDSCAPS_MIPMAP; - } - - return output; - } - - /// - /// Encodes all mipmap levels into a list of byte buffers. - /// - public List EncodeToRawBytes(Image inputImage) - { - List output = new List(); - IBcBlockEncoder compressedEncoder = null; - IRawEncoder uncompressedEncoder = null; - if (OutputOptions.format.IsCompressedFormat()) - { - compressedEncoder = GetEncoder(OutputOptions.format); - if (compressedEncoder == null) - { - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); - } - - } - else - { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); - - } - - uint numMipMaps = (uint)OutputOptions.maxMipMapLevel; - if (!OutputOptions.generateMipMaps) - { - numMipMaps = 1; - } - - var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); - - for (int i = 0; i < numMipMaps; i++) - { - byte[] encoded = null; - if (OutputOptions.format.IsCompressedFormat()) - { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[i].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, - !Debugger.IsAttached && Options.multiThreaded); - } - else - { - if (!mipChain[i].TryGetSinglePixelSpan(out var mipPixels)) { - throw new Exception("Cannot get pixel span."); - } - encoded = uncompressedEncoder.Encode(mipPixels); - } - - output.Add(encoded); - } - - foreach (var image in mipChain) - { - image.Dispose(); - } - - return output; - } - - /// - /// Encodes a single mip level of the input image to a byte buffer. - /// - public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int mipWidth, out int mipHeight) - { - if (mipLevel < 0) - { - throw new ArgumentException($"{nameof(mipLevel)} cannot be less than zero."); - } - - IBcBlockEncoder compressedEncoder = null; - IRawEncoder uncompressedEncoder = null; - if (OutputOptions.format.IsCompressedFormat()) - { - compressedEncoder = GetEncoder(OutputOptions.format); - if (compressedEncoder == null) - { - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); - } - } - else - { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); - - } - - uint numMipMaps = (uint)OutputOptions.maxMipMapLevel; - if (!OutputOptions.generateMipMaps) - { - numMipMaps = 1; - } - - var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); - - if (mipLevel > numMipMaps - 1) - { - foreach (var image in mipChain) - { - image.Dispose(); - } - throw new ArgumentException($"{nameof(mipLevel)} cannot be more than number of mipmaps"); - } - - byte[] encoded = null; - if (OutputOptions.format.IsCompressedFormat()) - { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mipLevel].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, - !Debugger.IsAttached && Options.multiThreaded); - } - else - { - if (!mipChain[mipLevel].TryGetSinglePixelSpan(out var mipPixels)) { - throw new Exception("Cannot get pixel span."); - } - encoded = uncompressedEncoder.Encode(mipPixels); - } - - mipWidth = mipChain[mipLevel].Width; - mipHeight = mipChain[mipLevel].Height; - - foreach (var image in mipChain) - { - image.Dispose(); - } - - return encoded; - } - - /// - /// Encodes all cubemap faces and mipmap levels into Ktx file and writes it to the output stream. - /// Order is +X, -X, +Y, -Y, +Z, -Z - /// - public void EncodeCubeMap(Image right, Image left, Image top, Image down, - Image back, Image front, Stream outputStream) - { - if (OutputOptions.fileFormat == OutputFileFormat.Ktx) - { - KtxFile output = EncodeCubeMapToKtx(right, left, top, down, back, front); - output.Write(outputStream); - } - else if (OutputOptions.fileFormat == OutputFileFormat.Dds) - { - DdsFile output = EncodeCubeMapToDds(right, left, top, down, back, front); - output.Write(outputStream); - } - } - - /// - /// Encodes all cubemap faces and mipmap levels into a Ktx file. - /// Order is +X, -X, +Y, -Y, +Z, -Z. Back maps to positive Z and front to negative Z. - /// - public KtxFile EncodeCubeMapToKtx(Image right, Image left, Image top, Image down, - Image back, Image front) - { - KtxFile output; - IBcBlockEncoder compressedEncoder = null; - IRawEncoder uncompressedEncoder = null; - - if (right.Width != left.Width || right.Width != top.Width || right.Width != down.Width - || right.Width != back.Width || right.Width != front.Width || - right.Height != left.Height || right.Height != top.Height || right.Height != down.Height - || right.Height != back.Height || right.Height != front.Height) - { - throw new ArgumentException("All input images of a cubemap should be the same size."); - } - - Image[] faces = new[] { right, left, top, down, back, front }; - - if (OutputOptions.format.IsCompressedFormat()) - { - compressedEncoder = GetEncoder(OutputOptions.format); - if (compressedEncoder == null) - { - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); - } - output = new KtxFile( - KtxHeader.InitializeCompressed(right.Width, right.Height, - compressedEncoder.GetInternalFormat(), - compressedEncoder.GetBaseInternalFormat())); - } - else - { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); - output = new KtxFile( - KtxHeader.InitializeUncompressed(right.Width, right.Height, - uncompressedEncoder.GetGlType(), - uncompressedEncoder.GetGlFormat(), - uncompressedEncoder.GetGlTypeSize(), - uncompressedEncoder.GetInternalFormat(), - uncompressedEncoder.GetBaseInternalFormat())); - - } - uint numMipMaps = (uint)OutputOptions.maxMipMapLevel; - if (!OutputOptions.generateMipMaps) - { - numMipMaps = 1; - } - - uint mipLength = MipMapper.CalculateMipChainLength(right.Width, right.Height, numMipMaps); - for (uint i = 0; i < mipLength; i++) - { - output.MipMaps.Add(new KtxMipmap(0, 0, 0, (uint)faces.Length)); - } - - for (int f = 0; f < faces.Length; f++) - { - - var mipChain = MipMapper.GenerateMipChain(faces[f], ref numMipMaps); - - for (int i = 0; i < numMipMaps; i++) - { - byte[] encoded = null; - if (OutputOptions.format.IsCompressedFormat()) - { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[i].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, - !Debugger.IsAttached && Options.multiThreaded); - } - else - { - if (!mipChain[i].TryGetSinglePixelSpan(out var mipPixels)) { - throw new Exception("Cannot get pixel span."); - } - encoded = uncompressedEncoder.Encode(mipPixels); - } - - if (f == 0) - { - output.MipMaps[i] = new KtxMipmap((uint)encoded.Length, - (uint)mipChain[i].Width, - (uint)mipChain[i].Height, (uint)faces.Length); - } - - output.MipMaps[i].Faces[f] = new KtxMipFace(encoded, - (uint)mipChain[i].Width, - (uint)mipChain[i].Height); - } - - foreach (var image in mipChain) - { - image.Dispose(); - } - } - - output.Header.NumberOfFaces = (uint)faces.Length; - output.Header.NumberOfMipmapLevels = mipLength; - - return output; - } - - /// - /// Encodes all cubemap faces and mipmap levels into a Dds file. - /// Order is +X, -X, +Y, -Y, +Z, -Z. Back maps to positive Z and front to negative Z. - /// - public DdsFile EncodeCubeMapToDds(Image right, Image left, Image top, Image down, - Image back, Image front) - { - DdsFile output; - IBcBlockEncoder compressedEncoder = null; - IRawEncoder uncompressedEncoder = null; - - if (right.Width != left.Width || right.Width != top.Width || right.Width != down.Width - || right.Width != back.Width || right.Width != front.Width || - right.Height != left.Height || right.Height != top.Height || right.Height != down.Height - || right.Height != back.Height || right.Height != front.Height) - { - throw new ArgumentException("All input images of a cubemap should be the same size."); - } - - Image[] faces = new[] { right, left, top, down, back, front }; - - if (OutputOptions.format.IsCompressedFormat()) - { - compressedEncoder = GetEncoder(OutputOptions.format); - if (compressedEncoder == null) - { - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); - } - - var (ddsHeader, dxt10Header) = DdsHeader.InitializeCompressed(right.Width, right.Height, - compressedEncoder.GetDxgiFormat()); - output = new DdsFile(ddsHeader, dxt10Header); - - if (OutputOptions.ddsBc1WriteAlphaFlag && - OutputOptions.format == CompressionFormat.BC1WithAlpha) - { - output.Header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DDPF_ALPHAPIXELS; - } - } - else - { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); - var ddsHeader = DdsHeader.InitializeUncompressed(right.Width, right.Height, - uncompressedEncoder.GetDxgiFormat()); - output = new DdsFile(ddsHeader); - } - - uint numMipMaps = (uint)OutputOptions.maxMipMapLevel; - if (!OutputOptions.generateMipMaps) - { - numMipMaps = 1; - } - - for (int f = 0; f < faces.Length; f++) - { - - var mipChain = MipMapper.GenerateMipChain(faces[f], ref numMipMaps); - - - for (int mip = 0; mip < numMipMaps; mip++) - { - byte[] encoded = null; - if (OutputOptions.format.IsCompressedFormat()) - { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, - !Debugger.IsAttached && Options.multiThreaded); - } - else - { - if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) { - throw new Exception("Cannot get pixel span."); - } - encoded = uncompressedEncoder.Encode(mipPixels); - } - - if (mip == 0) - { - output.Faces.Add(new DdsFace((uint)mipChain[mip].Width, (uint)mipChain[mip].Height, - (uint)encoded.Length, mipChain.Count)); - } - - output.Faces[f].MipMaps[mip] = new DdsMipMap(encoded, - (uint)mipChain[mip].Width, - (uint)mipChain[mip].Height); - } - - foreach (var image in mipChain) - { - image.Dispose(); - } - } - - output.Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX; - output.Header.dwMipMapCount = numMipMaps; - if (numMipMaps > 1) - { - output.Header.dwCaps |= HeaderCaps.DDSCAPS_MIPMAP; - } - output.Header.dwCaps2 |= HeaderCaps2.DDSCAPS2_CUBEMAP | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEX | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEX | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEY | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEY | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEZ | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEZ; - - return output; - } - } + { + /// + /// The input options of the encoder. + /// + public EncoderInputOptions InputOptions { get; } = new EncoderInputOptions(); + + /// + /// The output options of the encoder. + /// + public EncoderOutputOptions OutputOptions { get; } = new EncoderOutputOptions(); + + /// + /// The encoder options. + /// + public EncoderOptions Options { get; } = new EncoderOptions(); + + /// + /// Creates a new instance of . + /// + /// The block compression format to encode an image with. + public BcEncoder(CompressionFormat format = CompressionFormat.BC1) + { + OutputOptions.format = format; + } + + /// + /// Encodes all mipmap levels into a ktx or a dds file and writes it to the output stream. + /// + /// The image to encode. + /// The stream to write the encoded image to. + public void Encode(Image inputImage, Stream outputStream) + { + switch (OutputOptions.fileFormat) + { + case OutputFileFormat.Dds: + var dds = EncodeToDds(inputImage); + dds.Write(outputStream); + break; + + case OutputFileFormat.Ktx: + var ktx = EncodeToKtx(inputImage); + ktx.Write(outputStream); + break; + } + } + + /// + /// Encodes all mipmap levels into a Ktx file. + /// + /// The image to encode. + /// The Ktx file containing the encoded image. + public KtxFile EncodeToKtx(Image inputImage) + { + KtxFile output; + IBcBlockEncoder compressedEncoder = null; + IRawEncoder uncompressedEncoder = null; + + var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); + + // Setup encoders + var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + if (isCompressedFormat) + { + compressedEncoder = GetEncoder(OutputOptions.format); + if (compressedEncoder == null) + throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + + output = new KtxFile( + KtxHeader.InitializeCompressed(inputImage.Width, inputImage.Height, + compressedEncoder.GetInternalFormat(), + compressedEncoder.GetBaseInternalFormat())); + } + else + { + uncompressedEncoder = GetRawEncoder(OutputOptions.format); + output = new KtxFile( + KtxHeader.InitializeUncompressed(inputImage.Width, inputImage.Height, + uncompressedEncoder.GetGlType(), + uncompressedEncoder.GetGlFormat(), + uncompressedEncoder.GetGlTypeSize(), + uncompressedEncoder.GetInternalFormat(), + uncompressedEncoder.GetBaseInternalFormat())); + } + + // Encode mipmap levels + for (var mip = 0; mip < numMipMaps; mip++) + { + byte[] encoded; + if (isCompressedFormat) + { + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + !Debugger.IsAttached && Options.multiThreaded); + } + else + { + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + throw new Exception("Cannot get pixel span."); + + encoded = uncompressedEncoder.Encode(mipPixels); + } + + output.MipMaps.Add(new KtxMipmap((uint)encoded.Length, + (uint)inputImage.Width, + (uint)inputImage.Height, 1)); + output.MipMaps[mip].Faces[0] = new KtxMipFace(encoded, + (uint)inputImage.Width, + (uint)inputImage.Height); + } + + // Dispose all mipmap levels + foreach (var image in mipChain) + image.Dispose(); + + output.Header.NumberOfFaces = 1; + output.Header.NumberOfMipmapLevels = numMipMaps; + + return output; + } + + /// + /// Encodes all mipmap levels into a Dds file. + /// + /// The image to encode. + /// The Dds file containing the encoded image. + public DdsFile EncodeToDds(Image inputImage) + { + DdsFile output; + IBcBlockEncoder compressedEncoder = null; + IRawEncoder uncompressedEncoder = null; + + var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); + + // Setup encoder + var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + if (isCompressedFormat) + { + compressedEncoder = GetEncoder(OutputOptions.format); + if (compressedEncoder == null) + throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + + var (ddsHeader, dxt10Header) = DdsHeader.InitializeCompressed(inputImage.Width, inputImage.Height, + compressedEncoder.GetDxgiFormat()); + output = new DdsFile(ddsHeader, dxt10Header); + + if (OutputOptions.ddsBc1WriteAlphaFlag && + OutputOptions.format == CompressionFormat.BC1WithAlpha) + { + output.Header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DDPF_ALPHAPIXELS; + } + } + else + { + uncompressedEncoder = GetRawEncoder(OutputOptions.format); + var ddsHeader = DdsHeader.InitializeUncompressed(inputImage.Width, inputImage.Height, + uncompressedEncoder.GetDxgiFormat()); + output = new DdsFile(ddsHeader); + } + + // Encode mipmap levels + for (var mip = 0; mip < numMipMaps; mip++) + { + byte[] encoded; + if (isCompressedFormat) + { + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out var blocksWidth, out var blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + !Debugger.IsAttached && Options.multiThreaded); + } + else + { + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + throw new Exception("Cannot get pixel span."); + + encoded = uncompressedEncoder.Encode(mipPixels); + } + + if (mip == 0) + { + output.Faces.Add(new DdsFace((uint)inputImage.Width, (uint)inputImage.Height, + (uint)encoded.Length, (int)numMipMaps)); + } + + output.Faces[0].MipMaps[mip] = new DdsMipMap(encoded, + (uint)inputImage.Width, + (uint)inputImage.Height); + } + + // Dispose all mipmap levels + foreach (var image in mipChain) + image.Dispose(); + + output.Header.dwMipMapCount = numMipMaps; + if (numMipMaps > 1) + output.Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX | HeaderCaps.DDSCAPS_MIPMAP; + + return output; + } + + /// + /// Encodes all mipmap levels into a list of byte buffers. + /// + /// The image to encode. + /// A list of raw encoded data. + public IList EncodeToRawBytes(Image inputImage) + { + var output = new List(); + IBcBlockEncoder compressedEncoder = null; + IRawEncoder uncompressedEncoder = null; + + var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); + + // Setup encoder + var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + if (isCompressedFormat) + { + compressedEncoder = GetEncoder(OutputOptions.format); + if (compressedEncoder == null) + throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + } + else + { + uncompressedEncoder = GetRawEncoder(OutputOptions.format); + } + + // Encode all mipmap levels + for (var mip = 0; mip < numMipMaps; mip++) + { + byte[] encoded; + if (isCompressedFormat) + { + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + !Debugger.IsAttached && Options.multiThreaded); + } + else + { + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + throw new Exception("Cannot get pixel span."); + + encoded = uncompressedEncoder.Encode(mipPixels); + } + + output.Add(encoded); + } + + // Dispose all mipmap levels + foreach (var image in mipChain) + image.Dispose(); + + return output; + } + + /// + /// Encodes a single mip level of the input image to a byte buffer. + /// + /// The image to encode. + /// The mipmap to encode. + /// The width of the mipmap. + /// The height of the mipmap. + /// The raw encoded data. + public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int mipWidth, out int mipHeight) + { + if (mipLevel < 0) + throw new ArgumentException($"{nameof(mipLevel)} cannot be less than zero."); + + IBcBlockEncoder compressedEncoder = null; + IRawEncoder uncompressedEncoder = null; + + var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); + + // Setup encoder + var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + if (isCompressedFormat) + { + compressedEncoder = GetEncoder(OutputOptions.format); + if (compressedEncoder == null) + throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + } + else + { + uncompressedEncoder = GetRawEncoder(OutputOptions.format); + } + + // Dispose all mipmap levels + if (mipLevel > numMipMaps - 1) + { + foreach (var image in mipChain) + image.Dispose(); + + throw new ArgumentException($"{nameof(mipLevel)} cannot be more than number of mipmaps."); + } + + // Encode mipmap level + byte[] encoded; + if (isCompressedFormat) + { + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mipLevel].Frames[0], out int blocksWidth, out int blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + !Debugger.IsAttached && Options.multiThreaded); + } + else + { + if (!mipChain[mipLevel].TryGetSinglePixelSpan(out var mipPixels)) + throw new Exception("Cannot get pixel span."); + + encoded = uncompressedEncoder.Encode(mipPixels); + } + + mipWidth = mipChain[mipLevel].Width; + mipHeight = mipChain[mipLevel].Height; + + // Dispose all mipmap levels + foreach (var image in mipChain) + image.Dispose(); + + return encoded; + } + + /// + /// Encodes all cubemap faces and mipmap levels into Ktx file and writes it to the output stream. + /// Order is +X, -X, +Y, -Y, +Z, -Z + /// + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The stream to write the encoded image to. + public void EncodeCubeMap(Image right, Image left, Image top, Image down, + Image back, Image front, Stream outputStream) + { + switch (OutputOptions.fileFormat) + { + case OutputFileFormat.Ktx: + var ktx = EncodeCubeMapToKtx(right, left, top, down, back, front); + ktx.Write(outputStream); + break; + + case OutputFileFormat.Dds: + var dds = EncodeCubeMapToDds(right, left, top, down, back, front); + dds.Write(outputStream); + break; + } + } + + /// + /// Encodes all cubemap faces and mipmap levels into a Ktx file. + /// Order is +X, -X, +Y, -Y, +Z, -Z. Back maps to positive Z and front to negative Z. + /// + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The Ktx file containing the encoded image. + public KtxFile EncodeCubeMapToKtx(Image right, Image left, Image top, Image down, + Image back, Image front) + { + KtxFile output; + IBcBlockEncoder compressedEncoder = null; + IRawEncoder uncompressedEncoder = null; + + if (right.Width != left.Width || right.Width != top.Width || right.Width != down.Width + || right.Width != back.Width || right.Width != front.Width || + right.Height != left.Height || right.Height != top.Height || right.Height != down.Height + || right.Height != back.Height || right.Height != front.Height) + { + throw new ArgumentException("All input images of a cubemap should be the same size."); + } + + var faces = new[] { right, left, top, down, back, front }; + + // Setup encoder + var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + if (isCompressedFormat) + { + compressedEncoder = GetEncoder(OutputOptions.format); + if (compressedEncoder == null) + throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + + output = new KtxFile( + KtxHeader.InitializeCompressed(right.Width, right.Height, + compressedEncoder.GetInternalFormat(), + compressedEncoder.GetBaseInternalFormat())); + } + else + { + uncompressedEncoder = GetRawEncoder(OutputOptions.format); + output = new KtxFile( + KtxHeader.InitializeUncompressed(right.Width, right.Height, + uncompressedEncoder.GetGlType(), + uncompressedEncoder.GetGlFormat(), + uncompressedEncoder.GetGlTypeSize(), + uncompressedEncoder.GetInternalFormat(), + uncompressedEncoder.GetBaseInternalFormat())); + + } + + var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var mipLength = MipMapper.CalculateMipChainLength(right.Width, right.Height, numMipMaps); + for (uint i = 0; i < mipLength; i++) + { + output.MipMaps.Add(new KtxMipmap(0, 0, 0, (uint)faces.Length)); + } + + // Encode all faces + for (var face = 0; face < faces.Length; face++) + { + var mipChain = MipMapper.GenerateMipChain(faces[face], ref numMipMaps); + + // Encode all mipmap levels per face + for (var mip = 0; mip < numMipMaps; mip++) + { + byte[] encoded; + if (isCompressedFormat) + { + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + !Debugger.IsAttached && Options.multiThreaded); + } + else + { + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + throw new Exception("Cannot get pixel span."); + + encoded = uncompressedEncoder.Encode(mipPixels); + } + + if (face == 0) + { + output.MipMaps[mip] = new KtxMipmap((uint)encoded.Length, + (uint)mipChain[mip].Width, + (uint)mipChain[mip].Height, (uint)faces.Length); + } + + output.MipMaps[mip].Faces[face] = new KtxMipFace(encoded, + (uint)mipChain[mip].Width, + (uint)mipChain[mip].Height); + } + + // Dispose all mipmap levels + foreach (var image in mipChain) + image.Dispose(); + } + + output.Header.NumberOfFaces = (uint)faces.Length; + output.Header.NumberOfMipmapLevels = mipLength; + + return output; + } + + /// + /// Encodes all cubemap faces and mipmap levels into a Dds file. + /// Order is +X, -X, +Y, -Y, +Z, -Z. Back maps to positive Z and front to negative Z. + /// + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The right face of the cubemap. + /// The Dds file containing the encoded image. + public DdsFile EncodeCubeMapToDds(Image right, Image left, Image top, Image down, + Image back, Image front) + { + DdsFile output; + IBcBlockEncoder compressedEncoder = null; + IRawEncoder uncompressedEncoder = null; + + if (right.Width != left.Width || right.Width != top.Width || right.Width != down.Width + || right.Width != back.Width || right.Width != front.Width || + right.Height != left.Height || right.Height != top.Height || right.Height != down.Height + || right.Height != back.Height || right.Height != front.Height) + { + throw new ArgumentException("All input images of a cubemap should be the same size."); + } + + var faces = new[] { right, left, top, down, back, front }; + + // Setup encoder + var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + if (isCompressedFormat) + { + compressedEncoder = GetEncoder(OutputOptions.format); + if (compressedEncoder == null) + throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + + var (ddsHeader, dxt10Header) = DdsHeader.InitializeCompressed(right.Width, right.Height, + compressedEncoder.GetDxgiFormat()); + output = new DdsFile(ddsHeader, dxt10Header); + + if (OutputOptions.ddsBc1WriteAlphaFlag && + OutputOptions.format == CompressionFormat.BC1WithAlpha) + { + output.Header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DDPF_ALPHAPIXELS; + } + } + else + { + uncompressedEncoder = GetRawEncoder(OutputOptions.format); + var ddsHeader = DdsHeader.InitializeUncompressed(right.Width, right.Height, + uncompressedEncoder.GetDxgiFormat()); + + output = new DdsFile(ddsHeader); + } + + var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + + // Encode all faces + for (var face = 0; face < faces.Length; face++) + { + var mipChain = MipMapper.GenerateMipChain(faces[face], ref numMipMaps); + + // Encode all mipmap levels per face + for (var mip = 0; mip < numMipMaps; mip++) + { + byte[] encoded; + if (isCompressedFormat) + { + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + !Debugger.IsAttached && Options.multiThreaded); + } + else + { + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + throw new Exception("Cannot get pixel span."); + + encoded = uncompressedEncoder.Encode(mipPixels); + } + + if (mip == 0) + { + output.Faces.Add(new DdsFace((uint)mipChain[mip].Width, (uint)mipChain[mip].Height, + (uint)encoded.Length, mipChain.Count)); + } + + output.Faces[face].MipMaps[mip] = new DdsMipMap(encoded, + (uint)mipChain[mip].Width, + (uint)mipChain[mip].Height); + } + + // Dispose all mipmap levels + foreach (var image in mipChain) + image.Dispose(); + } + + output.Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX; + output.Header.dwMipMapCount = numMipMaps; + if (numMipMaps > 1) + { + output.Header.dwCaps |= HeaderCaps.DDSCAPS_MIPMAP; + } + output.Header.dwCaps2 |= HeaderCaps2.DDSCAPS2_CUBEMAP | + HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEX | + HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEX | + HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEY | + HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEY | + HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEZ | + HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEZ; + + return output; + } + + private IBcBlockEncoder GetEncoder(CompressionFormat format) + { + switch (format) + { + case CompressionFormat.BC1: + return new Bc1BlockEncoder(); + + case CompressionFormat.BC1WithAlpha: + return new Bc1AlphaBlockEncoder(); + + case CompressionFormat.BC2: + return new Bc2BlockEncoder(); + + case CompressionFormat.BC3: + return new Bc3BlockEncoder(); + + case CompressionFormat.BC4: + return new Bc4BlockEncoder(InputOptions.luminanceAsRed); + + case CompressionFormat.BC5: + return new Bc5BlockEncoder(); + + case CompressionFormat.BC7: + return new Bc7Encoder(); + + default: + return null; + } + } + + private IRawEncoder GetRawEncoder(CompressionFormat format) + { + switch (format) + { + case CompressionFormat.R: + return new RawLuminanceEncoder(InputOptions.luminanceAsRed); + + case CompressionFormat.RG: + return new RawRGEncoder(); + + case CompressionFormat.RGB: + return new RawRGBEncoder(); + + case CompressionFormat.RGBA: + return new RawRGBAEncoder(); + + default: + throw new ArgumentOutOfRangeException(nameof(format), format, null); + } + } + } } diff --git a/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs b/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs new file mode 100644 index 0000000..dbc59d8 --- /dev/null +++ b/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs @@ -0,0 +1,11 @@ +namespace BCnEncoder.Encoder.Options +{ + public class EncoderInputOptions + { + /// + /// If true, when encoding to a format that only includes a red channel, + /// use the pixel luminance instead of just the red channel. Default is false. + /// + public bool luminanceAsRed = false; + } +} diff --git a/BCnEnc.Net/Encoder/Options/EncoderOptions.cs b/BCnEnc.Net/Encoder/Options/EncoderOptions.cs new file mode 100644 index 0000000..df95b80 --- /dev/null +++ b/BCnEnc.Net/Encoder/Options/EncoderOptions.cs @@ -0,0 +1,13 @@ +namespace BCnEncoder.Encoder.Options +{ + public class EncoderOptions + { + /// + /// Whether the blocks should be encoded in parallel. This can be much faster than single-threaded encoding, + /// but is slow if multiple textures are being processed at the same time. + /// When a debugger is attached, the encoder defaults to single-threaded operation to ease debugging. + /// Default is true. + /// + public bool multiThreaded = true; + } +} diff --git a/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs b/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs new file mode 100644 index 0000000..d7fb794 --- /dev/null +++ b/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs @@ -0,0 +1,45 @@ +using BCnEncoder.Shared; + +namespace BCnEncoder.Encoder.Options +{ + public class EncoderOutputOptions + { + /// + /// Whether to generate mipMaps. Default is true. + /// + public bool generateMipMaps = true; + + /// + /// The maximum number of mipmap levels to generate. -1 or 0 is unbounded. + /// Default is -1. + /// + public int maxMipMapLevel = -1; + + /// + /// The compression format to use. Default is BC1. + /// + public CompressionFormat format = CompressionFormat.BC1; + + /// + /// The quality of the compression. Use either fast or balanced for testing. + /// Fast can be used for near real-time encoding for most algorithms. + /// Use bestQuality when needed. Default is balanced. + /// + public CompressionQuality quality = CompressionQuality.Balanced; + + /// + /// The output file format of the data. Either Ktx or Dds. + /// Default is Ktx. + /// + public OutputFileFormat fileFormat = OutputFileFormat.Ktx; + + /// + /// The DDS file format doesn't seem to have a standard for indicating whether a BC1 texture + /// includes 1bit of alpha. This option will write DDPF_ALPHAPIXELS flag to the header + /// to indicate the presence of an alpha channel. Some programs read and write this flag, + /// but some programs don't like it and get confused. Your mileage may vary. + /// Default is false. + /// + public bool ddsBc1WriteAlphaFlag = false; + } +} diff --git a/BCnEnc.Net/Shared/CompressionFormat.cs b/BCnEnc.Net/Shared/CompressionFormat.cs index 04bf275..f99ab71 100644 --- a/BCnEnc.Net/Shared/CompressionFormat.cs +++ b/BCnEnc.Net/Shared/CompressionFormat.cs @@ -1,70 +1,72 @@ namespace BCnEncoder.Shared { - public enum CompressionFormat - { - /// - /// Raw unsigned byte 8-bit Luminance data - /// - R, - /// - /// Raw unsigned byte 16-bit RG data - /// - RG, - /// - /// Raw unsigned byte 24-bit RGB data - /// - RGB, - /// - /// Raw unsigned byte 32-bit RGBA data - /// - RGBA, - /// - /// BC1 / DXT1 with no alpha. Very widely supported and good compression ratio. - /// - BC1, - /// - /// BC1 / DXT1 with 1-bit of alpha. - /// - BC1WithAlpha, - /// - /// BC2 / DXT3 encoding with alpha. Good for sharp alpha transitions. - /// - BC2, - /// - /// BC3 / DXT5 encoding with alpha. Good for smooth alpha transitions. - /// - BC3, - /// - /// BC4 single-channel encoding. Only luminance is encoded. - /// - BC4, - /// - /// BC5 dual-channel encoding. Only red and green channels are encoded. - /// - BC5, - /// - /// BC6H / BPTC float encoding. Can compress HDR textures without alpha. Currently not supported. - /// - BC6, - /// - /// BC7 / BPTC unorm encoding. Very high quality rgba or rgb encoding. Also very slow. - /// - BC7 - } + public enum CompressionFormat + { + /// + /// Raw unsigned byte 8-bit Luminance data + /// + R, + /// + /// Raw unsigned byte 16-bit RG data + /// + RG, + /// + /// Raw unsigned byte 24-bit RGB data + /// + RGB, + /// + /// Raw unsigned byte 32-bit RGBA data + /// + RGBA, + /// + /// BC1 / DXT1 with no alpha. Very widely supported and good compression ratio. + /// + BC1, + /// + /// BC1 / DXT1 with 1-bit of alpha. + /// + BC1WithAlpha, + /// + /// BC2 / DXT3 encoding with alpha. Good for sharp alpha transitions. + /// + BC2, + /// + /// BC3 / DXT5 encoding with alpha. Good for smooth alpha transitions. + /// + BC3, + /// + /// BC4 single-channel encoding. Only luminance is encoded. + /// + BC4, + /// + /// BC5 dual-channel encoding. Only red and green channels are encoded. + /// + BC5, + /// + /// BC6H / BPTC float encoding. Can compress HDR textures without alpha. Currently not supported. + /// + BC6, + /// + /// BC7 / BPTC unorm encoding. Very high quality rgba or rgb encoding. Also very slow. + /// + BC7 + } - public static class CompressionFormatExtensions { - public static bool IsCompressedFormat(this CompressionFormat format) - { - switch (format) { - case CompressionFormat.R: - case CompressionFormat.RG: - case CompressionFormat.RGB: - case CompressionFormat.RGBA: - return false; - - default: - return true; - } - } - } + public static class CompressionFormatExtensions + { + public static bool IsCompressedFormat(this CompressionFormat format) + { + switch (format) + { + case CompressionFormat.R: + case CompressionFormat.RG: + case CompressionFormat.RGB: + case CompressionFormat.RGBA: + return false; + + default: + return true; + } + } + } } From b6316edfb08518b273595a6ebe37575c977ea41a Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Sun, 10 Jan 2021 17:54:12 +0100 Subject: [PATCH 2/9] Add DecodeRaw methods to BcDecoder; --- BCnEnc.Net/Decoder/BcDecoder.cs | 99 +++++++++++++++++++ .../Decoder/Options/DecoderInputOptions.cs | 6 ++ .../Decoder/Options/DecoderOutputOptions.cs | 4 +- 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/BCnEnc.Net/Decoder/BcDecoder.cs b/BCnEnc.Net/Decoder/BcDecoder.cs index cff60dd..4caf508 100644 --- a/BCnEnc.Net/Decoder/BcDecoder.cs +++ b/BCnEnc.Net/Decoder/BcDecoder.cs @@ -23,6 +23,54 @@ public class BcDecoder /// public DecoderOutputOptions OutputOptions { get; } = new DecoderOutputOptions(); + /// + /// Decode raw encoded image data. + /// + /// The stream containing the encoded data. + /// The format the encoded data is in. + /// The pixelWidth of the image. + /// The pixelHeight of the image. + /// The decoded Rgba32 image. + public Image DecodeRaw(Stream inputStream, CompressionFormat format, int pixelWidth, int pixelHeight) + { + var dataArray = new byte[inputStream.Position]; + inputStream.Read(dataArray, 0, dataArray.Length); + + return DecodeRaw(dataArray, format, pixelWidth, pixelHeight); + } + + /// + /// Decode raw encoded image data. + /// + /// The array containing the encoded data. + /// The format the encoded data is in. + /// The pixelWidth of the image. + /// The pixelHeight of the image. + /// The decoded Rgba32 image. + public Image DecodeRaw(byte[] input, CompressionFormat format, int pixelWidth, int pixelHeight) + { + var isCompressedFormat = format.IsCompressedFormat(); + if (isCompressedFormat) + { + // Decode as compressed data + var decoder = GetDecoder(format); + var blocks = decoder.Decode(input, pixelWidth, pixelHeight, out var blockWidth, out var blockHeight); + + return ImageToBlocks.ImageFromRawBlocks(blocks, blockWidth, blockHeight, pixelWidth, pixelHeight); + } + + // Decode as raw data + var rawDecoder = GetRawDecoder(format); + + var image = new Image(pixelWidth, pixelHeight); + var output = rawDecoder.Decode(input, pixelWidth, pixelHeight); + if (!image.TryGetSinglePixelSpan(out var pixels)) + throw new Exception("Cannot get pixel span."); + + output.CopyTo(pixels); + return image; + } + /// /// Read a Ktx or a Dds file from a stream and decode it. /// @@ -393,5 +441,56 @@ private IRawDecoder GetRawDecoder(DXGI_FORMAT format) return null; } } + + private IBcBlockDecoder GetDecoder(CompressionFormat format) + { + switch (format) + { + case CompressionFormat.BC1: + return new Bc1NoAlphaDecoder(); + + case CompressionFormat.BC1WithAlpha: + return new Bc1ADecoder(); + + case CompressionFormat.BC2: + return new Bc2Decoder(); + + case CompressionFormat.BC3: + return new Bc3Decoder(); + + case CompressionFormat.BC4: + return new Bc4Decoder(InputOptions.luminanceAsRed); + + case CompressionFormat.BC5: + return new Bc5Decoder(); + + case CompressionFormat.BC7: + return new Bc7Decoder(); + + default: + return null; + } + } + + private IRawDecoder GetRawDecoder(CompressionFormat format) + { + switch (format) + { + case CompressionFormat.R: + return new RawRDecoder(InputOptions.luminanceAsRed); + + case CompressionFormat.RG: + return new RawRGDecoder(); + + case CompressionFormat.RGB: + return new RawRGBDecoder(); + + case CompressionFormat.RGBA: + return new RawRGBADecoder(); + + default: + throw new ArgumentOutOfRangeException(nameof(format), format, null); + } + } } } diff --git a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs index 9529ab4..e55d295 100644 --- a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs +++ b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs @@ -9,5 +9,11 @@ public class DecoderInputOptions /// Default is true. /// public bool ddsBc1ExpectAlpha = true; + + /// + /// If true, when encoding to a format that only includes a red channel, + /// use the pixel luminance instead of just the red channel. Default is false. + /// + public bool luminanceAsRed = false; } } diff --git a/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs index a0a8299..c1374f8 100644 --- a/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs +++ b/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs @@ -1,4 +1,6 @@ -namespace BCnEncoder.Decoder.Options +using BCnEncoder.Shared; + +namespace BCnEncoder.Decoder.Options { public class DecoderOutputOptions { From f27fec4cb78d093d5e58947fe3b977b1f5d88c7c Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Sun, 10 Jan 2021 20:56:37 +0100 Subject: [PATCH 3/9] Use already existing redAsLuminance from DecoderOutputOptions; --- BCnEnc.Net/Decoder/BcDecoder.cs | 4 ++-- BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/BCnEnc.Net/Decoder/BcDecoder.cs b/BCnEnc.Net/Decoder/BcDecoder.cs index 4caf508..0db77db 100644 --- a/BCnEnc.Net/Decoder/BcDecoder.cs +++ b/BCnEnc.Net/Decoder/BcDecoder.cs @@ -459,7 +459,7 @@ private IBcBlockDecoder GetDecoder(CompressionFormat format) return new Bc3Decoder(); case CompressionFormat.BC4: - return new Bc4Decoder(InputOptions.luminanceAsRed); + return new Bc4Decoder(OutputOptions.redAsLuminance); case CompressionFormat.BC5: return new Bc5Decoder(); @@ -477,7 +477,7 @@ private IRawDecoder GetRawDecoder(CompressionFormat format) switch (format) { case CompressionFormat.R: - return new RawRDecoder(InputOptions.luminanceAsRed); + return new RawRDecoder(OutputOptions.redAsLuminance); case CompressionFormat.RG: return new RawRGDecoder(); diff --git a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs index e55d295..9529ab4 100644 --- a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs +++ b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs @@ -9,11 +9,5 @@ public class DecoderInputOptions /// Default is true. /// public bool ddsBc1ExpectAlpha = true; - - /// - /// If true, when encoding to a format that only includes a red channel, - /// use the pixel luminance instead of just the red channel. Default is false. - /// - public bool luminanceAsRed = false; } } From 12f7f3e52b45a2300ce9008d44a8a20bc4a346fb Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Mon, 11 Jan 2021 12:31:52 +0100 Subject: [PATCH 4/9] Fix color endpoint interpolation; --- BCnEnc.Net/Shared/EncodedBlocks.cs | 910 ++++++++++++++--------------- BCnEnc.Net/Shared/Interpolation.cs | 40 ++ BCnEncTests/BC1Tests.cs | 16 +- 3 files changed, 503 insertions(+), 463 deletions(-) create mode 100644 BCnEnc.Net/Shared/Interpolation.cs diff --git a/BCnEnc.Net/Shared/EncodedBlocks.cs b/BCnEnc.Net/Shared/EncodedBlocks.cs index bf41884..e88cfa6 100644 --- a/BCnEnc.Net/Shared/EncodedBlocks.cs +++ b/BCnEnc.Net/Shared/EncodedBlocks.cs @@ -4,460 +4,460 @@ namespace BCnEncoder.Shared { - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct Bc1Block - { - public ColorRgb565 color0; - public ColorRgb565 color1; - public uint colorIndices; - - public int this[int index] - { - readonly get => (int)(colorIndices >> (index * 2)) & 0b11; - set - { - colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); - int val = value & 0b11; - colorIndices = (colorIndices | ((uint)val << (index * 2))); - } - } - - public readonly bool HasAlphaOrBlack => color0.data <= color1.data; - - public readonly RawBlock4X4Rgba32 Decode(bool useAlpha) - { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); - var pixels = output.AsSpan; - - var color0 = this.color0.ToColorRgb24(); - var color1 = this.color1.ToColorRgb24(); - - useAlpha = useAlpha && HasAlphaOrBlack; - - Span colors = HasAlphaOrBlack ? - stackalloc ColorRgb24[] { - color0, - color1, - color0 * (1.0 / 2.0) + color1 * (1.0 / 2.0), - new ColorRgb24(0, 0, 0) - } : stackalloc ColorRgb24[] { - color0, - color1, - color0 * (2.0 / 3.0) + color1 * (1.0 / 3.0), - color0 * (1.0 / 3.0) + color1 * (2.0 / 3.0) - }; - - for (int i = 0; i < pixels.Length; i++) - { - int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); - var color = colors[colorIndex]; - if (useAlpha && colorIndex == 3) - { - pixels[i] = new Rgba32(0, 0, 0, 0); - } - else - { - pixels[i] = new Rgba32(color.r, color.g, color.b, 255); - } - } - return output; - } - } - - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct Bc2Block - { - public ulong alphaColors; - public ColorRgb565 color0; - public ColorRgb565 color1; - public uint colorIndices; - - public int this[int index] - { - readonly get => (int)(colorIndices >> (index * 2)) & 0b11; - set - { - colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); - int val = value & 0b11; - colorIndices = (colorIndices | ((uint)val << (index * 2))); - } - } - - public readonly byte GetAlpha(int index) - { - ulong mask = 0xFUL << (index * 4); - int shift = (index * 4); - ulong alphaUnscaled = (((alphaColors & mask) >> shift)); - return (byte)((alphaUnscaled / 15.0) * 255); - } - - public void SetAlpha(int index, byte alpha) - { - ulong mask = 0xFUL << (index * 4); - int shift = (index * 4); - alphaColors &= ~mask; - byte a = (byte)((alpha / 255.0) * 15); - alphaColors |= (ulong)(a & 0xF) << shift; - } - - public readonly RawBlock4X4Rgba32 Decode() - { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); - var pixels = output.AsSpan; - - var color0 = this.color0.ToColorRgb24(); - var color1 = this.color1.ToColorRgb24(); - - Span colors = stackalloc ColorRgb24[] { - color0, - color1, - color0 * (2.0 / 3.0) + color1 * (1.0 / 3.0), - color0 * (1.0 / 3.0) + color1 * (2.0 / 3.0) - }; - - for (int i = 0; i < pixels.Length; i++) - { - int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); - var color = colors[colorIndex]; - - pixels[i] = new Rgba32(color.r, color.g, color.b, GetAlpha(i)); - } - return output; - } - } - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct Bc3Block - { - public ulong alphaBlock; - public ColorRgb565 color0; - public ColorRgb565 color1; - public uint colorIndices; - - public int this[int index] - { - readonly get => (int)(colorIndices >> (index * 2)) & 0b11; - set - { - colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); - int val = value & 0b11; - colorIndices = (colorIndices | ((uint)val << (index * 2))); - } - } - - public byte Alpha0 - { - readonly get => (byte)(alphaBlock & 0xFFUL); - set - { - alphaBlock &= ~0xFFUL; - alphaBlock |= value; - } - } - - public byte Alpha1 - { - readonly get => (byte)((alphaBlock >> 8) & 0xFFUL); - set - { - alphaBlock &= ~0xFF00UL; - alphaBlock |= (ulong)value << 8; - } - } - - public readonly byte GetAlphaIndex(int pixelIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong alphaIndex = (((alphaBlock & mask) >> shift)); - return (byte)alphaIndex; - } - - public void SetAlphaIndex(int pixelIndex, byte alphaIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - alphaBlock &= ~mask; - alphaBlock |= (ulong)(alphaIndex & 0b111) << shift; - } - - public readonly RawBlock4X4Rgba32 Decode() - { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); - var pixels = output.AsSpan; - - var color0 = this.color0.ToColorRgb24(); - var color1 = this.color1.ToColorRgb24(); - - var a0 = Alpha0; - var a1 = Alpha1; - Span colors = stackalloc ColorRgb24[] { - color0, - color1, - color0 * (2.0 / 3.0) + color1 * (1.0 / 3.0), - color0 * (1.0 / 3.0) + color1 * (2.0 / 3.0) - }; - - Span alphas = a0 > a1 ? stackalloc byte[] { - a0, - a1, - (byte)(6 / 7.0 * a0 + 1 / 7.0 * a1), - (byte)(5 / 7.0 * a0 + 2 / 7.0 * a1), - (byte)(4 / 7.0 * a0 + 3 / 7.0 * a1), - (byte)(3 / 7.0 * a0 + 4 / 7.0 * a1), - (byte)(2 / 7.0 * a0 + 5 / 7.0 * a1), - (byte)(1 / 7.0 * a0 + 6 / 7.0 * a1), - } : stackalloc byte[] { - a0, - a1, - (byte)(4 / 5.0 * a0 + 1 / 5.0 * a1), - (byte)(3 / 5.0 * a0 + 2 / 5.0 * a1), - (byte)(2 / 5.0 * a0 + 3 / 5.0 * a1), - (byte)(1 / 5.0 * a0 + 4 / 5.0 * a1), - 0, - 255 - }; - - for (int i = 0; i < pixels.Length; i++) - { - int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); - var color = colors[colorIndex]; - - pixels[i] = new Rgba32(color.r, color.g, color.b, alphas[GetAlphaIndex(i)]); - } - return output; - } - } - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct Bc4Block - { - public ulong redBlock; - - public byte Red0 - { - readonly get => (byte)(redBlock & 0xFFUL); - set - { - redBlock &= ~0xFFUL; - redBlock |= value; - } - } - - public byte Red1 - { - readonly get => (byte)((redBlock >> 8) & 0xFFUL); - set - { - redBlock &= ~0xFF00UL; - redBlock |= (ulong)value << 8; - } - } - - public readonly byte GetRedIndex(int pixelIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong redIndex = (((redBlock & mask) >> shift)); - return (byte)redIndex; - } - - public void SetRedIndex(int pixelIndex, byte redIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - redBlock &= ~mask; - redBlock |= (ulong)(redIndex & 0b111) << shift; - } - - public readonly RawBlock4X4Rgba32 Decode(bool redAsLuminance) - { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); - var pixels = output.AsSpan; - - var r0 = Red0; - var r1 = Red1; - - Span reds = r0 > r1 ? stackalloc byte[] { - r0, - r1, - (byte)(6 / 7.0 * r0 + 1 / 7.0 * r1), - (byte)(5 / 7.0 * r0 + 2 / 7.0 * r1), - (byte)(4 / 7.0 * r0 + 3 / 7.0 * r1), - (byte)(3 / 7.0 * r0 + 4 / 7.0 * r1), - (byte)(2 / 7.0 * r0 + 5 / 7.0 * r1), - (byte)(1 / 7.0 * r0 + 6 / 7.0 * r1), - } : stackalloc byte[] { - r0, - r1, - (byte)(4 / 5.0 * r0 + 1 / 5.0 * r1), - (byte)(3 / 5.0 * r0 + 2 / 5.0 * r1), - (byte)(2 / 5.0 * r0 + 3 / 5.0 * r1), - (byte)(1 / 5.0 * r0 + 4 / 5.0 * r1), - 0, - 255 - }; - - if (redAsLuminance) - { - for (int i = 0; i < pixels.Length; i++) - { - var index = GetRedIndex(i); - pixels[i] = new Rgba32(reds[index], reds[index], reds[index], 255); - } - } - else - { - for (int i = 0; i < pixels.Length; i++) - { - var index = GetRedIndex(i); - pixels[i] = new Rgba32(reds[index], 0, 0, 255); - } - } - - return output; - } - } - - [StructLayout(LayoutKind.Sequential)] - internal unsafe struct Bc5Block - { - public ulong redBlock; - public ulong greenBlock; - - public byte Red0 - { - readonly get => (byte)(redBlock & 0xFFUL); - set - { - redBlock &= ~0xFFUL; - redBlock |= value; - } - } - - public byte Red1 - { - readonly get => (byte)((redBlock >> 8) & 0xFFUL); - set - { - redBlock &= ~0xFF00UL; - redBlock |= (ulong)value << 8; - } - } - - public byte Green0 - { - readonly get => (byte)(greenBlock & 0xFFUL); - set - { - greenBlock &= ~0xFFUL; - greenBlock |= value; - } - } - - public byte Green1 - { - readonly get => (byte)((greenBlock >> 8) & 0xFFUL); - set - { - greenBlock &= ~0xFF00UL; - greenBlock |= (ulong)value << 8; - } - } - - public readonly byte GetRedIndex(int pixelIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong redIndex = (((redBlock & mask) >> shift)); - return (byte)redIndex; - } - - public void SetRedIndex(int pixelIndex, byte redIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - redBlock &= ~mask; - redBlock |= (ulong)(redIndex & 0b111) << shift; - } - - public readonly byte GetGreenIndex(int pixelIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong greenIndex = (((greenBlock & mask) >> shift)); - return (byte)greenIndex; - } - - public void SetGreenIndex(int pixelIndex, byte greenIndex) - { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - greenBlock &= ~mask; - greenBlock |= (ulong)(greenIndex & 0b111) << shift; - } - - public readonly RawBlock4X4Rgba32 Decode() - { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); - var pixels = output.AsSpan; - - var r0 = Red0; - var r1 = Red1; - - Span reds = r0 > r1 ? stackalloc byte[] { - r0, - r1, - (byte)(6 / 7.0 * r0 + 1 / 7.0 * r1), - (byte)(5 / 7.0 * r0 + 2 / 7.0 * r1), - (byte)(4 / 7.0 * r0 + 3 / 7.0 * r1), - (byte)(3 / 7.0 * r0 + 4 / 7.0 * r1), - (byte)(2 / 7.0 * r0 + 5 / 7.0 * r1), - (byte)(1 / 7.0 * r0 + 6 / 7.0 * r1), - } : stackalloc byte[] { - r0, - r1, - (byte)(4 / 5.0 * r0 + 1 / 5.0 * r1), - (byte)(3 / 5.0 * r0 + 2 / 5.0 * r1), - (byte)(2 / 5.0 * r0 + 3 / 5.0 * r1), - (byte)(1 / 5.0 * r0 + 4 / 5.0 * r1), - 0, - 255 - }; - - var g0 = Green0; - var g1 = Green1; - - Span greens = g0 > g1 ? stackalloc byte[] { - g0, - g1, - (byte)(6 / 7.0 * g0 + 1 / 7.0 * g1), - (byte)(5 / 7.0 * g0 + 2 / 7.0 * g1), - (byte)(4 / 7.0 * g0 + 3 / 7.0 * g1), - (byte)(3 / 7.0 * g0 + 4 / 7.0 * g1), - (byte)(2 / 7.0 * g0 + 5 / 7.0 * g1), - (byte)(1 / 7.0 * g0 + 6 / 7.0 * g1), - } : stackalloc byte[] { - g0, - g1, - (byte)(4 / 5.0 * g0 + 1 / 5.0 * g1), - (byte)(3 / 5.0 * g0 + 2 / 5.0 * g1), - (byte)(2 / 5.0 * g0 + 3 / 5.0 * g1), - (byte)(1 / 5.0 * g0 + 4 / 5.0 * g1), - 0, - 255 - }; - - for (int i = 0; i < pixels.Length; i++) - { - var redIndex = GetRedIndex(i); - var greenIndex = GetGreenIndex(i); - pixels[i] = new Rgba32(reds[redIndex], greens[greenIndex], 0, 255); - } - - return output; - } - } + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct Bc1Block + { + public ColorRgb565 color0; + public ColorRgb565 color1; + public uint colorIndices; + + public int this[int index] + { + readonly get => (int)(colorIndices >> (index * 2)) & 0b11; + set + { + colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); + int val = value & 0b11; + colorIndices = (colorIndices | ((uint)val << (index * 2))); + } + } + + public readonly bool HasAlphaOrBlack => color0.data <= color1.data; + + public readonly RawBlock4X4Rgba32 Decode(bool useAlpha) + { + RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var pixels = output.AsSpan; + + var color0 = this.color0.ToColorRgb24(); + var color1 = this.color1.ToColorRgb24(); + + useAlpha = useAlpha && HasAlphaOrBlack; + + Span colors = HasAlphaOrBlack ? + stackalloc ColorRgb24[] { + color0, + color1, + color0.Half(color1), + new ColorRgb24(0, 0, 0) + } : stackalloc ColorRgb24[] { + color0, + color1, + color0.Third(color1, 1), + color0.Third(color1, 2) + }; + + for (int i = 0; i < pixels.Length; i++) + { + int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); + var color = colors[colorIndex]; + if (useAlpha && colorIndex == 3) + { + pixels[i] = new Rgba32(0, 0, 0, 0); + } + else + { + pixels[i] = new Rgba32(color.r, color.g, color.b, 255); + } + } + return output; + } + } + + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct Bc2Block + { + public ulong alphaColors; + public ColorRgb565 color0; + public ColorRgb565 color1; + public uint colorIndices; + + public int this[int index] + { + readonly get => (int)(colorIndices >> (index * 2)) & 0b11; + set + { + colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); + int val = value & 0b11; + colorIndices = (colorIndices | ((uint)val << (index * 2))); + } + } + + public readonly byte GetAlpha(int index) + { + ulong mask = 0xFUL << (index * 4); + int shift = (index * 4); + ulong alphaUnscaled = (((alphaColors & mask) >> shift)); + return (byte)((alphaUnscaled / 15.0) * 255); + } + + public void SetAlpha(int index, byte alpha) + { + ulong mask = 0xFUL << (index * 4); + int shift = (index * 4); + alphaColors &= ~mask; + byte a = (byte)((alpha / 255.0) * 15); + alphaColors |= (ulong)(a & 0xF) << shift; + } + + public readonly RawBlock4X4Rgba32 Decode() + { + RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var pixels = output.AsSpan; + + var color0 = this.color0.ToColorRgb24(); + var color1 = this.color1.ToColorRgb24(); + + Span colors = stackalloc ColorRgb24[] { + color0, + color1, + color0.Third(color1, 1), + color0.Third(color1, 2) + }; + + for (int i = 0; i < pixels.Length; i++) + { + int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); + var color = colors[colorIndex]; + + pixels[i] = new Rgba32(color.r, color.g, color.b, GetAlpha(i)); + } + return output; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct Bc3Block + { + public ulong alphaBlock; + public ColorRgb565 color0; + public ColorRgb565 color1; + public uint colorIndices; + + public int this[int index] + { + readonly get => (int)(colorIndices >> (index * 2)) & 0b11; + set + { + colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); + int val = value & 0b11; + colorIndices = (colorIndices | ((uint)val << (index * 2))); + } + } + + public byte Alpha0 + { + readonly get => (byte)(alphaBlock & 0xFFUL); + set + { + alphaBlock &= ~0xFFUL; + alphaBlock |= value; + } + } + + public byte Alpha1 + { + readonly get => (byte)((alphaBlock >> 8) & 0xFFUL); + set + { + alphaBlock &= ~0xFF00UL; + alphaBlock |= (ulong)value << 8; + } + } + + public readonly byte GetAlphaIndex(int pixelIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + ulong alphaIndex = (((alphaBlock & mask) >> shift)); + return (byte)alphaIndex; + } + + public void SetAlphaIndex(int pixelIndex, byte alphaIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + alphaBlock &= ~mask; + alphaBlock |= (ulong)(alphaIndex & 0b111) << shift; + } + + public readonly RawBlock4X4Rgba32 Decode() + { + RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var pixels = output.AsSpan; + + var color0 = this.color0.ToColorRgb24(); + var color1 = this.color1.ToColorRgb24(); + + var a0 = Alpha0; + var a1 = Alpha1; + Span colors = stackalloc ColorRgb24[] { + color0, + color1, + color0.Third(color1, 1), + color0.Third(color1, 2) + }; + + Span alphas = a0 > a1 ? stackalloc byte[] { + a0, + a1, + (byte)Interpolation.Interpolate(a0, a1, 1, 7), + (byte)Interpolation.Interpolate(a0, a1, 2, 7), + (byte)Interpolation.Interpolate(a0, a1, 3, 7), + (byte)Interpolation.Interpolate(a0, a1, 4, 7), + (byte)Interpolation.Interpolate(a0, a1, 5, 7), + (byte)Interpolation.Interpolate(a0, a1, 6, 7) + } : stackalloc byte[] { + a0, + a1, + (byte)Interpolation.Interpolate(a0, a1, 1, 5), + (byte)Interpolation.Interpolate(a0, a1, 2, 5), + (byte)Interpolation.Interpolate(a0, a1, 3, 5), + (byte)Interpolation.Interpolate(a0, a1, 4, 5), + 0, + 255 + }; + + for (int i = 0; i < pixels.Length; i++) + { + int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); + var color = colors[colorIndex]; + + pixels[i] = new Rgba32(color.r, color.g, color.b, alphas[GetAlphaIndex(i)]); + } + return output; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct Bc4Block + { + public ulong redBlock; + + public byte Red0 + { + readonly get => (byte)(redBlock & 0xFFUL); + set + { + redBlock &= ~0xFFUL; + redBlock |= value; + } + } + + public byte Red1 + { + readonly get => (byte)((redBlock >> 8) & 0xFFUL); + set + { + redBlock &= ~0xFF00UL; + redBlock |= (ulong)value << 8; + } + } + + public readonly byte GetRedIndex(int pixelIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + ulong redIndex = (((redBlock & mask) >> shift)); + return (byte)redIndex; + } + + public void SetRedIndex(int pixelIndex, byte redIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + redBlock &= ~mask; + redBlock |= (ulong)(redIndex & 0b111) << shift; + } + + public readonly RawBlock4X4Rgba32 Decode(bool redAsLuminance) + { + RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var pixels = output.AsSpan; + + var r0 = Red0; + var r1 = Red1; + + Span reds = r0 > r1 ? stackalloc byte[] { + r0, + r1, + (byte)Interpolation.Interpolate(r0, r1, 1, 7), + (byte)Interpolation.Interpolate(r0, r1, 2, 7), + (byte)Interpolation.Interpolate(r0, r1, 3, 7), + (byte)Interpolation.Interpolate(r0, r1, 4, 7), + (byte)Interpolation.Interpolate(r0, r1, 5, 7), + (byte)Interpolation.Interpolate(r0, r1, 6, 7) + } : stackalloc byte[] { + r0, + r1, + (byte)Interpolation.Interpolate(r0, r1, 1, 5), + (byte)Interpolation.Interpolate(r0, r1, 2, 5), + (byte)Interpolation.Interpolate(r0, r1, 3, 5), + (byte)Interpolation.Interpolate(r0, r1, 4, 5), + 0, + 255 + }; + + if (redAsLuminance) + { + for (int i = 0; i < pixels.Length; i++) + { + var index = GetRedIndex(i); + pixels[i] = new Rgba32(reds[index], reds[index], reds[index], 255); + } + } + else + { + for (int i = 0; i < pixels.Length; i++) + { + var index = GetRedIndex(i); + pixels[i] = new Rgba32(reds[index], 0, 0, 255); + } + } + + return output; + } + } + + [StructLayout(LayoutKind.Sequential)] + internal unsafe struct Bc5Block + { + public ulong redBlock; + public ulong greenBlock; + + public byte Red0 + { + readonly get => (byte)(redBlock & 0xFFUL); + set + { + redBlock &= ~0xFFUL; + redBlock |= value; + } + } + + public byte Red1 + { + readonly get => (byte)((redBlock >> 8) & 0xFFUL); + set + { + redBlock &= ~0xFF00UL; + redBlock |= (ulong)value << 8; + } + } + + public byte Green0 + { + readonly get => (byte)(greenBlock & 0xFFUL); + set + { + greenBlock &= ~0xFFUL; + greenBlock |= value; + } + } + + public byte Green1 + { + readonly get => (byte)((greenBlock >> 8) & 0xFFUL); + set + { + greenBlock &= ~0xFF00UL; + greenBlock |= (ulong)value << 8; + } + } + + public readonly byte GetRedIndex(int pixelIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + ulong redIndex = (((redBlock & mask) >> shift)); + return (byte)redIndex; + } + + public void SetRedIndex(int pixelIndex, byte redIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + redBlock &= ~mask; + redBlock |= (ulong)(redIndex & 0b111) << shift; + } + + public readonly byte GetGreenIndex(int pixelIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + ulong greenIndex = (((greenBlock & mask) >> shift)); + return (byte)greenIndex; + } + + public void SetGreenIndex(int pixelIndex, byte greenIndex) + { + ulong mask = 0b0111UL << (pixelIndex * 3 + 16); + int shift = (pixelIndex * 3 + 16); + greenBlock &= ~mask; + greenBlock |= (ulong)(greenIndex & 0b111) << shift; + } + + public readonly RawBlock4X4Rgba32 Decode() + { + RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var pixels = output.AsSpan; + + var r0 = Red0; + var r1 = Red1; + + Span reds = r0 > r1 ? stackalloc byte[] { + r0, + r1, + (byte)Interpolation.Interpolate(r0, r1, 1, 7), + (byte)Interpolation.Interpolate(r0, r1, 2, 7), + (byte)Interpolation.Interpolate(r0, r1, 3, 7), + (byte)Interpolation.Interpolate(r0, r1, 4, 7), + (byte)Interpolation.Interpolate(r0, r1, 5, 7), + (byte)Interpolation.Interpolate(r0, r1, 6, 7) + } : stackalloc byte[] { + r0, + r1, + (byte)Interpolation.Interpolate(r0, r1, 1, 5), + (byte)Interpolation.Interpolate(r0, r1, 2, 5), + (byte)Interpolation.Interpolate(r0, r1, 3, 5), + (byte)Interpolation.Interpolate(r0, r1, 4, 5), + 0, + 255 + }; + + var g0 = Green0; + var g1 = Green1; + + Span greens = g0 > g1 ? stackalloc byte[] { + g0, + g1, + (byte)Interpolation.Interpolate(g0, g1, 1, 7), + (byte)Interpolation.Interpolate(g0, g1, 2, 7), + (byte)Interpolation.Interpolate(g0, g1, 3, 7), + (byte)Interpolation.Interpolate(g0, g1, 4, 7), + (byte)Interpolation.Interpolate(g0, g1, 5, 7), + (byte)Interpolation.Interpolate(g0, g1, 6, 7) + } : stackalloc byte[] { + g0, + g1, + (byte)Interpolation.Interpolate(g0, g1, 1, 5), + (byte)Interpolation.Interpolate(g0, g1, 2, 5), + (byte)Interpolation.Interpolate(g0, g1, 3, 5), + (byte)Interpolation.Interpolate(g0, g1, 4, 5), + 0, + 255 + }; + + for (int i = 0; i < pixels.Length; i++) + { + var redIndex = GetRedIndex(i); + var greenIndex = GetGreenIndex(i); + pixels[i] = new Rgba32(reds[redIndex], greens[greenIndex], 0, 255); + } + + return output; + } + } } diff --git a/BCnEnc.Net/Shared/Interpolation.cs b/BCnEnc.Net/Shared/Interpolation.cs new file mode 100644 index 0000000..aad559a --- /dev/null +++ b/BCnEnc.Net/Shared/Interpolation.cs @@ -0,0 +1,40 @@ +namespace BCnEncoder.Shared +{ + internal static class Interpolation + { + /// + /// Interpolates two colors by half. + /// + /// The first color endpoint. + /// The second color endpoint. + /// The interpolated color. + public static ColorRgb24 Half(this ColorRgb24 c0, ColorRgb24 c1) => + InterpolateColor(c0, c1, 1, 2); + + /// + /// Interpolates two colors by third. + /// + /// The first color endpoint. + /// The second color endpoint. + /// The dividend in the third. + /// The interpolated color. + public static ColorRgb24 Third(this ColorRgb24 c0, ColorRgb24 c1, int num) => + InterpolateColor(c0, c1, num, 3); + + /// + /// Interpolates two components. + /// + /// The first component. + /// The second component. + /// The dividend. + /// The divisor. + /// The interpolated component. + public static int Interpolate(int a, int b, int num, float den) => + (int)(((den - num) * a + num * b) / den); + + private static ColorRgb24 InterpolateColor(ColorRgb24 c0, ColorRgb24 c1, int num, float den) => new ColorRgb24( + (byte)Interpolate(c0.r, c1.r, num, den), + (byte)Interpolate(c0.g, c1.g, num, den), + (byte)Interpolate(c0.b, c1.b, num, den)); + } +} diff --git a/BCnEncTests/BC1Tests.cs b/BCnEncTests/BC1Tests.cs index 77492f4..4171d73 100644 --- a/BCnEncTests/BC1Tests.cs +++ b/BCnEncTests/BC1Tests.cs @@ -94,10 +94,10 @@ public class BC1Tests Assert.Equal(new Rgba32(0, 0, 0), raw.p21); Assert.Equal(new Rgba32(0, 0, 0), raw.p31); - Assert.Equal(new Rgba32(230, 228, 230), raw.p02); - Assert.Equal(new Rgba32(230, 228, 230), raw.p12); - Assert.Equal(new Rgba32(230, 228, 230), raw.p22); - Assert.Equal(new Rgba32(230, 228, 230), raw.p32); + Assert.Equal(new Rgba32(230, 229, 230), raw.p02); + Assert.Equal(new Rgba32(230, 229, 230), raw.p12); + Assert.Equal(new Rgba32(230, 229, 230), raw.p22); + Assert.Equal(new Rgba32(230, 229, 230), raw.p32); Assert.Equal(new Rgba32(255, 255, 255), raw.p03); Assert.Equal(new Rgba32(255, 255, 255), raw.p13); @@ -143,10 +143,10 @@ public class BC1Tests Assert.Equal(new Rgba32(0,0,0,0), raw.p21); Assert.Equal(new Rgba32(0,0,0,0), raw.p31); - Assert.Equal(new Rgba32(230, 228, 230), raw.p02); - Assert.Equal(new Rgba32(230, 228, 230), raw.p12); - Assert.Equal(new Rgba32(230, 228, 230), raw.p22); - Assert.Equal(new Rgba32(230, 228, 230), raw.p32); + Assert.Equal(new Rgba32(230, 229, 230), raw.p02); + Assert.Equal(new Rgba32(230, 229, 230), raw.p12); + Assert.Equal(new Rgba32(230, 229, 230), raw.p22); + Assert.Equal(new Rgba32(230, 229, 230), raw.p32); Assert.Equal(new Rgba32(255, 255, 255), raw.p03); Assert.Equal(new Rgba32(255, 255, 255), raw.p13); From 22505e78c95a1c4e764034e86da071aa3cd26d64 Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Mon, 11 Jan 2021 15:28:29 +0100 Subject: [PATCH 5/9] Add test to assert the functionality of raw byte encoding and decoding methods; --- BCnEncTests/RawTests.cs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 BCnEncTests/RawTests.cs diff --git a/BCnEncTests/RawTests.cs b/BCnEncTests/RawTests.cs new file mode 100644 index 0000000..9869230 --- /dev/null +++ b/BCnEncTests/RawTests.cs @@ -0,0 +1,32 @@ +using System.IO; +using BCnEncoder.Decoder; +using BCnEncoder.Encoder; +using BCnEncoder.Shared; +using Xunit; + +namespace BCnEncTests +{ + public class RawTests + { + [Fact] + public void Decode() + { + using var fs = File.OpenRead(@"../../../testImages/test_decompress_bc1.ktx"); + var ktx = KtxFile.Load(fs); + var decoder = new BcDecoder(); + var encoder = new BcEncoder(); + + var originalImage = decoder.Decode(ktx); + + var rawBytes = encoder.EncodeToRawBytes(originalImage); + var recodedImage = decoder.DecodeRaw(rawBytes[0], CompressionFormat.BC1, originalImage.Width, originalImage.Height); + + originalImage.TryGetSinglePixelSpan(out var originalPixels); + recodedImage.TryGetSinglePixelSpan(out var recodedPixels); + + // I don't know if this is the best possibility to compare the images + for (var i = 0; i < ktx.Header.PixelWidth * ktx.Header.PixelHeight; i++) + Assert.Equal(originalPixels[i], recodedPixels[i]); + } + } +} From 25f1bd2f831bfbb598a113a56c9ec6d7f203efd1 Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Mon, 11 Jan 2021 16:10:27 +0100 Subject: [PATCH 6/9] Cast Interpolate den parameter to float inline; --- BCnEnc.Net/Shared/Interpolation.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/BCnEnc.Net/Shared/Interpolation.cs b/BCnEnc.Net/Shared/Interpolation.cs index aad559a..140b00d 100644 --- a/BCnEnc.Net/Shared/Interpolation.cs +++ b/BCnEnc.Net/Shared/Interpolation.cs @@ -29,10 +29,10 @@ internal static class Interpolation /// The dividend. /// The divisor. /// The interpolated component. - public static int Interpolate(int a, int b, int num, float den) => - (int)(((den - num) * a + num * b) / den); + public static int Interpolate(int a, int b, int num, int den) => + (int)(((den - num) * a + num * b) / (float)den); - private static ColorRgb24 InterpolateColor(ColorRgb24 c0, ColorRgb24 c1, int num, float den) => new ColorRgb24( + private static ColorRgb24 InterpolateColor(ColorRgb24 c0, ColorRgb24 c1, int num, int den) => new ColorRgb24( (byte)Interpolate(c0.r, c1.r, num, den), (byte)Interpolate(c0.g, c1.g, num, den), (byte)Interpolate(c0.b, c1.b, num, den)); From abb062bd36f393123248de60ec0c89448ca0b843 Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Mon, 11 Jan 2021 16:21:36 +0100 Subject: [PATCH 7/9] RawTests uses ImageQuality.PeakSignalToNoiseRatio method to assert image equality; --- BCnEncTests/RawTests.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/BCnEncTests/RawTests.cs b/BCnEncTests/RawTests.cs index 9869230..9e0c5d5 100644 --- a/BCnEncTests/RawTests.cs +++ b/BCnEncTests/RawTests.cs @@ -24,9 +24,15 @@ public void Decode() originalImage.TryGetSinglePixelSpan(out var originalPixels); recodedImage.TryGetSinglePixelSpan(out var recodedPixels); - // I don't know if this is the best possibility to compare the images - for (var i = 0; i < ktx.Header.PixelWidth * ktx.Header.PixelHeight; i++) - Assert.Equal(originalPixels[i], recodedPixels[i]); + var psnr=ImageQuality.PeakSignalToNoiseRatio(originalPixels, recodedPixels); + if (encoder.OutputOptions.quality == CompressionQuality.Fast) + { + Assert.True(psnr > 25); + } + else + { + Assert.True(psnr > 30); + } } } } From e0425ff39c85aeb0b18d8128beb58cdc93ca2523 Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Mon, 11 Jan 2021 16:33:13 +0100 Subject: [PATCH 8/9] Rename color interpolation extensions; --- BCnEnc.Net/Shared/EncodedBlocks.cs | 14 +++++++------- BCnEnc.Net/Shared/Interpolation.cs | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/BCnEnc.Net/Shared/EncodedBlocks.cs b/BCnEnc.Net/Shared/EncodedBlocks.cs index e88cfa6..c106d49 100644 --- a/BCnEnc.Net/Shared/EncodedBlocks.cs +++ b/BCnEnc.Net/Shared/EncodedBlocks.cs @@ -38,13 +38,13 @@ internal unsafe struct Bc1Block stackalloc ColorRgb24[] { color0, color1, - color0.Half(color1), + color0.InterpolateHalf(color1), new ColorRgb24(0, 0, 0) } : stackalloc ColorRgb24[] { color0, color1, - color0.Third(color1, 1), - color0.Third(color1, 2) + color0.InterpolateThird(color1, 1), + color0.InterpolateThird(color1, 2) }; for (int i = 0; i < pixels.Length; i++) @@ -112,8 +112,8 @@ public void SetAlpha(int index, byte alpha) Span colors = stackalloc ColorRgb24[] { color0, color1, - color0.Third(color1, 1), - color0.Third(color1, 2) + color0.InterpolateThird(color1, 1), + color0.InterpolateThird(color1, 2) }; for (int i = 0; i < pixels.Length; i++) @@ -195,8 +195,8 @@ public void SetAlphaIndex(int pixelIndex, byte alphaIndex) Span colors = stackalloc ColorRgb24[] { color0, color1, - color0.Third(color1, 1), - color0.Third(color1, 2) + color0.InterpolateThird(color1, 1), + color0.InterpolateThird(color1, 2) }; Span alphas = a0 > a1 ? stackalloc byte[] { diff --git a/BCnEnc.Net/Shared/Interpolation.cs b/BCnEnc.Net/Shared/Interpolation.cs index 140b00d..c9c0779 100644 --- a/BCnEnc.Net/Shared/Interpolation.cs +++ b/BCnEnc.Net/Shared/Interpolation.cs @@ -8,7 +8,7 @@ internal static class Interpolation /// The first color endpoint. /// The second color endpoint. /// The interpolated color. - public static ColorRgb24 Half(this ColorRgb24 c0, ColorRgb24 c1) => + public static ColorRgb24 InterpolateHalf(this ColorRgb24 c0, ColorRgb24 c1) => InterpolateColor(c0, c1, 1, 2); /// @@ -18,7 +18,7 @@ internal static class Interpolation /// The second color endpoint. /// The dividend in the third. /// The interpolated color. - public static ColorRgb24 Third(this ColorRgb24 c0, ColorRgb24 c1, int num) => + public static ColorRgb24 InterpolateThird(this ColorRgb24 c0, ColorRgb24 c1, int num) => InterpolateColor(c0, c1, num, 3); /// From c1aef0bafeefb0f7084370a80b7258d2f0bf59b5 Mon Sep 17 00:00:00 2001 From: onepiecefreak3 Date: Mon, 11 Jan 2021 20:14:14 +0100 Subject: [PATCH 9/9] General code cleanup and style fixes; Further removing of code duplicates; --- BCnEnc.Net/Decoder/Bc7Decoder.cs | 32 - BCnEnc.Net/Decoder/BcBlockDecoder.cs | 247 +++--- BCnEnc.Net/Decoder/BcDecoder.cs | 182 ++-- .../Decoder/Options/DecoderInputOptions.cs | 7 +- .../Decoder/Options/DecoderOutputOptions.cs | 11 +- BCnEnc.Net/Decoder/RawDecoder.cs | 197 +++-- BCnEnc.Net/Encoder/Bc1BlockEncoder.cs | 116 +-- BCnEnc.Net/Encoder/Bc2BlockEncoder.cs | 52 +- BCnEnc.Net/Encoder/Bc3BlockEncoder.cs | 106 +-- BCnEnc.Net/Encoder/Bc4BlockEncoder.cs | 78 +- BCnEnc.Net/Encoder/Bc5BlockEncoder.cs | 84 +- BCnEnc.Net/Encoder/Bc7/Bc7Encoder.cs | 107 ++- BCnEnc.Net/Encoder/Bc7/Bc7EncodingHelpers.cs | 286 +++---- BCnEnc.Net/Encoder/Bc7/Bc7Mode0Encoder.cs | 20 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode1Encoder.cs | 18 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode2Encoder.cs | 18 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode3Encoder.cs | 20 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode4Encoder.cs | 34 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode5Encoder.cs | 32 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode6Encoder.cs | 14 +- BCnEnc.Net/Encoder/Bc7/Bc7Mode7Encoder.cs | 20 +- BCnEnc.Net/Encoder/BcEncoder.cs | 203 +++-- BCnEnc.Net/Encoder/ColorChooser.cs | 70 +- BCnEnc.Net/Encoder/ColorVariationGenerator.cs | 10 +- BCnEnc.Net/Encoder/CompressionQuality.cs | 6 +- BCnEnc.Net/Encoder/IBcBlockEncoder.cs | 4 +- .../Encoder/Options/EncoderInputOptions.cs | 7 +- BCnEnc.Net/Encoder/Options/EncoderOptions.cs | 3 + .../Encoder/Options/EncoderOutputOptions.cs | 23 +- BCnEnc.Net/Encoder/RawEncoders.cs | 86 +- BCnEnc.Net/Shared/Bc7Block.cs | 298 +++---- .../Shared/BinaryReaderWriterExtensions.cs | 14 +- BCnEnc.Net/Shared/ByteHelper.cs | 26 +- BCnEnc.Net/Shared/Colors.cs | 280 +++---- BCnEnc.Net/Shared/CompressionFormat.cs | 30 +- BCnEnc.Net/Shared/DdsFile.cs | 790 +++++++++--------- BCnEnc.Net/Shared/EncodedBlocks.cs | 110 +-- BCnEnc.Net/Shared/GLFormat.cs | 326 ++++---- BCnEnc.Net/Shared/ImageQuality.cs | 8 +- BCnEnc.Net/Shared/ImageToBlocks.cs | 60 +- BCnEnc.Net/Shared/KtxFile.cs | 132 +-- BCnEnc.Net/Shared/LinearClustering.cs | 156 ++-- BCnEnc.Net/Shared/MipMapper.cs | 10 +- BCnEnc.Net/Shared/OutputFileFormat.cs | 4 +- BCnEnc.Net/Shared/PcaVectors.cs | 204 ++--- BCnEnc.Net/Shared/RawBlocks.cs | 14 +- BCnEnc.Net/Shared/RgbBoundingBox.cs | 116 +-- BCnEncTests/Bc7BlockTests.cs | 4 +- BCnEncTests/DdsReadTests.cs | 26 +- BCnEncTests/DdsWritingTests.cs | 64 +- BCnEncTests/DecodingTests.cs | 72 +- BCnEncTests/EncodingTest.cs | 68 +- BCnEncTests/RawTests.cs | 4 +- BCnEncTests/TestHelper.cs | 6 +- 54 files changed, 2478 insertions(+), 2437 deletions(-) delete mode 100644 BCnEnc.Net/Decoder/Bc7Decoder.cs diff --git a/BCnEnc.Net/Decoder/Bc7Decoder.cs b/BCnEnc.Net/Decoder/Bc7Decoder.cs deleted file mode 100644 index 11a72b6..0000000 --- a/BCnEnc.Net/Decoder/Bc7Decoder.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.IO; -using System.Runtime.InteropServices; -using BCnEncoder.Shared; - -namespace BCnEncoder.Decoder -{ - internal class Bc7Decoder : IBcBlockDecoder - { - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - var rawBlock = encodedBlocks[x + y * blockWidth]; - output[x, y] = rawBlock.Decode(); - } - } - - return output; - } - } -} diff --git a/BCnEnc.Net/Decoder/BcBlockDecoder.cs b/BCnEnc.Net/Decoder/BcBlockDecoder.cs index 5bfa778..37dea11 100644 --- a/BCnEnc.Net/Decoder/BcBlockDecoder.cs +++ b/BCnEnc.Net/Decoder/BcBlockDecoder.cs @@ -5,152 +5,103 @@ namespace BCnEncoder.Decoder { - internal interface IBcBlockDecoder { - RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, - out int blockHeight); - } - - internal class Bc1NoAlphaDecoder : IBcBlockDecoder { - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - output[x, y] = encodedBlocks[x + y * blockWidth].Decode(false); - } - } - - return output; - } - } - - internal class Bc1ADecoder : IBcBlockDecoder { - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - output[x, y] = encodedBlocks[x + y * blockWidth].Decode(true); - } - } - - return output; - } - } - - internal class Bc2Decoder : IBcBlockDecoder { - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - output[x, y] = encodedBlocks[x + y * blockWidth].Decode(); - } - } - - return output; - } - } - - internal class Bc3Decoder : IBcBlockDecoder { - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - output[x, y] = encodedBlocks[x + y * blockWidth].Decode(); - } - } - - return output; - } - } - - internal class Bc4Decoder : IBcBlockDecoder { - private readonly bool redAsLuminance; - public Bc4Decoder(bool redAsLuminance) { - this.redAsLuminance = redAsLuminance; - } - - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - output[x, y] = encodedBlocks[x + y * blockWidth].Decode(redAsLuminance); - } - } - - return output; - } - } - - internal class Bc5Decoder : IBcBlockDecoder { - - public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) { - blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); - blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); - - if (data.Length != (blockWidth * blockHeight * Marshal.SizeOf())) { - throw new InvalidDataException(); - } - - var encodedBlocks = MemoryMarshal.Cast(data); - - RawBlock4X4Rgba32[,] output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; - - for (int x = 0; x < blockWidth; x++) { - for (int y = 0; y < blockHeight; y++) { - output[x, y] = encodedBlocks[x + y * blockWidth].Decode(); - } - } - - return output; - } - } + internal interface IBcBlockDecoder + { + RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, + out int blockHeight); + } + + internal abstract class BaseBcBlockDecoder : IBcBlockDecoder + where T : struct + { + public RawBlock4X4Rgba32[,] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight, out int blockWidth, out int blockHeight) + { + blockWidth = (int)MathF.Ceiling(pixelWidth / 4.0f); + blockHeight = (int)MathF.Ceiling(pixelHeight / 4.0f); + + if (data.Length != blockWidth * blockHeight * Marshal.SizeOf()) + { + throw new InvalidDataException("Given data does not match expected length."); + } + + var encodedBlocks = MemoryMarshal.Cast(data); + + var output = new RawBlock4X4Rgba32[blockWidth, blockHeight]; + + for (var x = 0; x < blockWidth; x++) + { + for (var y = 0; y < blockHeight; y++) + { + output[x, y] = DecodeBlock(encodedBlocks[x + y * blockWidth]); + } + } + + return output; + } + + protected abstract RawBlock4X4Rgba32 DecodeBlock(T block); + } + + internal class Bc1NoAlphaDecoder : BaseBcBlockDecoder + { + protected override RawBlock4X4Rgba32 DecodeBlock(Bc1Block block) + { + return block.Decode(false); + } + } + + internal class Bc1ADecoder : BaseBcBlockDecoder + { + protected override RawBlock4X4Rgba32 DecodeBlock(Bc1Block block) + { + return block.Decode(true); + } + } + + internal class Bc2Decoder : BaseBcBlockDecoder + { + protected override RawBlock4X4Rgba32 DecodeBlock(Bc2Block block) + { + return block.Decode(); + } + } + + internal class Bc3Decoder : BaseBcBlockDecoder + { + protected override RawBlock4X4Rgba32 DecodeBlock(Bc3Block block) + { + return block.Decode(); + } + } + + internal class Bc4Decoder : BaseBcBlockDecoder + { + private readonly bool redAsLuminance; + + public Bc4Decoder(bool redAsLuminance) + { + this.redAsLuminance = redAsLuminance; + } + + protected override RawBlock4X4Rgba32 DecodeBlock(Bc4Block block) + { + return block.Decode(redAsLuminance); + } + } + + internal class Bc5Decoder : BaseBcBlockDecoder + { + protected override RawBlock4X4Rgba32 DecodeBlock(Bc5Block block) + { + return block.Decode(); + } + } + + internal class Bc7Decoder : BaseBcBlockDecoder + { + protected override RawBlock4X4Rgba32 DecodeBlock(Bc7Block block) + { + return block.Decode(); + } + } } diff --git a/BCnEnc.Net/Decoder/BcDecoder.cs b/BCnEnc.Net/Decoder/BcDecoder.cs index 0db77db..7698856 100644 --- a/BCnEnc.Net/Decoder/BcDecoder.cs +++ b/BCnEnc.Net/Decoder/BcDecoder.cs @@ -9,7 +9,7 @@ namespace BCnEncoder.Decoder { /// - /// Decodes compressed files into Rgba format. + /// Decodes compressed files into Rgba Format. /// public class BcDecoder { @@ -27,7 +27,7 @@ public class BcDecoder /// Decode raw encoded image data. /// /// The stream containing the encoded data. - /// The format the encoded data is in. + /// The Format the encoded data is in. /// The pixelWidth of the image. /// The pixelHeight of the image. /// The decoded Rgba32 image. @@ -43,7 +43,7 @@ public Image DecodeRaw(Stream inputStream, CompressionFormat format, int /// Decode raw encoded image data. /// /// The array containing the encoded data. - /// The format the encoded data is in. + /// The Format the encoded data is in. /// The pixelWidth of the image. /// The pixelHeight of the image. /// The decoded Rgba32 image. @@ -65,7 +65,9 @@ public Image DecodeRaw(byte[] input, CompressionFormat format, int pixel var image = new Image(pixelWidth, pixelHeight); var output = rawDecoder.Decode(input, pixelWidth, pixelHeight); if (!image.TryGetSinglePixelSpan(out var pixels)) + { throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); return image; @@ -194,9 +196,9 @@ private Image[] Decode(KtxFile file, bool allMipMaps) { var images = new Image[file.MipMaps.Count]; - if (IsSupportedRawFormat(file.Header.GlInternalFormat)) + if (IsSupportedRawFormat(file.header.GlInternalFormat)) { - var decoder = GetRawDecoder(file.Header.GlInternalFormat); + var decoder = GetRawDecoder(file.header.GlInternalFormat); var mipMaps = allMipMaps ? file.MipMaps.Count : 1; for (var mip = 0; mip < mipMaps; mip++) @@ -208,7 +210,9 @@ private Image[] Decode(KtxFile file, bool allMipMaps) var image = new Image((int)pixelWidth, (int)pixelHeight); var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); if (!image.TryGetSinglePixelSpan(out var pixels)) + { throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); images[mip] = image; @@ -216,9 +220,11 @@ private Image[] Decode(KtxFile file, bool allMipMaps) } else { - var decoder = GetDecoder(file.Header.GlInternalFormat); + var decoder = GetDecoder(file.header.GlInternalFormat); if (decoder == null) - throw new NotSupportedException($"This format is not supported: {file.Header.GlInternalFormat}"); + { + throw new NotSupportedException($"This Format is not supported: {file.header.GlInternalFormat}"); + } var mipMaps = allMipMaps ? file.MipMaps.Count : 1; for (var mip = 0; mip < mipMaps; mip++) @@ -244,13 +250,13 @@ private Image[] Decode(KtxFile file, bool allMipMaps) /// An array of decoded Rgba32 images. private Image[] Decode(DdsFile file, bool allMipMaps) { - var images = new Image[file.Header.dwMipMapCount]; + var images = new Image[file.header.dwMipMapCount]; - if (IsSupportedRawFormat(file.Header.ddsPixelFormat.DxgiFormat)) + if (IsSupportedRawFormat(file.header.ddsPixelFormat.DxgiFormat)) { - var decoder = GetRawDecoder(file.Header.ddsPixelFormat.DxgiFormat); + var decoder = GetRawDecoder(file.header.ddsPixelFormat.DxgiFormat); - var mipMaps = allMipMaps ? file.Header.dwMipMapCount : 1; + var mipMaps = allMipMaps ? file.header.dwMipMapCount : 1; for (var mip = 0; mip < mipMaps; mip++) { var data = file.Faces[0].MipMaps[mip].Data; @@ -260,7 +266,9 @@ private Image[] Decode(DdsFile file, bool allMipMaps) var image = new Image((int)pixelWidth, (int)pixelHeight); var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); if (!image.TryGetSinglePixelSpan(out var pixels)) + { throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); images[mip] = image; @@ -268,15 +276,17 @@ private Image[] Decode(DdsFile file, bool allMipMaps) } else { - var format = file.Header.ddsPixelFormat.IsDxt10Format ? - file.Dxt10Header.dxgiFormat : - file.Header.ddsPixelFormat.DxgiFormat; - var decoder = GetDecoder(format, file.Header); + var format = file.header.ddsPixelFormat.IsDxt10Format ? + file.dxt10Header.dxgiFormat : + file.header.ddsPixelFormat.DxgiFormat; + var decoder = GetDecoder(format, file.header); if (decoder == null) - throw new NotSupportedException($"This format is not supported: {format}"); + { + throw new NotSupportedException($"This Format is not supported: {format}"); + } - for (var mip = 0; mip < file.Header.dwMipMapCount; mip++) + for (var mip = 0; mip < file.header.dwMipMapCount; mip++) { var data = file.Faces[0].MipMaps[mip].Data; var pixelWidth = file.Faces[0].MipMaps[mip].Width; @@ -299,10 +309,10 @@ private bool IsSupportedRawFormat(GlInternalFormat format) { switch (format) { - case GlInternalFormat.GL_R8: - case GlInternalFormat.GL_RG8: - case GlInternalFormat.GL_RGB8: - case GlInternalFormat.GL_RGBA8: + case GlInternalFormat.GlR8: + case GlInternalFormat.GlRg8: + case GlInternalFormat.GlRgb8: + case GlInternalFormat.GlRgba8: return true; default: @@ -310,13 +320,13 @@ private bool IsSupportedRawFormat(GlInternalFormat format) } } - private bool IsSupportedRawFormat(DXGI_FORMAT format) + private bool IsSupportedRawFormat(DxgiFormat format) { switch (format) { - case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: + case DxgiFormat.DxgiFormatR8Unorm: + case DxgiFormat.DxgiFormatR8G8Unorm: + case DxgiFormat.DxgiFormatR8G8B8A8Unorm: return true; default: @@ -328,29 +338,29 @@ private IBcBlockDecoder GetDecoder(GlInternalFormat format) { switch (format) { - case GlInternalFormat.GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GlInternalFormat.GlCompressedRgbS3TcDxt1Ext: return new Bc1NoAlphaDecoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GlInternalFormat.GlCompressedRgbaS3TcDxt1Ext: return new Bc1ADecoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GlInternalFormat.GlCompressedRgbaS3TcDxt3Ext: return new Bc2Decoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GlInternalFormat.GlCompressedRgbaS3TcDxt5Ext: return new Bc3Decoder(); - case GlInternalFormat.GL_COMPRESSED_RED_RGTC1_EXT: - return new Bc4Decoder(OutputOptions.redAsLuminance); + case GlInternalFormat.GlCompressedRedRgtc1Ext: + return new Bc4Decoder(OutputOptions.RedAsLuminance); - case GlInternalFormat.GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GlInternalFormat.GlCompressedRedGreenRgtc2Ext: return new Bc5Decoder(); - case GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case GlInternalFormat.GlCompressedRgbaBptcUnormArb: return new Bc7Decoder(); // TODO: Not sure what to do with SRGB input. - case GlInternalFormat.GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + case GlInternalFormat.GlCompressedSrgbAlphaBptcUnormArb: return new Bc7Decoder(); default: @@ -358,44 +368,44 @@ private IBcBlockDecoder GetDecoder(GlInternalFormat format) } } - private IBcBlockDecoder GetDecoder(DXGI_FORMAT format, DdsHeader header) + private IBcBlockDecoder GetDecoder(DxgiFormat format, DdsHeader header) { switch (format) { - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS: - if ((header.ddsPixelFormat.dwFlags & PixelFormatFlags.DDPF_ALPHAPIXELS) != 0) + case DxgiFormat.DxgiFormatBc1Unorm: + case DxgiFormat.DxgiFormatBc1UnormSrgb: + case DxgiFormat.DxgiFormatBc1Typeless: + if ((header.ddsPixelFormat.dwFlags & PixelFormatFlags.DdpfAlphapixels) != 0) return new Bc1ADecoder(); - if (InputOptions.ddsBc1ExpectAlpha) + if (InputOptions.DdsBc1ExpectAlpha) return new Bc1ADecoder(); return new Bc1NoAlphaDecoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS: + case DxgiFormat.DxgiFormatBc2Unorm: + case DxgiFormat.DxgiFormatBc2UnormSrgb: + case DxgiFormat.DxgiFormatBc2Typeless: return new Bc2Decoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS: + case DxgiFormat.DxgiFormatBc3Unorm: + case DxgiFormat.DxgiFormatBc3UnormSrgb: + case DxgiFormat.DxgiFormatBc3Typeless: return new Bc3Decoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS: - return new Bc4Decoder(OutputOptions.redAsLuminance); + case DxgiFormat.DxgiFormatBc4Unorm: + case DxgiFormat.DxgiFormatBc4Snorm: + case DxgiFormat.DxgiFormatBc4Typeless: + return new Bc4Decoder(OutputOptions.RedAsLuminance); - case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS: + case DxgiFormat.DxgiFormatBc5Unorm: + case DxgiFormat.DxgiFormatBc5Snorm: + case DxgiFormat.DxgiFormatBc5Typeless: return new Bc5Decoder(); - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS: + case DxgiFormat.DxgiFormatBc7Unorm: + case DxgiFormat.DxgiFormatBc7UnormSrgb: + case DxgiFormat.DxgiFormatBc7Typeless: return new Bc7Decoder(); default: @@ -407,35 +417,35 @@ private IRawDecoder GetRawDecoder(GlInternalFormat format) { switch (format) { - case GlInternalFormat.GL_R8: - return new RawRDecoder(OutputOptions.redAsLuminance); + case GlInternalFormat.GlR8: + return new RawRDecoder(OutputOptions.RedAsLuminance); - case GlInternalFormat.GL_RG8: - return new RawRGDecoder(); + case GlInternalFormat.GlRg8: + return new RawRgDecoder(); - case GlInternalFormat.GL_RGB8: - return new RawRGBDecoder(); + case GlInternalFormat.GlRgb8: + return new RawRgbDecoder(); - case GlInternalFormat.GL_RGBA8: - return new RawRGBADecoder(); + case GlInternalFormat.GlRgba8: + return new RawRgbaDecoder(); default: return null; } } - private IRawDecoder GetRawDecoder(DXGI_FORMAT format) + private IRawDecoder GetRawDecoder(DxgiFormat format) { switch (format) { - case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: - return new RawRDecoder(OutputOptions.redAsLuminance); + case DxgiFormat.DxgiFormatR8Unorm: + return new RawRDecoder(OutputOptions.RedAsLuminance); - case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: - return new RawRGDecoder(); + case DxgiFormat.DxgiFormatR8G8Unorm: + return new RawRgDecoder(); - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: - return new RawRGBADecoder(); + case DxgiFormat.DxgiFormatR8G8B8A8Unorm: + return new RawRgbaDecoder(); default: return null; @@ -446,25 +456,25 @@ private IBcBlockDecoder GetDecoder(CompressionFormat format) { switch (format) { - case CompressionFormat.BC1: + case CompressionFormat.Bc1: return new Bc1NoAlphaDecoder(); - case CompressionFormat.BC1WithAlpha: + case CompressionFormat.Bc1WithAlpha: return new Bc1ADecoder(); - case CompressionFormat.BC2: + case CompressionFormat.Bc2: return new Bc2Decoder(); - case CompressionFormat.BC3: + case CompressionFormat.Bc3: return new Bc3Decoder(); - case CompressionFormat.BC4: - return new Bc4Decoder(OutputOptions.redAsLuminance); + case CompressionFormat.Bc4: + return new Bc4Decoder(OutputOptions.RedAsLuminance); - case CompressionFormat.BC5: + case CompressionFormat.Bc5: return new Bc5Decoder(); - case CompressionFormat.BC7: + case CompressionFormat.Bc7: return new Bc7Decoder(); default: @@ -477,16 +487,16 @@ private IRawDecoder GetRawDecoder(CompressionFormat format) switch (format) { case CompressionFormat.R: - return new RawRDecoder(OutputOptions.redAsLuminance); + return new RawRDecoder(OutputOptions.RedAsLuminance); - case CompressionFormat.RG: - return new RawRGDecoder(); + case CompressionFormat.Rg: + return new RawRgDecoder(); - case CompressionFormat.RGB: - return new RawRGBDecoder(); + case CompressionFormat.Rgb: + return new RawRgbDecoder(); - case CompressionFormat.RGBA: - return new RawRGBADecoder(); + case CompressionFormat.Rgba: + return new RawRgbaDecoder(); default: throw new ArgumentOutOfRangeException(nameof(format), format, null); diff --git a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs index 9529ab4..ed2e650 100644 --- a/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs +++ b/BCnEnc.Net/Decoder/Options/DecoderInputOptions.cs @@ -1,13 +1,16 @@ namespace BCnEncoder.Decoder.Options { + /// + /// A class for the decoder input options. + /// public class DecoderInputOptions { /// - /// The DDS file format doesn't seem to have a standard for indicating whether a BC1 texture + /// The DDS file Format doesn't seem to have a standard for indicating whether a BC1 texture /// includes 1bit of alpha. This option will assume that all Bc1 textures contain alpha. /// If this option is false, but the dds header includes a DDPF_ALPHAPIXELS flag, alpha will be included. /// Default is true. /// - public bool ddsBc1ExpectAlpha = true; + public bool DdsBc1ExpectAlpha { get; set; } = true; } } diff --git a/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs b/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs index c1374f8..6cb2526 100644 --- a/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs +++ b/BCnEnc.Net/Decoder/Options/DecoderOutputOptions.cs @@ -1,13 +1,14 @@ -using BCnEncoder.Shared; - -namespace BCnEncoder.Decoder.Options +namespace BCnEncoder.Decoder.Options { + /// + /// A class for the decoder output options. + /// public class DecoderOutputOptions { /// - /// If true, when decoding from a format that only includes a red channel, + /// If true, when decoding from a Format that only includes a red channel, /// output pixels will have all colors set to the same value (greyscale). Default is true. /// - public bool redAsLuminance = true; + public bool RedAsLuminance { get; set; } = true; } } diff --git a/BCnEnc.Net/Decoder/RawDecoder.cs b/BCnEnc.Net/Decoder/RawDecoder.cs index 75f77fe..64332e3 100644 --- a/BCnEnc.Net/Decoder/RawDecoder.cs +++ b/BCnEnc.Net/Decoder/RawDecoder.cs @@ -1,76 +1,139 @@ -using System; -using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.PixelFormats; +using System; namespace BCnEncoder.Decoder { - internal interface IRawDecoder { - Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight); - } + internal interface IRawDecoder + { + Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight); + } - public class RawRDecoder : IRawDecoder { - private readonly bool redAsLuminance; - public RawRDecoder(bool redAsLuminance) { - this.redAsLuminance = redAsLuminance; - } + /// + /// A class to decode data to R components. + /// + public class RawRDecoder : IRawDecoder + { + private readonly bool redAsLuminance; - public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) { - Rgba32[] output = new Rgba32[pixelWidth * pixelHeight]; - for (int i = 0; i < output.Length; i++) { - if (redAsLuminance) { - output[i].R = data[i]; - output[i].G = data[i]; - output[i].B = data[i]; - } - else { - output[i].R = data[i]; - output[i].G = 0; - output[i].B = 0; - } - output[i].A = 255; - } - return output; - } - } + /// + /// Create a new instance of . + /// + /// If the decoded component should be used as the red component or luminence. + public RawRDecoder(bool redAsLuminance) + { + this.redAsLuminance = redAsLuminance; + } - public class RawRGDecoder : IRawDecoder - { - public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) { - Rgba32[] output = new Rgba32[pixelWidth * pixelHeight]; - for (int i = 0; i < output.Length; i++) { - output[i].R = data[i * 2]; - output[i].G = data[i * 2 + 1]; - output[i].B = 0; - output[i].A = 255; - } - return output; - } - } + /// + /// Decode the data to color components. + /// + /// The data to decode. + /// The width of the image in pixels. + /// The height of the image in pixels. + /// The decoded color components. + public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) + { + var output = new Rgba32[pixelWidth * pixelHeight]; + for (var i = 0; i < output.Length; i++) + { + if (redAsLuminance) + { + output[i].R = data[i]; + output[i].G = data[i]; + output[i].B = data[i]; + } + else + { + output[i].R = data[i]; + output[i].G = 0; + output[i].B = 0; + } - public class RawRGBDecoder : IRawDecoder - { - public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) { - Rgba32[] output = new Rgba32[pixelWidth * pixelHeight]; - for (int i = 0; i < output.Length; i++) { - output[i].R = data[i * 3]; - output[i].G = data[i * 3 + 1]; - output[i].B = data[i * 3 + 2]; - output[i].A = 255; - } - return output; - } - } + output[i].A = 255; + } - public class RawRGBADecoder : IRawDecoder - { - public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) { - Rgba32[] output = new Rgba32[pixelWidth * pixelHeight]; - for (int i = 0; i < output.Length; i++) { - output[i].R = data[i * 4]; - output[i].G = data[i * 4 + 1]; - output[i].B = data[i * 4 + 2]; - output[i].A = data[i * 4 + 3]; - } - return output; - } - } + return output; + } + } + + /// + /// A class to decode data to RG components. + /// + public class RawRgDecoder : IRawDecoder + { + /// + /// Decode the data to color components. + /// + /// The data to decode. + /// The width of the image in pixels. + /// The height of the image in pixels. + /// The decoded color components. + public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) + { + var output = new Rgba32[pixelWidth * pixelHeight]; + for (var i = 0; i < output.Length; i++) + { + output[i].R = data[i * 2]; + output[i].G = data[i * 2 + 1]; + output[i].B = 0; + output[i].A = 255; + } + + return output; + } + } + + /// + /// A class to decode data to RGB components. + /// + public class RawRgbDecoder : IRawDecoder + { + /// + /// Decode the data to color components. + /// + /// The data to decode. + /// The width of the image in pixels. + /// The height of the image in pixels. + /// The decoded color components. + public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) + { + var output = new Rgba32[pixelWidth * pixelHeight]; + for (var i = 0; i < output.Length; i++) + { + output[i].R = data[i * 3]; + output[i].G = data[i * 3 + 1]; + output[i].B = data[i * 3 + 2]; + output[i].A = 255; + } + + return output; + } + } + + /// + /// A class to decode data to RGBA components. + /// + public class RawRgbaDecoder : IRawDecoder + { + /// + /// Decode the data to color components. + /// + /// The data to decode. + /// The width of the image in pixels. + /// The height of the image in pixels. + /// The decoded color components. + public Rgba32[] Decode(ReadOnlySpan data, int pixelWidth, int pixelHeight) + { + var output = new Rgba32[pixelWidth * pixelHeight]; + for (var i = 0; i < output.Length; i++) + { + output[i].R = data[i * 4]; + output[i].G = data[i * 4 + 1]; + output[i].B = data[i * 4 + 2]; + output[i].A = data[i * 4 + 3]; + } + + return output; + } + } } diff --git a/BCnEnc.Net/Encoder/Bc1BlockEncoder.cs b/BCnEnc.Net/Encoder/Bc1BlockEncoder.cs index 0a0c95d..d53f86d 100644 --- a/BCnEnc.Net/Encoder/Bc1BlockEncoder.cs +++ b/BCnEnc.Net/Encoder/Bc1BlockEncoder.cs @@ -10,20 +10,20 @@ internal class Bc1BlockEncoder : IBcBlockEncoder public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } @@ -50,24 +50,24 @@ private Bc1Block EncodeBlock(RawBlock4X4Rgba32 block, CompressionQuality quality public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + return GlInternalFormat.GlCompressedRgbS3TcDxt1Ext; } - public GLFormat GetBaseInternalFormat() + public GlFormat GetBaseInternalFormat() { - return GLFormat.GL_RGB; + return GlFormat.GlRgb; } - public DXGI_FORMAT GetDxgiFormat() + public DxgiFormat GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; + return DxgiFormat.DxgiFormatBc1Unorm; } #region Encoding private stuff private static Bc1Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0, ColorRgb565 color1, out float error, float rWeight = 0.3f, float gWeight = 0.6f, float bWeight = 0.1f) { - Bc1Block output = new Bc1Block(); + var output = new Bc1Block(); var pixels = rawBlock.AsSpan; @@ -91,7 +91,7 @@ private static Bc1Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 }; error = 0; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var color = pixels[i]; output[i] = ColorChooser.ChooseClosestColor4(colors, color, rWeight, gWeight, bWeight, out var e); @@ -111,14 +111,14 @@ private static class Bc1BlockEncoderFast internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { - Bc1Block output = new Bc1Block(); + var output = new Bc1Block(); var pixels = rawBlock.AsSpan; RgbBoundingBox.Create565(pixels, out var min, out var max); - ColorRgb565 c0 = max; - ColorRgb565 c1 = min; + var c0 = max; + var c1 = min; output = TryColors(rawBlock, c0, c1, out var error); @@ -127,14 +127,14 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) } private static class Bc1BlockEncoderBalanced { - private const int maxTries = 24 * 2; - private const float errorThreshold = 0.05f; + private const int MaxTries_ = 24 * 2; + private const float ErrorThreshold_ = 0.05f; internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; @@ -147,9 +147,9 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - Bc1Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); if (newC0.data < newC1.data) @@ -169,7 +169,7 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = newC1; } - if (bestError < errorThreshold) { + if (bestError < ErrorThreshold_) { break; } } @@ -180,14 +180,14 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc1BlockEncoderSlow { - private const int maxTries = 9999; - private const float errorThreshold = 0.01f; + private const int MaxTries_ = 9999; + private const float ErrorThreshold_ = 0.01f; internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; @@ -200,11 +200,11 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - Bc1Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - int lastChanged = 0; + var lastChanged = 0; - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); if (newC0.data < newC1.data) @@ -227,7 +227,7 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) lastChanged = 0; } - if (bestError < errorThreshold || lastChanged > ColorVariationGenerator.VarPatternCount) { + if (bestError < ErrorThreshold_ || lastChanged > ColorVariationGenerator.VarPatternCount) { break; } } @@ -244,20 +244,20 @@ internal class Bc1AlphaBlockEncoder : IBcBlockEncoder public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } @@ -284,22 +284,22 @@ private Bc1Block EncodeBlock(RawBlock4X4Rgba32 block, CompressionQuality quality public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + return GlInternalFormat.GlCompressedRgbaS3TcDxt1Ext; } - public GLFormat GetBaseInternalFormat() + public GlFormat GetBaseInternalFormat() { - return GLFormat.GL_RGBA; + return GlFormat.GlRgba; } - public DXGI_FORMAT GetDxgiFormat() + public DxgiFormat GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; + return DxgiFormat.DxgiFormatBc1Unorm; } private static Bc1Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0, ColorRgb565 color1, out float error, float rWeight = 0.3f, float gWeight = 0.6f, float bWeight = 0.1f) { - Bc1Block output = new Bc1Block(); + var output = new Bc1Block(); var pixels = rawBlock.AsSpan; @@ -309,7 +309,7 @@ private static Bc1Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 var c0 = color0.ToColorRgb24(); var c1 = color1.ToColorRgb24(); - bool hasAlpha = output.HasAlphaOrBlack; + var hasAlpha = output.HasAlphaOrBlack; ReadOnlySpan colors = hasAlpha ? stackalloc ColorRgb24[] { @@ -325,7 +325,7 @@ private static Bc1Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 }; error = 0; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var color = pixels[i]; output[i] = ColorChooser.ChooseClosestColor4AlphaCutoff(colors, color, rWeight, gWeight, bWeight, @@ -344,16 +344,16 @@ private static class Bc1AlphaBlockEncoderFast internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { - Bc1Block output = new Bc1Block(); + var output = new Bc1Block(); var pixels = rawBlock.AsSpan; - bool hasAlpha = rawBlock.HasTransparentPixels(); + var hasAlpha = rawBlock.HasTransparentPixels(); RgbBoundingBox.Create565AlphaCutoff(pixels, out var min, out var max); - ColorRgb565 c0 = max; - ColorRgb565 c1 = min; + var c0 = max; + var c1 = min; if (hasAlpha && c0.data > c1.data) { @@ -370,17 +370,17 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc1AlphaBlockEncoderBalanced { - private const int maxTries = 24 * 2; - private const float errorThreshold = 0.05f; + private const int MaxTries_ = 24 * 2; + private const float ErrorThreshold_ = 0.05f; internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - bool hasAlpha = rawBlock.HasTransparentPixels(); + var hasAlpha = rawBlock.HasTransparentPixels(); - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; @@ -397,9 +397,9 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - Bc1Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); if (!hasAlpha && newC0.data < newC1.data) @@ -423,7 +423,7 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = newC1; } - if (bestError < errorThreshold) { + if (bestError < ErrorThreshold_) { break; } } @@ -434,16 +434,16 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc1AlphaBlockEncoderSlow { - private const int maxTries = 9999; - private const float errorThreshold = 0.05f; + private const int MaxTries_ = 9999; + private const float ErrorThreshold_ = 0.05f; internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - bool hasAlpha = rawBlock.HasTransparentPixels(); + var hasAlpha = rawBlock.HasTransparentPixels(); - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; @@ -460,10 +460,10 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - Bc1Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - int lastChanged = 0; - for (int i = 0; i < maxTries; i++) { + var lastChanged = 0; + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); if (!hasAlpha && newC0.data < newC1.data) @@ -490,7 +490,7 @@ internal static Bc1Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) lastChanged = 0; } - if (bestError < errorThreshold || lastChanged > ColorVariationGenerator.VarPatternCount) { + if (bestError < ErrorThreshold_ || lastChanged > ColorVariationGenerator.VarPatternCount) { break; } } diff --git a/BCnEnc.Net/Encoder/Bc2BlockEncoder.cs b/BCnEnc.Net/Encoder/Bc2BlockEncoder.cs index 2820452..5b15c90 100644 --- a/BCnEnc.Net/Encoder/Bc2BlockEncoder.cs +++ b/BCnEnc.Net/Encoder/Bc2BlockEncoder.cs @@ -10,20 +10,20 @@ internal class Bc2BlockEncoder : IBcBlockEncoder public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } @@ -50,23 +50,23 @@ private Bc2Block EncodeBlock(RawBlock4X4Rgba32 block, CompressionQuality quality public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + return GlInternalFormat.GlCompressedRgbaS3TcDxt3Ext; } - public GLFormat GetBaseInternalFormat() + public GlFormat GetBaseInternalFormat() { - return GLFormat.GL_RGBA; + return GlFormat.GlRgba; } - public DXGI_FORMAT GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; + public DxgiFormat GetDxgiFormat() { + return DxgiFormat.DxgiFormatBc2Unorm; } #region Encoding private stuff private static Bc2Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0, ColorRgb565 color1, out float error, float rWeight = 0.3f, float gWeight = 0.6f, float bWeight = 0.1f) { - Bc2Block output = new Bc2Block(); + var output = new Bc2Block(); var pixels = rawBlock.AsSpan; @@ -84,7 +84,7 @@ private static Bc2Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 }; error = 0; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var color = pixels[i]; output.SetAlpha(i, color.A); @@ -110,8 +110,8 @@ internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) PcaVectors.Create(pixels, out var mean, out var principalAxis); PcaVectors.GetMinMaxColor565(pixels, mean, principalAxis, out var min, out var max); - ColorRgb565 c0 = max; - ColorRgb565 c1 = min; + var c0 = max; + var c1 = min; var output = TryColors(rawBlock, c0, c1, out var _); @@ -120,22 +120,22 @@ internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) } private static class Bc2BlockEncoderBalanced { - private const int maxTries = 24 * 2; - private const float errorThreshold = 0.05f; + private const int MaxTries_ = 24 * 2; + private const float ErrorThreshold_ = 0.05f; internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; var c1 = min; - Bc2Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); var block = TryColors(rawBlock, newC0, newC1, out var error); @@ -148,7 +148,7 @@ internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = newC1; } - if (bestError < errorThreshold) { + if (bestError < ErrorThreshold_) { break; } } @@ -159,15 +159,15 @@ internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc2BlockEncoderSlow { - private const int maxTries = 9999; - private const float errorThreshold = 0.01f; + private const int MaxTries_ = 9999; + private const float ErrorThreshold_ = 0.01f; internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; @@ -180,11 +180,11 @@ internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - Bc2Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - int lastChanged = 0; + var lastChanged = 0; - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); if (newC0.data < newC1.data) @@ -207,7 +207,7 @@ internal static Bc2Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) lastChanged = 0; } - if (bestError < errorThreshold || lastChanged > ColorVariationGenerator.VarPatternCount) { + if (bestError < ErrorThreshold_ || lastChanged > ColorVariationGenerator.VarPatternCount) { break; } } diff --git a/BCnEnc.Net/Encoder/Bc3BlockEncoder.cs b/BCnEnc.Net/Encoder/Bc3BlockEncoder.cs index 5957da8..04b854f 100644 --- a/BCnEnc.Net/Encoder/Bc3BlockEncoder.cs +++ b/BCnEnc.Net/Encoder/Bc3BlockEncoder.cs @@ -11,20 +11,20 @@ internal class Bc3BlockEncoder : IBcBlockEncoder public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } @@ -51,23 +51,23 @@ private Bc3Block EncodeBlock(RawBlock4X4Rgba32 block, CompressionQuality quality public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + return GlInternalFormat.GlCompressedRgbaS3TcDxt5Ext; } - public GLFormat GetBaseInternalFormat() + public GlFormat GetBaseInternalFormat() { - return GLFormat.GL_RGBA; + return GlFormat.GlRgba; } - public DXGI_FORMAT GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; + public DxgiFormat GetDxgiFormat() { + return DxgiFormat.DxgiFormatBc3Unorm; } #region Encoding private stuff private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0, ColorRgb565 color1, out float error, float rWeight = 0.3f, float gWeight = 0.6f, float bWeight = 0.1f) { - Bc3Block output = new Bc3Block(); + var output = new Bc3Block(); var pixels = rawBlock.AsSpan; @@ -85,7 +85,7 @@ private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 }; error = 0; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var color = pixels[i]; output[i] = ColorChooser.ChooseClosestColor4(colors, color, rWeight, gWeight, bWeight, out var e); @@ -101,8 +101,8 @@ private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 //Find min and max alpha byte minAlpha = 255; byte maxAlpha = 0; - bool hasExtremeValues = false; - for (int i = 0; i < pixels.Length; i++) { + var hasExtremeValues = false; + for (var i = 0; i < pixels.Length; i++) { if (pixels[i].A < 255 && pixels[i].A > 0) { if (pixels[i].A < minAlpha) minAlpha = pixels[i].A; if (pixels[i].A > maxAlpha) maxAlpha = pixels[i].A; @@ -114,10 +114,10 @@ private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 int SelectAlphaIndices(ref Bc3Block block) { - int cumulativeError = 0; + var cumulativeError = 0; var a0 = block.Alpha0; var a1 = block.Alpha1; - Span alphas = a0 > a1 ? stackalloc byte[] { + var alphas = a0 > a1 ? stackalloc byte[] { a0, a1, (byte) (6/7.0 * a0 + 1/7.0 * a1), @@ -137,11 +137,11 @@ private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 255 }; var pixels = rawBlock.AsSpan; - for (int i = 0; i < pixels.Length; i++) { + for (var i = 0; i < pixels.Length; i++) { byte bestIndex = 0; - int bestError = Math.Abs(pixels[i].A - alphas[0]); + var bestError = Math.Abs(pixels[i].A - alphas[0]); for (byte j = 1; j < alphas.Length; j++) { - int error = Math.Abs(pixels[i].A - alphas[j]); + var error = Math.Abs(pixels[i].A - alphas[j]); if (error < bestError) { bestIndex = j; bestError = error; @@ -167,78 +167,78 @@ private static Bc3Block TryColors(RawBlock4X4Rgba32 rawBlock, ColorRgb565 color0 var best = colorBlock; best.Alpha0 = maxAlpha; best.Alpha1 = minAlpha; - int bestError = SelectAlphaIndices(ref best); + var bestError = SelectAlphaIndices(ref best); if (bestError == 0) { return best; } for (byte i = 1; i < variations; i++) { { - byte a0 = ByteHelper.ClampToByte(maxAlpha - i * 2); - byte a1 = ByteHelper.ClampToByte(minAlpha + i * 2); + var a0 = ByteHelper.ClampToByte(maxAlpha - i * 2); + var a1 = ByteHelper.ClampToByte(minAlpha + i * 2); var block = colorBlock; block.Alpha0 = hasExtremeValues ? a1 : a0; block.Alpha1 = hasExtremeValues ? a0 : a1; - int error = SelectAlphaIndices(ref block); + var error = SelectAlphaIndices(ref block); if (error < bestError) { best = block; bestError = error; } } { - byte a0 = ByteHelper.ClampToByte(maxAlpha + i * 2); - byte a1 = ByteHelper.ClampToByte(minAlpha - i * 2); + var a0 = ByteHelper.ClampToByte(maxAlpha + i * 2); + var a1 = ByteHelper.ClampToByte(minAlpha - i * 2); var block = colorBlock; block.Alpha0 = hasExtremeValues ? a1 : a0; block.Alpha1 = hasExtremeValues ? a0 : a1; - int error = SelectAlphaIndices(ref block); + var error = SelectAlphaIndices(ref block); if (error < bestError) { best = block; bestError = error; } } { - byte a0 = ByteHelper.ClampToByte(maxAlpha); - byte a1 = ByteHelper.ClampToByte(minAlpha - i * 2); + var a0 = ByteHelper.ClampToByte(maxAlpha); + var a1 = ByteHelper.ClampToByte(minAlpha - i * 2); var block = colorBlock; block.Alpha0 = hasExtremeValues ? a1 : a0; block.Alpha1 = hasExtremeValues ? a0 : a1; - int error = SelectAlphaIndices(ref block); + var error = SelectAlphaIndices(ref block); if (error < bestError) { best = block; bestError = error; } } { - byte a0 = ByteHelper.ClampToByte(maxAlpha + i * 2); - byte a1 = ByteHelper.ClampToByte(minAlpha); + var a0 = ByteHelper.ClampToByte(maxAlpha + i * 2); + var a1 = ByteHelper.ClampToByte(minAlpha); var block = colorBlock; block.Alpha0 = hasExtremeValues ? a1 : a0; block.Alpha1 = hasExtremeValues ? a0 : a1; - int error = SelectAlphaIndices(ref block); + var error = SelectAlphaIndices(ref block); if (error < bestError) { best = block; bestError = error; } } { - byte a0 = ByteHelper.ClampToByte(maxAlpha); - byte a1 = ByteHelper.ClampToByte(minAlpha + i * 2); + var a0 = ByteHelper.ClampToByte(maxAlpha); + var a1 = ByteHelper.ClampToByte(minAlpha + i * 2); var block = colorBlock; block.Alpha0 = hasExtremeValues ? a1 : a0; block.Alpha1 = hasExtremeValues ? a0 : a1; - int error = SelectAlphaIndices(ref block); + var error = SelectAlphaIndices(ref block); if (error < bestError) { best = block; bestError = error; } } { - byte a0 = ByteHelper.ClampToByte(maxAlpha - i * 2); - byte a1 = ByteHelper.ClampToByte(minAlpha); + var a0 = ByteHelper.ClampToByte(maxAlpha - i * 2); + var a1 = ByteHelper.ClampToByte(minAlpha); var block = colorBlock; block.Alpha0 = hasExtremeValues ? a1 : a0; block.Alpha1 = hasExtremeValues ? a0 : a1; - int error = SelectAlphaIndices(ref block); + var error = SelectAlphaIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -268,8 +268,8 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) PcaVectors.Create(pixels, out var mean, out var principalAxis); PcaVectors.GetMinMaxColor565(pixels, mean, principalAxis, out var min, out var max); - ColorRgb565 c0 = max; - ColorRgb565 c1 = min; + var c0 = max; + var c1 = min; if (c0.data <= c1.data) { @@ -278,7 +278,7 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - var output = TryColors(rawBlock, c0, c1, out float _); + var output = TryColors(rawBlock, c0, c1, out var _); output = FindAlphaValues(output, rawBlock, 3); return output; @@ -286,22 +286,22 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) } private static class Bc3BlockEncoderBalanced { - private const int maxTries = 24 * 2; - private const float errorThreshold = 0.05f; + private const int MaxTries_ = 24 * 2; + private const float ErrorThreshold_ = 0.05f; internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; var c1 = min; - Bc3Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); var block = TryColors(rawBlock, newC0, newC1, out var error); @@ -314,7 +314,7 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = newC1; } - if (bestError < errorThreshold) { + if (bestError < ErrorThreshold_) { break; } } @@ -325,15 +325,15 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc3BlockEncoderSlow { - private const int maxTries = 9999; - private const float errorThreshold = 0.01f; + private const int MaxTries_ = 9999; + private const float ErrorThreshold_ = 0.01f; internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { var pixels = rawBlock.AsSpan; - PcaVectors.Create(pixels, out System.Numerics.Vector3 mean, out System.Numerics.Vector3 pa); + PcaVectors.Create(pixels, out var mean, out var pa); PcaVectors.GetMinMaxColor565(pixels, mean, pa, out var min, out var max); var c0 = max; @@ -346,11 +346,11 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) c1 = c; } - Bc3Block best = TryColors(rawBlock, c0, c1, out float bestError); + var best = TryColors(rawBlock, c0, c1, out var bestError); - int lastChanged = 0; + var lastChanged = 0; - for (int i = 0; i < maxTries; i++) { + for (var i = 0; i < MaxTries_; i++) { var (newC0, newC1) = ColorVariationGenerator.Variate565(c0, c1, i); if (newC0.data < newC1.data) @@ -373,7 +373,7 @@ internal static Bc3Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) lastChanged = 0; } - if (bestError < errorThreshold || lastChanged > ColorVariationGenerator.VarPatternCount) { + if (bestError < ErrorThreshold_ || lastChanged > ColorVariationGenerator.VarPatternCount) { break; } } diff --git a/BCnEnc.Net/Encoder/Bc4BlockEncoder.cs b/BCnEnc.Net/Encoder/Bc4BlockEncoder.cs index 456907d..632238f 100644 --- a/BCnEnc.Net/Encoder/Bc4BlockEncoder.cs +++ b/BCnEnc.Net/Encoder/Bc4BlockEncoder.cs @@ -15,17 +15,17 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) { + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } } @@ -34,10 +34,10 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } private Bc4Block EncodeBlock(RawBlock4X4Rgba32 block, CompressionQuality quality) { - Bc4Block output = new Bc4Block(); - byte[] colors = new byte[16]; + var output = new Bc4Block(); + var colors = new byte[16]; var pixels = block.AsSpan; - for (int i = 0; i < 16; i++) { + for (var i = 0; i < 16; i++) { if (luminanceAsRed) { colors[i] = (byte)(new ColorYCbCr(pixels[i]).y * 255); } @@ -59,15 +59,15 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RED_RGTC1_EXT; + return GlInternalFormat.GlCompressedRedRgtc1Ext; } - public GLFormat GetBaseInternalFormat() { - return GLFormat.GL_RED; + public GlFormat GetBaseInternalFormat() { + return GlFormat.GlRed; } - public DXGI_FORMAT GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM; + public DxgiFormat GetDxgiFormat() { + return DxgiFormat.DxgiFormatBc4Unorm; } #region Encoding private stuff @@ -77,8 +77,8 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { //Find min and max alpha byte min = 255; byte max = 0; - bool hasExtremeValues = false; - for (int i = 0; i < pixels.Length; i++) { + var hasExtremeValues = false; + for (var i = 0; i < pixels.Length; i++) { if (pixels[i] < 255 && pixels[i] > 0) { if (pixels[i] < min) min = pixels[i]; if (pixels[i] > max) max = pixels[i]; @@ -90,10 +90,10 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { int SelectIndices(ref Bc4Block block) { - int cumulativeError = 0; + var cumulativeError = 0; var c0 = block.Red0; var c1 = block.Red1; - Span colors = c0 > c1 + var colors = c0 > c1 ? stackalloc byte[] { c0, c1, @@ -114,11 +114,11 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { 0, 255 }; - for (int i = 0; i < pixels.Length; i++) { + for (var i = 0; i < pixels.Length; i++) { byte bestIndex = 0; - int bestError = Math.Abs(pixels[i] - colors[0]); + var bestError = Math.Abs(pixels[i] - colors[0]); for (byte j = 1; j < colors.Length; j++) { - int error = Math.Abs(pixels[i] - colors[j]); + var error = Math.Abs(pixels[i] - colors[j]); if (error < bestError) { bestIndex = j; bestError = error; @@ -146,19 +146,19 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { var best = colorBlock; best.Red0 = max; best.Red1 = min; - int bestError = SelectIndices(ref best); + var bestError = SelectIndices(ref best); if (bestError == 0) { return best; } - for (byte i = (byte)variations; i > 0; i--) { + for (var i = (byte)variations; i > 0; i--) { { - byte c0 = ByteHelper.ClampToByte(max - i); - byte c1 = ByteHelper.ClampToByte(min + i); + var c0 = ByteHelper.ClampToByte(max - i); + var c1 = ByteHelper.ClampToByte(min + i); var block = colorBlock; block.Red0 = hasExtremeValues ? c1 : c0; block.Red1 = hasExtremeValues ? c0 : c1; - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -167,12 +167,12 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } } { - byte c0 = ByteHelper.ClampToByte(max + i); - byte c1 = ByteHelper.ClampToByte(min - i); + var c0 = ByteHelper.ClampToByte(max + i); + var c1 = ByteHelper.ClampToByte(min - i); var block = colorBlock; block.Red0 = hasExtremeValues ? c1 : c0; block.Red1 = hasExtremeValues ? c0 : c1; - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -181,12 +181,12 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } } { - byte c0 = ByteHelper.ClampToByte(max); - byte c1 = ByteHelper.ClampToByte(min - i); + var c0 = ByteHelper.ClampToByte(max); + var c1 = ByteHelper.ClampToByte(min - i); var block = colorBlock; block.Red0 = hasExtremeValues ? c1 : c0; block.Red1 = hasExtremeValues ? c0 : c1; - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -195,12 +195,12 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } } { - byte c0 = ByteHelper.ClampToByte(max + i); - byte c1 = ByteHelper.ClampToByte(min); + var c0 = ByteHelper.ClampToByte(max + i); + var c1 = ByteHelper.ClampToByte(min); var block = colorBlock; block.Red0 = hasExtremeValues ? c1 : c0; block.Red1 = hasExtremeValues ? c0 : c1; - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -209,12 +209,12 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } } { - byte c0 = ByteHelper.ClampToByte(max); - byte c1 = ByteHelper.ClampToByte(min + i); + var c0 = ByteHelper.ClampToByte(max); + var c1 = ByteHelper.ClampToByte(min + i); var block = colorBlock; block.Red0 = hasExtremeValues ? c1 : c0; block.Red1 = hasExtremeValues ? c0 : c1; - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -223,12 +223,12 @@ internal class Bc4BlockEncoder : IBcBlockEncoder { } } { - byte c0 = ByteHelper.ClampToByte(max - i); - byte c1 = ByteHelper.ClampToByte(min); + var c0 = ByteHelper.ClampToByte(max - i); + var c1 = ByteHelper.ClampToByte(min); var block = colorBlock; block.Red0 = hasExtremeValues ? c1 : c0; block.Red1 = hasExtremeValues ? c0 : c1; - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; diff --git a/BCnEnc.Net/Encoder/Bc5BlockEncoder.cs b/BCnEnc.Net/Encoder/Bc5BlockEncoder.cs index de1c28a..2f86bae 100644 --- a/BCnEnc.Net/Encoder/Bc5BlockEncoder.cs +++ b/BCnEnc.Net/Encoder/Bc5BlockEncoder.cs @@ -10,17 +10,17 @@ internal class Bc5BlockEncoder : IBcBlockEncoder { public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) { + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } } @@ -29,17 +29,17 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } private Bc5Block EncodeBlock(RawBlock4X4Rgba32 block, CompressionQuality quality) { - Bc5Block output = new Bc5Block(); - byte[] reds = new byte[16]; - byte[] greens = new byte[16]; + var output = new Bc5Block(); + var reds = new byte[16]; + var greens = new byte[16]; var pixels = block.AsSpan; - for (int i = 0; i < 16; i++) { + for (var i = 0; i < 16; i++) { reds[i] = pixels[i].R; greens[i] = pixels[i].G; } - int variations = 0; - int errorThreshold = 0; + var variations = 0; + var errorThreshold = 0; switch (quality) { case CompressionQuality.Fast: variations = 3; @@ -101,15 +101,15 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RED_GREEN_RGTC2_EXT; + return GlInternalFormat.GlCompressedRedGreenRgtc2Ext; } - public GLFormat GetBaseInternalFormat() { - return GLFormat.GL_RG; + public GlFormat GetBaseInternalFormat() { + return GlFormat.GlRg; } - public DXGI_FORMAT GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM; + public DxgiFormat GetDxgiFormat() { + return DxgiFormat.DxgiFormatBc5Unorm; } #region Encoding private stuff @@ -124,8 +124,8 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight //Find min and max alpha byte min = 255; byte max = 0; - bool hasExtremeValues = false; - for (int i = 0; i < pixels.Length; i++) { + var hasExtremeValues = false; + for (var i = 0; i < pixels.Length; i++) { if (pixels[i] < 255 && pixels[i] > 0) { if (pixels[i] < min) min = pixels[i]; if (pixels[i] > max) max = pixels[i]; @@ -137,12 +137,12 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight int SelectIndices(ref Bc5Block block) { - int cumulativeError = 0; + var cumulativeError = 0; //var c0 = block.Red0; //var c1 = block.Red1; var c0 = col0Getter(block); var c1 = col1Getter(block); - Span colors = c0 > c1 + var colors = c0 > c1 ? stackalloc byte[] { c0, c1, @@ -163,11 +163,11 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight 0, 255 }; - for (int i = 0; i < pixels.Length; i++) { + for (var i = 0; i < pixels.Length; i++) { byte bestIndex = 0; - int bestError = Math.Abs(pixels[i] - colors[0]); + var bestError = Math.Abs(pixels[i] - colors[0]); for (byte j = 1; j < colors.Length; j++) { - int error = Math.Abs(pixels[i] - colors[j]); + var error = Math.Abs(pixels[i] - colors[j]); if (error < bestError) { bestIndex = j; bestError = error; @@ -200,21 +200,21 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight //best.Red1 = min; best = col0Setter(best, max); best = col1Setter(best, min); - int bestError = SelectIndices(ref best); + var bestError = SelectIndices(ref best); if (bestError == 0) { return best; } - for (byte i = (byte)variations; i > 0; i--) { + for (var i = (byte)variations; i > 0; i--) { { - byte c0 = ByteHelper.ClampToByte(max - i); - byte c1 = ByteHelper.ClampToByte(min + i); + var c0 = ByteHelper.ClampToByte(max - i); + var c1 = ByteHelper.ClampToByte(min + i); var block = colorBlock; //block.Red0 = hasExtremeValues ? c1 : c0; //block.Red1 = hasExtremeValues ? c0 : c1; block = col0Setter(block, hasExtremeValues ? c1 : c0); block = col1Setter(block, hasExtremeValues ? c0 : c1); - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -223,14 +223,14 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } } { - byte c0 = ByteHelper.ClampToByte(max + i); - byte c1 = ByteHelper.ClampToByte(min - i); + var c0 = ByteHelper.ClampToByte(max + i); + var c1 = ByteHelper.ClampToByte(min - i); var block = colorBlock; //block.Red0 = hasExtremeValues ? c1 : c0; //block.Red1 = hasExtremeValues ? c0 : c1; block = col0Setter(block, hasExtremeValues ? c1 : c0); block = col1Setter(block, hasExtremeValues ? c0 : c1); - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -239,14 +239,14 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } } { - byte c0 = ByteHelper.ClampToByte(max); - byte c1 = ByteHelper.ClampToByte(min - i); + var c0 = ByteHelper.ClampToByte(max); + var c1 = ByteHelper.ClampToByte(min - i); var block = colorBlock; //block.Red0 = hasExtremeValues ? c1 : c0; //block.Red1 = hasExtremeValues ? c0 : c1; block = col0Setter(block, hasExtremeValues ? c1 : c0); block = col1Setter(block, hasExtremeValues ? c0 : c1); - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -255,14 +255,14 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } } { - byte c0 = ByteHelper.ClampToByte(max + i); - byte c1 = ByteHelper.ClampToByte(min); + var c0 = ByteHelper.ClampToByte(max + i); + var c1 = ByteHelper.ClampToByte(min); var block = colorBlock; //block.Red0 = hasExtremeValues ? c1 : c0; //block.Red1 = hasExtremeValues ? c0 : c1; block = col0Setter(block, hasExtremeValues ? c1 : c0); block = col1Setter(block, hasExtremeValues ? c0 : c1); - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -271,14 +271,14 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } } { - byte c0 = ByteHelper.ClampToByte(max); - byte c1 = ByteHelper.ClampToByte(min + i); + var c0 = ByteHelper.ClampToByte(max); + var c1 = ByteHelper.ClampToByte(min + i); var block = colorBlock; //block.Red0 = hasExtremeValues ? c1 : c0; //block.Red1 = hasExtremeValues ? c0 : c1; block = col0Setter(block, hasExtremeValues ? c1 : c0); block = col1Setter(block, hasExtremeValues ? c0 : c1); - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; @@ -287,14 +287,14 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight } } { - byte c0 = ByteHelper.ClampToByte(max - i); - byte c1 = ByteHelper.ClampToByte(min); + var c0 = ByteHelper.ClampToByte(max - i); + var c1 = ByteHelper.ClampToByte(min); var block = colorBlock; //block.Red0 = hasExtremeValues ? c1 : c0; //block.Red1 = hasExtremeValues ? c0 : c1; block = col0Setter(block, hasExtremeValues ? c1 : c0); block = col1Setter(block, hasExtremeValues ? c0 : c1); - int error = SelectIndices(ref block); + var error = SelectIndices(ref block); if (error < bestError) { best = block; bestError = error; diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Encoder.cs index cde1c20..f163c3e 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Encoder.cs @@ -11,21 +11,20 @@ internal class Bc7Encoder : IBcBlockEncoder public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel) { - byte[] outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; - Span outputBlocks = MemoryMarshal.Cast(outputData); - + var outputData = new byte[blockWidth * blockHeight * Marshal.SizeOf()]; + var outputBlocks = MemoryMarshal.Cast(outputData); if (parallel) { Parallel.For(0, blocks.Length, i => { - Span outputBlocks = MemoryMarshal.Cast(outputData); + var outputBlocks = MemoryMarshal.Cast(outputData); outputBlocks[i] = EncodeBlock(blocks[i], quality); }); } else { - for (int i = 0; i < blocks.Length; i++) + for (var i = 0; i < blocks.Length; i++) { outputBlocks[i] = EncodeBlock(blocks[i], quality); } @@ -37,34 +36,34 @@ public byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight public GlInternalFormat GetInternalFormat() { - return GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + return GlInternalFormat.GlCompressedRgbaBptcUnormArb; } - public GLFormat GetBaseInternalFormat() + public GlFormat GetBaseInternalFormat() { - return GLFormat.GL_RGBA; + return GlFormat.GlRgba; } - public DXGI_FORMAT GetDxgiFormat() { - return DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM; + public DxgiFormat GetDxgiFormat() { + return DxgiFormat.DxgiFormatBc7Unorm; } private static ClusterIndices4X4 CreateClusterIndexBlock(RawBlock4X4Rgba32 raw, out int outputNumClusters, int numClusters = 3) { - ClusterIndices4X4 indexBlock = new ClusterIndices4X4(); + var indexBlock = new ClusterIndices4X4(); var indices = LinearClustering.ClusterPixels(raw.AsSpan, 4, 4, numClusters, 1, 10, false); var output = indexBlock.AsSpan; - for (int i = 0; i < output.Length; i++) + for (var i = 0; i < output.Length; i++) { output[i] = indices[i]; } - int nClusters = indexBlock.NumClusters; + var nClusters = indexBlock.NumClusters; if (nClusters < numClusters) { indexBlock = indexBlock.Reduce(out nClusters); @@ -92,8 +91,8 @@ private static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock, CompressionQuali private static class Bc7EncoderFast { - private const float errorThreshold = 0.005f; - private const int maxTries = 5; + private const float ErrorThreshold_ = 0.005f; + private const int MaxTries_ = 5; private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[] best2SubsetPartitions, int[] best3SubsetPartitions, bool alpha) { @@ -105,7 +104,7 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ else { yield return Bc7Mode6Encoder.EncodeBlock(rawBlock, 6); - for (int i = 0; i < 64; i++) { + for (var i = 0; i < 64; i++) { if(best3SubsetPartitions[i] < 16) { yield return Bc7Mode0Encoder.EncodeBlock(rawBlock, 3, best3SubsetPartitions[i]); } @@ -118,25 +117,25 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { - bool hasAlpha = rawBlock.HasTransparentPixels(); + var hasAlpha = rawBlock.HasTransparentPixels(); - var indexBlock2 = CreateClusterIndexBlock(rawBlock, out int clusters2, 2); - var indexBlock3 = CreateClusterIndexBlock(rawBlock, out int clusters3, 3); + var indexBlock2 = CreateClusterIndexBlock(rawBlock, out var clusters2, 2); + var indexBlock3 = CreateClusterIndexBlock(rawBlock, out var clusters3, 3); if (clusters2 < 2) { clusters2 = clusters3; indexBlock2 = indexBlock3; } - int[] best2SubsetPartitions = Bc7EncodingHelpers.Rank2SubsetPartitions(indexBlock2, clusters2); - int[] best3SubsetPartitions = Bc7EncodingHelpers.Rank3SubsetPartitions(indexBlock3, clusters3); + var best2SubsetPartitions = Bc7EncodingHelpers.Rank2SubsetPartitions(indexBlock2, clusters2); + var best3SubsetPartitions = Bc7EncodingHelpers.Rank3SubsetPartitions(indexBlock3, clusters3); float bestError = 99999; - Bc7Block best = new Bc7Block(); - int tries = 0; - foreach (Bc7Block block in TryMethods(rawBlock, best2SubsetPartitions, best3SubsetPartitions, hasAlpha)) { + var best = new Bc7Block(); + var tries = 0; + foreach (var block in TryMethods(rawBlock, best2SubsetPartitions, best3SubsetPartitions, hasAlpha)) { var decoded = block.Decode(); - float error = rawBlock.CalculateYCbCrAlphaError(decoded); + var error = rawBlock.CalculateYCbCrAlphaError(decoded); tries++; if(error < bestError) { @@ -144,7 +143,7 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) bestError = error; } - if (error < errorThreshold || tries > maxTries) { + if (error < ErrorThreshold_ || tries > MaxTries_) { break; } @@ -156,8 +155,8 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc7EncoderBalanced { - private const float errorThreshold = 0.005f; - private const int maxTries = 25; + private const float ErrorThreshold_ = 0.005f; + private const int MaxTries_ = 25; private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[] best2SubsetPartitions, int[] best3SubsetPartitions, bool alpha) { @@ -166,7 +165,7 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ yield return Bc7Mode6Encoder.EncodeBlock(rawBlock, 6); yield return Bc7Mode5Encoder.EncodeBlock(rawBlock, 4); yield return Bc7Mode4Encoder.EncodeBlock(rawBlock, 4); - for (int i = 0; i < 64; i++) + for (var i = 0; i < 64; i++) { yield return Bc7Mode7Encoder.EncodeBlock(rawBlock, 3, best2SubsetPartitions[i]); } @@ -176,7 +175,7 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ yield return Bc7Mode6Encoder.EncodeBlock(rawBlock, 6); yield return Bc7Mode5Encoder.EncodeBlock(rawBlock, 4); yield return Bc7Mode4Encoder.EncodeBlock(rawBlock, 4); - for (int i = 0; i < 64; i++) { + for (var i = 0; i < 64; i++) { if(best3SubsetPartitions[i] < 16) { yield return Bc7Mode0Encoder.EncodeBlock(rawBlock, 3, best3SubsetPartitions[i]); } @@ -191,25 +190,25 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { - bool hasAlpha = rawBlock.HasTransparentPixels(); + var hasAlpha = rawBlock.HasTransparentPixels(); - var indexBlock2 = CreateClusterIndexBlock(rawBlock, out int clusters2, 2); - var indexBlock3 = CreateClusterIndexBlock(rawBlock, out int clusters3, 3); + var indexBlock2 = CreateClusterIndexBlock(rawBlock, out var clusters2, 2); + var indexBlock3 = CreateClusterIndexBlock(rawBlock, out var clusters3, 3); if (clusters2 < 2) { clusters2 = clusters3; indexBlock2 = indexBlock3; } - int[] best2SubsetPartitions = Bc7EncodingHelpers.Rank2SubsetPartitions(indexBlock2, clusters2); - int[] best3SubsetPartitions = Bc7EncodingHelpers.Rank3SubsetPartitions(indexBlock3, clusters3); + var best2SubsetPartitions = Bc7EncodingHelpers.Rank2SubsetPartitions(indexBlock2, clusters2); + var best3SubsetPartitions = Bc7EncodingHelpers.Rank3SubsetPartitions(indexBlock3, clusters3); float bestError = 99999; - Bc7Block best = new Bc7Block(); - int tries = 0; - foreach (Bc7Block block in TryMethods(rawBlock, best2SubsetPartitions, best3SubsetPartitions, hasAlpha)) { + var best = new Bc7Block(); + var tries = 0; + foreach (var block in TryMethods(rawBlock, best2SubsetPartitions, best3SubsetPartitions, hasAlpha)) { var decoded = block.Decode(); - float error = rawBlock.CalculateYCbCrAlphaError(decoded); + var error = rawBlock.CalculateYCbCrAlphaError(decoded); tries++; if(error < bestError) { @@ -217,7 +216,7 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) bestError = error; } - if (error < errorThreshold || tries > maxTries) { + if (error < ErrorThreshold_ || tries > MaxTries_) { break; } @@ -230,8 +229,8 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) private static class Bc7EncoderBestQuality { - private const float errorThreshold = 0.001f; - private const int maxTries = 40; + private const float ErrorThreshold_ = 0.001f; + private const int MaxTries_ = 40; private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[] best2SubsetPartitions, int[] best3SubsetPartitions, bool alpha) { @@ -240,7 +239,7 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ yield return Bc7Mode6Encoder.EncodeBlock(rawBlock, 8); yield return Bc7Mode5Encoder.EncodeBlock(rawBlock, 5); yield return Bc7Mode4Encoder.EncodeBlock(rawBlock, 5); - for (int i = 0; i < 64; i++) + for (var i = 0; i < 64; i++) { yield return Bc7Mode7Encoder.EncodeBlock(rawBlock, 4, best2SubsetPartitions[i]); @@ -251,7 +250,7 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ yield return Bc7Mode6Encoder.EncodeBlock(rawBlock, 8); yield return Bc7Mode5Encoder.EncodeBlock(rawBlock, 5); yield return Bc7Mode4Encoder.EncodeBlock(rawBlock, 5); - for (int i = 0; i < 64; i++) { + for (var i = 0; i < 64; i++) { if(best3SubsetPartitions[i] < 16) { yield return Bc7Mode0Encoder.EncodeBlock(rawBlock, 4, best3SubsetPartitions[i]); } @@ -266,26 +265,26 @@ private static IEnumerable TryMethods(RawBlock4X4Rgba32 rawBlock, int[ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) { - bool hasAlpha = rawBlock.HasTransparentPixels(); + var hasAlpha = rawBlock.HasTransparentPixels(); - var indexBlock2 = CreateClusterIndexBlock(rawBlock, out int clusters2, 2); - var indexBlock3 = CreateClusterIndexBlock(rawBlock, out int clusters3, 3); + var indexBlock2 = CreateClusterIndexBlock(rawBlock, out var clusters2, 2); + var indexBlock3 = CreateClusterIndexBlock(rawBlock, out var clusters3, 3); if (clusters2 < 2) { clusters2 = clusters3; indexBlock2 = indexBlock3; } - int[] best2SubsetPartitions = Bc7EncodingHelpers.Rank2SubsetPartitions(indexBlock2, clusters2); - int[] best3SubsetPartitions = Bc7EncodingHelpers.Rank3SubsetPartitions(indexBlock3, clusters3); + var best2SubsetPartitions = Bc7EncodingHelpers.Rank2SubsetPartitions(indexBlock2, clusters2); + var best3SubsetPartitions = Bc7EncodingHelpers.Rank3SubsetPartitions(indexBlock3, clusters3); float bestError = 99999; - Bc7Block best = new Bc7Block(); - int tries = 0; - foreach (Bc7Block block in TryMethods(rawBlock, best2SubsetPartitions, best3SubsetPartitions, hasAlpha)) { + var best = new Bc7Block(); + var tries = 0; + foreach (var block in TryMethods(rawBlock, best2SubsetPartitions, best3SubsetPartitions, hasAlpha)) { var decoded = block.Decode(); - float error = rawBlock.CalculateYCbCrAlphaError(decoded); + var error = rawBlock.CalculateYCbCrAlphaError(decoded); tries++; if(error < bestError) { @@ -293,7 +292,7 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 rawBlock) bestError = error; } - if (error < errorThreshold || tries > maxTries) { + if (error < ErrorThreshold_ || tries > MaxTries_) { break; } diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7EncodingHelpers.cs b/BCnEnc.Net/Encoder/Bc7/Bc7EncodingHelpers.cs index 24371cd..0187ed7 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7EncodingHelpers.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7EncodingHelpers.cs @@ -33,12 +33,12 @@ public int NumClusters { var t = AsSpan; Span clusters = stackalloc int[16]; - int distinct = 0; - for (int i = 0; i < 16; i++) + var distinct = 0; + for (var i = 0; i < 16; i++) { var cluster = t[i]; - bool found = false; - for (int j = 0; j < distinct; j++) + var found = false; + for (var j = 0; j < distinct; j++) { if (clusters[j] == cluster) { @@ -67,12 +67,12 @@ public ClusterIndices4X4 Reduce(out int numClusters) Span mapKey = stackalloc int[numClusters]; var indices = AsSpan; var outIndices = result.AsSpan; - int next = 0; - for (int i = 0; i < 16; i++) + var next = 0; + for (var i = 0; i < 16; i++) { var cluster = indices[i]; - bool found = false; - for (int j = 0; j < next; j++) + var found = false; + for (var j = 0; j < next; j++) { if (mapKey[j] == cluster) { @@ -210,7 +210,7 @@ public static void ExpandEndpoints(Bc7BlockType type, ColorRgba32[] endpoints, b { if (type == Bc7BlockType.Type0 || type == Bc7BlockType.Type1 || type == Bc7BlockType.Type3 || type == Bc7BlockType.Type6 || type == Bc7BlockType.Type7) { - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { endpoints[i] <<= 1; } @@ -224,7 +224,7 @@ public static void ExpandEndpoints(Bc7BlockType type, ColorRgba32[] endpoints, b } else { - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { endpoints[i] |= pBits[i]; } @@ -233,7 +233,7 @@ public static void ExpandEndpoints(Bc7BlockType type, ColorRgba32[] endpoints, b var colorPrecision = GetColorComponentPrecisionWithPBit(type); var alphaPrecision = GetAlphaComponentPrecisionWithPBit(type); - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { // ColorComponentPrecision & AlphaComponentPrecision includes pbit // left shift endpoint components so that their MSB lies in bit 7 @@ -253,7 +253,7 @@ public static void ExpandEndpoints(Bc7BlockType type, ColorRgba32[] endpoints, b //set alpha equal to 255 if (type == Bc7BlockType.Type0 || type == Bc7BlockType.Type1 || type == Bc7BlockType.Type2 || type == Bc7BlockType.Type3) { - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { endpoints[i].a = 255; } @@ -294,28 +294,28 @@ public static ColorRgba32 ExpandEndpoint(Bc7BlockType type, ColorRgba32 endpoint public static int SelectBest2SubsetPartition(ClusterIndices4X4 reducedIndicesBlock, int numDistinctClusters, out int bestError) { - bool first = true; + var first = true; bestError = 999; - int bestPartition = 0; + var bestPartition = 0; int CalculatePartitionError(int partitionIndex) { - int error = 0; + var error = 0; ReadOnlySpan partitionTable = Bc7Block.Subsets2PartitionTable[partitionIndex]; Span subset0 = stackalloc int[numDistinctClusters]; Span subset1 = stackalloc int[numDistinctClusters]; - int max0Idx = 0; - int max1Idx = 0; + var max0Idx = 0; + var max1Idx = 0; //Calculate largest cluster index for each subset - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset0[r]++; - int count = subset0[r]; + var count = subset0[r]; if (count > subset0[max0Idx]) { max0Idx = r; @@ -323,9 +323,9 @@ int CalculatePartitionError(int partitionIndex) } else { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset1[r]++; - int count = subset1[r]; + var count = subset1[r]; if (count > subset1[max1Idx]) { max1Idx = r; @@ -334,7 +334,7 @@ int CalculatePartitionError(int partitionIndex) } // Calculate error by counting as error everything that does not match the largest cluster - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { @@ -349,9 +349,9 @@ int CalculatePartitionError(int partitionIndex) return error; } - for (int i = 0; i < 64; i++) // Loop through all possible indices + for (var i = 0; i < 64; i++) // Loop through all possible indices { - int error = CalculatePartitionError(i); + var error = CalculatePartitionError(i); if (first) { bestError = error; @@ -375,26 +375,26 @@ int CalculatePartitionError(int partitionIndex) public static int[] Rank2SubsetPartitions(ClusterIndices4X4 reducedIndicesBlock, int numDistinctClusters) { - int[] output = Enumerable.Range(0, 64).ToArray(); + var output = Enumerable.Range(0, 64).ToArray(); int CalculatePartitionError(int partitionIndex) { - int error = 0; + var error = 0; ReadOnlySpan partitionTable = Bc7Block.Subsets2PartitionTable[partitionIndex]; Span subset0 = stackalloc int[numDistinctClusters]; Span subset1 = stackalloc int[numDistinctClusters]; - int max0Idx = 0; - int max1Idx = 0; + var max0Idx = 0; + var max1Idx = 0; //Calculate largest cluster index for each subset - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset0[r]++; - int count = subset0[r]; + var count = subset0[r]; if (count > subset0[max0Idx]) { max0Idx = r; @@ -402,9 +402,9 @@ int CalculatePartitionError(int partitionIndex) } else { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset1[r]++; - int count = subset1[r]; + var count = subset1[r]; if (count > subset1[max1Idx]) { max1Idx = r; @@ -413,7 +413,7 @@ int CalculatePartitionError(int partitionIndex) } // Calculate error by counting as error everything that does not match the largest cluster - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { @@ -435,32 +435,32 @@ int CalculatePartitionError(int partitionIndex) public static int SelectBest3SubsetPartition(ClusterIndices4X4 reducedIndicesBlock, int numDistinctClusters, out int bestError) { - bool first = true; + var first = true; bestError = 999; - int bestPartition = 0; + var bestPartition = 0; int CalculatePartitionError(int partitionIndex) { - int error = 0; + var error = 0; ReadOnlySpan partitionTable = Bc7Block.Subsets3PartitionTable[partitionIndex]; Span subset0 = stackalloc int[numDistinctClusters]; Span subset1 = stackalloc int[numDistinctClusters]; Span subset2 = stackalloc int[numDistinctClusters]; - int max0Idx = 0; - int max1Idx = 0; - int max2Idx = 0; + var max0Idx = 0; + var max1Idx = 0; + var max2Idx = 0; //Calculate largest cluster index for each subset - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset0[r]++; - int count = subset0[r]; + var count = subset0[r]; if (count > subset0[max0Idx]) { max0Idx = r; @@ -468,9 +468,9 @@ int CalculatePartitionError(int partitionIndex) } else if (partitionTable[i] == 1) { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset1[r]++; - int count = subset1[r]; + var count = subset1[r]; if (count > subset1[max1Idx]) { max1Idx = r; @@ -478,9 +478,9 @@ int CalculatePartitionError(int partitionIndex) } else { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset2[r]++; - int count = subset2[r]; + var count = subset2[r]; if (count > subset2[max2Idx]) { max2Idx = r; @@ -489,7 +489,7 @@ int CalculatePartitionError(int partitionIndex) } // Calculate error by counting as error everything that does not match the largest cluster - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { @@ -508,9 +508,9 @@ int CalculatePartitionError(int partitionIndex) return error; } - for (int i = 0; i < 64; i++) // Loop through all possible indices + for (var i = 0; i < 64; i++) // Loop through all possible indices { - int error = CalculatePartitionError(i); + var error = CalculatePartitionError(i); if (first) { bestError = error; @@ -534,28 +534,28 @@ int CalculatePartitionError(int partitionIndex) public static int[] Rank3SubsetPartitions(ClusterIndices4X4 reducedIndicesBlock, int numDistinctClusters) { - int[] output = Enumerable.Range(0, 64).ToArray(); + var output = Enumerable.Range(0, 64).ToArray(); int CalculatePartitionError(int partitionIndex) { - int error = 0; + var error = 0; ReadOnlySpan partitionTable = Bc7Block.Subsets3PartitionTable[partitionIndex]; Span subset0 = stackalloc int[numDistinctClusters]; Span subset1 = stackalloc int[numDistinctClusters]; Span subset2 = stackalloc int[numDistinctClusters]; - int max0Idx = 0; - int max1Idx = 0; - int max2Idx = 0; + var max0Idx = 0; + var max1Idx = 0; + var max2Idx = 0; //Calculate largest cluster index for each subset - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset0[r]++; - int count = subset0[r]; + var count = subset0[r]; if (count > subset0[max0Idx]) { max0Idx = r; @@ -563,9 +563,9 @@ int CalculatePartitionError(int partitionIndex) } else if (partitionTable[i] == 1) { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset1[r]++; - int count = subset1[r]; + var count = subset1[r]; if (count > subset1[max1Idx]) { max1Idx = r; @@ -573,9 +573,9 @@ int CalculatePartitionError(int partitionIndex) } else { - int r = reducedIndicesBlock[i]; + var r = reducedIndicesBlock[i]; subset2[r]++; - int count = subset2[r]; + var count = subset2[r]; if (count > subset2[max2Idx]) { max2Idx = r; @@ -584,7 +584,7 @@ int CalculatePartitionError(int partitionIndex) } // Calculate error by counting as error everything that does not match the largest cluster - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == 0) { @@ -627,8 +627,8 @@ int CalculatePartitionError(int partitionIndex) var originalPixels = block.AsSpan; - int count = 0; - for (int i = 0; i < 16; i++) + var count = 0; + for (var i = 0; i < 16; i++) { if (partitionTable[i] == subsetIndex) { @@ -637,8 +637,8 @@ int CalculatePartitionError(int partitionIndex) } Span subsetColors = stackalloc Rgba32[count]; - int next = 0; - for (int i = 0; i < 16; i++) + var next = 0; + for (var i = 0; i < 16; i++) { if (partitionTable[i] == subsetIndex) { @@ -655,8 +655,8 @@ int CalculatePartitionError(int partitionIndex) public static ColorRgba32 ScaleDownEndpoint(ColorRgba32 endpoint, Bc7BlockType type, bool ignoreAlpha, out byte pBit) { - int colorPrecision = GetColorComponentPrecisionWithPBit(type); - int alphaPrecision = GetAlphaComponentPrecisionWithPBit(type); + var colorPrecision = GetColorComponentPrecisionWithPBit(type); + var alphaPrecision = GetAlphaComponentPrecisionWithPBit(type); var r = (byte)(endpoint.r >> (8 - colorPrecision)); var g = (byte)(endpoint.g >> (8 - colorPrecision)); @@ -665,14 +665,14 @@ public static ColorRgba32 ScaleDownEndpoint(ColorRgba32 endpoint, Bc7BlockType t if (TypeHasPBits(type)) { - int pBitVotingMask = (1 << (8 - colorPrecision + 1)) - 1; + var pBitVotingMask = (1 << (8 - colorPrecision + 1)) - 1; float pBitVotes = 0; pBitVotes += endpoint.r & pBitVotingMask; pBitVotes += endpoint.g & pBitVotingMask; pBitVotes += endpoint.b & pBitVotingMask; pBitVotes /= 3; - if (pBitVotes >= (pBitVotingMask / 2f)) + if (pBitVotes >= pBitVotingMask / 2f) { pBit = 1; } @@ -708,19 +708,19 @@ public static ColorRgba32 ScaleDownEndpoint(ColorRgba32 endpoint, Bc7BlockType t byte InterpolateByte(byte e0, byte e1, int index, int indexPrecision) { if (indexPrecision == 0) return e0; - ReadOnlySpan aWeights2 = Bc7Block.colorInterpolationWeights2; - ReadOnlySpan aWeights3 = Bc7Block.colorInterpolationWeights3; - ReadOnlySpan aWeights4 = Bc7Block.colorInterpolationWeights4; + var aWeights2 = Bc7Block.ColorInterpolationWeights2; + var aWeights3 = Bc7Block.ColorInterpolationWeights3; + var aWeights4 = Bc7Block.ColorInterpolationWeights4; if(indexPrecision == 2) - return (byte) (((64 - aWeights2[index])* (e0) + aWeights2[index]*(e1) + 32) >> 6); + return (byte) (((64 - aWeights2[index])* e0 + aWeights2[index]*e1 + 32) >> 6); else if(indexPrecision == 3) - return (byte) (((64 - aWeights3[index])*(e0) + aWeights3[index]*(e1) + 32) >> 6); + return (byte) (((64 - aWeights3[index])*e0 + aWeights3[index]*e1 + 32) >> 6); else // indexprecision == 4 - return (byte) (((64 - aWeights4[index])*(e0) + aWeights4[index]*(e1) + 32) >> 6); + return (byte) (((64 - aWeights4[index])*e0 + aWeights4[index]*e1 + 32) >> 6); } - ColorRgba32 result = new ColorRgba32( + var result = new ColorRgba32( InterpolateByte(endPointStart.r, endPointEnd.r, colorIndex, colorBitCount), InterpolateByte(endPointStart.g, endPointEnd.g, colorIndex, colorBitCount), InterpolateByte(endPointStart.b, endPointEnd.b, colorIndex, colorBitCount), @@ -741,10 +741,10 @@ public static void ClampEndpoint(ref ColorRgba32 endpoint, byte colorMax, byte a private static int FindClosestColorIndex(ColorYCbCrAlpha color, ReadOnlySpan colors, out float bestError) { bestError = color.CalcDistWeighted(colors[0], 4, 2); - int bestIndex = 0; - for (int i = 1; i < colors.Length; i++) + var bestIndex = 0; + for (var i = 1; i < colors.Length; i++) { - float error = color.CalcDistWeighted(colors[i], 4, 2); + var error = color.CalcDistWeighted(colors[i], 4, 2); if (error < bestError) { bestIndex = i; @@ -757,10 +757,10 @@ private static int FindClosestColorIndex(ColorYCbCrAlpha color, ReadOnlySpan colors, out float bestError) { bestError = color.CalcDistWeighted(colors[0], 4); - int bestIndex = 0; - for (int i = 1; i < colors.Length; i++) + var bestIndex = 0; + for (var i = 1; i < colors.Length; i++) { - float error = color.CalcDistWeighted(colors[i], 4); + var error = color.CalcDistWeighted(colors[i], 4); if (error < bestError) { bestIndex = i; @@ -777,8 +777,8 @@ private static int FindClosestColorIndex(ColorYCbCr color, ReadOnlySpan alphas, out float bestError) { bestError = (alpha - alphas[0]) * (alpha - alphas[0]); - int bestIndex = 0; - for (int i = 1; i < alphas.Length; i++) + var bestIndex = 0; + for (var i = 1; i < alphas.Length; i++) { float error = (alpha - alphas[i]) * (alpha - alphas[i]); if (error < bestError) @@ -799,21 +799,21 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, private static float TrySubsetEndpoints(Bc7BlockType type, RawBlock4X4Rgba32 raw, ColorRgba32 ep0, ColorRgba32 ep1, ReadOnlySpan partitionTable, int subsetIndex, int type4IdxMode) { - int colorIndexPrecision = GetColorIndexBitCount(type, type4IdxMode); - int alphaIndexPrecision = GetAlphaIndexBitCount(type, type4IdxMode); + var colorIndexPrecision = GetColorIndexBitCount(type, type4IdxMode); + var alphaIndexPrecision = GetAlphaIndexBitCount(type, type4IdxMode); if (type == Bc7BlockType.Type4 || type == Bc7BlockType.Type5) { //separate indices for color and alpha Span colors = stackalloc ColorYCbCr[1 << colorIndexPrecision]; Span alphas = stackalloc byte[1 << alphaIndexPrecision]; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { colors[i] = new ColorYCbCr(InterpolateColor(ep0, ep1, i, 0, colorIndexPrecision, 0)); } - for (int i = 0; i < alphas.Length; i++) + for (var i = 0; i < alphas.Length; i++) { alphas[i] = InterpolateColor(ep0, ep1, 0, i, 0, alphaIndexPrecision).a; @@ -822,7 +822,7 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, var pixels = raw.AsSpan; float error = 0; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var pixelColor = new ColorYCbCr(pixels[i]); @@ -837,7 +837,7 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, else { Span colors = stackalloc ColorYCbCrAlpha[1 << colorIndexPrecision]; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { colors[i] = new ColorYCbCrAlpha(InterpolateColor(ep0, ep1, i, i, colorIndexPrecision, alphaIndexPrecision)); @@ -847,7 +847,7 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, float error = 0; float count = 0; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == subsetIndex) { @@ -868,8 +868,8 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, public static void FillSubsetIndices(Bc7BlockType type, RawBlock4X4Rgba32 raw, ColorRgba32 ep0, ColorRgba32 ep1, ReadOnlySpan partitionTable, int subsetIndex, Span indicesToFill) { - int colorIndexPrecision = GetColorIndexBitCount(type); - int alphaIndexPrecision = GetAlphaIndexBitCount(type); + var colorIndexPrecision = GetColorIndexBitCount(type); + var alphaIndexPrecision = GetAlphaIndexBitCount(type); if (type == Bc7BlockType.Type4 || type == Bc7BlockType.Type5) { //separate indices for color and alpha @@ -878,7 +878,7 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, else { Span colors = stackalloc ColorYCbCrAlpha[1 << colorIndexPrecision]; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { colors[i] = new ColorYCbCrAlpha(InterpolateColor(ep0, ep1, i, i, colorIndexPrecision, alphaIndexPrecision)); @@ -886,7 +886,7 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, var pixels = raw.AsSpan; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { if (partitionTable[i] == subsetIndex) { @@ -905,21 +905,21 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, public static void FillAlphaColorIndices(Bc7BlockType type, RawBlock4X4Rgba32 raw, ColorRgba32 ep0, ColorRgba32 ep1, Span colorIndicesToFill, Span alphaIndicesToFill, int idxMode = 0) { - int colorIndexPrecision = GetColorIndexBitCount(type, idxMode); - int alphaIndexPrecision = GetAlphaIndexBitCount(type, idxMode); + var colorIndexPrecision = GetColorIndexBitCount(type, idxMode); + var alphaIndexPrecision = GetAlphaIndexBitCount(type, idxMode); if (type == Bc7BlockType.Type4 || type == Bc7BlockType.Type5) { Span colors = stackalloc ColorYCbCr[1 << colorIndexPrecision]; Span alphas = stackalloc byte[1 << alphaIndexPrecision]; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { colors[i] = new ColorYCbCr(InterpolateColor(ep0, ep1, i, 0, colorIndexPrecision, 0)); } - for (int i = 0; i < alphas.Length; i++) + for (var i = 0; i < alphas.Length; i++) { alphas[i] = InterpolateColor(ep0, ep1, 0, i, 0, alphaIndexPrecision).a; @@ -927,7 +927,7 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, var pixels = raw.AsSpan; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var pixelColor = new ColorYCbCr(pixels[i]); @@ -948,51 +948,51 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, int variation, ReadOnlySpan partitionTable, int subsetIndex, bool variatePBits, bool variateAlpha, int type4IdxMode = 0) { - byte colorMax = (byte)((1 << GetColorComponentPrecision(type)) - 1); - byte alphaMax = (byte)((1 << GetAlphaComponentPrecision(type)) - 1); + var colorMax = (byte)((1 << GetColorComponentPrecision(type)) - 1); + var alphaMax = (byte)((1 << GetAlphaComponentPrecision(type)) - 1); - float bestError = TrySubsetEndpoints(type, raw, + var bestError = TrySubsetEndpoints(type, raw, ExpandEndpoint(type, ep0, pBit0), ExpandEndpoint(type, ep1, pBit1), partitionTable, subsetIndex, type4IdxMode ); - ReadOnlySpan varPatternR = variateAlpha + ReadOnlySpan patternR = variateAlpha ? varPatternRAlpha : varPatternRNoAlpha; - ReadOnlySpan varPatternG = variateAlpha + ReadOnlySpan patternG = variateAlpha ? varPatternGAlpha : varPatternGNoAlpha; - ReadOnlySpan varPatternB = variateAlpha + ReadOnlySpan patternB = variateAlpha ? varPatternBAlpha : varPatternBNoAlpha; - ReadOnlySpan varPatternA = variateAlpha + ReadOnlySpan patternA = variateAlpha ? varPatternAAlpha : varPatternANoAlpha; while (variation > 0) { - bool foundBetter = false; + var foundBetter = false; - for (int i = 0; i < varPatternR.Length; i++) + for (var i = 0; i < patternR.Length; i++) { - ColorRgba32 testEndPoint0 = new ColorRgba32( - (byte)(ep0.r - variation * varPatternR[i]), - (byte)(ep0.g - variation * varPatternG[i]), - (byte)(ep0.b - variation * varPatternB[i]), - (byte)(ep0.a - variation * varPatternA[i]) + var testEndPoint0 = new ColorRgba32( + (byte)(ep0.r - variation * patternR[i]), + (byte)(ep0.g - variation * patternG[i]), + (byte)(ep0.b - variation * patternB[i]), + (byte)(ep0.a - variation * patternA[i]) ); - ColorRgba32 testEndPoint1 = new ColorRgba32( - (byte)(ep1.r + variation * varPatternR[i]), - (byte)(ep1.g + variation * varPatternG[i]), - (byte)(ep1.b + variation * varPatternB[i]), - (byte)(ep1.a + variation * varPatternA[i]) + var testEndPoint1 = new ColorRgba32( + (byte)(ep1.r + variation * patternR[i]), + (byte)(ep1.g + variation * patternG[i]), + (byte)(ep1.b + variation * patternB[i]), + (byte)(ep1.a + variation * patternA[i]) ); ClampEndpoint(ref testEndPoint0, colorMax, alphaMax); ClampEndpoint(ref testEndPoint1, colorMax, alphaMax); - float error = TrySubsetEndpoints(type, raw, + var error = TrySubsetEndpoints(type, raw, ExpandEndpoint(type, testEndPoint0, pBit0), ExpandEndpoint(type, testEndPoint1, pBit1), partitionTable, subsetIndex, type4IdxMode ); @@ -1005,17 +1005,17 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, } } - for (int i = 0; i < varPatternR.Length; i++) + for (var i = 0; i < patternR.Length; i++) { - ColorRgba32 testEndPoint0 = new ColorRgba32( - (byte)(ep0.r + variation * varPatternR[i]), - (byte)(ep0.g + variation * varPatternG[i]), - (byte)(ep0.b + variation * varPatternB[i]), - (byte)(ep0.a + variation * varPatternA[i]) + var testEndPoint0 = new ColorRgba32( + (byte)(ep0.r + variation * patternR[i]), + (byte)(ep0.g + variation * patternG[i]), + (byte)(ep0.b + variation * patternB[i]), + (byte)(ep0.a + variation * patternA[i]) ); ClampEndpoint(ref testEndPoint0, colorMax, alphaMax); - float error = TrySubsetEndpoints(type, raw, + var error = TrySubsetEndpoints(type, raw, ExpandEndpoint(type, testEndPoint0, pBit0), ExpandEndpoint(type, ep1, pBit1), partitionTable, subsetIndex, type4IdxMode ); @@ -1027,17 +1027,17 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, } } - for (int i = 0; i < varPatternR.Length; i++) + for (var i = 0; i < patternR.Length; i++) { - ColorRgba32 testEndPoint1 = new ColorRgba32( - (byte)(ep1.r + variation * varPatternR[i]), - (byte)(ep1.g + variation * varPatternG[i]), - (byte)(ep1.b + variation * varPatternB[i]), - (byte)(ep1.a + variation * varPatternA[i]) + var testEndPoint1 = new ColorRgba32( + (byte)(ep1.r + variation * patternR[i]), + (byte)(ep1.g + variation * patternG[i]), + (byte)(ep1.b + variation * patternB[i]), + (byte)(ep1.a + variation * patternA[i]) ); ClampEndpoint(ref testEndPoint1, colorMax, alphaMax); - float error = TrySubsetEndpoints(type, raw, + var error = TrySubsetEndpoints(type, raw, ExpandEndpoint(type, ep0, pBit0), ExpandEndpoint(type, testEndPoint1, pBit1), partitionTable, subsetIndex, type4IdxMode ); @@ -1052,8 +1052,8 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, if (variatePBits) { { - byte testPBit0 = pBit0 == 0 ? (byte)1 : (byte)0; - float error = TrySubsetEndpoints(type, raw, + var testPBit0 = pBit0 == 0 ? (byte)1 : (byte)0; + var error = TrySubsetEndpoints(type, raw, ExpandEndpoint(type, ep0, testPBit0), ExpandEndpoint(type, ep1, pBit1), partitionTable, subsetIndex, type4IdxMode ); @@ -1065,8 +1065,8 @@ private static int FindClosestAlphaIndex(byte alpha, ReadOnlySpan alphas, } } { - byte testPBit1 = pBit1 == 0 ? (byte)1 : (byte)0; - float error = TrySubsetEndpoints(type, raw, + var testPBit1 = pBit1 == 0 ? (byte)1 : (byte)0; + var error = TrySubsetEndpoints(type, raw, ExpandEndpoint(type, ep0, pBit0), ExpandEndpoint(type, ep1, testPBit1), partitionTable, subsetIndex, type4IdxMode ); @@ -1092,10 +1092,10 @@ public static RawBlock4X4Rgba32 RotateBlockColors(RawBlock4X4Rgba32 block, int r return block; } - RawBlock4X4Rgba32 rotated = new RawBlock4X4Rgba32(); + var rotated = new RawBlock4X4Rgba32(); var pixels = block.AsSpan; var output = rotated.AsSpan; - for (int i = 0; i < 16; i++) + for (var i = 0; i < 16; i++) { var c = pixels[i]; switch (rotation) diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode0Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode0Encoder.cs index 1469173..12977d5 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode0Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode0Encoder.cs @@ -8,7 +8,7 @@ internal static class Bc7Mode0Encoder public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation, int bestPartition) { - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); const Bc7BlockType type = Bc7BlockType.Type0; if(bestPartition >= 16) @@ -16,26 +16,26 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariatio throw new IndexOutOfRangeException("Mode0 only has 16 partitions"); } - ColorRgba32[] endpoints = new ColorRgba32[6]; - byte[] pBits = new byte[6]; + var endpoints = new ColorRgba32[6]; + var pBits = new byte[6]; ReadOnlySpan partitionTable = Bc7Block.Subsets3PartitionTable[bestPartition]; - byte[] indices = new byte[16]; + var indices = new byte[16]; - int[] anchorIndices = new int[] { + var anchorIndices = new int[] { 0, Bc7Block.Subsets3AnchorIndices2[bestPartition], Bc7Block.Subsets3AnchorIndices3[bestPartition] }; - for (int subset = 0; subset < 3; subset++) { + for (var subset = 0; subset < 3; subset++) { Bc7EncodingHelpers.GetInitialUnscaledEndpointsForSubset(block, out var ep0, out var ep1, partitionTable, subset); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out byte pBit0); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out byte pBit1); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out var pBit0); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out var pBit1); Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, block, ref scaledEp0, ref scaledEp1, ref pBit0, ref pBit1, startingVariation, partitionTable, subset, true, false); diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode1Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode1Encoder.cs index e8d9a51..735a82e 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode1Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode1Encoder.cs @@ -8,28 +8,28 @@ internal static class Bc7Mode1Encoder public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation, int bestPartition) { - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); const Bc7BlockType type = Bc7BlockType.Type1; - ColorRgba32[] endpoints = new ColorRgba32[4]; - byte[] pBits = new byte[2]; + var endpoints = new ColorRgba32[4]; + var pBits = new byte[2]; ReadOnlySpan partitionTable = Bc7Block.Subsets2PartitionTable[bestPartition]; - byte[] indices = new byte[16]; + var indices = new byte[16]; - int[] anchorIndices = new int[] { + var anchorIndices = new int[] { 0, Bc7Block.Subsets2AnchorIndices[bestPartition] }; - for (int subset = 0; subset < 2; subset++) { + for (var subset = 0; subset < 2; subset++) { Bc7EncodingHelpers.GetInitialUnscaledEndpointsForSubset(block, out var ep0, out var ep1, partitionTable, subset); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out byte pBit); - ColorRgba32 scaledEp1 = + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out var pBit); + var scaledEp1 = Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out pBit); Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, block, ref scaledEp0, diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode2Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode2Encoder.cs index dee4405..d6fd5eb 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode2Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode2Encoder.cs @@ -8,28 +8,28 @@ internal static class Bc7Mode2Encoder public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation, int bestPartition) { - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); const Bc7BlockType type = Bc7BlockType.Type2; - ColorRgba32[] endpoints = new ColorRgba32[6]; + var endpoints = new ColorRgba32[6]; ReadOnlySpan partitionTable = Bc7Block.Subsets3PartitionTable[bestPartition]; - byte[] indices = new byte[16]; + var indices = new byte[16]; - int[] anchorIndices = new int[] { + var anchorIndices = new int[] { 0, Bc7Block.Subsets3AnchorIndices2[bestPartition], Bc7Block.Subsets3AnchorIndices3[bestPartition] }; - for (int subset = 0; subset < 3; subset++) { + for (var subset = 0; subset < 3; subset++) { Bc7EncodingHelpers.GetInitialUnscaledEndpointsForSubset(block, out var ep0, out var ep1, partitionTable, subset); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out byte _); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out byte _); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out var _); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out var _); byte pBit = 0; Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, block, ref scaledEp0, diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode3Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode3Encoder.cs index 61dd40b..49ae4ed 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode3Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode3Encoder.cs @@ -8,28 +8,28 @@ internal static class Bc7Mode3Encoder public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation, int bestPartition) { - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); const Bc7BlockType type = Bc7BlockType.Type3; - ColorRgba32[] endpoints = new ColorRgba32[4]; - byte[] pBits = new byte[4]; + var endpoints = new ColorRgba32[4]; + var pBits = new byte[4]; ReadOnlySpan partitionTable = Bc7Block.Subsets2PartitionTable[bestPartition]; - byte[] indices = new byte[16]; + var indices = new byte[16]; - int[] anchorIndices = new int[] { + var anchorIndices = new int[] { 0, Bc7Block.Subsets2AnchorIndices[bestPartition] }; - for (int subset = 0; subset < 2; subset++) { + for (var subset = 0; subset < 2; subset++) { Bc7EncodingHelpers.GetInitialUnscaledEndpointsForSubset(block, out var ep0, out var ep1, partitionTable, subset); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out byte pBit0); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out byte pBit1); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, true, out var pBit0); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, true, out var pBit1); Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, block, ref scaledEp0, ref scaledEp1, ref pBit0, ref pBit1, startingVariation, partitionTable, subset, true, false); diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode4Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode4Encoder.cs index c25df51..55bf8f6 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode4Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode4Encoder.cs @@ -6,8 +6,8 @@ namespace BCnEncoder.Encoder.Bc7 internal static class Bc7Mode4Encoder { - private static ReadOnlySpan partitionTable => new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - const int subset = 0; + private static ReadOnlySpan PartitionTable => new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const int Subset_ = 0; public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation) { @@ -15,36 +15,36 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariatio Span outputs = stackalloc Bc7Block[8]; - for (int idxMode = 0; idxMode < 2; idxMode++) + for (var idxMode = 0; idxMode < 2; idxMode++) { - for (int rotation = 0; rotation < 4; rotation++) + for (var rotation = 0; rotation < 4; rotation++) { var rotatedBlock = Bc7EncodingHelpers.RotateBlockColors(block, rotation); - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); Bc7EncodingHelpers.GetInitialUnscaledEndpoints(rotatedBlock, out var ep0, out var ep1); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, false, out byte _); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, false, out byte _); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, false, out var _); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, false, out var _); byte pBit = 0; //fake pBit Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, rotatedBlock, ref scaledEp0, - ref scaledEp1, ref pBit, ref pBit, startingVariation, partitionTable, subset, + ref scaledEp1, ref pBit, ref pBit, startingVariation, PartitionTable, Subset_, false, true, idxMode); ep0 = Bc7EncodingHelpers.ExpandEndpoint(type, scaledEp0, 0); ep1 = Bc7EncodingHelpers.ExpandEndpoint(type, scaledEp1, 0); - byte[] colorIndices = new byte[16]; - byte[] alphaIndices = new byte[16]; + var colorIndices = new byte[16]; + var alphaIndices = new byte[16]; Bc7EncodingHelpers.FillAlphaColorIndices(type, rotatedBlock, ep0, ep1, colorIndices, alphaIndices, idxMode); - bool needsRedo = false; + var needsRedo = false; if ((colorIndices[0] & (idxMode == 0 ? 0b10 : 0b100)) > 0) //If anchor index most significant bit is 1, switch endpoints @@ -105,16 +105,16 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariatio } } - int bestIndex = 0; + var bestIndex = 0; float bestError = 0; - bool first = true; + var first = true; // Find best out of generated blocks - for (int i = 0; i < outputs.Length; i++) + for (var i = 0; i < outputs.Length; i++) { var decoded = outputs[i].Decode(); - float error = block.CalculateYCbCrAlphaError(decoded); + var error = block.CalculateYCbCrAlphaError(decoded); if (error < bestError || first) { first = false; diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode5Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode5Encoder.cs index 1b5c881..1d97ac6 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode5Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode5Encoder.cs @@ -5,8 +5,8 @@ namespace BCnEncoder.Encoder.Bc7 { internal static class Bc7Mode5Encoder { - private static ReadOnlySpan partitionTable => new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - const int subset = 0; + private static ReadOnlySpan PartitionTable => new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + const int Subset_ = 0; public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation) { @@ -14,32 +14,32 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariatio Span outputs = stackalloc Bc7Block[4]; - for (int rotation = 0; rotation < 4; rotation++) { + for (var rotation = 0; rotation < 4; rotation++) { var rotatedBlock = Bc7EncodingHelpers.RotateBlockColors(block, rotation); - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); Bc7EncodingHelpers.GetInitialUnscaledEndpoints(rotatedBlock, out var ep0, out var ep1); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, false, out byte _); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, false, out byte _); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, false, out var _); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, false, out var _); byte pBit = 0; //fake pBit Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, rotatedBlock, ref scaledEp0, - ref scaledEp1, ref pBit, ref pBit, startingVariation, partitionTable, subset, false, true); + ref scaledEp1, ref pBit, ref pBit, startingVariation, PartitionTable, Subset_, false, true); ep0 = Bc7EncodingHelpers.ExpandEndpoint(type, scaledEp0, 0); ep1 = Bc7EncodingHelpers.ExpandEndpoint(type, scaledEp1, 0); - byte[] colorIndices = new byte[16]; - byte[] alphaIndices = new byte[16]; + var colorIndices = new byte[16]; + var alphaIndices = new byte[16]; Bc7EncodingHelpers.FillAlphaColorIndices(type, rotatedBlock, ep0, ep1, colorIndices, alphaIndices); - bool needsRedo = false; + var needsRedo = false; if ((colorIndices[0] & 0b10) > 0) //If anchor index most significant bit is 1, switch endpoints { @@ -85,15 +85,15 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariatio outputs[rotation] = output; } - int bestIndex = 0; + var bestIndex = 0; float bestError = 0; - bool first = true; + var first = true; // Find best out of generated blocks - for (int i = 0; i < outputs.Length; i++) { + for (var i = 0; i < outputs.Length; i++) { var decoded = outputs[i].Decode(); - float error = block.CalculateYCbCrAlphaError(decoded); + var error = block.CalculateYCbCrAlphaError(decoded); if(error < bestError || first) { first = false; bestError = error; diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode6Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode6Encoder.cs index 844a51d..e0d141a 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode6Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode6Encoder.cs @@ -8,15 +8,15 @@ internal static class Bc7Mode6Encoder public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation) { - bool hasAlpha = block.HasTransparentPixels(); + var hasAlpha = block.HasTransparentPixels(); - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); Bc7EncodingHelpers.GetInitialUnscaledEndpoints(block, out var ep0, out var ep1); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, Bc7BlockType.Type6, false, out byte pBit0); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, Bc7BlockType.Type6, false, out byte pBit1); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, Bc7BlockType.Type6, false, out var pBit0); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, Bc7BlockType.Type6, false, out var pBit1); ReadOnlySpan partitionTable = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const int subset = 0; @@ -33,7 +33,7 @@ public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariatio ep0 = Bc7EncodingHelpers.ExpandEndpoint(Bc7BlockType.Type6, scaledEp0, pBit0); ep1 = Bc7EncodingHelpers.ExpandEndpoint(Bc7BlockType.Type6, scaledEp1, pBit1); - byte[] indices = new byte[16]; + var indices = new byte[16]; Bc7EncodingHelpers.FillSubsetIndices(Bc7BlockType.Type6, block, ep0, ep1, diff --git a/BCnEnc.Net/Encoder/Bc7/Bc7Mode7Encoder.cs b/BCnEnc.Net/Encoder/Bc7/Bc7Mode7Encoder.cs index d58bf5e..7dc363c 100644 --- a/BCnEnc.Net/Encoder/Bc7/Bc7Mode7Encoder.cs +++ b/BCnEnc.Net/Encoder/Bc7/Bc7Mode7Encoder.cs @@ -8,28 +8,28 @@ internal static class Bc7Mode7Encoder public static Bc7Block EncodeBlock(RawBlock4X4Rgba32 block, int startingVariation, int bestPartition) { - Bc7Block output = new Bc7Block(); + var output = new Bc7Block(); const Bc7BlockType type = Bc7BlockType.Type7; - ColorRgba32[] endpoints = new ColorRgba32[4]; - byte[] pBits = new byte[4]; + var endpoints = new ColorRgba32[4]; + var pBits = new byte[4]; ReadOnlySpan partitionTable = Bc7Block.Subsets2PartitionTable[bestPartition]; - byte[] indices = new byte[16]; + var indices = new byte[16]; - int[] anchorIndices = new int[] { + var anchorIndices = new int[] { 0, Bc7Block.Subsets2AnchorIndices[bestPartition] }; - for (int subset = 0; subset < 2; subset++) { + for (var subset = 0; subset < 2; subset++) { Bc7EncodingHelpers.GetInitialUnscaledEndpointsForSubset(block, out var ep0, out var ep1, partitionTable, subset); - ColorRgba32 scaledEp0 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, false, out byte pBit0); - ColorRgba32 scaledEp1 = - Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, false, out byte pBit1); + var scaledEp0 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep0, type, false, out var pBit0); + var scaledEp1 = + Bc7EncodingHelpers.ScaleDownEndpoint(ep1, type, false, out var pBit1); Bc7EncodingHelpers.OptimizeSubsetEndpointsWithPBit(type, block, ref scaledEp0, ref scaledEp1, ref pBit0, ref pBit1, startingVariation, partitionTable, subset, true, true); diff --git a/BCnEnc.Net/Encoder/BcEncoder.cs b/BCnEnc.Net/Encoder/BcEncoder.cs index 6446af2..7e4ec08 100644 --- a/BCnEnc.Net/Encoder/BcEncoder.cs +++ b/BCnEnc.Net/Encoder/BcEncoder.cs @@ -33,10 +33,10 @@ public class BcEncoder /// /// Creates a new instance of . /// - /// The block compression format to encode an image with. - public BcEncoder(CompressionFormat format = CompressionFormat.BC1) + /// The block compression Format to encode an image with. + public BcEncoder(CompressionFormat format = CompressionFormat.Bc1) { - OutputOptions.format = format; + OutputOptions.Format = format; } /// @@ -46,7 +46,7 @@ public BcEncoder(CompressionFormat format = CompressionFormat.BC1) /// The stream to write the encoded image to. public void Encode(Image inputImage, Stream outputStream) { - switch (OutputOptions.fileFormat) + switch (OutputOptions.FileFormat) { case OutputFileFormat.Dds: var dds = EncodeToDds(inputImage); @@ -71,16 +71,18 @@ public KtxFile EncodeToKtx(Image inputImage) IBcBlockEncoder compressedEncoder = null; IRawEncoder uncompressedEncoder = null; - var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var numMipMaps = OutputOptions.GenerateMipMaps ? (uint)OutputOptions.MaxMipMapLevel : 1; var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); // Setup encoders - var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + var isCompressedFormat = OutputOptions.Format.IsCompressedFormat(); if (isCompressedFormat) { - compressedEncoder = GetEncoder(OutputOptions.format); + compressedEncoder = GetEncoder(OutputOptions.Format); if (compressedEncoder == null) - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + { + throw new NotSupportedException($"This Format is not supported: {OutputOptions.Format}"); + } output = new KtxFile( KtxHeader.InitializeCompressed(inputImage.Width, inputImage.Height, @@ -89,7 +91,7 @@ public KtxFile EncodeToKtx(Image inputImage) } else { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); + uncompressedEncoder = GetRawEncoder(OutputOptions.Format); output = new KtxFile( KtxHeader.InitializeUncompressed(inputImage.Width, inputImage.Height, uncompressedEncoder.GetGlType(), @@ -105,8 +107,8 @@ public KtxFile EncodeToKtx(Image inputImage) byte[] encoded; if (isCompressedFormat) { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out var blocksWidth, out var blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.Quality, !Debugger.IsAttached && Options.multiThreaded); } else @@ -129,8 +131,8 @@ public KtxFile EncodeToKtx(Image inputImage) foreach (var image in mipChain) image.Dispose(); - output.Header.NumberOfFaces = 1; - output.Header.NumberOfMipmapLevels = numMipMaps; + output.header.NumberOfFaces = 1; + output.header.NumberOfMipmapLevels = numMipMaps; return output; } @@ -146,30 +148,32 @@ public DdsFile EncodeToDds(Image inputImage) IBcBlockEncoder compressedEncoder = null; IRawEncoder uncompressedEncoder = null; - var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var numMipMaps = OutputOptions.GenerateMipMaps ? (uint)OutputOptions.MaxMipMapLevel : 1; var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); // Setup encoder - var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + var isCompressedFormat = OutputOptions.Format.IsCompressedFormat(); if (isCompressedFormat) { - compressedEncoder = GetEncoder(OutputOptions.format); + compressedEncoder = GetEncoder(OutputOptions.Format); if (compressedEncoder == null) - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + { + throw new NotSupportedException($"This Format is not supported: {OutputOptions.Format}"); + } var (ddsHeader, dxt10Header) = DdsHeader.InitializeCompressed(inputImage.Width, inputImage.Height, compressedEncoder.GetDxgiFormat()); output = new DdsFile(ddsHeader, dxt10Header); - if (OutputOptions.ddsBc1WriteAlphaFlag && - OutputOptions.format == CompressionFormat.BC1WithAlpha) + if (OutputOptions.DdsBc1WriteAlphaFlag && + OutputOptions.Format == CompressionFormat.Bc1WithAlpha) { - output.Header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DDPF_ALPHAPIXELS; + output.header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DdpfAlphapixels; } } else { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); + uncompressedEncoder = GetRawEncoder(OutputOptions.Format); var ddsHeader = DdsHeader.InitializeUncompressed(inputImage.Width, inputImage.Height, uncompressedEncoder.GetDxgiFormat()); output = new DdsFile(ddsHeader); @@ -182,13 +186,15 @@ public DdsFile EncodeToDds(Image inputImage) if (isCompressedFormat) { var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out var blocksWidth, out var blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.Quality, !Debugger.IsAttached && Options.multiThreaded); } else { if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + { throw new Exception("Cannot get pixel span."); + } encoded = uncompressedEncoder.Encode(mipPixels); } @@ -206,11 +212,15 @@ public DdsFile EncodeToDds(Image inputImage) // Dispose all mipmap levels foreach (var image in mipChain) + { image.Dispose(); + } - output.Header.dwMipMapCount = numMipMaps; + output.header.dwMipMapCount = numMipMaps; if (numMipMaps > 1) - output.Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX | HeaderCaps.DDSCAPS_MIPMAP; + { + output.header.dwCaps |= HeaderCaps.DdscapsComplex | HeaderCaps.DdscapsMipmap; + } return output; } @@ -226,20 +236,22 @@ public IList EncodeToRawBytes(Image inputImage) IBcBlockEncoder compressedEncoder = null; IRawEncoder uncompressedEncoder = null; - var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var numMipMaps = OutputOptions.GenerateMipMaps ? (uint)OutputOptions.MaxMipMapLevel : 1; var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); // Setup encoder - var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + var isCompressedFormat = OutputOptions.Format.IsCompressedFormat(); if (isCompressedFormat) { - compressedEncoder = GetEncoder(OutputOptions.format); + compressedEncoder = GetEncoder(OutputOptions.Format); if (compressedEncoder == null) - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + { + throw new NotSupportedException($"This Format is not supported: {OutputOptions.Format}"); + } } else { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); + uncompressedEncoder = GetRawEncoder(OutputOptions.Format); } // Encode all mipmap levels @@ -248,14 +260,16 @@ public IList EncodeToRawBytes(Image inputImage) byte[] encoded; if (isCompressedFormat) { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out var blocksWidth, out var blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.Quality, !Debugger.IsAttached && Options.multiThreaded); } else { if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + { throw new Exception("Cannot get pixel span."); + } encoded = uncompressedEncoder.Encode(mipPixels); } @@ -265,7 +279,9 @@ public IList EncodeToRawBytes(Image inputImage) // Dispose all mipmap levels foreach (var image in mipChain) + { image.Dispose(); + } return output; } @@ -286,27 +302,31 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m IBcBlockEncoder compressedEncoder = null; IRawEncoder uncompressedEncoder = null; - var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var numMipMaps = OutputOptions.GenerateMipMaps ? (uint)OutputOptions.MaxMipMapLevel : 1; var mipChain = MipMapper.GenerateMipChain(inputImage, ref numMipMaps); // Setup encoder - var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + var isCompressedFormat = OutputOptions.Format.IsCompressedFormat(); if (isCompressedFormat) { - compressedEncoder = GetEncoder(OutputOptions.format); + compressedEncoder = GetEncoder(OutputOptions.Format); if (compressedEncoder == null) - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + { + throw new NotSupportedException($"This Format is not supported: {OutputOptions.Format}"); + } } else { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); + uncompressedEncoder = GetRawEncoder(OutputOptions.Format); } // Dispose all mipmap levels if (mipLevel > numMipMaps - 1) { foreach (var image in mipChain) + { image.Dispose(); + } throw new ArgumentException($"{nameof(mipLevel)} cannot be more than number of mipmaps."); } @@ -315,14 +335,16 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m byte[] encoded; if (isCompressedFormat) { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mipLevel].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mipLevel].Frames[0], out var blocksWidth, out var blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.Quality, !Debugger.IsAttached && Options.multiThreaded); } else { if (!mipChain[mipLevel].TryGetSinglePixelSpan(out var mipPixels)) + { throw new Exception("Cannot get pixel span."); + } encoded = uncompressedEncoder.Encode(mipPixels); } @@ -332,7 +354,9 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m // Dispose all mipmap levels foreach (var image in mipChain) + { image.Dispose(); + } return encoded; } @@ -351,7 +375,7 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m public void EncodeCubeMap(Image right, Image left, Image top, Image down, Image back, Image front, Stream outputStream) { - switch (OutputOptions.fileFormat) + switch (OutputOptions.FileFormat) { case OutputFileFormat.Ktx: var ktx = EncodeCubeMapToKtx(right, left, top, down, back, front); @@ -394,12 +418,14 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m var faces = new[] { right, left, top, down, back, front }; // Setup encoder - var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + var isCompressedFormat = OutputOptions.Format.IsCompressedFormat(); if (isCompressedFormat) { - compressedEncoder = GetEncoder(OutputOptions.format); + compressedEncoder = GetEncoder(OutputOptions.Format); if (compressedEncoder == null) - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + { + throw new NotSupportedException($"This Format is not supported: {OutputOptions.Format}"); + } output = new KtxFile( KtxHeader.InitializeCompressed(right.Width, right.Height, @@ -408,7 +434,7 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m } else { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); + uncompressedEncoder = GetRawEncoder(OutputOptions.Format); output = new KtxFile( KtxHeader.InitializeUncompressed(right.Width, right.Height, uncompressedEncoder.GetGlType(), @@ -419,7 +445,7 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m } - var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var numMipMaps = OutputOptions.GenerateMipMaps ? (uint)OutputOptions.MaxMipMapLevel : 1; var mipLength = MipMapper.CalculateMipChainLength(right.Width, right.Height, numMipMaps); for (uint i = 0; i < mipLength; i++) { @@ -437,14 +463,16 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m byte[] encoded; if (isCompressedFormat) { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out var blocksWidth, out var blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.Quality, !Debugger.IsAttached && Options.multiThreaded); } else { if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + { throw new Exception("Cannot get pixel span."); + } encoded = uncompressedEncoder.Encode(mipPixels); } @@ -463,11 +491,13 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m // Dispose all mipmap levels foreach (var image in mipChain) + { image.Dispose(); + } } - output.Header.NumberOfFaces = (uint)faces.Length; - output.Header.NumberOfMipmapLevels = mipLength; + output.header.NumberOfFaces = (uint)faces.Length; + output.header.NumberOfMipmapLevels = mipLength; return output; } @@ -501,33 +531,35 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m var faces = new[] { right, left, top, down, back, front }; // Setup encoder - var isCompressedFormat = OutputOptions.format.IsCompressedFormat(); + var isCompressedFormat = OutputOptions.Format.IsCompressedFormat(); if (isCompressedFormat) { - compressedEncoder = GetEncoder(OutputOptions.format); + compressedEncoder = GetEncoder(OutputOptions.Format); if (compressedEncoder == null) - throw new NotSupportedException($"This format is not supported: {OutputOptions.format}"); + { + throw new NotSupportedException($"This Format is not supported: {OutputOptions.Format}"); + } var (ddsHeader, dxt10Header) = DdsHeader.InitializeCompressed(right.Width, right.Height, compressedEncoder.GetDxgiFormat()); output = new DdsFile(ddsHeader, dxt10Header); - if (OutputOptions.ddsBc1WriteAlphaFlag && - OutputOptions.format == CompressionFormat.BC1WithAlpha) + if (OutputOptions.DdsBc1WriteAlphaFlag && + OutputOptions.Format == CompressionFormat.Bc1WithAlpha) { - output.Header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DDPF_ALPHAPIXELS; + output.header.ddsPixelFormat.dwFlags |= PixelFormatFlags.DdpfAlphapixels; } } else { - uncompressedEncoder = GetRawEncoder(OutputOptions.format); + uncompressedEncoder = GetRawEncoder(OutputOptions.Format); var ddsHeader = DdsHeader.InitializeUncompressed(right.Width, right.Height, uncompressedEncoder.GetDxgiFormat()); output = new DdsFile(ddsHeader); } - var numMipMaps = OutputOptions.generateMipMaps ? (uint)OutputOptions.maxMipMapLevel : 1; + var numMipMaps = OutputOptions.GenerateMipMaps ? (uint)OutputOptions.MaxMipMapLevel : 1; // Encode all faces for (var face = 0; face < faces.Length; face++) @@ -540,14 +572,16 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m byte[] encoded; if (isCompressedFormat) { - var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out int blocksWidth, out int blocksHeight); - encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.quality, + var blocks = ImageToBlocks.ImageTo4X4(mipChain[mip].Frames[0], out var blocksWidth, out var blocksHeight); + encoded = compressedEncoder.Encode(blocks, blocksWidth, blocksHeight, OutputOptions.Quality, !Debugger.IsAttached && Options.multiThreaded); } else { if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) + { throw new Exception("Cannot get pixel span."); + } encoded = uncompressedEncoder.Encode(mipPixels); } @@ -565,22 +599,25 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m // Dispose all mipmap levels foreach (var image in mipChain) + { image.Dispose(); + } } - output.Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX; - output.Header.dwMipMapCount = numMipMaps; + output.header.dwCaps |= HeaderCaps.DdscapsComplex; + output.header.dwMipMapCount = numMipMaps; if (numMipMaps > 1) { - output.Header.dwCaps |= HeaderCaps.DDSCAPS_MIPMAP; + output.header.dwCaps |= HeaderCaps.DdscapsMipmap; } - output.Header.dwCaps2 |= HeaderCaps2.DDSCAPS2_CUBEMAP | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEX | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEX | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEY | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEY | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEZ | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEZ; + + output.header.dwCaps2 |= HeaderCaps2.Ddscaps2Cubemap | + HeaderCaps2.Ddscaps2CubemapPositivex | + HeaderCaps2.Ddscaps2CubemapNegativex | + HeaderCaps2.Ddscaps2CubemapPositivey | + HeaderCaps2.Ddscaps2CubemapNegativey | + HeaderCaps2.Ddscaps2CubemapPositivez | + HeaderCaps2.Ddscaps2CubemapNegativez; return output; } @@ -589,25 +626,25 @@ private IBcBlockEncoder GetEncoder(CompressionFormat format) { switch (format) { - case CompressionFormat.BC1: + case CompressionFormat.Bc1: return new Bc1BlockEncoder(); - case CompressionFormat.BC1WithAlpha: + case CompressionFormat.Bc1WithAlpha: return new Bc1AlphaBlockEncoder(); - case CompressionFormat.BC2: + case CompressionFormat.Bc2: return new Bc2BlockEncoder(); - case CompressionFormat.BC3: + case CompressionFormat.Bc3: return new Bc3BlockEncoder(); - case CompressionFormat.BC4: - return new Bc4BlockEncoder(InputOptions.luminanceAsRed); + case CompressionFormat.Bc4: + return new Bc4BlockEncoder(InputOptions.LuminanceAsRed); - case CompressionFormat.BC5: + case CompressionFormat.Bc5: return new Bc5BlockEncoder(); - case CompressionFormat.BC7: + case CompressionFormat.Bc7: return new Bc7Encoder(); default: @@ -620,16 +657,16 @@ private IRawEncoder GetRawEncoder(CompressionFormat format) switch (format) { case CompressionFormat.R: - return new RawLuminanceEncoder(InputOptions.luminanceAsRed); + return new RawLuminanceEncoder(InputOptions.LuminanceAsRed); - case CompressionFormat.RG: - return new RawRGEncoder(); + case CompressionFormat.Rg: + return new RawRgEncoder(); - case CompressionFormat.RGB: - return new RawRGBEncoder(); + case CompressionFormat.Rgb: + return new RawRgbEncoder(); - case CompressionFormat.RGBA: - return new RawRGBAEncoder(); + case CompressionFormat.Rgba: + return new RawRgbaEncoder(); default: throw new ArgumentOutOfRangeException(nameof(format), format, null); diff --git a/BCnEnc.Net/Encoder/ColorChooser.cs b/BCnEnc.Net/Encoder/ColorChooser.cs index ae4ac45..505cee0 100644 --- a/BCnEnc.Net/Encoder/ColorChooser.cs +++ b/BCnEnc.Net/Encoder/ColorChooser.cs @@ -24,17 +24,17 @@ public static int ChooseClosestColor4(ReadOnlySpan colors, Rgba32 co + MathF.Abs(colors[3].b - color.B) * bWeight, }; - int b0 = d[0] > d[3] ? 1 : 0; - int b1 = d[1] > d[2] ? 1 : 0; - int b2 = d[0] > d[2] ? 1 : 0; - int b3 = d[1] > d[3] ? 1 : 0; - int b4 = d[2] > d[3] ? 1 : 0; + var b0 = d[0] > d[3] ? 1 : 0; + var b1 = d[1] > d[2] ? 1 : 0; + var b2 = d[0] > d[2] ? 1 : 0; + var b3 = d[1] > d[3] ? 1 : 0; + var b4 = d[2] > d[3] ? 1 : 0; - int x0 = b1 & b2; - int x1 = b0 & b3; - int x2 = b0 & b4; + var x0 = b1 & b2; + var x1 = b0 & b3; + var x2 = b0 & b4; - int idx = (x2 | ((x0 | x1) << 1)); + var idx = x2 | ((x0 | x1) << 1); error = d[idx]; return idx; } @@ -66,15 +66,15 @@ public static int ChooseClosestColor4AlphaCutoff(ReadOnlySpan colors + MathF.Abs(colors[3].b - color.B) * bWeight, }; - int b0 = d[0] > d[2] ? 1 : 0; - int b1 = d[1] > d[3] ? 1 : 0; - int b2 = d[0] > d[3] ? 1 : 0; - int b3 = d[1] > d[2] ? 1 : 0; - int nb3 = d[1] > d[2] ? 0 : 1; - int b4 = d[0] > d[1] ? 1 : 0; - int b5 = d[2] > d[3] ? 1 : 0; + var b0 = d[0] > d[2] ? 1 : 0; + var b1 = d[1] > d[3] ? 1 : 0; + var b2 = d[0] > d[3] ? 1 : 0; + var b3 = d[1] > d[2] ? 1 : 0; + var nb3 = d[1] > d[2] ? 0 : 1; + var b4 = d[0] > d[1] ? 1 : 0; + var b5 = d[2] > d[3] ? 1 : 0; - int idx = (nb3 & b4) | (b2 & b5) | (((b0 & b3) | (b1 & b2)) << 1); + var idx = (nb3 & b4) | (b2 & b5) | (((b0 & b3) | (b1 & b2)) << 1); error = d[idx]; return idx; @@ -82,15 +82,15 @@ public static int ChooseClosestColor4AlphaCutoff(ReadOnlySpan colors public static int ChooseClosestColor(Span colors, Rgba32 color) { - int closest = 0; - int closestError = + var closest = 0; + var closestError = Math.Abs(colors[0].r - color.R) + Math.Abs(colors[0].g - color.G) + Math.Abs(colors[0].b - color.B); - for (int i = 1; i < colors.Length; i++) + for (var i = 1; i < colors.Length; i++) { - int error = + var error = Math.Abs(colors[i].r - color.R) + Math.Abs(colors[i].g - color.G) + Math.Abs(colors[i].b - color.B); @@ -105,16 +105,16 @@ public static int ChooseClosestColor(Span colors, Rgba32 color) public static int ChooseClosestColor(Span colors, Rgba32 color) { - int closest = 0; - int closestError = + var closest = 0; + var closestError = Math.Abs(colors[0].r - color.R) + Math.Abs(colors[0].g - color.G) + Math.Abs(colors[0].b - color.B) + Math.Abs(colors[0].a - color.A); - for (int i = 1; i < colors.Length; i++) + for (var i = 1; i < colors.Length; i++) { - int error = + var error = Math.Abs(colors[i].r - color.R) + Math.Abs(colors[i].g - color.G) + Math.Abs(colors[i].b - color.B) @@ -135,16 +135,16 @@ public static int ChooseClosestColorAlphaCutOff(Span colors, Rgba32 return 3; } - int closest = 0; - int closestError = + var closest = 0; + var closestError = Math.Abs(colors[0].r - color.R) + Math.Abs(colors[0].g - color.G) + Math.Abs(colors[0].b - color.B); - for (int i = 1; i < colors.Length; i++) + for (var i = 1; i < colors.Length; i++) { if (i == 3) continue; // Skip transparent - int error = + var error = Math.Abs(colors[i].r - color.R) + Math.Abs(colors[i].g - color.G) + Math.Abs(colors[i].b - color.B); @@ -159,15 +159,15 @@ public static int ChooseClosestColorAlphaCutOff(Span colors, Rgba32 public static int ChooseClosestColor(Span colors, ColorYCbCr color, float luminanceMultiplier = 4) { - int closest = 0; + var closest = 0; float closestError = 0; - bool first = true; + var first = true; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { - float error = MathF.Abs(colors[i].y - color.y) * luminanceMultiplier - + MathF.Abs(colors[i].cb - color.cb) - + MathF.Abs(colors[i].cr - color.cr); + var error = MathF.Abs(colors[i].y - color.y) * luminanceMultiplier + + MathF.Abs(colors[i].cb - color.cb) + + MathF.Abs(colors[i].cr - color.cr); if (first) { closestError = error; diff --git a/BCnEnc.Net/Encoder/ColorVariationGenerator.cs b/BCnEnc.Net/Encoder/ColorVariationGenerator.cs index 96185ed..d505361 100644 --- a/BCnEnc.Net/Encoder/ColorVariationGenerator.cs +++ b/BCnEnc.Net/Encoder/ColorVariationGenerator.cs @@ -15,7 +15,7 @@ internal static class ColorVariationGenerator public static int VarPatternCount => varPatternEp0R.Length; public static (ColorRgb565, ColorRgb565) Variate565(ColorRgb565 c0, ColorRgb565 c1, int i) { - int idx = i % varPatternEp0R.Length; + var idx = i % varPatternEp0R.Length; var newEp0 = new ColorRgb565(); var newEp1 = new ColorRgb565(); @@ -33,11 +33,11 @@ internal static class ColorVariationGenerator public static List GenerateVariationsSidewaysMax(int variations, ColorYCbCr min, ColorYCbCr max) { - List colors = new List(); + var colors = new List(); colors.Add(min.ToColorRgb565()); colors.Add(max.ToColorRgb565()); - for (int i = 0; i < variations; i++) + for (var i = 0; i < variations; i++) { max.y -= 0.05f; min.y += 0.05f; @@ -86,11 +86,11 @@ public static List GenerateVariationsSidewaysMax(int variations, Co public static List GenerateVariationsSidewaysMinMax(int variations, ColorYCbCr min, ColorYCbCr max) { - List colors = new List(); + var colors = new List(); colors.Add(min.ToColorRgb565()); colors.Add(max.ToColorRgb565()); - for (int i = 0; i < variations; i++) + for (var i = 0; i < variations; i++) { max.y -= 0.05f; min.y += 0.05f; diff --git a/BCnEnc.Net/Encoder/CompressionQuality.cs b/BCnEnc.Net/Encoder/CompressionQuality.cs index b857a45..27dda30 100644 --- a/BCnEnc.Net/Encoder/CompressionQuality.cs +++ b/BCnEnc.Net/Encoder/CompressionQuality.cs @@ -3,15 +3,15 @@ public enum CompressionQuality { /// - /// Fast, but low quality. Especially bad with gradients. + /// Fast, but low Quality. Especially bad with gradients. /// Fast, /// - /// Strikes a balance between speed and quality. Good enough for most purposes. + /// Strikes a balance between speed and Quality. Good enough for most purposes. /// Balanced, /// - /// Aims for best quality encoding. Can be very slow. + /// Aims for best Quality encoding. Can be very slow. /// BestQuality } diff --git a/BCnEnc.Net/Encoder/IBcBlockEncoder.cs b/BCnEnc.Net/Encoder/IBcBlockEncoder.cs index 1801c16..add7372 100644 --- a/BCnEnc.Net/Encoder/IBcBlockEncoder.cs +++ b/BCnEnc.Net/Encoder/IBcBlockEncoder.cs @@ -8,8 +8,8 @@ internal interface IBcBlockEncoder { byte[] Encode(RawBlock4X4Rgba32[] blocks, int blockWidth, int blockHeight, CompressionQuality quality, bool parallel = true); GlInternalFormat GetInternalFormat(); - GLFormat GetBaseInternalFormat(); - DXGI_FORMAT GetDxgiFormat(); + GlFormat GetBaseInternalFormat(); + DxgiFormat GetDxgiFormat(); } diff --git a/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs b/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs index dbc59d8..2cd9948 100644 --- a/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs +++ b/BCnEnc.Net/Encoder/Options/EncoderInputOptions.cs @@ -1,11 +1,14 @@ namespace BCnEncoder.Encoder.Options { + /// + /// The input options for the decoder. + /// public class EncoderInputOptions { /// - /// If true, when encoding to a format that only includes a red channel, + /// If true, when encoding to a Format that only includes a red channel, /// use the pixel luminance instead of just the red channel. Default is false. /// - public bool luminanceAsRed = false; + public bool LuminanceAsRed { get; set; } = false; } } diff --git a/BCnEnc.Net/Encoder/Options/EncoderOptions.cs b/BCnEnc.Net/Encoder/Options/EncoderOptions.cs index df95b80..1aea697 100644 --- a/BCnEnc.Net/Encoder/Options/EncoderOptions.cs +++ b/BCnEnc.Net/Encoder/Options/EncoderOptions.cs @@ -1,5 +1,8 @@ namespace BCnEncoder.Encoder.Options { + /// + /// General options for the encoder. + /// public class EncoderOptions { /// diff --git a/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs b/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs index d7fb794..6839889 100644 --- a/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs +++ b/BCnEnc.Net/Encoder/Options/EncoderOutputOptions.cs @@ -2,44 +2,47 @@ namespace BCnEncoder.Encoder.Options { + /// + /// The output options for the encoder. + /// public class EncoderOutputOptions { /// /// Whether to generate mipMaps. Default is true. /// - public bool generateMipMaps = true; + public bool GenerateMipMaps { get; set; } = true; /// /// The maximum number of mipmap levels to generate. -1 or 0 is unbounded. /// Default is -1. /// - public int maxMipMapLevel = -1; + public int MaxMipMapLevel { get; set; } = -1; /// - /// The compression format to use. Default is BC1. + /// The compression Format to use. Default is BC1. /// - public CompressionFormat format = CompressionFormat.BC1; + public CompressionFormat Format { get; set; } = CompressionFormat.Bc1; /// - /// The quality of the compression. Use either fast or balanced for testing. + /// The Quality of the compression. Use either fast or balanced for testing. /// Fast can be used for near real-time encoding for most algorithms. /// Use bestQuality when needed. Default is balanced. /// - public CompressionQuality quality = CompressionQuality.Balanced; + public CompressionQuality Quality { get; set; } = CompressionQuality.Balanced; /// - /// The output file format of the data. Either Ktx or Dds. + /// The output file Format of the data. Either Ktx or Dds. /// Default is Ktx. /// - public OutputFileFormat fileFormat = OutputFileFormat.Ktx; + public OutputFileFormat FileFormat { get; set; } = OutputFileFormat.Ktx; /// - /// The DDS file format doesn't seem to have a standard for indicating whether a BC1 texture + /// The DDS file Format doesn't seem to have a standard for indicating whether a BC1 texture /// includes 1bit of alpha. This option will write DDPF_ALPHAPIXELS flag to the header /// to indicate the presence of an alpha channel. Some programs read and write this flag, /// but some programs don't like it and get confused. Your mileage may vary. /// Default is false. /// - public bool ddsBc1WriteAlphaFlag = false; + public bool DdsBc1WriteAlphaFlag { get; set; } = false; } } diff --git a/BCnEnc.Net/Encoder/RawEncoders.cs b/BCnEnc.Net/Encoder/RawEncoders.cs index 0b5c16a..2369c40 100644 --- a/BCnEnc.Net/Encoder/RawEncoders.cs +++ b/BCnEnc.Net/Encoder/RawEncoders.cs @@ -8,11 +8,11 @@ internal interface IRawEncoder { byte[] Encode(ReadOnlySpan pixels); GlInternalFormat GetInternalFormat(); - GLFormat GetBaseInternalFormat(); - GLFormat GetGlFormat(); - GLType GetGlType(); + GlFormat GetBaseInternalFormat(); + GlFormat GetGlFormat(); + GlType GetGlType(); uint GetGlTypeSize(); - DXGI_FORMAT GetDxgiFormat(); + DxgiFormat GetDxgiFormat(); } internal class RawLuminanceEncoder : IRawEncoder { @@ -23,8 +23,8 @@ internal class RawLuminanceEncoder : IRawEncoder { } public byte[] Encode(ReadOnlySpan pixels) { - byte[] output = new byte[pixels.Length]; - for (int i = 0; i < pixels.Length; i++) { + var output = new byte[pixels.Length]; + for (var i = 0; i < pixels.Length; i++) { if (useLuminance) { output[i] = (byte)(new ColorYCbCr(pixels[i]).y * 255); } @@ -37,27 +37,27 @@ internal class RawLuminanceEncoder : IRawEncoder { } public GlInternalFormat GetInternalFormat() - => GlInternalFormat.GL_R8; + => GlInternalFormat.GlR8; - public GLFormat GetBaseInternalFormat() - => GLFormat.GL_RED; + public GlFormat GetBaseInternalFormat() + => GlFormat.GlRed; - public GLFormat GetGlFormat() => GLFormat.GL_RED; + public GlFormat GetGlFormat() => GlFormat.GlRed; - public GLType GetGlType() - => GLType.GL_BYTE; + public GlType GetGlType() + => GlType.GlByte; public uint GetGlTypeSize() => 1; - public DXGI_FORMAT GetDxgiFormat() => DXGI_FORMAT.DXGI_FORMAT_R8_UNORM; + public DxgiFormat GetDxgiFormat() => DxgiFormat.DxgiFormatR8Unorm; } - internal class RawRGEncoder : IRawEncoder + internal class RawRgEncoder : IRawEncoder { public byte[] Encode(ReadOnlySpan pixels) { - byte[] output = new byte[pixels.Length * 2]; - for (int i = 0; i < pixels.Length; i++) { + var output = new byte[pixels.Length * 2]; + for (var i = 0; i < pixels.Length; i++) { output[i * 2] = pixels[i].R; output[i * 2 + 1] = pixels[i].G; } @@ -65,27 +65,27 @@ internal class RawRGEncoder : IRawEncoder } public GlInternalFormat GetInternalFormat() - => GlInternalFormat.GL_RG8; + => GlInternalFormat.GlRg8; - public GLFormat GetBaseInternalFormat() - => GLFormat.GL_RG; + public GlFormat GetBaseInternalFormat() + => GlFormat.GlRg; - public GLFormat GetGlFormat() => GLFormat.GL_RG; + public GlFormat GetGlFormat() => GlFormat.GlRg; - public GLType GetGlType() - => GLType.GL_BYTE; + public GlType GetGlType() + => GlType.GlByte; public uint GetGlTypeSize() => 1; - public DXGI_FORMAT GetDxgiFormat() => DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM; + public DxgiFormat GetDxgiFormat() => DxgiFormat.DxgiFormatR8G8Unorm; } - internal class RawRGBEncoder : IRawEncoder + internal class RawRgbEncoder : IRawEncoder { public byte[] Encode(ReadOnlySpan pixels) { - byte[] output = new byte[pixels.Length * 3]; - for (int i = 0; i < pixels.Length; i++) { + var output = new byte[pixels.Length * 3]; + for (var i = 0; i < pixels.Length; i++) { output[i * 3] = pixels[i].R; output[i * 3 + 1] = pixels[i].G; output[i * 3 + 2] = pixels[i].B; @@ -94,27 +94,27 @@ internal class RawRGBEncoder : IRawEncoder } public GlInternalFormat GetInternalFormat() - => GlInternalFormat.GL_RGB8; + => GlInternalFormat.GlRgb8; - public GLFormat GetBaseInternalFormat() - => GLFormat.GL_RGB; + public GlFormat GetBaseInternalFormat() + => GlFormat.GlRgb; - public GLFormat GetGlFormat() => GLFormat.GL_RGB; + public GlFormat GetGlFormat() => GlFormat.GlRgb; - public GLType GetGlType() - => GLType.GL_BYTE; + public GlType GetGlType() + => GlType.GlByte; public uint GetGlTypeSize() => 1; - public DXGI_FORMAT GetDxgiFormat() => throw new NotSupportedException("RGB format is not supported for dds files."); + public DxgiFormat GetDxgiFormat() => throw new NotSupportedException("RGB Format is not supported for dds files."); } - internal class RawRGBAEncoder : IRawEncoder + internal class RawRgbaEncoder : IRawEncoder { public byte[] Encode(ReadOnlySpan pixels) { - byte[] output = new byte[pixels.Length * 4]; - for (int i = 0; i < pixels.Length; i++) { + var output = new byte[pixels.Length * 4]; + for (var i = 0; i < pixels.Length; i++) { output[i * 4] = pixels[i].R; output[i * 4 + 1] = pixels[i].G; output[i * 4 + 2] = pixels[i].B; @@ -124,19 +124,19 @@ internal class RawRGBAEncoder : IRawEncoder } public GlInternalFormat GetInternalFormat() - => GlInternalFormat.GL_RGBA8; + => GlInternalFormat.GlRgba8; - public GLFormat GetBaseInternalFormat() - => GLFormat.GL_RGBA; + public GlFormat GetBaseInternalFormat() + => GlFormat.GlRgba; - public GLFormat GetGlFormat() => GLFormat.GL_RGBA; + public GlFormat GetGlFormat() => GlFormat.GlRgba; - public GLType GetGlType() - => GLType.GL_BYTE; + public GlType GetGlType() + => GlType.GlByte; public uint GetGlTypeSize() => 1; - public DXGI_FORMAT GetDxgiFormat() => DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM; + public DxgiFormat GetDxgiFormat() => DxgiFormat.DxgiFormatR8G8B8A8Unorm; } } diff --git a/BCnEnc.Net/Shared/Bc7Block.cs b/BCnEnc.Net/Shared/Bc7Block.cs index c63e1a8..9539177 100644 --- a/BCnEnc.Net/Shared/Bc7Block.cs +++ b/BCnEnc.Net/Shared/Bc7Block.cs @@ -23,9 +23,9 @@ internal struct Bc7Block public ulong lowBits; public ulong highBits; - public static ReadOnlySpan colorInterpolationWeights2 => new byte[] { 0, 21, 43, 64 }; - public static ReadOnlySpan colorInterpolationWeights3 => new byte[] { 0, 9, 18, 27, 37, 46, 55, 64 }; - public static ReadOnlySpan colorInterpolationWeights4 => new byte[] { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; + public static ReadOnlySpan ColorInterpolationWeights2 => new byte[] { 0, 21, 43, 64 }; + public static ReadOnlySpan ColorInterpolationWeights3 => new byte[] { 0, 9, 18, 27, 37, 46, 55, 64 }; + public static ReadOnlySpan ColorInterpolationWeights4 => new byte[] { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; public static readonly int[][] Subsets2PartitionTable = { @@ -199,9 +199,9 @@ public Bc7BlockType Type { get { - for (int i = 0; i < 8; i++) + for (var i = 0; i < 8; i++) { - ulong mask = (ulong)(1 << i); + var mask = (ulong)(1 << i); if ((lowBits & mask) == mask) { return (Bc7BlockType)i; @@ -531,7 +531,7 @@ private void FinalizeEndpoints(ColorRgba32[] endpoints) { if (HasPBits) { - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { endpoints[i] <<= 1; } @@ -546,7 +546,7 @@ private void FinalizeEndpoints(ColorRgba32[] endpoints) } else { - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { endpoints[i] |= pBits[i]; } @@ -555,7 +555,7 @@ private void FinalizeEndpoints(ColorRgba32[] endpoints) var colorPrecision = ColorComponentPrecision; var alphaPrecision = AlphaComponentPrecision; - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { // ColorComponentPrecision & AlphaComponentPrecision includes pbit // left shift endpoint components so that their MSB lies in bit 7 @@ -575,7 +575,7 @@ private void FinalizeEndpoints(ColorRgba32[] endpoints) //set alpha equal to 255 if (!HasAlpha) { - for (int i = 0; i < endpoints.Length; i++) + for (var i = 0; i < endpoints.Length; i++) { endpoints[i].a = 255; } @@ -584,7 +584,7 @@ private void FinalizeEndpoints(ColorRgba32[] endpoints) public ColorRgba32[] ExtractEndpoints() { - ColorRgba32[] endpoints = new ColorRgba32[NumSubsets * 2]; + var endpoints = new ColorRgba32[NumSubsets * 2]; ExtractRawEndpoints(endpoints); FinalizeEndpoints(endpoints); return endpoints; @@ -614,7 +614,7 @@ private int GetIndexOffset(Bc7BlockType type, int numSubsets, int partitionIndex } if (numSubsets == 2) { - int anchorIndex = Subsets2AnchorIndices[partitionIndex]; + var anchorIndex = Subsets2AnchorIndices[partitionIndex]; if (index <= anchorIndex) { return bitCount * index - 1; @@ -626,8 +626,8 @@ private int GetIndexOffset(Bc7BlockType type, int numSubsets, int partitionIndex } if (numSubsets == 3) { - int anchor2Index = Subsets3AnchorIndices2[partitionIndex]; - int anchor3Index = Subsets3AnchorIndices3[partitionIndex]; + var anchor2Index = Subsets3AnchorIndices2[partitionIndex]; + var anchor3Index = Subsets3AnchorIndices3[partitionIndex]; if (index <= anchor2Index && index <= anchor3Index) { @@ -653,7 +653,7 @@ private int GetIndexBitCount(int numSubsets, int partitionIndex, int bitCount, i if (index == 0) return bitCount - 1; if (numSubsets == 2) { - int anchorIndex = Subsets2AnchorIndices[partitionIndex]; + var anchorIndex = Subsets2AnchorIndices[partitionIndex]; if (index == anchorIndex) { return bitCount - 1; @@ -661,8 +661,8 @@ private int GetIndexBitCount(int numSubsets, int partitionIndex, int bitCount, i } else if (numSubsets == 3) { - int anchor2Index = Subsets3AnchorIndices2[partitionIndex]; - int anchor3Index = Subsets3AnchorIndices3[partitionIndex]; + var anchor2Index = Subsets3AnchorIndices2[partitionIndex]; + var anchor3Index = Subsets3AnchorIndices3[partitionIndex]; if (index == anchor2Index) { return bitCount - 1; @@ -675,7 +675,7 @@ private int GetIndexBitCount(int numSubsets, int partitionIndex, int bitCount, i return bitCount; } - private int GetIndexBegin(Bc7BlockType type, int bitCount, bool IsAlpha) + private int GetIndexBegin(Bc7BlockType type, int bitCount, bool isAlpha) { switch (type) { @@ -697,7 +697,7 @@ private int GetIndexBegin(Bc7BlockType type, int bitCount, bool IsAlpha) return 81; } case Bc7BlockType.Type5: - if (IsAlpha) + if (isAlpha) { return 97; } @@ -716,17 +716,17 @@ private int GetIndexBegin(Bc7BlockType type, int bitCount, bool IsAlpha) private int GetAlphaIndex(Bc7BlockType type, int numSubsets, int partitionIndex, int bitCount, int index) { if (bitCount == 0) return 0; // No Alpha - int indexOffset = GetIndexOffset(type, numSubsets, partitionIndex, bitCount, index); - int indexBitCount = GetIndexBitCount(numSubsets, partitionIndex, bitCount, index); - int indexBegin = GetIndexBegin(type, bitCount, true); + var indexOffset = GetIndexOffset(type, numSubsets, partitionIndex, bitCount, index); + var indexBitCount = GetIndexBitCount(numSubsets, partitionIndex, bitCount, index); + var indexBegin = GetIndexBegin(type, bitCount, true); return (int)ByteHelper.ExtractFrom128(lowBits, highBits, indexBegin + indexOffset, indexBitCount); } private int GetColorIndex(Bc7BlockType type, int numSubsets, int partitionIndex, int bitCount, int index) { - int indexOffset = GetIndexOffset(type, numSubsets, partitionIndex, bitCount, index); - int indexBitCount = GetIndexBitCount(numSubsets, partitionIndex, bitCount, index); - int indexBegin = GetIndexBegin(type, bitCount, false); + var indexOffset = GetIndexOffset(type, numSubsets, partitionIndex, bitCount, index); + var indexBitCount = GetIndexBitCount(numSubsets, partitionIndex, bitCount, index); + var indexBegin = GetIndexBegin(type, bitCount, false); return (int)ByteHelper.ExtractFrom128(lowBits, highBits, indexBegin + indexOffset, indexBitCount); } @@ -736,19 +736,19 @@ private int GetColorIndex(Bc7BlockType type, int numSubsets, int partitionIndex, byte InterpolateByte(byte e0, byte e1, int index, int indexPrecision) { if (indexPrecision == 0) return e0; - ReadOnlySpan aWeights2 = colorInterpolationWeights2; - ReadOnlySpan aWeights3 = colorInterpolationWeights3; - ReadOnlySpan aWeights4 = colorInterpolationWeights4; + var aWeights2 = ColorInterpolationWeights2; + var aWeights3 = ColorInterpolationWeights3; + var aWeights4 = ColorInterpolationWeights4; if(indexPrecision == 2) - return (byte) (((64 - aWeights2[index])* (e0) + aWeights2[index]*(e1) + 32) >> 6); + return (byte) (((64 - aWeights2[index])* e0 + aWeights2[index]*e1 + 32) >> 6); else if(indexPrecision == 3) - return (byte) (((64 - aWeights3[index])*(e0) + aWeights3[index]*(e1) + 32) >> 6); + return (byte) (((64 - aWeights3[index])*e0 + aWeights3[index]*e1 + 32) >> 6); else // indexprecision == 4 - return (byte) (((64 - aWeights4[index])*(e0) + aWeights4[index]*(e1) + 32) >> 6); + return (byte) (((64 - aWeights4[index])*e0 + aWeights4[index]*e1 + 32) >> 6); } - ColorRgba32 result = new ColorRgba32( + var result = new ColorRgba32( InterpolateByte(endPointStart.r, endPointEnd.r, colorIndex, colorBitCount), InterpolateByte(endPointStart.g, endPointEnd.g, colorIndex, colorBitCount), InterpolateByte(endPointStart.b, endPointEnd.b, colorIndex, colorBitCount), @@ -781,13 +781,13 @@ private int GetColorIndex(Bc7BlockType type, int numSubsets, int partitionIndex, public RawBlock4X4Rgba32 Decode() { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var output = new RawBlock4X4Rgba32(); var type = Type; ////decode partition data from explicit partition bits //subset_index = 0; - int numSubsets = 1; - int partitionIndex = 0; + var numSubsets = 1; + var partitionIndex = 0; if (HasSubsets) { @@ -798,31 +798,31 @@ public RawBlock4X4Rgba32 Decode() var pixels = output.AsSpan; - bool hasRotationBits = HasRotationBits; + var hasRotationBits = HasRotationBits; int rotation = RotationBits; - ColorRgba32[] endpoints = ExtractEndpoints(); - for (int i = 0; i < pixels.Length; i++) + var endpoints = ExtractEndpoints(); + for (var i = 0; i < pixels.Length; i++) { - int subsetIndex = GetPartitionIndex(numSubsets, partitionIndex, i); + var subsetIndex = GetPartitionIndex(numSubsets, partitionIndex, i); - ColorRgba32 endPointStart = endpoints[2 * subsetIndex]; - ColorRgba32 endPointEnd = endpoints[2 * subsetIndex + 1]; + var endPointStart = endpoints[2 * subsetIndex]; + var endPointEnd = endpoints[2 * subsetIndex + 1]; - int alphaBitCount = AlphaIndexBitCount; - int colorBitCount = ColorIndexBitCount; - int alphaIndex = GetAlphaIndex(type, numSubsets, partitionIndex, alphaBitCount, i); - int colorIndex = GetColorIndex(type, numSubsets, partitionIndex, colorBitCount, i); + var alphaBitCount = AlphaIndexBitCount; + var colorBitCount = ColorIndexBitCount; + var alphaIndex = GetAlphaIndex(type, numSubsets, partitionIndex, alphaBitCount, i); + var colorIndex = GetColorIndex(type, numSubsets, partitionIndex, colorBitCount, i); - ColorRgba32 outputColor = InterpolateColor(endPointStart, endPointEnd, colorIndex, alphaIndex, + var outputColor = InterpolateColor(endPointStart, endPointEnd, colorIndex, alphaIndex, colorBitCount, alphaBitCount); if (hasRotationBits) { //Decode the 2 color rotation bits as follows: - // 00 – Block format is Scalar(A) Vector(RGB) - no swapping - // 01 – Block format is Scalar(R) Vector(AGB) - swap A and R - // 10 – Block format is Scalar(G) Vector(RAB) - swap A and G - // 11 - Block format is Scalar(B) Vector(RGA) - swap A and B + // 00 – Block Format is Scalar(A) Vector(RGB) - no swapping + // 01 – Block Format is Scalar(R) Vector(AGB) - swap A and R + // 10 – Block Format is Scalar(G) Vector(RAB) - swap A and G + // 11 - Block Format is Scalar(B) Vector(RGA) - swap A and B outputColor = SwapChannels(outputColor, rotation); } @@ -837,37 +837,37 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(partitionIndex4Bit < 16, "Mode 0 should have 4bit partition index"); Debug.Assert(subsetEndpoints.Length == 6, "Mode 0 should have 6 endpoints"); Debug.Assert(subsetEndpoints.All(x => x.Length == 3) , "Mode 0 should have RGB endpoints"); - Debug.Assert(subsetEndpoints.All(x => x.All(y => y < (1 << 4))) , "Mode 0 should have 4bit endpoints"); + Debug.Assert(subsetEndpoints.All(x => x.All(y => y < 1 << 4)) , "Mode 0 should have 4bit endpoints"); Debug.Assert(pBits.Length == 6, "Mode 0 should have 6 pBits"); Debug.Assert(indices.Length == 16, "Provide 16 indices"); - Debug.Assert(indices.All(x => x < (1 << 3)) , "Mode 0 should have 3bit indices"); + Debug.Assert(indices.All(x => x < 1 << 3) , "Mode 0 should have 3bit indices"); lowBits = 1; // Set Mode 0 highBits = 0; lowBits = ByteHelper.Store4(lowBits, 1, (byte) partitionIndex4Bit); - int nextIdx = 5; + var nextIdx = 5; //Store endpoints - for (int i = 0; i < subsetEndpoints[0].Length; i++) { - for (int j = 0; j < subsetEndpoints.Length; j++) { + for (var i = 0; i < subsetEndpoints[0].Length; i++) { + for (var j = 0; j < subsetEndpoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 4, subsetEndpoints[j][i]); nextIdx += 4; } } //Store pBits - for (int i = 0; i < pBits.Length; i++) { + for (var i = 0; i < pBits.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 1, pBits[i]); nextIdx++; } Debug.Assert(nextIdx == 83); - int colorBitCount = ColorIndexBitCount; - int indexBegin = GetIndexBegin(Bc7BlockType.Type0, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type0, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var indexBegin = GetIndexBegin(Bc7BlockType.Type0, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type0, NumSubsets, partitionIndex4Bit, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, partitionIndex4Bit, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, @@ -879,37 +879,37 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(partitionIndex6Bit < 64, "Mode 1 should have 6bit partition index"); Debug.Assert(subsetEndpoints.Length == 4, "Mode 1 should have 4 endpoints"); Debug.Assert(subsetEndpoints.All(x => x.Length == 3) , "Mode 1 should have RGB endpoints"); - Debug.Assert(subsetEndpoints.All(x => x.All(y => y < (1 << 6))) , "Mode 1 should have 6bit endpoints"); + Debug.Assert(subsetEndpoints.All(x => x.All(y => y < 1 << 6)) , "Mode 1 should have 6bit endpoints"); Debug.Assert(pBits.Length == 2, "Mode 1 should have 2 pBits"); Debug.Assert(indices.Length == 16, "Provide 16 indices"); - Debug.Assert(indices.All(x => x < (1 << 3)) , "Mode 1 should have 3bit indices"); + Debug.Assert(indices.All(x => x < 1 << 3) , "Mode 1 should have 3bit indices"); lowBits = 2; // Set Mode 1 highBits = 0; lowBits = ByteHelper.Store6(lowBits, 2, (byte) partitionIndex6Bit); - int nextIdx = 8; + var nextIdx = 8; //Store endpoints - for (int i = 0; i < subsetEndpoints[0].Length; i++) { - for (int j = 0; j < subsetEndpoints.Length; j++) { + for (var i = 0; i < subsetEndpoints[0].Length; i++) { + for (var j = 0; j < subsetEndpoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 6, subsetEndpoints[j][i]); nextIdx += 6; } } //Store pBits - for (int i = 0; i < pBits.Length; i++) { + for (var i = 0; i < pBits.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 1, pBits[i]); nextIdx++; } Debug.Assert(nextIdx == 82); - int colorBitCount = ColorIndexBitCount; - int indexBegin = GetIndexBegin(Bc7BlockType.Type1, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type1, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var indexBegin = GetIndexBegin(Bc7BlockType.Type1, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type1, NumSubsets, partitionIndex6Bit, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, partitionIndex6Bit, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, @@ -921,19 +921,19 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(partitionIndex6Bit < 64, "Mode 2 should have 6bit partition index"); Debug.Assert(subsetEndpoints.Length == 6, "Mode 2 should have 6 endpoints"); Debug.Assert(subsetEndpoints.All(x => x.Length == 3) , "Mode 2 should have RGB endpoints"); - Debug.Assert(subsetEndpoints.All(x => x.All(y => y < (1 << 5))) , "Mode 2 should have 5bit endpoints"); + Debug.Assert(subsetEndpoints.All(x => x.All(y => y < 1 << 5)) , "Mode 2 should have 5bit endpoints"); Debug.Assert(indices.Length == 16, "Provide 16 indices"); - Debug.Assert(indices.All(x => x < (1 << 2)) , "Mode 2 should have 2bit indices"); + Debug.Assert(indices.All(x => x < 1 << 2) , "Mode 2 should have 2bit indices"); lowBits = 0b100; // Set Mode 2 highBits = 0; lowBits = ByteHelper.Store6(lowBits, 3, (byte) partitionIndex6Bit); - int nextIdx = 9; + var nextIdx = 9; //Store endpoints - for (int i = 0; i < subsetEndpoints[0].Length; i++) { - for (int j = 0; j < subsetEndpoints.Length; j++) { + for (var i = 0; i < subsetEndpoints[0].Length; i++) { + for (var j = 0; j < subsetEndpoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 5, subsetEndpoints[j][i]); nextIdx += 5; @@ -941,12 +941,12 @@ public RawBlock4X4Rgba32 Decode() } Debug.Assert(nextIdx == 99); - int colorBitCount = ColorIndexBitCount; - int indexBegin = GetIndexBegin(Bc7BlockType.Type2, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type2, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var indexBegin = GetIndexBegin(Bc7BlockType.Type2, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type2, NumSubsets, partitionIndex6Bit, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, partitionIndex6Bit, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, @@ -958,39 +958,39 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(partitionIndex6Bit < 64, "Mode 3 should have 6bit partition index"); Debug.Assert(subsetEndpoints.Length == 4, "Mode 3 should have 4 endpoints"); Debug.Assert(subsetEndpoints.All(x => x.Length == 3) , "Mode 3 should have RGB endpoints"); - Debug.Assert(subsetEndpoints.All(x => x.All(y => y < (1 << 7))) , "Mode 3 should have 7bit endpoints"); + Debug.Assert(subsetEndpoints.All(x => x.All(y => y < 1 << 7)) , "Mode 3 should have 7bit endpoints"); Debug.Assert(pBits.Length == 4, "Mode 3 should have 4 pBits"); Debug.Assert(indices.Length == 16, "Provide 16 indices"); - Debug.Assert(indices.All(x => x < (1 << 2)) , "Mode 3 should have 2bit indices"); + Debug.Assert(indices.All(x => x < 1 << 2) , "Mode 3 should have 2bit indices"); lowBits = 0b1000; // Set Mode 3 highBits = 0; lowBits = ByteHelper.Store6(lowBits, 4, (byte) partitionIndex6Bit); - int nextIdx = 10; + var nextIdx = 10; //Store endpoints - for (int i = 0; i < subsetEndpoints[0].Length; i++) { - for (int j = 0; j < subsetEndpoints.Length; j++) { + for (var i = 0; i < subsetEndpoints[0].Length; i++) { + for (var j = 0; j < subsetEndpoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 7, subsetEndpoints[j][i]); nextIdx += 7; } } //Store pBits - for (int i = 0; i < pBits.Length; i++) { + for (var i = 0; i < pBits.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 1, pBits[i]); nextIdx++; } Debug.Assert(nextIdx == 98); - int colorBitCount = ColorIndexBitCount; - int indexBegin = GetIndexBegin(Bc7BlockType.Type3, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type3, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var indexBegin = GetIndexBegin(Bc7BlockType.Type3, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type3, NumSubsets, partitionIndex6Bit, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, partitionIndex6Bit, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, @@ -1003,14 +1003,14 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(idxMode < 2, "IndexMode can only be 0 or 1"); Debug.Assert(colorEndPoints.Length == 2, "Mode 4 should have 2 endpoints"); Debug.Assert(colorEndPoints.All(x => x.Length == 3) , "Mode 4 should have RGB color endpoints"); - Debug.Assert(colorEndPoints.All(x => x.All(y => y < (1 << 5))) , "Mode 4 should have 5bit color endpoints"); + Debug.Assert(colorEndPoints.All(x => x.All(y => y < 1 << 5)) , "Mode 4 should have 5bit color endpoints"); Debug.Assert(alphaEndPoints.Length == 2, "Mode 4 should have 2 endpoints"); - Debug.Assert(alphaEndPoints.All(x => x < (1 << 6)) , "Mode 4 should have 6bit alpha endpoints"); + Debug.Assert(alphaEndPoints.All(x => x < 1 << 6) , "Mode 4 should have 6bit alpha endpoints"); Debug.Assert(indices2Bit.Length == 16, "Provide 16 indices"); - Debug.Assert(indices2Bit.All(x => x < (1 << 2)) , "Mode 4 should have 2bit indices"); + Debug.Assert(indices2Bit.All(x => x < 1 << 2) , "Mode 4 should have 2bit indices"); Debug.Assert(indices3Bit.Length == 16, "Provide 16 indices"); - Debug.Assert(indices3Bit.All(x => x < (1 << 3)) , "Mode 4 should have 3bit indices"); + Debug.Assert(indices3Bit.All(x => x < 1 << 3) , "Mode 4 should have 3bit indices"); lowBits = 0b10000; // Set Mode 4 highBits = 0; @@ -1018,29 +1018,29 @@ public RawBlock4X4Rgba32 Decode() lowBits = ByteHelper.Store2(lowBits, 5, (byte) rotation); lowBits = ByteHelper.Store1(lowBits, 7, (byte) idxMode); - int nextIdx = 8; + var nextIdx = 8; //Store color endpoints - for (int i = 0; i < colorEndPoints[0].Length; i++) { - for (int j = 0; j < colorEndPoints.Length; j++) { + for (var i = 0; i < colorEndPoints[0].Length; i++) { + for (var j = 0; j < colorEndPoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 5, colorEndPoints[j][i]); nextIdx += 5; } } //Store alpha endpoints - for (int i = 0; i < alphaEndPoints.Length; i++) { + for (var i = 0; i < alphaEndPoints.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 6, alphaEndPoints[i]); nextIdx+=6; } Debug.Assert(nextIdx == 50); - int colorBitCount = ColorIndexBitCount; - int colorIndexBegin = GetIndexBegin(Bc7BlockType.Type4, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type4, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var colorIndexBegin = GetIndexBegin(Bc7BlockType.Type4, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type4, NumSubsets, 0, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, 0, colorBitCount, i); if (idxMode == 0) { @@ -1053,12 +1053,12 @@ public RawBlock4X4Rgba32 Decode() } } - int alphaBitCount = AlphaIndexBitCount; - int alphaIndexBegin = GetIndexBegin(Bc7BlockType.Type4, alphaBitCount, true); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type4, NumSubsets, + var alphaBitCount = AlphaIndexBitCount; + var alphaIndexBegin = GetIndexBegin(Bc7BlockType.Type4, alphaBitCount, true); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type4, NumSubsets, 0, alphaBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, 0, alphaBitCount, i); if (idxMode == 0) { @@ -1076,42 +1076,42 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(rotation < 4, "Rotation can only be 0-3"); Debug.Assert(colorEndPoints.Length == 2, "Mode 5 should have 2 endpoints"); Debug.Assert(colorEndPoints.All(x => x.Length == 3) , "Mode 5 should have RGB color endpoints"); - Debug.Assert(colorEndPoints.All(x => x.All(y => y < (1 << 7))) , "Mode 5 should have 7bit color endpoints"); + Debug.Assert(colorEndPoints.All(x => x.All(y => y < 1 << 7)) , "Mode 5 should have 7bit color endpoints"); Debug.Assert(alphaEndPoints.Length == 2, "Mode 5 should have 2 endpoints"); Debug.Assert(colorIndices.Length == 16, "Provide 16 indices"); - Debug.Assert(colorIndices.All(x => x < (1 << 2)) , "Mode 5 should have 2bit color indices"); + Debug.Assert(colorIndices.All(x => x < 1 << 2) , "Mode 5 should have 2bit color indices"); Debug.Assert(alphaIndices.Length == 16, "Provide 16 indices"); - Debug.Assert(alphaIndices.All(x => x < (1 << 2)) , "Mode 5 should have 2bit alpha indices"); + Debug.Assert(alphaIndices.All(x => x < 1 << 2) , "Mode 5 should have 2bit alpha indices"); lowBits = 0b100000; // Set Mode 5 highBits = 0; lowBits = ByteHelper.Store2(lowBits, 6, (byte) rotation); - int nextIdx = 8; + var nextIdx = 8; //Store color endpoints - for (int i = 0; i < colorEndPoints[0].Length; i++) { - for (int j = 0; j < colorEndPoints.Length; j++) { + for (var i = 0; i < colorEndPoints[0].Length; i++) { + for (var j = 0; j < colorEndPoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 7, colorEndPoints[j][i]); nextIdx += 7; } } //Store alpha endpoints - for (int i = 0; i < alphaEndPoints.Length; i++) { + for (var i = 0; i < alphaEndPoints.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 8, alphaEndPoints[i]); nextIdx+=8; } Debug.Assert(nextIdx == 66); - int colorBitCount = ColorIndexBitCount; - int colorIndexBegin = GetIndexBegin(Bc7BlockType.Type5, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type5, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var colorIndexBegin = GetIndexBegin(Bc7BlockType.Type5, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type5, NumSubsets, 0, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, 0, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, @@ -1119,12 +1119,12 @@ public RawBlock4X4Rgba32 Decode() } - int alphaBitCount = AlphaIndexBitCount; - int alphaIndexBegin = GetIndexBegin(Bc7BlockType.Type5, alphaBitCount, true); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type5, NumSubsets, + var alphaBitCount = AlphaIndexBitCount; + var alphaIndexBegin = GetIndexBegin(Bc7BlockType.Type5, alphaBitCount, true); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type5, NumSubsets, 0, alphaBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, 0, alphaBitCount, i); @@ -1139,38 +1139,38 @@ public RawBlock4X4Rgba32 Decode() "Mode 6 should have 2 endpoints"); Debug.Assert(colorAlphaEndPoints.All(x => x.Length == 4) , "Mode 6 should have RGBA color endpoints"); - Debug.Assert(colorAlphaEndPoints.All(x => x.All(y => y < (1 << 7))) , + Debug.Assert(colorAlphaEndPoints.All(x => x.All(y => y < 1 << 7)) , "Mode 6 should have 7bit color and alpha endpoints"); Debug.Assert(pBits.Length == 2, "Mode 6 should have 2 pBits"); Debug.Assert(indices.Length == 16, "Provide 16 indices"); - Debug.Assert(indices.All(x => x < (1 << 4)) , "Mode 6 should have 4bit color indices"); + Debug.Assert(indices.All(x => x < 1 << 4) , "Mode 6 should have 4bit color indices"); lowBits = 0b1000000; // Set Mode 6 highBits = 0; - int nextIdx = 7; + var nextIdx = 7; //Store color and alpha endpoints - for (int i = 0; i < colorAlphaEndPoints[0].Length; i++) { - for (int j = 0; j < colorAlphaEndPoints.Length; j++) { + for (var i = 0; i < colorAlphaEndPoints[0].Length; i++) { + for (var j = 0; j < colorAlphaEndPoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 7, colorAlphaEndPoints[j][i]); nextIdx += 7; } } //Store pBits - for (int i = 0; i < pBits.Length; i++) { + for (var i = 0; i < pBits.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 1, pBits[i]); nextIdx++; } Debug.Assert(nextIdx == 65); - int colorBitCount = ColorIndexBitCount; - int colorIndexBegin = GetIndexBegin(Bc7BlockType.Type6, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type6, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var colorIndexBegin = GetIndexBegin(Bc7BlockType.Type6, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type6, NumSubsets, 0, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, 0, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, @@ -1183,39 +1183,39 @@ public RawBlock4X4Rgba32 Decode() Debug.Assert(partitionIndex6Bit < 64, "Mode 7 should have 6bit partition index"); Debug.Assert(subsetEndpoints.Length == 4, "Mode 7 should have 4 endpoints"); Debug.Assert(subsetEndpoints.All(x => x.Length == 4) , "Mode 7 should have RGBA endpoints"); - Debug.Assert(subsetEndpoints.All(x => x.All(y => y < (1 << 5))) , "Mode 7 should have 5bit endpoints"); + Debug.Assert(subsetEndpoints.All(x => x.All(y => y < 1 << 5)) , "Mode 7 should have 5bit endpoints"); Debug.Assert(pBits.Length == 4, "Mode 7 should have 4 pBits"); Debug.Assert(indices.Length == 16, "Provide 16 indices"); - Debug.Assert(indices.All(x => x < (1 << 2)) , "Mode 3 should have 2bit indices"); + Debug.Assert(indices.All(x => x < 1 << 2) , "Mode 3 should have 2bit indices"); lowBits = 0b10000000; // Set Mode 7 highBits = 0; lowBits = ByteHelper.Store6(lowBits, 8, (byte) partitionIndex6Bit); - int nextIdx = 14; + var nextIdx = 14; //Store endpoints - for (int i = 0; i < subsetEndpoints[0].Length; i++) { - for (int j = 0; j < subsetEndpoints.Length; j++) { + for (var i = 0; i < subsetEndpoints[0].Length; i++) { + for (var j = 0; j < subsetEndpoints.Length; j++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 5, subsetEndpoints[j][i]); nextIdx += 5; } } //Store pBits - for (int i = 0; i < pBits.Length; i++) { + for (var i = 0; i < pBits.Length; i++) { (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, nextIdx, 1, pBits[i]); nextIdx++; } Debug.Assert(nextIdx == 98); - int colorBitCount = ColorIndexBitCount; - int indexBegin = GetIndexBegin(Bc7BlockType.Type7, colorBitCount, false); - for (int i = 0; i < 16; i++) { - int indexOffset = GetIndexOffset(Bc7BlockType.Type7, NumSubsets, + var colorBitCount = ColorIndexBitCount; + var indexBegin = GetIndexBegin(Bc7BlockType.Type7, colorBitCount, false); + for (var i = 0; i < 16; i++) { + var indexOffset = GetIndexOffset(Bc7BlockType.Type7, NumSubsets, partitionIndex6Bit, colorBitCount, i); - int indexBitCount = GetIndexBitCount(NumSubsets, + var indexBitCount = GetIndexBitCount(NumSubsets, partitionIndex6Bit, colorBitCount, i); (lowBits, highBits) = ByteHelper.StoreTo128(lowBits, highBits, diff --git a/BCnEnc.Net/Shared/BinaryReaderWriterExtensions.cs b/BCnEnc.Net/Shared/BinaryReaderWriterExtensions.cs index ebdf410..d81fac1 100644 --- a/BCnEnc.Net/Shared/BinaryReaderWriterExtensions.cs +++ b/BCnEnc.Net/Shared/BinaryReaderWriterExtensions.cs @@ -9,25 +9,25 @@ internal static class BinaryReaderWriterExtensions { public static unsafe void WriteStruct(this BinaryWriter bw, T t) where T : unmanaged { - int size = Unsafe.SizeOf(); - byte* bytes = stackalloc byte[size]; + var size = Unsafe.SizeOf(); + var bytes = stackalloc byte[size]; Unsafe.Write(bytes, t); - Span bSpan = new Span(bytes, size); + var bSpan = new Span(bytes, size); bw.Write(bSpan); } public static unsafe T ReadStruct(this BinaryReader br) where T : unmanaged { - int size = Unsafe.SizeOf(); - byte* bytes = stackalloc byte[size]; - Span bSpan = new Span(bytes, size); + var size = Unsafe.SizeOf(); + var bytes = stackalloc byte[size]; + var bSpan = new Span(bytes, size); br.Read(bSpan); return Unsafe.Read(bytes); } public static void AddPadding(this BinaryWriter bw, uint padding) { - for (int i = 0; i < padding; i++) + for (var i = 0; i < padding; i++) { bw.Write((byte)0); } diff --git a/BCnEnc.Net/Shared/ByteHelper.cs b/BCnEnc.Net/Shared/ByteHelper.cs index 4359cf2..7c60b60 100644 --- a/BCnEnc.Net/Shared/ByteHelper.cs +++ b/BCnEnc.Net/Shared/ByteHelper.cs @@ -128,8 +128,8 @@ public static ulong Extract(ulong source, int index, int bitCount) { unchecked { - ulong mask = (0b1UL << bitCount) - 1; - return ((source >> index) & mask); + var mask = (0b1UL << bitCount) - 1; + return (source >> index) & mask; } } @@ -137,7 +137,7 @@ public static ulong Store(ulong dest, int index, int bitCount, ulong value) { unchecked { - ulong mask = (0b1UL << bitCount) - 1; + var mask = (0b1UL << bitCount) - 1; dest &= ~(mask << index); dest |= (value & mask) << index; return dest; @@ -156,13 +156,13 @@ public static ulong ExtractFrom128(ulong low, ulong high, int index, int bitCoun } else { //handle boundary case - int lowIndex = index; - int lowBitCount = 64 - index; - int highBitCount = bitCount - lowBitCount; - int highIndex = 0; + var lowIndex = index; + var lowBitCount = 64 - index; + var highBitCount = bitCount - lowBitCount; + var highIndex = 0; - ulong value = Extract(low, lowIndex, lowBitCount); - ulong hVal = Extract(high, highIndex, highBitCount); + var value = Extract(low, lowIndex, lowBitCount); + var hVal = Extract(high, highIndex, highBitCount); value = Store(value, lowBitCount, highBitCount, hVal); return value; } @@ -180,10 +180,10 @@ public static (ulong, ulong) StoreTo128(ulong low, ulong high, int index, int bi } else { //handle boundary case - int lowIndex = index; - int lowBitCount = 64 - index; - int highBitCount = bitCount - lowBitCount; - int highIndex = 0; + var lowIndex = index; + var lowBitCount = 64 - index; + var highBitCount = bitCount - lowBitCount; + var highIndex = 0; var l = Store(low, lowIndex, lowBitCount, value); value >>= lowBitCount; diff --git a/BCnEnc.Net/Shared/Colors.cs b/BCnEnc.Net/Shared/Colors.cs index 620cff7..03a2bc5 100644 --- a/BCnEnc.Net/Shared/Colors.cs +++ b/BCnEnc.Net/Shared/Colors.cs @@ -31,76 +31,76 @@ public override int GetHashCode() return !left.Equals(right); } - private const ushort RedMask = 0b11111_000000_00000; - private const int RedShift = 11; - private const ushort GreenMask = 0b00000_111111_00000; - private const int GreenShift = 5; - private const ushort BlueMask = 0b00000_000000_11111; + private const ushort RedMask_ = 0b11111_000000_00000; + private const int RedShift_ = 11; + private const ushort GreenMask_ = 0b00000_111111_00000; + private const int GreenShift_ = 5; + private const ushort BlueMask_ = 0b00000_000000_11111; public ushort data; public byte R { readonly get { - int r5 = ((data & RedMask) >> RedShift); + var r5 = (data & RedMask_) >> RedShift_; return (byte)((r5 << 3) | (r5 >> 2)); } set { - int r5 = value >> 3; - data = (ushort)(data & ~RedMask); - data = (ushort)(data | (r5 << RedShift)); + var r5 = value >> 3; + data = (ushort)(data & ~RedMask_); + data = (ushort)(data | (r5 << RedShift_)); } } public byte G { readonly get { - int g6 = ((data & GreenMask) >> GreenShift); + var g6 = (data & GreenMask_) >> GreenShift_; return (byte)((g6 << 2) | (g6 >> 4)); } set { - int g6 = value >> 2; - data = (ushort)(data & ~GreenMask); - data = (ushort)(data | (g6 << GreenShift)); + var g6 = value >> 2; + data = (ushort)(data & ~GreenMask_); + data = (ushort)(data | (g6 << GreenShift_)); } } public byte B { readonly get { - int b5 = (data & BlueMask); + var b5 = data & BlueMask_; return (byte)((b5 << 3) | (b5 >> 2)); } set { - int b5 = value >> 3; - data = (ushort)(data & ~BlueMask); + var b5 = value >> 3; + data = (ushort)(data & ~BlueMask_); data = (ushort)(data | b5); } } public int RawR { - readonly get { return ((data & RedMask) >> RedShift); } + readonly get { return (data & RedMask_) >> RedShift_; } set { if (value > 31) value = 31; if (value < 0) value = 0; - data = (ushort)(data & ~RedMask); - data = (ushort)(data | ((value) << RedShift)); + data = (ushort)(data & ~RedMask_); + data = (ushort)(data | (value << RedShift_)); } } public int RawG { - readonly get { return ((data & GreenMask) >> GreenShift); } + readonly get { return (data & GreenMask_) >> GreenShift_; } set { if (value > 63) value = 63; if (value < 0) value = 0; - data = (ushort)(data & ~GreenMask); - data = (ushort)(data | ((value) << GreenShift)); + data = (ushort)(data & ~GreenMask_); + data = (ushort)(data | (value << GreenShift_)); } } public int RawB { - readonly get { return (data & BlueMask); } + readonly get { return data & BlueMask_; } set { if (value > 31) value = 31; if (value < 0) value = 0; - data = (ushort)(data & ~BlueMask); + data = (ushort)(data & ~BlueMask_); data = (ushort)(data | value); } } @@ -174,7 +174,7 @@ public override int GetHashCode() { unchecked { - int hashCode = r.GetHashCode(); + var hashCode = r.GetHashCode(); hashCode = (hashCode * 397) ^ g.GetHashCode(); hashCode = (hashCode * 397) ^ b.GetHashCode(); hashCode = (hashCode * 397) ^ a.GetHashCode(); @@ -236,10 +236,10 @@ public override int GetHashCode() public static ColorRgba32 operator <<(ColorRgba32 left, int right) { return new ColorRgba32( - ByteHelper.ClampToByte((left.r << right)), - ByteHelper.ClampToByte((left.g << right)), - ByteHelper.ClampToByte((left.b << right)), - ByteHelper.ClampToByte((left.a << right)) + ByteHelper.ClampToByte(left.r << right), + ByteHelper.ClampToByte(left.g << right), + ByteHelper.ClampToByte(left.b << right), + ByteHelper.ClampToByte(left.a << right) ); } @@ -249,10 +249,10 @@ public override int GetHashCode() public static ColorRgba32 operator >>(ColorRgba32 left, int right) { return new ColorRgba32( - ByteHelper.ClampToByte((left.r >> right)), - ByteHelper.ClampToByte((left.g >> right)), - ByteHelper.ClampToByte((left.b >> right)), - ByteHelper.ClampToByte((left.a >> right)) + ByteHelper.ClampToByte(left.r >> right), + ByteHelper.ClampToByte(left.g >> right), + ByteHelper.ClampToByte(left.b >> right), + ByteHelper.ClampToByte(left.a >> right) ); } @@ -262,10 +262,10 @@ public override int GetHashCode() public static ColorRgba32 operator |(ColorRgba32 left, ColorRgba32 right) { return new ColorRgba32( - ByteHelper.ClampToByte((left.r | right.r)), - ByteHelper.ClampToByte((left.g | right.g)), - ByteHelper.ClampToByte((left.b | right.b)), - ByteHelper.ClampToByte((left.a | right.a)) + ByteHelper.ClampToByte(left.r | right.r), + ByteHelper.ClampToByte(left.g | right.g), + ByteHelper.ClampToByte(left.b | right.b), + ByteHelper.ClampToByte(left.a | right.a) ); } @@ -275,10 +275,10 @@ public override int GetHashCode() public static ColorRgba32 operator |(ColorRgba32 left, int right) { return new ColorRgba32( - ByteHelper.ClampToByte((left.r | right)), - ByteHelper.ClampToByte((left.g | right)), - ByteHelper.ClampToByte((left.b | right)), - ByteHelper.ClampToByte((left.a | right)) + ByteHelper.ClampToByte(left.r | right), + ByteHelper.ClampToByte(left.g | right), + ByteHelper.ClampToByte(left.b | right), + ByteHelper.ClampToByte(left.a | right) ); } @@ -288,10 +288,10 @@ public override int GetHashCode() public static ColorRgba32 operator &(ColorRgba32 left, ColorRgba32 right) { return new ColorRgba32( - ByteHelper.ClampToByte((left.r & right.r)), - ByteHelper.ClampToByte((left.g & right.g)), - ByteHelper.ClampToByte((left.b & right.b)), - ByteHelper.ClampToByte((left.a & right.a)) + ByteHelper.ClampToByte(left.r & right.r), + ByteHelper.ClampToByte(left.g & right.g), + ByteHelper.ClampToByte(left.b & right.b), + ByteHelper.ClampToByte(left.a & right.a) ); } @@ -301,10 +301,10 @@ public override int GetHashCode() public static ColorRgba32 operator &(ColorRgba32 left, int right) { return new ColorRgba32( - ByteHelper.ClampToByte((left.r & right)), - ByteHelper.ClampToByte((left.g & right)), - ByteHelper.ClampToByte((left.b & right)), - ByteHelper.ClampToByte((left.a & right)) + ByteHelper.ClampToByte(left.r & right), + ByteHelper.ClampToByte(left.g & right), + ByteHelper.ClampToByte(left.b & right), + ByteHelper.ClampToByte(left.a & right) ); } @@ -359,7 +359,7 @@ public override int GetHashCode() { unchecked { - int hashCode = r.GetHashCode(); + var hashCode = r.GetHashCode(); hashCode = (hashCode * 397) ^ g.GetHashCode(); hashCode = (hashCode * 397) ^ b.GetHashCode(); return hashCode; @@ -430,78 +430,78 @@ public ColorYCbCr(float y, float cb, float cr) public ColorYCbCr(ColorRgb24 rgb) { - float fr = (float)rgb.r / 255; - float fg = (float)rgb.g / 255; - float fb = (float)rgb.b / 255; + var fr = (float)rgb.r / 255; + var fg = (float)rgb.g / 255; + var fb = (float)rgb.b / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; } public ColorYCbCr(ColorRgb565 rgb) { - float fr = (float)rgb.R / 255; - float fg = (float)rgb.G / 255; - float fb = (float)rgb.B / 255; + var fr = (float)rgb.R / 255; + var fg = (float)rgb.G / 255; + var fb = (float)rgb.B / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; } public ColorYCbCr(ColorRgba32 rgba) { - float fr = (float)rgba.r / 255; - float fg = (float)rgba.g / 255; - float fb = (float)rgba.b / 255; + var fr = (float)rgba.r / 255; + var fg = (float)rgba.g / 255; + var fb = (float)rgba.b / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; } public ColorYCbCr(Rgba32 rgb) { - float fr = (float)rgb.R / 255; - float fg = (float)rgb.G / 255; - float fb = (float)rgb.B / 255; + var fr = (float)rgb.R / 255; + var fg = (float)rgb.G / 255; + var fb = (float)rgb.B / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; } public ColorYCbCr(Vector3 vec) { - float fr = (float) vec.X; - float fg = (float) vec.Y; - float fb = (float) vec.Z; + var fr = (float) vec.X; + var fg = (float) vec.Y; + var fb = (float) vec.Z; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; } public ColorRgb565 ToColorRgb565() { - float r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); - float g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); - float b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); + var r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); + var g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); + var b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); return new ColorRgb565((byte)(r * 255), (byte)(g * 255), (byte)(b * 255)); } public override string ToString() { - float r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); - float g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); - float b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); + var r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); + var g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); + var b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); return $"r : {r * 255} g : {g * 255} b : {b * 255}"; } public float CalcDistWeighted(ColorYCbCr other, float yWeight = 4) { - float dy = (y - other.y) * (y - other.y) * yWeight; - float dcb = (cb - other.cb) * (cb - other.cb); - float dcr = (cr - other.cr) * (cr - other.cr); + var dy = (y - other.y) * (y - other.y) * yWeight; + var dcb = (cb - other.cb) * (cb - other.cb); + var dcr = (cr - other.cr) * (cr - other.cr); return MathF.Sqrt(dy + dcb + dcr); } @@ -523,9 +523,9 @@ public ColorYCbCr(Rgba32 rgb) } public Rgba32 ToRgba32() { - float r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); - float g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); - float b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); + var r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); + var g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); + var b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); return new Rgba32((byte)(r * 255), (byte)(g * 255), (byte)(b * 255), 255); } @@ -548,74 +548,74 @@ public ColorYCbCrAlpha(float y, float cb, float cr, float alpha) public ColorYCbCrAlpha(ColorRgb24 rgb) { - float fr = (float)rgb.r / 255; - float fg = (float)rgb.g / 255; - float fb = (float)rgb.b / 255; + var fr = (float)rgb.r / 255; + var fg = (float)rgb.g / 255; + var fb = (float)rgb.b / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; alpha = 1; } public ColorYCbCrAlpha(ColorRgb565 rgb) { - float fr = (float)rgb.R / 255; - float fg = (float)rgb.G / 255; - float fb = (float)rgb.B / 255; + var fr = (float)rgb.R / 255; + var fg = (float)rgb.G / 255; + var fb = (float)rgb.B / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; alpha = 1; } public ColorYCbCrAlpha(ColorRgba32 rgba) { - float fr = (float)rgba.r / 255; - float fg = (float)rgba.g / 255; - float fb = (float)rgba.b / 255; + var fr = (float)rgba.r / 255; + var fg = (float)rgba.g / 255; + var fb = (float)rgba.b / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; alpha = rgba.a / 255f; } public ColorYCbCrAlpha(Rgba32 rgb) { - float fr = (float)rgb.R / 255; - float fg = (float)rgb.G / 255; - float fb = (float)rgb.B / 255; + var fr = (float)rgb.R / 255; + var fg = (float)rgb.G / 255; + var fb = (float)rgb.B / 255; - y = (0.2989f * fr + 0.5866f * fg + 0.1145f * fb); - cb = (-0.1687f * fr - 0.3313f * fg + 0.5000f * fb); - cr = (0.5000f * fr - 0.4184f * fg - 0.0816f * fb); + y = 0.2989f * fr + 0.5866f * fg + 0.1145f * fb; + cb = -0.1687f * fr - 0.3313f * fg + 0.5000f * fb; + cr = 0.5000f * fr - 0.4184f * fg - 0.0816f * fb; alpha = rgb.A / 255f; } public ColorRgb565 ToColorRgb565() { - float r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); - float g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); - float b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); + var r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); + var g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); + var b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); return new ColorRgb565((byte)(r * 255), (byte)(g * 255), (byte)(b * 255)); } public override string ToString() { - float r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); - float g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); - float b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); + var r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); + var g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); + var b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); return $"r : {r * 255} g : {g * 255} b : {b * 255}"; } public float CalcDistWeighted(ColorYCbCrAlpha other, float yWeight = 4, float aWeight = 1) { - float dy = (y - other.y) * (y - other.y) * yWeight; - float dcb = (cb - other.cb) * (cb - other.cb); - float dcr = (cr - other.cr) * (cr - other.cr); - float da = (alpha - other.alpha) * (alpha - other.alpha) * aWeight; + var dy = (y - other.y) * (y - other.y) * yWeight; + var dcb = (cb - other.cb) * (cb - other.cb); + var dcr = (cr - other.cr) * (cr - other.cr); + var da = (alpha - other.alpha) * (alpha - other.alpha) * aWeight; return MathF.Sqrt(dy + dcb + dcr + da); } @@ -639,9 +639,9 @@ public ColorYCbCrAlpha(Rgba32 rgb) } public Rgba32 ToRgba32() { - float r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); - float g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); - float b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); + var r = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 0.0000 * cb + 1.4022 * cr))); + var g = Math.Max(0.0f, Math.Min(1.0f, (float)(y - 0.3456 * cb - 0.7145 * cr))); + var b = Math.Max(0.0f, Math.Min(1.0f, (float)(y + 1.7710 * cb + 0.0000 * cr))); return new Rgba32((byte)(r * 255), (byte)(g * 255), (byte)(b * 255), (byte)(alpha * 255)); } @@ -663,9 +663,9 @@ internal struct ColorXyz { } public static ColorXyz ColorToXyz(ColorRgb24 color) { - float r = PivotRgb(color.r / 255.0f); - float g = PivotRgb(color.g / 255.0f); - float b = PivotRgb(color.b / 255.0f); + var r = PivotRgb(color.r / 255.0f); + var g = PivotRgb(color.g / 255.0f); + var b = PivotRgb(color.b / 255.0f); // Observer. = 2°, Illuminant = D65 return new ColorXyz(r * 0.4124f + g * 0.3576f + b * 0.1805f, r * 0.2126f + g * 0.7152f + b * 0.0722f, r * 0.0193f + g * 0.1192f + b * 0.9505f); @@ -701,25 +701,25 @@ internal struct ColorLab { } public static ColorLab ColorToLab(ColorRgb24 color) { - ColorXyz xyz = new ColorXyz(color); + var xyz = new ColorXyz(color); return XyzToLab(xyz); } public static ColorLab XyzToLab(ColorXyz xyz) { - float REF_X = 95.047f; // Observer= 2°, Illuminant= D65 - float REF_Y = 100.000f; - float REF_Z = 108.883f; + var refX = 95.047f; // Observer= 2°, Illuminant= D65 + var refY = 100.000f; + var refZ = 108.883f; - float x = PivotXyz(xyz.x / REF_X); - float y = PivotXyz(xyz.y / REF_Y); - float z = PivotXyz(xyz.z / REF_Z); + var x = PivotXyz(xyz.x / refX); + var y = PivotXyz(xyz.y / refY); + var z = PivotXyz(xyz.z / refZ); return new ColorLab(116 * y - 16, 500 * (x - y), 200 * (y - z)); } private static float PivotXyz(float n) { - float i = MathF.Cbrt(n); + var i = MathF.Cbrt(n); return n > 0.008856f ? i : 7.787f * n + 16 / 116f; } } diff --git a/BCnEnc.Net/Shared/CompressionFormat.cs b/BCnEnc.Net/Shared/CompressionFormat.cs index f99ab71..a9e5fe7 100644 --- a/BCnEnc.Net/Shared/CompressionFormat.cs +++ b/BCnEnc.Net/Shared/CompressionFormat.cs @@ -9,47 +9,47 @@ public enum CompressionFormat /// /// Raw unsigned byte 16-bit RG data /// - RG, + Rg, /// /// Raw unsigned byte 24-bit RGB data /// - RGB, + Rgb, /// /// Raw unsigned byte 32-bit RGBA data /// - RGBA, + Rgba, /// /// BC1 / DXT1 with no alpha. Very widely supported and good compression ratio. /// - BC1, + Bc1, /// /// BC1 / DXT1 with 1-bit of alpha. /// - BC1WithAlpha, + Bc1WithAlpha, /// /// BC2 / DXT3 encoding with alpha. Good for sharp alpha transitions. /// - BC2, + Bc2, /// /// BC3 / DXT5 encoding with alpha. Good for smooth alpha transitions. /// - BC3, + Bc3, /// /// BC4 single-channel encoding. Only luminance is encoded. /// - BC4, + Bc4, /// /// BC5 dual-channel encoding. Only red and green channels are encoded. /// - BC5, + Bc5, /// /// BC6H / BPTC float encoding. Can compress HDR textures without alpha. Currently not supported. /// - BC6, + Bc6, /// - /// BC7 / BPTC unorm encoding. Very high quality rgba or rgb encoding. Also very slow. + /// BC7 / BPTC unorm encoding. Very high Quality rgba or rgb encoding. Also very slow. /// - BC7 + Bc7 } public static class CompressionFormatExtensions @@ -59,9 +59,9 @@ public static bool IsCompressedFormat(this CompressionFormat format) switch (format) { case CompressionFormat.R: - case CompressionFormat.RG: - case CompressionFormat.RGB: - case CompressionFormat.RGBA: + case CompressionFormat.Rg: + case CompressionFormat.Rgb: + case CompressionFormat.Rgba: return false; default: diff --git a/BCnEnc.Net/Shared/DdsFile.cs b/BCnEnc.Net/Shared/DdsFile.cs index 229c529..867d5b0 100644 --- a/BCnEnc.Net/Shared/DdsFile.cs +++ b/BCnEnc.Net/Shared/DdsFile.cs @@ -8,39 +8,39 @@ namespace BCnEncoder.Shared { public class DdsFile { - public DdsHeader Header; - public DdsHeaderDxt10 Dxt10Header; + public DdsHeader header; + public DdsHeaderDxt10 dxt10Header; public List Faces { get; } = new List(); public DdsFile() { } public DdsFile(DdsHeader header) { - this.Header = header; + this.header = header; } public DdsFile(DdsHeader header, DdsHeaderDxt10 dxt10Header) { - this.Header = header; - this.Dxt10Header = dxt10Header; + this.header = header; + this.dxt10Header = dxt10Header; } public static DdsFile Load(Stream s) { - using (BinaryReader br = new BinaryReader(s, Encoding.UTF8, true)) + using (var br = new BinaryReader(s, Encoding.UTF8, true)) { var magic = br.ReadUInt32(); if (magic != 0x20534444U) { throw new FormatException("The file does not contain a dds file."); } - DdsHeader header = br.ReadStruct(); + var header = br.ReadStruct(); DdsHeaderDxt10 dxt10Header = default; if (header.dwSize != 124) { throw new FormatException("The file header contains invalid dwSize."); } - bool dxt10Format = header.ddsPixelFormat.IsDxt10Format; + var dxt10Format = header.ddsPixelFormat.IsDxt10Format; DdsFile output; @@ -54,19 +54,19 @@ public static DdsFile Load(Stream s) output = new DdsFile(header); } - uint mipMapCount = (header.dwCaps & HeaderCaps.DDSCAPS_MIPMAP) != 0 ? header.dwMipMapCount : 1; - uint faceCount = ((header.dwCaps2 & HeaderCaps2.DDSCAPS2_CUBEMAP) != 0) ? (uint)6 : (uint)1; - uint width = header.dwWidth; - uint height = header.dwHeight; + var mipMapCount = (header.dwCaps & HeaderCaps.DdscapsMipmap) != 0 ? header.dwMipMapCount : 1; + var faceCount = (header.dwCaps2 & HeaderCaps2.Ddscaps2Cubemap) != 0 ? (uint)6 : (uint)1; + var width = header.dwWidth; + var height = header.dwHeight; - for (int face = 0; face < faceCount; face++) + for (var face = 0; face < faceCount; face++) { - uint sizeInBytes = Math.Max(1, ((width + 3) / 4)) * Math.Max(1, ((height + 3) / 4)); + var sizeInBytes = Math.Max(1, (width + 3) / 4) * Math.Max(1, (height + 3) / 4); if (!dxt10Format) { if (header.ddsPixelFormat.IsDxt1To5CompressedFormat) { - if (header.ddsPixelFormat.DxgiFormat == DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM) + if (header.ddsPixelFormat.DxgiFormat == DxgiFormat.DxgiFormatBc1Unorm) { sizeInBytes *= 8; } @@ -90,19 +90,19 @@ public static DdsFile Load(Stream s) } output.Faces.Add(new DdsFace(width, height, sizeInBytes, (int)mipMapCount)); - for (int mip = 0; mip < mipMapCount; mip++) + for (var mip = 0; mip < mipMapCount; mip++) { - uint mipWidth = header.dwWidth / (uint)(Math.Pow(2, mip)); - uint mipHeight = header.dwHeight / (uint)(Math.Pow(2, mip)); + var mipWidth = header.dwWidth / (uint)Math.Pow(2, mip); + var mipHeight = header.dwHeight / (uint)Math.Pow(2, mip); if (mip > 0) //Calculate new byteSize { - sizeInBytes = Math.Max(1, ((mipWidth + 3) / 4)) * Math.Max(1, ((mipHeight + 3) / 4)); + sizeInBytes = Math.Max(1, (mipWidth + 3) / 4) * Math.Max(1, (mipHeight + 3) / 4); if (!dxt10Format) { if (header.ddsPixelFormat.IsDxt1To5CompressedFormat) { - if (header.ddsPixelFormat.DxgiFormat == DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM) + if (header.ddsPixelFormat.DxgiFormat == DxgiFormat.DxgiFormatBc1Unorm) { sizeInBytes *= 8; } @@ -113,7 +113,7 @@ public static DdsFile Load(Stream s) } else { - sizeInBytes = header.dwPitchOrLinearSize / (uint)(Math.Pow(2, mip)) * mipHeight; + sizeInBytes = header.dwPitchOrLinearSize / (uint)Math.Pow(2, mip) * mipHeight; } } else if (dxt10Header.dxgiFormat.IsCompressedFormat()) @@ -122,10 +122,10 @@ public static DdsFile Load(Stream s) } else { - sizeInBytes = header.dwPitchOrLinearSize / (uint)(Math.Pow(2, mip)) * mipHeight; + sizeInBytes = header.dwPitchOrLinearSize / (uint)Math.Pow(2, mip) * mipHeight; } } - byte[] data = new byte[sizeInBytes]; + var data = new byte[sizeInBytes]; br.Read(data); output.Faces[face].MipMaps[mip] = new DdsMipMap(data, mipWidth, mipHeight); } @@ -142,53 +142,53 @@ public void Write(Stream outputStream) throw new InvalidOperationException("The DDS structure should have at least 1 mipmap level and 1 Face before writing to file."); } - Header.dwFlags |= HeaderFlags.REQUIRED; + header.dwFlags |= HeaderFlags.Required; - Header.dwMipMapCount = (uint)Faces[0].MipMaps.Length; - if (Header.dwMipMapCount > 1) // MipMaps + header.dwMipMapCount = (uint)Faces[0].MipMaps.Length; + if (header.dwMipMapCount > 1) // MipMaps { - Header.dwCaps |= HeaderCaps.DDSCAPS_MIPMAP | HeaderCaps.DDSCAPS_COMPLEX; + header.dwCaps |= HeaderCaps.DdscapsMipmap | HeaderCaps.DdscapsComplex; } if (Faces.Count == 6) // CubeMap { - Header.dwCaps |= HeaderCaps.DDSCAPS_COMPLEX; - Header.dwCaps2 |= HeaderCaps2.DDSCAPS2_CUBEMAP | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEX | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEX | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEY | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEY | - HeaderCaps2.DDSCAPS2_CUBEMAP_POSITIVEZ | - HeaderCaps2.DDSCAPS2_CUBEMAP_NEGATIVEZ; + header.dwCaps |= HeaderCaps.DdscapsComplex; + header.dwCaps2 |= HeaderCaps2.Ddscaps2Cubemap | + HeaderCaps2.Ddscaps2CubemapPositivex | + HeaderCaps2.Ddscaps2CubemapNegativex | + HeaderCaps2.Ddscaps2CubemapPositivey | + HeaderCaps2.Ddscaps2CubemapNegativey | + HeaderCaps2.Ddscaps2CubemapPositivez | + HeaderCaps2.Ddscaps2CubemapNegativez; } - Header.dwWidth = Faces[0].Width; - Header.dwHeight = Faces[0].Height; + header.dwWidth = Faces[0].Width; + header.dwHeight = Faces[0].Height; - for (int i = 0; i < Faces.Count; i++) + for (var i = 0; i < Faces.Count; i++) { - if (Faces[i].Width != Header.dwWidth || Faces[i].Height != Header.dwHeight) + if (Faces[i].Width != header.dwWidth || Faces[i].Height != header.dwHeight) { throw new InvalidOperationException("Faces with different sizes are not supported."); } } - int faceCount = Faces.Count; - int mipCount = (int)Header.dwMipMapCount; + var faceCount = Faces.Count; + var mipCount = (int)header.dwMipMapCount; - using (BinaryWriter bw = new BinaryWriter(outputStream, Encoding.UTF8, true)) + using (var bw = new BinaryWriter(outputStream, Encoding.UTF8, true)) { bw.Write(0x20534444U); // magic 'DDS ' - bw.WriteStruct(Header); + bw.WriteStruct(header); - if (Header.ddsPixelFormat.IsDxt10Format) + if (header.ddsPixelFormat.IsDxt10Format) { - bw.WriteStruct(Dxt10Header); + bw.WriteStruct(dxt10Header); } - for (int face = 0; face < faceCount; face++) + for (var face = 0; face < faceCount; face++) { - for (int mip = 0; mip < mipCount; mip++) + for (var mip = 0; mip < mipCount; mip++) { bw.Write(Faces[face].MipMaps[mip].Data); } @@ -218,44 +218,44 @@ public unsafe struct DdsHeader public uint dwCaps4; public uint dwReserved2; - public static (DdsHeader, DdsHeaderDxt10) InitializeCompressed(int width, int height, DXGI_FORMAT format) + public static (DdsHeader, DdsHeaderDxt10) InitializeCompressed(int width, int height, DxgiFormat format) { - DdsHeader header = new DdsHeader(); - DdsHeaderDxt10 dxt10Header = new DdsHeaderDxt10(); + var header = new DdsHeader(); + var dxt10Header = new DdsHeaderDxt10(); header.dwSize = 124; - header.dwFlags = HeaderFlags.REQUIRED; + header.dwFlags = HeaderFlags.Required; header.dwWidth = (uint)width; header.dwHeight = (uint)height; header.dwDepth = 1; header.dwMipMapCount = 1; - header.dwCaps = HeaderCaps.DDSCAPS_TEXTURE; + header.dwCaps = HeaderCaps.DdscapsTexture; - if (format == DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM) + if (format == DxgiFormat.DxgiFormatBc1Unorm) { header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_FOURCC, - dwFourCC = DdsPixelFormat.DXT1 + dwFlags = PixelFormatFlags.DdpfFourcc, + dwFourCc = DdsPixelFormat.Dxt1 }; } - else if (format == DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM) + else if (format == DxgiFormat.DxgiFormatBc2Unorm) { header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_FOURCC, - dwFourCC = DdsPixelFormat.DXT3 + dwFlags = PixelFormatFlags.DdpfFourcc, + dwFourCc = DdsPixelFormat.Dxt3 }; } - else if (format == DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM) + else if (format == DxgiFormat.DxgiFormatBc3Unorm) { header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_FOURCC, - dwFourCC = DdsPixelFormat.DXT5 + dwFlags = PixelFormatFlags.DdpfFourcc, + dwFourCc = DdsPixelFormat.Dxt5 }; } else @@ -263,59 +263,59 @@ public static (DdsHeader, DdsHeaderDxt10) InitializeCompressed(int width, int he header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_FOURCC, - dwFourCC = DdsPixelFormat.DX10 + dwFlags = PixelFormatFlags.DdpfFourcc, + dwFourCc = DdsPixelFormat.Dx10 }; dxt10Header.arraySize = 1; dxt10Header.dxgiFormat = format; - dxt10Header.resourceDimension = D3D10_RESOURCE_DIMENSION.D3D10_RESOURCE_DIMENSION_TEXTURE2D; + dxt10Header.resourceDimension = D3D10ResourceDimension.D3D10ResourceDimensionTexture2D; } return (header, dxt10Header); } - public static DdsHeader InitializeUncompressed(int width, int height, DXGI_FORMAT format) + public static DdsHeader InitializeUncompressed(int width, int height, DxgiFormat format) { - DdsHeader header = new DdsHeader(); + var header = new DdsHeader(); header.dwSize = 124; - header.dwFlags = HeaderFlags.REQUIRED | HeaderFlags.DDSD_PITCH; + header.dwFlags = HeaderFlags.Required | HeaderFlags.DdsdPitch; header.dwWidth = (uint)width; header.dwHeight = (uint)height; header.dwDepth = 1; header.dwMipMapCount = 1; - header.dwCaps = HeaderCaps.DDSCAPS_TEXTURE; + header.dwCaps = HeaderCaps.DdscapsTexture; - if (format == DXGI_FORMAT.DXGI_FORMAT_R8_UNORM) + if (format == DxgiFormat.DxgiFormatR8Unorm) { header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_LUMINANCE, - dwRGBBitCount = 8, + dwFlags = PixelFormatFlags.DdpfLuminance, + dwRgbBitCount = 8, dwRBitMask = 0xFF }; header.dwPitchOrLinearSize = (uint)((width * 8 + 7) / 8); } - else if (format == DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM) + else if (format == DxgiFormat.DxgiFormatR8G8Unorm) { header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_LUMINANCE | PixelFormatFlags.DDPF_ALPHAPIXELS, - dwRGBBitCount = 16, + dwFlags = PixelFormatFlags.DdpfLuminance | PixelFormatFlags.DdpfAlphapixels, + dwRgbBitCount = 16, dwRBitMask = 0xFF, dwGBitMask = 0xFF00 }; header.dwPitchOrLinearSize = (uint)((width * 16 + 7) / 8); } - else if (format == DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM) + else if (format == DxgiFormat.DxgiFormatR8G8B8A8Unorm) { header.ddsPixelFormat = new DdsPixelFormat() { dwSize = 32, - dwFlags = PixelFormatFlags.DDPF_RGB | PixelFormatFlags.DDPF_ALPHAPIXELS, - dwRGBBitCount = 32, + dwFlags = PixelFormatFlags.DdpfRgb | PixelFormatFlags.DdpfAlphapixels, + dwRgbBitCount = 32, dwRBitMask = 0xFF, dwGBitMask = 0xFF00, dwBBitMask = 0xFF0000, @@ -325,7 +325,7 @@ public static DdsHeader InitializeUncompressed(int width, int height, DXGI_FORMA } else { - throw new NotImplementedException("This format is not implemented in this method"); + throw new NotImplementedException("This Format is not implemented in this method"); } return header; @@ -334,112 +334,112 @@ public static DdsHeader InitializeUncompressed(int width, int height, DXGI_FORMA public struct DdsPixelFormat { - public const uint DXT1 = 0x31545844U; - public const uint DXT2 = 0x32545844U; - public const uint DXT3 = 0x33545844U; - public const uint DXT4 = 0x34545844U; - public const uint DXT5 = 0x35545844U; - public const uint DX10 = 0x30315844U; + public const uint Dxt1 = 0x31545844U; + public const uint Dxt2 = 0x32545844U; + public const uint Dxt3 = 0x33545844U; + public const uint Dxt4 = 0x34545844U; + public const uint Dxt5 = 0x35545844U; + public const uint Dx10 = 0x30315844U; public uint dwSize; public PixelFormatFlags dwFlags; - public uint dwFourCC; - public uint dwRGBBitCount; + public uint dwFourCc; + public uint dwRgbBitCount; public uint dwRBitMask; public uint dwGBitMask; public uint dwBBitMask; public uint dwABitMask; - public DXGI_FORMAT DxgiFormat + public DxgiFormat DxgiFormat { get { - if ((dwFlags & PixelFormatFlags.DDPF_FOURCC) != 0) + if ((dwFlags & PixelFormatFlags.DdpfFourcc) != 0) { - switch (dwFourCC) + switch (dwFourCc) { case 0x31545844U: - return DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM; + return DxgiFormat.DxgiFormatBc1Unorm; case 0x33545844U: - return DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM; + return DxgiFormat.DxgiFormatBc2Unorm; case 0x35545844U: - return DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM; + return DxgiFormat.DxgiFormatBc3Unorm; } } else { - if ((dwFlags & PixelFormatFlags.DDPF_RGB) != 0) // RGB/A + if ((dwFlags & PixelFormatFlags.DdpfRgb) != 0) // RGB/A { - if ((dwFlags & PixelFormatFlags.DDPF_ALPHAPIXELS) != 0) //RGBA + if ((dwFlags & PixelFormatFlags.DdpfAlphapixels) != 0) //RGBA { - if (dwRGBBitCount == 32) + if (dwRgbBitCount == 32) { if (dwRBitMask == 0xff && dwGBitMask == 0xff00 && dwBBitMask == 0xff0000 && dwABitMask == 0xff000000) { - return DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM; + return DxgiFormat.DxgiFormatR8G8B8A8Unorm; } else if (dwRBitMask == 0x0000ff && dwGBitMask == 0xff00 && dwBBitMask == 0xff && dwABitMask == 0xff000000) { - return DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM; + return DxgiFormat.DxgiFormatB8G8R8A8Unorm; } } } else //RGB { - if (dwRGBBitCount == 32) + if (dwRgbBitCount == 32) { if (dwRBitMask == 0x0000ff && dwGBitMask == 0xff00 && dwBBitMask == 0xff) { - return DXGI_FORMAT.DXGI_FORMAT_B8G8R8X8_UNORM; + return DxgiFormat.DxgiFormatB8G8R8X8Unorm; } } } } - else if ((dwFlags & PixelFormatFlags.DDPF_LUMINANCE) != 0) // R/RG + else if ((dwFlags & PixelFormatFlags.DdpfLuminance) != 0) // R/RG { - if ((dwFlags & PixelFormatFlags.DDPF_ALPHAPIXELS) != 0) // RG + if ((dwFlags & PixelFormatFlags.DdpfAlphapixels) != 0) // RG { - if (dwRGBBitCount == 16) + if (dwRgbBitCount == 16) { if (dwRBitMask == 0x0000ff && dwGBitMask == 0xff00) { - return DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM; + return DxgiFormat.DxgiFormatR8G8Unorm; } } } else // Luminance only { - if (dwRGBBitCount == 8) + if (dwRgbBitCount == 8) { if (dwRBitMask == 0x0000ff && dwGBitMask == 0xff00) { - return DXGI_FORMAT.DXGI_FORMAT_R8_UNORM; + return DxgiFormat.DxgiFormatR8Unorm; } } } } } - return DXGI_FORMAT.DXGI_FORMAT_UNKNOWN; + return DxgiFormat.DxgiFormatUnknown; } } - public bool IsDxt10Format => ((dwFlags & PixelFormatFlags.DDPF_FOURCC) == PixelFormatFlags.DDPF_FOURCC) - && dwFourCC == DX10; + public bool IsDxt10Format => (dwFlags & PixelFormatFlags.DdpfFourcc) == PixelFormatFlags.DdpfFourcc + && dwFourCc == Dx10; - public bool IsDxt1To5CompressedFormat => ((dwFlags & PixelFormatFlags.DDPF_FOURCC) == PixelFormatFlags.DDPF_FOURCC) - && (dwFourCC == DXT1 - || dwFourCC == DXT2 - || dwFourCC == DXT3 - || dwFourCC == DXT4 - || dwFourCC == DXT5); + public bool IsDxt1To5CompressedFormat => (dwFlags & PixelFormatFlags.DdpfFourcc) == PixelFormatFlags.DdpfFourcc + && (dwFourCc == Dxt1 + || dwFourCc == Dxt2 + || dwFourCc == Dxt3 + || dwFourCc == Dxt4 + || dwFourCc == Dxt5); } public struct DdsHeaderDxt10 { - public DXGI_FORMAT dxgiFormat; - public D3D10_RESOURCE_DIMENSION resourceDimension; + public DxgiFormat dxgiFormat; + public D3D10ResourceDimension resourceDimension; public uint miscFlag; public uint arraySize; public uint miscFlags2; @@ -486,37 +486,37 @@ public enum HeaderFlags : uint /// /// Required in every .dds file. /// - DDSD_CAPS = 0x1, + DdsdCaps = 0x1, /// /// Required in every .dds file. /// - DDSD_HEIGHT = 0x2, + DdsdHeight = 0x2, /// /// Required in every .dds file. /// - DDSD_WIDTH = 0x4, + DdsdWidth = 0x4, /// /// Required when pitch is provided for an uncompressed texture. /// - DDSD_PITCH = 0x8, + DdsdPitch = 0x8, /// /// Required in every .dds file. /// - DDSD_PIXELFORMAT = 0x1000, + DdsdPixelformat = 0x1000, /// /// Required in a mipmapped texture. /// - DDSD_MIPMAPCOUNT = 0x20000, + DdsdMipmapcount = 0x20000, /// /// Required when pitch is provided for a compressed texture. /// - DDSD_LINEARSIZE = 0x80000, + DdsdLinearsize = 0x80000, /// /// Required in a depth texture. /// - DDSD_DEPTH = 0x800000, + DdsdDepth = 0x800000, - REQUIRED = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT + Required = DdsdCaps | DdsdHeight | DdsdWidth | DdsdPixelformat } /// @@ -528,15 +528,15 @@ public enum HeaderCaps : uint /// /// Optional; must be used on any file that contains more than one surface (a mipmap, a cubic environment map, or mipmapped volume texture). /// - DDSCAPS_COMPLEX = 0x8, + DdscapsComplex = 0x8, /// /// Optional; should be used for a mipmap. /// - DDSCAPS_MIPMAP = 0x400000, + DdscapsMipmap = 0x400000, /// /// Required /// - DDSCAPS_TEXTURE = 0x1000 + DdscapsTexture = 0x1000 } /// @@ -548,35 +548,35 @@ public enum HeaderCaps2 : uint /// /// Required for a cube map. /// - DDSCAPS2_CUBEMAP = 0x200, + Ddscaps2Cubemap = 0x200, /// /// Required when these surfaces are stored in a cube map. /// - DDSCAPS2_CUBEMAP_POSITIVEX = 0x400, + Ddscaps2CubemapPositivex = 0x400, /// /// Required when these surfaces are stored in a cube map. /// - DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800, + Ddscaps2CubemapNegativex = 0x800, /// /// Required when these surfaces are stored in a cube map. /// - DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000, + Ddscaps2CubemapPositivey = 0x1000, /// /// Required when these surfaces are stored in a cube map. /// - DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000, + Ddscaps2CubemapNegativey = 0x2000, /// /// Required when these surfaces are stored in a cube map. /// - DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000, + Ddscaps2CubemapPositivez = 0x4000, /// /// Required when these surfaces are stored in a cube map. /// - DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000, + Ddscaps2CubemapNegativez = 0x8000, /// /// Required for a volume texture. /// - DDSCAPS2_VOLUME = 0x200000 + Ddscaps2Volume = 0x200000 } [Flags] @@ -585,403 +585,403 @@ public enum PixelFormatFlags : uint /// /// Texture contains alpha data; dwRGBAlphaBitMask contains valid data. /// - DDPF_ALPHAPIXELS = 0x1, + DdpfAlphapixels = 0x1, /// /// Used in some older DDS files for alpha channel only uncompressed data (dwRGBBitCount contains the alpha channel bitcount; dwABitMask contains valid data) /// - DDPF_ALPHA = 0x2, + DdpfAlpha = 0x2, /// /// Texture contains compressed RGB data; dwFourCC contains valid data. /// - DDPF_FOURCC = 0x4, + DdpfFourcc = 0x4, /// /// Texture contains uncompressed RGB data; dwRGBBitCount and the RGB masks (dwRBitMask, dwGBitMask, dwBBitMask) contain valid data. /// - DDPF_RGB = 0x40, + DdpfRgb = 0x40, /// /// Used in some older DDS files for YUV uncompressed data (dwRGBBitCount contains the YUV bit count; dwRBitMask contains the Y mask, dwGBitMask contains the U mask, dwBBitMask contains the V mask) /// - DDPF_YUV = 0x200, + DdpfYuv = 0x200, /// /// Used in some older DDS files for single channel color uncompressed data (dwRGBBitCount contains the luminance channel bit count; dwRBitMask contains the channel mask). Can be combined with DDPF_ALPHAPIXELS for a two channel DDS file. /// - DDPF_LUMINANCE = 0x20000 + DdpfLuminance = 0x20000 } - public enum D3D10_RESOURCE_DIMENSION : uint + public enum D3D10ResourceDimension : uint { - D3D10_RESOURCE_DIMENSION_UNKNOWN, - D3D10_RESOURCE_DIMENSION_BUFFER, - D3D10_RESOURCE_DIMENSION_TEXTURE1D, - D3D10_RESOURCE_DIMENSION_TEXTURE2D, - D3D10_RESOURCE_DIMENSION_TEXTURE3D + D3D10ResourceDimensionUnknown, + D3D10ResourceDimensionBuffer, + D3D10ResourceDimensionTexture1D, + D3D10ResourceDimensionTexture2D, + D3D10ResourceDimensionTexture3D }; - public enum DXGI_FORMAT : uint + public enum DxgiFormat : uint { - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_R32G32B32A32_TYPELESS, - DXGI_FORMAT_R32G32B32A32_FLOAT, - DXGI_FORMAT_R32G32B32A32_UINT, - DXGI_FORMAT_R32G32B32A32_SINT, - DXGI_FORMAT_R32G32B32_TYPELESS, - DXGI_FORMAT_R32G32B32_FLOAT, - DXGI_FORMAT_R32G32B32_UINT, - DXGI_FORMAT_R32G32B32_SINT, - DXGI_FORMAT_R16G16B16A16_TYPELESS, - DXGI_FORMAT_R16G16B16A16_FLOAT, - DXGI_FORMAT_R16G16B16A16_UNORM, - DXGI_FORMAT_R16G16B16A16_UINT, - DXGI_FORMAT_R16G16B16A16_SNORM, - DXGI_FORMAT_R16G16B16A16_SINT, - DXGI_FORMAT_R32G32_TYPELESS, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32_UINT, - DXGI_FORMAT_R32G32_SINT, - DXGI_FORMAT_R32G8X24_TYPELESS, - DXGI_FORMAT_D32_FLOAT_S8X24_UINT, - DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, - DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, - DXGI_FORMAT_R10G10B10A2_TYPELESS, - DXGI_FORMAT_R10G10B10A2_UNORM, - DXGI_FORMAT_R10G10B10A2_UINT, - DXGI_FORMAT_R11G11B10_FLOAT, - DXGI_FORMAT_R8G8B8A8_TYPELESS, - DXGI_FORMAT_R8G8B8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, - DXGI_FORMAT_R8G8B8A8_UINT, - DXGI_FORMAT_R8G8B8A8_SNORM, - DXGI_FORMAT_R8G8B8A8_SINT, - DXGI_FORMAT_R16G16_TYPELESS, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16_UNORM, - DXGI_FORMAT_R16G16_UINT, - DXGI_FORMAT_R16G16_SNORM, - DXGI_FORMAT_R16G16_SINT, - DXGI_FORMAT_R32_TYPELESS, - DXGI_FORMAT_D32_FLOAT, - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32_UINT, - DXGI_FORMAT_R32_SINT, - DXGI_FORMAT_R24G8_TYPELESS, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_R24_UNORM_X8_TYPELESS, - DXGI_FORMAT_X24_TYPELESS_G8_UINT, - DXGI_FORMAT_R8G8_TYPELESS, - DXGI_FORMAT_R8G8_UNORM, - DXGI_FORMAT_R8G8_UINT, - DXGI_FORMAT_R8G8_SNORM, - DXGI_FORMAT_R8G8_SINT, - DXGI_FORMAT_R16_TYPELESS, - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_R16_UNORM, - DXGI_FORMAT_R16_UINT, - DXGI_FORMAT_R16_SNORM, - DXGI_FORMAT_R16_SINT, - DXGI_FORMAT_R8_TYPELESS, - DXGI_FORMAT_R8_UNORM, - DXGI_FORMAT_R8_UINT, - DXGI_FORMAT_R8_SNORM, - DXGI_FORMAT_R8_SINT, - DXGI_FORMAT_A8_UNORM, - DXGI_FORMAT_R1_UNORM, - DXGI_FORMAT_R9G9B9E5_SHAREDEXP, - DXGI_FORMAT_R8G8_B8G8_UNORM, - DXGI_FORMAT_G8R8_G8B8_UNORM, - DXGI_FORMAT_BC1_TYPELESS, - DXGI_FORMAT_BC1_UNORM, - DXGI_FORMAT_BC1_UNORM_SRGB, - DXGI_FORMAT_BC2_TYPELESS, - DXGI_FORMAT_BC2_UNORM, - DXGI_FORMAT_BC2_UNORM_SRGB, - DXGI_FORMAT_BC3_TYPELESS, - DXGI_FORMAT_BC3_UNORM, - DXGI_FORMAT_BC3_UNORM_SRGB, - DXGI_FORMAT_BC4_TYPELESS, - DXGI_FORMAT_BC4_UNORM, - DXGI_FORMAT_BC4_SNORM, - DXGI_FORMAT_BC5_TYPELESS, - DXGI_FORMAT_BC5_UNORM, - DXGI_FORMAT_BC5_SNORM, - DXGI_FORMAT_B5G6R5_UNORM, - DXGI_FORMAT_B5G5R5A1_UNORM, - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_B8G8R8X8_UNORM, - DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, - DXGI_FORMAT_B8G8R8A8_TYPELESS, - DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, - DXGI_FORMAT_B8G8R8X8_TYPELESS, - DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, - DXGI_FORMAT_BC6H_TYPELESS, - DXGI_FORMAT_BC6H_UF16, - DXGI_FORMAT_BC6H_SF16, - DXGI_FORMAT_BC7_TYPELESS, - DXGI_FORMAT_BC7_UNORM, - DXGI_FORMAT_BC7_UNORM_SRGB, - DXGI_FORMAT_AYUV, - DXGI_FORMAT_Y410, - DXGI_FORMAT_Y416, - DXGI_FORMAT_NV12, - DXGI_FORMAT_P010, - DXGI_FORMAT_P016, - DXGI_FORMAT_420_OPAQUE, - DXGI_FORMAT_YUY2, - DXGI_FORMAT_Y210, - DXGI_FORMAT_Y216, - DXGI_FORMAT_NV11, - DXGI_FORMAT_AI44, - DXGI_FORMAT_IA44, - DXGI_FORMAT_P8, - DXGI_FORMAT_A8P8, - DXGI_FORMAT_B4G4R4A4_UNORM, - DXGI_FORMAT_P208, - DXGI_FORMAT_V208, - DXGI_FORMAT_V408, - DXGI_FORMAT_FORCE_UINT + DxgiFormatUnknown, + DxgiFormatR32G32B32A32Typeless, + DxgiFormatR32G32B32A32Float, + DxgiFormatR32G32B32A32Uint, + DxgiFormatR32G32B32A32Sint, + DxgiFormatR32G32B32Typeless, + DxgiFormatR32G32B32Float, + DxgiFormatR32G32B32Uint, + DxgiFormatR32G32B32Sint, + DxgiFormatR16G16B16A16Typeless, + DxgiFormatR16G16B16A16Float, + DxgiFormatR16G16B16A16Unorm, + DxgiFormatR16G16B16A16Uint, + DxgiFormatR16G16B16A16Snorm, + DxgiFormatR16G16B16A16Sint, + DxgiFormatR32G32Typeless, + DxgiFormatR32G32Float, + DxgiFormatR32G32Uint, + DxgiFormatR32G32Sint, + DxgiFormatR32G8X24Typeless, + DxgiFormatD32FloatS8X24Uint, + DxgiFormatR32FloatX8X24Typeless, + DxgiFormatX32TypelessG8X24Uint, + DxgiFormatR10G10B10A2Typeless, + DxgiFormatR10G10B10A2Unorm, + DxgiFormatR10G10B10A2Uint, + DxgiFormatR11G11B10Float, + DxgiFormatR8G8B8A8Typeless, + DxgiFormatR8G8B8A8Unorm, + DxgiFormatR8G8B8A8UnormSrgb, + DxgiFormatR8G8B8A8Uint, + DxgiFormatR8G8B8A8Snorm, + DxgiFormatR8G8B8A8Sint, + DxgiFormatR16G16Typeless, + DxgiFormatR16G16Float, + DxgiFormatR16G16Unorm, + DxgiFormatR16G16Uint, + DxgiFormatR16G16Snorm, + DxgiFormatR16G16Sint, + DxgiFormatR32Typeless, + DxgiFormatD32Float, + DxgiFormatR32Float, + DxgiFormatR32Uint, + DxgiFormatR32Sint, + DxgiFormatR24G8Typeless, + DxgiFormatD24UnormS8Uint, + DxgiFormatR24UnormX8Typeless, + DxgiFormatX24TypelessG8Uint, + DxgiFormatR8G8Typeless, + DxgiFormatR8G8Unorm, + DxgiFormatR8G8Uint, + DxgiFormatR8G8Snorm, + DxgiFormatR8G8Sint, + DxgiFormatR16Typeless, + DxgiFormatR16Float, + DxgiFormatD16Unorm, + DxgiFormatR16Unorm, + DxgiFormatR16Uint, + DxgiFormatR16Snorm, + DxgiFormatR16Sint, + DxgiFormatR8Typeless, + DxgiFormatR8Unorm, + DxgiFormatR8Uint, + DxgiFormatR8Snorm, + DxgiFormatR8Sint, + DxgiFormatA8Unorm, + DxgiFormatR1Unorm, + DxgiFormatR9G9B9E5Sharedexp, + DxgiFormatR8G8B8G8Unorm, + DxgiFormatG8R8G8B8Unorm, + DxgiFormatBc1Typeless, + DxgiFormatBc1Unorm, + DxgiFormatBc1UnormSrgb, + DxgiFormatBc2Typeless, + DxgiFormatBc2Unorm, + DxgiFormatBc2UnormSrgb, + DxgiFormatBc3Typeless, + DxgiFormatBc3Unorm, + DxgiFormatBc3UnormSrgb, + DxgiFormatBc4Typeless, + DxgiFormatBc4Unorm, + DxgiFormatBc4Snorm, + DxgiFormatBc5Typeless, + DxgiFormatBc5Unorm, + DxgiFormatBc5Snorm, + DxgiFormatB5G6R5Unorm, + DxgiFormatB5G5R5A1Unorm, + DxgiFormatB8G8R8A8Unorm, + DxgiFormatB8G8R8X8Unorm, + DxgiFormatR10G10B10XrBiasA2Unorm, + DxgiFormatB8G8R8A8Typeless, + DxgiFormatB8G8R8A8UnormSrgb, + DxgiFormatB8G8R8X8Typeless, + DxgiFormatB8G8R8X8UnormSrgb, + DxgiFormatBc6HTypeless, + DxgiFormatBc6HUf16, + DxgiFormatBc6HSf16, + DxgiFormatBc7Typeless, + DxgiFormatBc7Unorm, + DxgiFormatBc7UnormSrgb, + DxgiFormatAyuv, + DxgiFormatY410, + DxgiFormatY416, + DxgiFormatNv12, + DxgiFormatP010, + DxgiFormatP016, + DxgiFormat420Opaque, + DxgiFormatYuy2, + DxgiFormatY210, + DxgiFormatY216, + DxgiFormatNv11, + DxgiFormatAi44, + DxgiFormatIa44, + DxgiFormatP8, + DxgiFormatA8P8, + DxgiFormatB4G4R4A4Unorm, + DxgiFormatP208, + DxgiFormatV208, + DxgiFormatV408, + DxgiFormatForceUint }; public static class DxgiFormatExtensions { - public static int GetByteSize(this DXGI_FORMAT format) + public static int GetByteSize(this DxgiFormat format) { switch (format) { - case DXGI_FORMAT.DXGI_FORMAT_UNKNOWN: + case DxgiFormat.DxgiFormatUnknown: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DxgiFormat.DxgiFormatR32G32B32A32Typeless: return 4 * 4; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_FLOAT: + case DxgiFormat.DxgiFormatR32G32B32A32Float: return 4 * 4; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_UINT: + case DxgiFormat.DxgiFormatR32G32B32A32Uint: return 4 * 4; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32A32_SINT: + case DxgiFormat.DxgiFormatR32G32B32A32Sint: return 4 * 4; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_TYPELESS: + case DxgiFormat.DxgiFormatR32G32B32Typeless: return 4 * 3; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_FLOAT: + case DxgiFormat.DxgiFormatR32G32B32Float: return 4 * 3; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_UINT: + case DxgiFormat.DxgiFormatR32G32B32Uint: return 4 * 3; - case DXGI_FORMAT.DXGI_FORMAT_R32G32B32_SINT: + case DxgiFormat.DxgiFormatR32G32B32Sint: return 4 * 3; - case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DxgiFormat.DxgiFormatR16G16B16A16Typeless: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_FLOAT: + case DxgiFormat.DxgiFormatR16G16B16A16Float: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_UNORM: + case DxgiFormat.DxgiFormatR16G16B16A16Unorm: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_UINT: + case DxgiFormat.DxgiFormatR16G16B16A16Uint: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_SNORM: + case DxgiFormat.DxgiFormatR16G16B16A16Snorm: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R16G16B16A16_SINT: + case DxgiFormat.DxgiFormatR16G16B16A16Sint: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R32G32_TYPELESS: + case DxgiFormat.DxgiFormatR32G32Typeless: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R32G32_FLOAT: + case DxgiFormat.DxgiFormatR32G32Float: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R32G32_UINT: + case DxgiFormat.DxgiFormatR32G32Uint: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R32G32_SINT: + case DxgiFormat.DxgiFormatR32G32Sint: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_R32G8X24_TYPELESS: + case DxgiFormat.DxgiFormatR32G8X24Typeless: return 4 * 2; - case DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DxgiFormat.DxgiFormatD32FloatS8X24Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DxgiFormat.DxgiFormatR32FloatX8X24Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + case DxgiFormat.DxgiFormatX32TypelessG8X24Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DxgiFormat.DxgiFormatR10G10B10A2Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UNORM: + case DxgiFormat.DxgiFormatR10G10B10A2Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R10G10B10A2_UINT: + case DxgiFormat.DxgiFormatR10G10B10A2Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R11G11B10_FLOAT: + case DxgiFormat.DxgiFormatR11G11B10Float: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DxgiFormat.DxgiFormatR8G8B8A8Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM: + case DxgiFormat.DxgiFormatR8G8B8A8Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DxgiFormat.DxgiFormatR8G8B8A8UnormSrgb: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UINT: + case DxgiFormat.DxgiFormatR8G8B8A8Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_SNORM: + case DxgiFormat.DxgiFormatR8G8B8A8Snorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_SINT: + case DxgiFormat.DxgiFormatR8G8B8A8Sint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R16G16_TYPELESS: + case DxgiFormat.DxgiFormatR16G16Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R16G16_FLOAT: + case DxgiFormat.DxgiFormatR16G16Float: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R16G16_UNORM: + case DxgiFormat.DxgiFormatR16G16Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R16G16_UINT: + case DxgiFormat.DxgiFormatR16G16Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R16G16_SNORM: + case DxgiFormat.DxgiFormatR16G16Snorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R16G16_SINT: + case DxgiFormat.DxgiFormatR16G16Sint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R32_TYPELESS: + case DxgiFormat.DxgiFormatR32Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_D32_FLOAT: + case DxgiFormat.DxgiFormatD32Float: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R32_FLOAT: + case DxgiFormat.DxgiFormatR32Float: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R32_UINT: + case DxgiFormat.DxgiFormatR32Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R32_SINT: + case DxgiFormat.DxgiFormatR32Sint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R24G8_TYPELESS: + case DxgiFormat.DxgiFormatR24G8Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_D24_UNORM_S8_UINT: + case DxgiFormat.DxgiFormatD24UnormS8Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DxgiFormat.DxgiFormatR24UnormX8Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DxgiFormat.DxgiFormatX24TypelessG8Uint: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8_TYPELESS: + case DxgiFormat.DxgiFormatR8G8Typeless: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R8G8_UNORM: + case DxgiFormat.DxgiFormatR8G8Unorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R8G8_UINT: + case DxgiFormat.DxgiFormatR8G8Uint: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R8G8_SNORM: + case DxgiFormat.DxgiFormatR8G8Snorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R8G8_SINT: + case DxgiFormat.DxgiFormatR8G8Sint: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R16_TYPELESS: + case DxgiFormat.DxgiFormatR16Typeless: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R16_FLOAT: + case DxgiFormat.DxgiFormatR16Float: return 2; - case DXGI_FORMAT.DXGI_FORMAT_D16_UNORM: + case DxgiFormat.DxgiFormatD16Unorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R16_UNORM: + case DxgiFormat.DxgiFormatR16Unorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R16_UINT: + case DxgiFormat.DxgiFormatR16Uint: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R16_SNORM: + case DxgiFormat.DxgiFormatR16Snorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R16_SINT: + case DxgiFormat.DxgiFormatR16Sint: return 2; - case DXGI_FORMAT.DXGI_FORMAT_R8_TYPELESS: + case DxgiFormat.DxgiFormatR8Typeless: return 1; - case DXGI_FORMAT.DXGI_FORMAT_R8_UNORM: + case DxgiFormat.DxgiFormatR8Unorm: return 1; - case DXGI_FORMAT.DXGI_FORMAT_R8_UINT: + case DxgiFormat.DxgiFormatR8Uint: return 1; - case DXGI_FORMAT.DXGI_FORMAT_R8_SNORM: + case DxgiFormat.DxgiFormatR8Snorm: return 1; - case DXGI_FORMAT.DXGI_FORMAT_R8_SINT: + case DxgiFormat.DxgiFormatR8Sint: return 1; - case DXGI_FORMAT.DXGI_FORMAT_A8_UNORM: + case DxgiFormat.DxgiFormatA8Unorm: return 1; - case DXGI_FORMAT.DXGI_FORMAT_R1_UNORM: + case DxgiFormat.DxgiFormatR1Unorm: return 1; - case DXGI_FORMAT.DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DxgiFormat.DxgiFormatR9G9B9E5Sharedexp: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R8G8_B8G8_UNORM: + case DxgiFormat.DxgiFormatR8G8B8G8Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_G8R8_G8B8_UNORM: + case DxgiFormat.DxgiFormatG8R8G8B8Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS: + case DxgiFormat.DxgiFormatBc1Typeless: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM: + case DxgiFormat.DxgiFormatBc1Unorm: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB: + case DxgiFormat.DxgiFormatBc1UnormSrgb: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS: + case DxgiFormat.DxgiFormatBc2Typeless: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM: + case DxgiFormat.DxgiFormatBc2Unorm: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB: + case DxgiFormat.DxgiFormatBc2UnormSrgb: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS: + case DxgiFormat.DxgiFormatBc3Typeless: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM: + case DxgiFormat.DxgiFormatBc3Unorm: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB: + case DxgiFormat.DxgiFormatBc3UnormSrgb: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS: + case DxgiFormat.DxgiFormatBc4Typeless: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: + case DxgiFormat.DxgiFormatBc4Unorm: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM: + case DxgiFormat.DxgiFormatBc4Snorm: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS: + case DxgiFormat.DxgiFormatBc5Typeless: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: + case DxgiFormat.DxgiFormatBc5Unorm: return 8; - case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM: + case DxgiFormat.DxgiFormatBc5Snorm: return 8; - case DXGI_FORMAT.DXGI_FORMAT_B5G6R5_UNORM: + case DxgiFormat.DxgiFormatB5G6R5Unorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_B5G5R5A1_UNORM: + case DxgiFormat.DxgiFormatB5G5R5A1Unorm: return 2; - case DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM: + case DxgiFormat.DxgiFormatB8G8R8A8Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_B8G8R8X8_UNORM: + case DxgiFormat.DxgiFormatB8G8R8X8Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DxgiFormat.DxgiFormatR10G10B10XrBiasA2Unorm: return 4; - case DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DxgiFormat.DxgiFormatB8G8R8A8Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DxgiFormat.DxgiFormatB8G8R8A8UnormSrgb: return 4; - case DXGI_FORMAT.DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DxgiFormat.DxgiFormatB8G8R8X8Typeless: return 4; - case DXGI_FORMAT.DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DxgiFormat.DxgiFormatB8G8R8X8UnormSrgb: return 4; - case DXGI_FORMAT.DXGI_FORMAT_BC6H_TYPELESS: + case DxgiFormat.DxgiFormatBc6HTypeless: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16: + case DxgiFormat.DxgiFormatBc6HUf16: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16: + case DxgiFormat.DxgiFormatBc6HSf16: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS: + case DxgiFormat.DxgiFormatBc7Typeless: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: + case DxgiFormat.DxgiFormatBc7Unorm: return 16; - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB: + case DxgiFormat.DxgiFormatBc7UnormSrgb: return 16; - case DXGI_FORMAT.DXGI_FORMAT_P8: + case DxgiFormat.DxgiFormatP8: return 1; - case DXGI_FORMAT.DXGI_FORMAT_A8P8: + case DxgiFormat.DxgiFormatA8P8: return 2; - case DXGI_FORMAT.DXGI_FORMAT_B4G4R4A4_UNORM: + case DxgiFormat.DxgiFormatB4G4R4A4Unorm: return 2; } return 4; } - public static bool IsCompressedFormat(this DXGI_FORMAT format) + public static bool IsCompressedFormat(this DxgiFormat format) { switch (format) { - case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB: + case DxgiFormat.DxgiFormatBc1Typeless: + case DxgiFormat.DxgiFormatBc1Unorm: + case DxgiFormat.DxgiFormatBc1UnormSrgb: + case DxgiFormat.DxgiFormatBc2Typeless: + case DxgiFormat.DxgiFormatBc2Unorm: + case DxgiFormat.DxgiFormatBc2UnormSrgb: + case DxgiFormat.DxgiFormatBc3Typeless: + case DxgiFormat.DxgiFormatBc3Unorm: + case DxgiFormat.DxgiFormatBc3UnormSrgb: + case DxgiFormat.DxgiFormatBc4Typeless: + case DxgiFormat.DxgiFormatBc4Unorm: + case DxgiFormat.DxgiFormatBc4Snorm: + case DxgiFormat.DxgiFormatBc5Typeless: + case DxgiFormat.DxgiFormatBc5Unorm: + case DxgiFormat.DxgiFormatBc5Snorm: + case DxgiFormat.DxgiFormatBc6HTypeless: + case DxgiFormat.DxgiFormatBc6HUf16: + case DxgiFormat.DxgiFormatBc6HSf16: + case DxgiFormat.DxgiFormatBc7Typeless: + case DxgiFormat.DxgiFormatBc7Unorm: + case DxgiFormat.DxgiFormatBc7UnormSrgb: return true; default: diff --git a/BCnEnc.Net/Shared/EncodedBlocks.cs b/BCnEnc.Net/Shared/EncodedBlocks.cs index c106d49..499cee3 100644 --- a/BCnEnc.Net/Shared/EncodedBlocks.cs +++ b/BCnEnc.Net/Shared/EncodedBlocks.cs @@ -16,9 +16,9 @@ internal unsafe struct Bc1Block readonly get => (int)(colorIndices >> (index * 2)) & 0b11; set { - colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); - int val = value & 0b11; - colorIndices = (colorIndices | ((uint)val << (index * 2))); + colorIndices = (uint)(colorIndices & ~(0b11 << (index * 2))); + var val = value & 0b11; + colorIndices = colorIndices | ((uint)val << (index * 2)); } } @@ -26,7 +26,7 @@ internal unsafe struct Bc1Block public readonly RawBlock4X4Rgba32 Decode(bool useAlpha) { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var output = new RawBlock4X4Rgba32(); var pixels = output.AsSpan; var color0 = this.color0.ToColorRgb24(); @@ -34,7 +34,7 @@ internal unsafe struct Bc1Block useAlpha = useAlpha && HasAlphaOrBlack; - Span colors = HasAlphaOrBlack ? + var colors = HasAlphaOrBlack ? stackalloc ColorRgb24[] { color0, color1, @@ -47,9 +47,9 @@ internal unsafe struct Bc1Block color0.InterpolateThird(color1, 2) }; - for (int i = 0; i < pixels.Length; i++) + for (var i = 0; i < pixels.Length; i++) { - int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); + var colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); var color = colors[colorIndex]; if (useAlpha && colorIndex == 3) { @@ -78,32 +78,32 @@ internal unsafe struct Bc2Block readonly get => (int)(colorIndices >> (index * 2)) & 0b11; set { - colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); - int val = value & 0b11; - colorIndices = (colorIndices | ((uint)val << (index * 2))); + colorIndices = (uint)(colorIndices & ~(0b11 << (index * 2))); + var val = value & 0b11; + colorIndices = colorIndices | ((uint)val << (index * 2)); } } public readonly byte GetAlpha(int index) { - ulong mask = 0xFUL << (index * 4); - int shift = (index * 4); - ulong alphaUnscaled = (((alphaColors & mask) >> shift)); - return (byte)((alphaUnscaled / 15.0) * 255); + var mask = 0xFUL << (index * 4); + var shift = index * 4; + var alphaUnscaled = (alphaColors & mask) >> shift; + return (byte)(alphaUnscaled / 15.0 * 255); } public void SetAlpha(int index, byte alpha) { - ulong mask = 0xFUL << (index * 4); - int shift = (index * 4); + var mask = 0xFUL << (index * 4); + var shift = index * 4; alphaColors &= ~mask; - byte a = (byte)((alpha / 255.0) * 15); + var a = (byte)(alpha / 255.0 * 15); alphaColors |= (ulong)(a & 0xF) << shift; } public readonly RawBlock4X4Rgba32 Decode() { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var output = new RawBlock4X4Rgba32(); var pixels = output.AsSpan; var color0 = this.color0.ToColorRgb24(); @@ -116,9 +116,9 @@ public void SetAlpha(int index, byte alpha) color0.InterpolateThird(color1, 2) }; - for (int i = 0; i < pixels.Length; i++) + for (var i = 0; i < pixels.Length; i++) { - int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); + var colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); var color = colors[colorIndex]; pixels[i] = new Rgba32(color.r, color.g, color.b, GetAlpha(i)); @@ -140,9 +140,9 @@ internal unsafe struct Bc3Block readonly get => (int)(colorIndices >> (index * 2)) & 0b11; set { - colorIndices = (uint)(colorIndices & (~(0b11 << (index * 2)))); - int val = value & 0b11; - colorIndices = (colorIndices | ((uint)val << (index * 2))); + colorIndices = (uint)(colorIndices & ~(0b11 << (index * 2))); + var val = value & 0b11; + colorIndices = colorIndices | ((uint)val << (index * 2)); } } @@ -168,23 +168,23 @@ public byte Alpha1 public readonly byte GetAlphaIndex(int pixelIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong alphaIndex = (((alphaBlock & mask) >> shift)); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; + var alphaIndex = (alphaBlock & mask) >> shift; return (byte)alphaIndex; } public void SetAlphaIndex(int pixelIndex, byte alphaIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; alphaBlock &= ~mask; alphaBlock |= (ulong)(alphaIndex & 0b111) << shift; } public readonly RawBlock4X4Rgba32 Decode() { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var output = new RawBlock4X4Rgba32(); var pixels = output.AsSpan; var color0 = this.color0.ToColorRgb24(); @@ -199,7 +199,7 @@ public void SetAlphaIndex(int pixelIndex, byte alphaIndex) color0.InterpolateThird(color1, 2) }; - Span alphas = a0 > a1 ? stackalloc byte[] { + var alphas = a0 > a1 ? stackalloc byte[] { a0, a1, (byte)Interpolation.Interpolate(a0, a1, 1, 7), @@ -219,9 +219,9 @@ public void SetAlphaIndex(int pixelIndex, byte alphaIndex) 255 }; - for (int i = 0; i < pixels.Length; i++) + for (var i = 0; i < pixels.Length; i++) { - int colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); + var colorIndex = (int)((colorIndices >> (i * 2)) & 0b11); var color = colors[colorIndex]; pixels[i] = new Rgba32(color.r, color.g, color.b, alphas[GetAlphaIndex(i)]); @@ -257,29 +257,29 @@ public byte Red1 public readonly byte GetRedIndex(int pixelIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong redIndex = (((redBlock & mask) >> shift)); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; + var redIndex = (redBlock & mask) >> shift; return (byte)redIndex; } public void SetRedIndex(int pixelIndex, byte redIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; redBlock &= ~mask; redBlock |= (ulong)(redIndex & 0b111) << shift; } public readonly RawBlock4X4Rgba32 Decode(bool redAsLuminance) { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var output = new RawBlock4X4Rgba32(); var pixels = output.AsSpan; var r0 = Red0; var r1 = Red1; - Span reds = r0 > r1 ? stackalloc byte[] { + var reds = r0 > r1 ? stackalloc byte[] { r0, r1, (byte)Interpolation.Interpolate(r0, r1, 1, 7), @@ -301,7 +301,7 @@ public void SetRedIndex(int pixelIndex, byte redIndex) if (redAsLuminance) { - for (int i = 0; i < pixels.Length; i++) + for (var i = 0; i < pixels.Length; i++) { var index = GetRedIndex(i); pixels[i] = new Rgba32(reds[index], reds[index], reds[index], 255); @@ -309,7 +309,7 @@ public void SetRedIndex(int pixelIndex, byte redIndex) } else { - for (int i = 0; i < pixels.Length; i++) + for (var i = 0; i < pixels.Length; i++) { var index = GetRedIndex(i); pixels[i] = new Rgba32(reds[index], 0, 0, 255); @@ -368,45 +368,45 @@ public byte Green1 public readonly byte GetRedIndex(int pixelIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong redIndex = (((redBlock & mask) >> shift)); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; + var redIndex = (redBlock & mask) >> shift; return (byte)redIndex; } public void SetRedIndex(int pixelIndex, byte redIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; redBlock &= ~mask; redBlock |= (ulong)(redIndex & 0b111) << shift; } public readonly byte GetGreenIndex(int pixelIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); - ulong greenIndex = (((greenBlock & mask) >> shift)); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; + var greenIndex = (greenBlock & mask) >> shift; return (byte)greenIndex; } public void SetGreenIndex(int pixelIndex, byte greenIndex) { - ulong mask = 0b0111UL << (pixelIndex * 3 + 16); - int shift = (pixelIndex * 3 + 16); + var mask = 0b0111UL << (pixelIndex * 3 + 16); + var shift = pixelIndex * 3 + 16; greenBlock &= ~mask; greenBlock |= (ulong)(greenIndex & 0b111) << shift; } public readonly RawBlock4X4Rgba32 Decode() { - RawBlock4X4Rgba32 output = new RawBlock4X4Rgba32(); + var output = new RawBlock4X4Rgba32(); var pixels = output.AsSpan; var r0 = Red0; var r1 = Red1; - Span reds = r0 > r1 ? stackalloc byte[] { + var reds = r0 > r1 ? stackalloc byte[] { r0, r1, (byte)Interpolation.Interpolate(r0, r1, 1, 7), @@ -429,7 +429,7 @@ public void SetGreenIndex(int pixelIndex, byte greenIndex) var g0 = Green0; var g1 = Green1; - Span greens = g0 > g1 ? stackalloc byte[] { + var greens = g0 > g1 ? stackalloc byte[] { g0, g1, (byte)Interpolation.Interpolate(g0, g1, 1, 7), @@ -449,7 +449,7 @@ public void SetGreenIndex(int pixelIndex, byte greenIndex) 255 }; - for (int i = 0; i < pixels.Length; i++) + for (var i = 0; i < pixels.Length; i++) { var redIndex = GetRedIndex(i); var greenIndex = GetGreenIndex(i); diff --git a/BCnEnc.Net/Shared/GLFormat.cs b/BCnEnc.Net/Shared/GLFormat.cs index 77e50ce..3c02c11 100644 --- a/BCnEnc.Net/Shared/GLFormat.cs +++ b/BCnEnc.Net/Shared/GLFormat.cs @@ -1,193 +1,193 @@ namespace BCnEncoder.Shared { - public enum GLFormat : uint + public enum GlFormat : uint { - GL_RED = 0x1903, - GL_BGRA = 0x80E1, - GL_RGB = 0x1907, - GL_RGBA = 0x1908, - GL_RG = 0x8227, - GL_RED_INTEGER = 0x8D94, - GL_RG_INTEGER = 0x8228, - GL_RED_SNORM = 0x8F90, - GL_RG_SNORM = 0x8F91, - GL_RGB_SNORM = 0x8F92, - GL_RGBA_SNORM = 0x8F93, + GlRed = 0x1903, + GlBgra = 0x80E1, + GlRgb = 0x1907, + GlRgba = 0x1908, + GlRg = 0x8227, + GlRedInteger = 0x8D94, + GlRgInteger = 0x8228, + GlRedSnorm = 0x8F90, + GlRgSnorm = 0x8F91, + GlRgbSnorm = 0x8F92, + GlRgbaSnorm = 0x8F93, } - public enum GLType : uint + public enum GlType : uint { - GL_BYTE = 5120, - GL_UNSIGNED_BYTE = 5121, - GL_SHORT = 5122, - GL_UNSIGNED_SHORT = 5123, - GL_INT = 5124, - GL_UNSIGNED_INT = 5125, - GL_FLOAT = 5126, - GL_HALF_FLOAT = 5131, - GL_UNSIGNED_BYTE_2_3_3_REV = 33634, - GL_UNSIGNED_BYTE_3_3_2 = 32818, - GL_UNSIGNED_INT_10_10_10_2 = 32822, - GL_UNSIGNED_INT_2_10_10_10_REV = 33640, - GL_UNSIGNED_INT_8_8_8_8 = 32821, - GL_UNSIGNED_INT_8_8_8_8_REV = 33639, - GL_UNSIGNED_SHORT_1_5_5_5_REV = 33638, - GL_UNSIGNED_SHORT_4_4_4_4 = 32819, - GL_UNSIGNED_SHORT_4_4_4_4_REV = 33637, - GL_UNSIGNED_SHORT_5_5_5_1 = 32820, - GL_UNSIGNED_SHORT_5_6_5 = 33635, - GL_UNSIGNED_SHORT_5_6_5_REV = 33636 + GlByte = 5120, + GlUnsignedByte = 5121, + GlShort = 5122, + GlUnsignedShort = 5123, + GlInt = 5124, + GlUnsignedInt = 5125, + GlFloat = 5126, + GlHalfFloat = 5131, + GlUnsignedByte233Rev = 33634, + GlUnsignedByte332 = 32818, + GlUnsignedInt1010102 = 32822, + GlUnsignedInt2101010Rev = 33640, + GlUnsignedInt8888 = 32821, + GlUnsignedInt8888Rev = 33639, + GlUnsignedShort1555Rev = 33638, + GlUnsignedShort4444 = 32819, + GlUnsignedShort4444Rev = 33637, + GlUnsignedShort5551 = 32820, + GlUnsignedShort565 = 33635, + GlUnsignedShort565Rev = 33636 } public enum GlInternalFormat : uint { - GL_RGBA4 = 0x8056, - GL_RGB5 = 0x8050, - GL_RGB565 = 0x8D62, - GL_RGBA8 = 0x8058, - GL_RGB5_A1 = 0x8057, - GL_RGBA16 = 0x805B, - GL_DEPTH_COMPONENT16 = 0x81A5, - GL_DEPTH_COMPONENT24 = 0x81A6, - GL_DEPTH_COMPONENT32F = 36012, - GL_STENCIL_INDEX8 = 36168, - GL_DEPTH24_STENCIL8 = 0x88F0, - GL_DEPTH32F_STENCIL8 = 36013, - - GL_R8 = 0x8229, - GL_RG8 = 0x822B, - GL_RG16 = 0x822C, - GL_R16F = 0x822D, - GL_R32F = 0x822E, - GL_RG16F = 0x822F, - GL_RG32F = 0x8230, - GL_RGBA32F = 0x8814, - GL_RGBA16F = 0x881A, - - GL_R8UI = 33330, - GL_R8I = 33329, - GL_R16 = 33322, - GL_R16I = 33331, - GL_R16UI = 33332, - GL_R32I = 33333, - GL_R32UI = 33334, - - - GL_RG8I = 33335, - GL_RG8UI = 33336, - GL_RG16I = 33337, - GL_RG16UI = 33338, - GL_RG32I = 33339, - GL_RG32UI = 33340, - - GL_RGB8 = 32849, - GL_RGB8I = 36239, - GL_RGB8UI = 36221, - - GL_RGBA12 = 32858, - GL_RGBA2 = 32853, - GL_RGBA8I = 36238, - GL_RGBA8UI = 36220, - - GL_RGBA16I = 36232, - GL_RGBA16UI = 36214, - GL_RGBA32I = 36226, - GL_RGBA32UI = 36208, - - - GL_R8_SNORM = 0x8F94, - GL_RG8_SNORM = 0x8F95, - GL_RGB8_SNORM = 0x8F96, - GL_RGBA8_SNORM = 0x8F97, - GL_R16_SNORM = 0x8F98, - GL_RG16_SNORM = 0x8F99, - GL_RGB16_SNORM = 0x8F9A, - GL_RGBA16_SNORM = 0x8F9B, - - GL_RGB10_A2 = 32857, - GL_RGB10_A2UI = 36975, - - GL_RGB16 = 32852, - GL_RGB16F = 34843, - GL_RGB16I = 36233, - GL_RGB16UI = 36215, - - GL_RGB32F = 34837, - GL_RGB32I = 36227, - GL_RGB32UI = 36209, + GlRgba4 = 0x8056, + GlRgb5 = 0x8050, + GlRgb565 = 0x8D62, + GlRgba8 = 0x8058, + GlRgb5A1 = 0x8057, + GlRgba16 = 0x805B, + GlDepthComponent16 = 0x81A5, + GlDepthComponent24 = 0x81A6, + GlDepthComponent32F = 36012, + GlStencilIndex8 = 36168, + GlDepth24Stencil8 = 0x88F0, + GlDepth32FStencil8 = 36013, + + GlR8 = 0x8229, + GlRg8 = 0x822B, + GlRg16 = 0x822C, + GlR16F = 0x822D, + GlR32F = 0x822E, + GlRg16F = 0x822F, + GlRg32F = 0x8230, + GlRgba32F = 0x8814, + GlRgba16F = 0x881A, + + GlR8Ui = 33330, + GlR8I = 33329, + GlR16 = 33322, + GlR16I = 33331, + GlR16Ui = 33332, + GlR32I = 33333, + GlR32Ui = 33334, + + + GlRg8I = 33335, + GlRg8Ui = 33336, + GlRg16I = 33337, + GlRg16Ui = 33338, + GlRg32I = 33339, + GlRg32Ui = 33340, + + GlRgb8 = 32849, + GlRgb8I = 36239, + GlRgb8Ui = 36221, + + GlRgba12 = 32858, + GlRgba2 = 32853, + GlRgba8I = 36238, + GlRgba8Ui = 36220, + + GlRgba16I = 36232, + GlRgba16Ui = 36214, + GlRgba32I = 36226, + GlRgba32Ui = 36208, + + + GlR8Snorm = 0x8F94, + GlRg8Snorm = 0x8F95, + GlRgb8Snorm = 0x8F96, + GlRgba8Snorm = 0x8F97, + GlR16Snorm = 0x8F98, + GlRg16Snorm = 0x8F99, + GlRgb16Snorm = 0x8F9A, + GlRgba16Snorm = 0x8F9B, + + GlRgb10A2 = 32857, + GlRgb10A2Ui = 36975, + + GlRgb16 = 32852, + GlRgb16F = 34843, + GlRgb16I = 36233, + GlRgb16Ui = 36215, + + GlRgb32F = 34837, + GlRgb32I = 36227, + GlRgb32Ui = 36209, //BC1 - GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0, - GL_COMPRESSED_SRGB_S3TC_DXT1_EXT = 0x8C4C, - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1, - GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT = 0x8C4D, + GlCompressedRgbS3TcDxt1Ext = 0x83F0, + GlCompressedSrgbS3TcDxt1Ext = 0x8C4C, + GlCompressedRgbaS3TcDxt1Ext = 0x83F1, + GlCompressedSrgbAlphaS3TcDxt1Ext = 0x8C4D, //BC2 - GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2, - GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT = 0x8C4E, + GlCompressedRgbaS3TcDxt3Ext = 0x83F2, + GlCompressedSrgbAlphaS3TcDxt3Ext = 0x8C4E, //BC3 - GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3, - GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT = 0x8C4F, + GlCompressedRgbaS3TcDxt5Ext = 0x83F3, + GlCompressedSrgbAlphaS3TcDxt5Ext = 0x8C4F, //BC4 & BC5 - GL_COMPRESSED_RED_GREEN_RGTC2_EXT = 36285, - GL_COMPRESSED_RED_RGTC1_EXT = 36283, - GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT = 36286, - GL_COMPRESSED_SIGNED_RED_RGTC1_EXT = 36284, + GlCompressedRedGreenRgtc2Ext = 36285, + GlCompressedRedRgtc1Ext = 36283, + GlCompressedSignedRedGreenRgtc2Ext = 36286, + GlCompressedSignedRedRgtc1Ext = 36284, //BC6 & BC7 - GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB = 36494, - GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB = 36495, - GL_COMPRESSED_RGBA_BPTC_UNORM_ARB = 36492, - GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB = 36493, + GlCompressedRgbBptcSignedFloatArb = 36494, + GlCompressedRgbBptcUnsignedFloatArb = 36495, + GlCompressedRgbaBptcUnormArb = 36492, + GlCompressedSrgbAlphaBptcUnormArb = 36493, // ETC1 & 2 - GL_ETC1_RGB8_OES = 0x8D64, + GlEtc1Rgb8Oes = 0x8D64, - GL_COMPRESSED_R11_EAC = 0x9270, - GL_COMPRESSED_SIGNED_R11_EAC = 0x9271, - GL_COMPRESSED_RG11_EAC = 0x9272, - GL_COMPRESSED_SIGNED_RG11_EAC = 0x9273, + GlCompressedR11Eac = 0x9270, + GlCompressedSignedR11Eac = 0x9271, + GlCompressedRg11Eac = 0x9272, + GlCompressedSignedRg11Eac = 0x9273, - GL_COMPRESSED_RGB8_ETC2 = 0x9274, - GL_COMPRESSED_SRGB8_ETC2 = 0x9275, - GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9276, - GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 = 0x9277, - GL_COMPRESSED_RGBA8_ETC2_EAC = 0x9278, - GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC = 0x9279, + GlCompressedRgb8Etc2 = 0x9274, + GlCompressedSrgb8Etc2 = 0x9275, + GlCompressedRgb8PunchthroughAlpha1Etc2 = 0x9276, + GlCompressedSrgb8PunchthroughAlpha1Etc2 = 0x9277, + GlCompressedRgba8Etc2Eac = 0x9278, + GlCompressedSrgb8Alpha8Etc2Eac = 0x9279, // ASTC - GL_COMPRESSED_RGBA_ASTC_4x4_KHR = 0x93B0, - GL_COMPRESSED_RGBA_ASTC_5x4_KHR = 0x93B1, - GL_COMPRESSED_RGBA_ASTC_5x5_KHR = 0x93B2, - GL_COMPRESSED_RGBA_ASTC_6x5_KHR = 0x93B3, - GL_COMPRESSED_RGBA_ASTC_6x6_KHR = 0x93B4, - GL_COMPRESSED_RGBA_ASTC_8x5_KHR = 0x93B5, - GL_COMPRESSED_RGBA_ASTC_8x6_KHR = 0x93B6, - GL_COMPRESSED_RGBA_ASTC_8x8_KHR = 0x93B7, - GL_COMPRESSED_RGBA_ASTC_10x5_KHR = 0x93B8, - GL_COMPRESSED_RGBA_ASTC_10x6_KHR = 0x93B9, - GL_COMPRESSED_RGBA_ASTC_10x8_KHR = 0x93BA, - GL_COMPRESSED_RGBA_ASTC_10x10_KHR = 0x93BB, - GL_COMPRESSED_RGBA_ASTC_12x10_KHR = 0x93BC, - GL_COMPRESSED_RGBA_ASTC_12x12_KHR = 0x93BD, - - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR = 0x93D0, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR = 0x93D1, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR = 0x93D2, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR = 0x93D3, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR = 0x93D4, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR = 0x93D5, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR = 0x93D6, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR = 0x93D7, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR = 0x93D8, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR = 0x93D9, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR = 0x93DA, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR = 0x93DB, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR = 0x93DC, - GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD + GlCompressedRgbaAstc4X4Khr = 0x93B0, + GlCompressedRgbaAstc5X4Khr = 0x93B1, + GlCompressedRgbaAstc5X5Khr = 0x93B2, + GlCompressedRgbaAstc6X5Khr = 0x93B3, + GlCompressedRgbaAstc6X6Khr = 0x93B4, + GlCompressedRgbaAstc8X5Khr = 0x93B5, + GlCompressedRgbaAstc8X6Khr = 0x93B6, + GlCompressedRgbaAstc8X8Khr = 0x93B7, + GlCompressedRgbaAstc10X5Khr = 0x93B8, + GlCompressedRgbaAstc10X6Khr = 0x93B9, + GlCompressedRgbaAstc10X8Khr = 0x93BA, + GlCompressedRgbaAstc10X10Khr = 0x93BB, + GlCompressedRgbaAstc12X10Khr = 0x93BC, + GlCompressedRgbaAstc12X12Khr = 0x93BD, + + GlCompressedSrgb8Alpha8Astc4X4Khr = 0x93D0, + GlCompressedSrgb8Alpha8Astc5X4Khr = 0x93D1, + GlCompressedSrgb8Alpha8Astc5X5Khr = 0x93D2, + GlCompressedSrgb8Alpha8Astc6X5Khr = 0x93D3, + GlCompressedSrgb8Alpha8Astc6X6Khr = 0x93D4, + GlCompressedSrgb8Alpha8Astc8X5Khr = 0x93D5, + GlCompressedSrgb8Alpha8Astc8X6Khr = 0x93D6, + GlCompressedSrgb8Alpha8Astc8X8Khr = 0x93D7, + GlCompressedSrgb8Alpha8Astc10X5Khr = 0x93D8, + GlCompressedSrgb8Alpha8Astc10X6Khr = 0x93D9, + GlCompressedSrgb8Alpha8Astc10X8Khr = 0x93DA, + GlCompressedSrgb8Alpha8Astc10X10Khr = 0x93DB, + GlCompressedSrgb8Alpha8Astc12X10Khr = 0x93DC, + GlCompressedSrgb8Alpha8Astc12X12Khr = 0x93DD } } diff --git a/BCnEnc.Net/Shared/ImageQuality.cs b/BCnEnc.Net/Shared/ImageQuality.cs index 1def66f..dc7e477 100644 --- a/BCnEnc.Net/Shared/ImageQuality.cs +++ b/BCnEnc.Net/Shared/ImageQuality.cs @@ -10,14 +10,14 @@ public class ImageQuality throw new ArgumentException("Both spans should be the same length"); } float error = 0; - for (int i = 0; i < original.Length; i++) { + for (var i = 0; i < original.Length; i++) { var o = new ColorYCbCr(original[i]); var c = new ColorYCbCr(other[i]); error += (o.y - c.y) * (o.y - c.y); error += (o.cb - c.cb) * (o.cb - c.cb); error += (o.cr - c.cr) * (o.cr - c.cr); if (countAlpha) { - error += ((original[i].A - other[i].A) / 255.0f) * ((original[i].A - other[i].A) / 255.0f); + error += (original[i].A - other[i].A) / 255.0f * ((original[i].A - other[i].A) / 255.0f); } } @@ -40,12 +40,12 @@ public class ImageQuality throw new ArgumentException("Both spans should be the same length"); } float error = 0; - for (int i = 0; i < original.Length; i++) { + for (var i = 0; i < original.Length; i++) { var o = new ColorYCbCr(original[i]); var c = new ColorYCbCr(other[i]); error += (o.y - c.y) * (o.y - c.y); if (countAlpha) { - error += ((original[i].A - other[i].A) / 255.0f) * ((original[i].A - other[i].A) / 255.0f); + error += (original[i].A - other[i].A) / 255.0f * ((original[i].A - other[i].A) / 255.0f); } } diff --git a/BCnEnc.Net/Shared/ImageToBlocks.cs b/BCnEnc.Net/Shared/ImageToBlocks.cs index fb8b7bb..4f3b1e7 100644 --- a/BCnEnc.Net/Shared/ImageToBlocks.cs +++ b/BCnEnc.Net/Shared/ImageToBlocks.cs @@ -12,21 +12,21 @@ internal static RawBlock4X4Rgba32[] ImageTo4X4(ImageFrame image, out int { blocksWidth = (int)MathF.Ceiling(image.Width / 4.0f); blocksHeight = (int)MathF.Ceiling(image.Height / 4.0f); - RawBlock4X4Rgba32[] output = new RawBlock4X4Rgba32[blocksWidth * blocksHeight]; + var output = new RawBlock4X4Rgba32[blocksWidth * blocksHeight]; if (!image.TryGetSinglePixelSpan(out var pixels)) { throw new Exception("Cannot get pixel span."); } - for (int y = 0; y < image.Height; y++) + for (var y = 0; y < image.Height; y++) { - for (int x = 0; x < image.Width; x++) + for (var x = 0; x < image.Width; x++) { - Rgba32 color = pixels[x + y * image.Width]; - int blockIndexX = (int)MathF.Floor(x / 4.0f); - int blockIndexY = (int)MathF.Floor(y / 4.0f); - int blockInternalIndexX = x % 4; - int blockInternalIndexY = y % 4; + var color = pixels[x + y * image.Width]; + var blockIndexX = (int)MathF.Floor(x / 4.0f); + var blockIndexY = (int)MathF.Floor(y / 4.0f); + var blockInternalIndexX = x % 4; + var blockInternalIndexY = y % 4; output[blockIndexX + blockIndexY * blocksWidth][blockInternalIndexX, blockInternalIndexY] = color; } @@ -35,13 +35,13 @@ internal static RawBlock4X4Rgba32[] ImageTo4X4(ImageFrame image, out int //Fill in block y with edge color if (image.Height % 4 != 0) { - int yPaddingStart = image.Height % 4; - for (int i = 0; i < blocksWidth; i++) + var yPaddingStart = image.Height % 4; + for (var i = 0; i < blocksWidth; i++) { var lastBlock = output[i + blocksWidth * (blocksHeight - 1)]; - for (int y = yPaddingStart; y < 4; y++) + for (var y = yPaddingStart; y < 4; y++) { - for (int x = 0; x < 4; x++) + for (var x = 0; x < 4; x++) { lastBlock[x, y] = lastBlock[x, y - 1]; } @@ -53,13 +53,13 @@ internal static RawBlock4X4Rgba32[] ImageTo4X4(ImageFrame image, out int //Fill in block x with edge color if (image.Width % 4 != 0) { - int xPaddingStart = image.Width % 4; - for (int i = 0; i < blocksHeight; i++) + var xPaddingStart = image.Width % 4; + for (var i = 0; i < blocksHeight; i++) { var lastBlock = output[blocksWidth - 1 + i * blocksWidth]; - for (int x = xPaddingStart; x < 4; x++) + for (var x = xPaddingStart; x < 4; x++) { - for (int y = 0; y < 4; y++) + for (var y = 0; y < 4; y++) { lastBlock[x, y] = lastBlock[x - 1, y]; } @@ -77,20 +77,20 @@ internal static Image ImageFromRawBlocks(RawBlock4X4Rgba32[,] blocks, in internal static Image ImageFromRawBlocks(RawBlock4X4Rgba32[,] blocks, int blocksWidth, int blocksHeight, int pixelWidth, int pixelHeight) { - Image output = new Image(pixelWidth, pixelHeight); + var output = new Image(pixelWidth, pixelHeight); if (!output.TryGetSinglePixelSpan(out var pixels)) { throw new Exception("Cannot get pixel span."); } - for (int y = 0; y < output.Height; y++) + for (var y = 0; y < output.Height; y++) { - for (int x = 0; x < output.Width; x++) + for (var x = 0; x < output.Width; x++) { - int blockIndexX = (int)MathF.Floor(x / 4.0f); - int blockIndexY = (int)MathF.Floor(y / 4.0f); - int blockInternalIndexX = x % 4; - int blockInternalIndexY = y % 4; + var blockIndexX = (int)MathF.Floor(x / 4.0f); + var blockIndexY = (int)MathF.Floor(y / 4.0f); + var blockInternalIndexX = x % 4; + var blockInternalIndexY = y % 4; pixels[x + y * output.Width] = blocks[blockIndexX, blockIndexY] @@ -107,20 +107,20 @@ internal static Image ImageFromRawBlocks(RawBlock4X4Rgba32[] blocks, int internal static Image ImageFromRawBlocks(RawBlock4X4Rgba32[] blocks, int blocksWidth, int blocksHeight, int pixelWidth, int pixelHeight) { - Image output = new Image(pixelWidth, pixelHeight); + var output = new Image(pixelWidth, pixelHeight); if (!output.TryGetSinglePixelSpan(out var pixels)) { throw new Exception("Cannot get pixel span."); } - for (int y = 0; y < output.Height; y++) + for (var y = 0; y < output.Height; y++) { - for (int x = 0; x < output.Width; x++) + for (var x = 0; x < output.Width; x++) { - int blockIndexX = (int)MathF.Floor(x / 4.0f); - int blockIndexY = (int)MathF.Floor(y / 4.0f); - int blockInternalIndexX = x % 4; - int blockInternalIndexY = y % 4; + var blockIndexX = (int)MathF.Floor(x / 4.0f); + var blockIndexY = (int)MathF.Floor(y / 4.0f); + var blockInternalIndexX = x % 4; + var blockInternalIndexY = y % 4; pixels[x + y * output.Width] = blocks[blockIndexX + blockIndexY * blocksWidth] diff --git a/BCnEnc.Net/Shared/KtxFile.cs b/BCnEnc.Net/Shared/KtxFile.cs index 27ce05f..47bc782 100644 --- a/BCnEnc.Net/Shared/KtxFile.cs +++ b/BCnEnc.Net/Shared/KtxFile.cs @@ -15,14 +15,14 @@ namespace BCnEncoder.Shared public class KtxFile { - public KtxHeader Header; + public KtxHeader header; public List KeyValuePairs { get; } = new List(); public List MipMaps { get; } = new List(); public KtxFile() { } public KtxFile(KtxHeader header) { - Header = header; + this.header = header; } /// @@ -35,44 +35,44 @@ public void Write(Stream s) throw new InvalidOperationException("The KTX structure should have at least 1 mipmap level and 1 Face before writing to file."); } - using (BinaryWriter bw = new BinaryWriter(s, UTF8, true)) + using (var bw = new BinaryWriter(s, UTF8, true)) { - uint bytesOfKeyValueData = (uint)KeyValuePairs.Sum(x => x.GetSizeWithPadding()); + var bytesOfKeyValueData = (uint)KeyValuePairs.Sum(x => x.GetSizeWithPadding()); - Header.BytesOfKeyValueData = bytesOfKeyValueData; - Header.NumberOfFaces = MipMaps[0].NumberOfFaces; - Header.NumberOfMipmapLevels = (uint)MipMaps.Count; - Header.NumberOfArrayElements = 0; + header.BytesOfKeyValueData = bytesOfKeyValueData; + header.NumberOfFaces = MipMaps[0].NumberOfFaces; + header.NumberOfMipmapLevels = (uint)MipMaps.Count; + header.NumberOfArrayElements = 0; - if (!Header.VerifyHeader()) + if (!header.VerifyHeader()) { throw new InvalidOperationException("Please verify the header validity before writing to file."); } - bw.WriteStruct(Header); + bw.WriteStruct(header); - foreach (KtxKeyValuePair keyValuePair in KeyValuePairs) + foreach (var keyValuePair in KeyValuePairs) { KtxKeyValuePair.WriteKeyValuePair(bw, keyValuePair); } - for (int mip = 0; mip < Header.NumberOfMipmapLevels; mip++) + for (var mip = 0; mip < header.NumberOfMipmapLevels; mip++) { - uint imageSize = MipMaps[mip].SizeInBytes; + var imageSize = MipMaps[mip].SizeInBytes; bw.Write(imageSize); - bool isCubemap = Header.NumberOfFaces == 6 && Header.NumberOfArrayElements == 0; - for (int f = 0; f < Header.NumberOfFaces; f++) + var isCubemap = header.NumberOfFaces == 6 && header.NumberOfArrayElements == 0; + for (var f = 0; f < header.NumberOfFaces; f++) { bw.Write(MipMaps[mip].Faces[f].Data); - uint cubePadding = 0u; + var cubePadding = 0u; if (isCubemap) { - cubePadding = 3 - ((imageSize + 3) % 4); + cubePadding = 3 - (imageSize + 3) % 4; } bw.AddPadding(cubePadding); } - uint mipPaddingBytes = 3 - ((imageSize + 3) % 4); + var mipPaddingBytes = 3 - (imageSize + 3) % 4; bw.AddPadding(mipPaddingBytes); } @@ -85,49 +85,49 @@ public void Write(Stream s) public static KtxFile Load(Stream s) { - using (BinaryReader br = new BinaryReader(s, UTF8, true)) + using (var br = new BinaryReader(s, UTF8, true)) { - KtxHeader header = br.ReadStruct(); + var header = br.ReadStruct(); if (header.NumberOfArrayElements > 0) { throw new NotSupportedException("KTX files with arrays are not supported."); } - KtxFile ktx = new KtxFile(header); + var ktx = new KtxFile(header); - int keyValuePairBytesRead = 0; + var keyValuePairBytesRead = 0; while (keyValuePairBytesRead < header.BytesOfKeyValueData) { - KtxKeyValuePair kvp = KtxKeyValuePair.ReadKeyValuePair(br, out int read); + var kvp = KtxKeyValuePair.ReadKeyValuePair(br, out var read); keyValuePairBytesRead += read; ktx.KeyValuePairs.Add(kvp); } - uint numberOfFaces = Math.Max(1, header.NumberOfFaces); + var numberOfFaces = Math.Max(1, header.NumberOfFaces); ktx.MipMaps.Capacity = (int)header.NumberOfMipmapLevels; for (uint mipLevel = 0; mipLevel < header.NumberOfMipmapLevels; mipLevel++) { - uint imageSize = br.ReadUInt32(); - uint mipWidth = header.PixelWidth / (uint)(Math.Pow(2, mipLevel)); - uint mipHeight = header.PixelHeight / (uint)(Math.Pow(2, mipLevel)); + var imageSize = br.ReadUInt32(); + var mipWidth = header.PixelWidth / (uint)Math.Pow(2, mipLevel); + var mipHeight = header.PixelHeight / (uint)Math.Pow(2, mipLevel); ktx.MipMaps.Add(new KtxMipmap(imageSize, mipWidth, mipHeight, numberOfFaces)); - bool cubemap = header.NumberOfFaces > 1 && header.NumberOfArrayElements == 0; + var cubemap = header.NumberOfFaces > 1 && header.NumberOfArrayElements == 0; for (uint face = 0; face < numberOfFaces; face++) { - byte[] faceData = br.ReadBytes((int)imageSize); + var faceData = br.ReadBytes((int)imageSize); ktx.MipMaps[(int)mipLevel].Faces[(int)face] = new KtxMipFace(faceData, mipWidth, mipHeight); if (cubemap) { - uint cubePadding = 0u; - cubePadding = 3 - ((imageSize + 3) % 4); + var cubePadding = 0u; + cubePadding = 3 - (imageSize + 3) % 4; br.SkipPadding(cubePadding); } } - uint mipPaddingBytes = 3 - ((imageSize + 3) % 4); + var mipPaddingBytes = 3 - (imageSize + 3) % 4; br.SkipPadding(mipPaddingBytes); } @@ -142,11 +142,11 @@ public ulong GetTotalSize() { ulong totalSize = 0; - for (int mipLevel = 0; mipLevel < Header.NumberOfMipmapLevels; mipLevel++) + for (var mipLevel = 0; mipLevel < header.NumberOfMipmapLevels; mipLevel++) { - for (int face = 0; face < Header.NumberOfFaces; face++) + for (var face = 0; face < header.NumberOfFaces; face++) { - KtxMipFace ktxface = MipMaps[mipLevel].Faces[face]; + var ktxface = MipMaps[mipLevel].Faces[face]; totalSize += ktxface.SizeInBytes; } } @@ -159,13 +159,13 @@ public ulong GetTotalSize() /// public byte[] GetAllTextureDataFaceMajor() { - byte[] result = new byte[GetTotalSize()]; + var result = new byte[GetTotalSize()]; uint start = 0; - for (int face = 0; face < Header.NumberOfFaces; face++) + for (var face = 0; face < header.NumberOfFaces; face++) { - for (int mipLevel = 0; mipLevel < Header.NumberOfMipmapLevels; mipLevel++) + for (var mipLevel = 0; mipLevel < header.NumberOfMipmapLevels; mipLevel++) { - KtxMipFace ktxMipFace = MipMaps[mipLevel].Faces[face]; + var ktxMipFace = MipMaps[mipLevel].Faces[face]; ktxMipFace.Data.CopyTo(result, (int)start); start += ktxMipFace.SizeInBytes; } @@ -179,13 +179,13 @@ public byte[] GetAllTextureDataFaceMajor() /// public byte[] GetAllTextureDataMipMajor() { - byte[] result = new byte[GetTotalSize()]; + var result = new byte[GetTotalSize()]; uint start = 0; - for (int mipLevel = 0; mipLevel < Header.NumberOfMipmapLevels; mipLevel++) + for (var mipLevel = 0; mipLevel < header.NumberOfMipmapLevels; mipLevel++) { - for (int face = 0; face < Header.NumberOfFaces; face++) + for (var face = 0; face < header.NumberOfFaces; face++) { - KtxMipFace ktxMipFace = MipMaps[mipLevel].Faces[face]; + var ktxMipFace = MipMaps[mipLevel].Faces[face]; ktxMipFace.Data.CopyTo(result, (int)start); start += ktxMipFace.SizeInBytes; } @@ -207,16 +207,16 @@ public KtxKeyValuePair(string key, byte[] value) public uint GetSizeWithPadding() { - int keySpanLength = UTF8.GetByteCount(Key); - uint totalSize = (uint)(keySpanLength + 1 + Value.Length); - int paddingBytes = (int)(3 - ((totalSize + 3) % 4)); + var keySpanLength = UTF8.GetByteCount(Key); + var totalSize = (uint)(keySpanLength + 1 + Value.Length); + var paddingBytes = (int)(3 - (totalSize + 3) % 4); return (uint)(totalSize + paddingBytes); } public static KtxKeyValuePair ReadKeyValuePair(BinaryReader br, out int bytesRead) { - uint totalSize = br.ReadUInt32(); + var totalSize = br.ReadUInt32(); Span keyValueBytes = stackalloc byte[(int)totalSize]; br.Read(keyValueBytes); @@ -236,15 +236,15 @@ public static KtxKeyValuePair ReadKeyValuePair(BinaryReader br, out int bytesRea } - int keySize = i; - string key = UTF8.GetString(keyValueBytes.Slice(0, keySize)); + var keySize = i; + var key = UTF8.GetString(keyValueBytes.Slice(0, keySize)); - int valueSize = (int)(totalSize - keySize - 1); - Span valueBytes = keyValueBytes.Slice(i + 1, valueSize); - byte[] value = new byte[valueSize]; + var valueSize = (int)(totalSize - keySize - 1); + var valueBytes = keyValueBytes.Slice(i + 1, valueSize); + var value = new byte[valueSize]; valueBytes.CopyTo(value); - int paddingBytes = (int)(3 - ((totalSize + 3) % 4)); + var paddingBytes = (int)(3 - (totalSize + 3) % 4); br.SkipPadding(paddingBytes); bytesRead = (int)(totalSize + paddingBytes + sizeof(uint)); @@ -253,12 +253,12 @@ public static KtxKeyValuePair ReadKeyValuePair(BinaryReader br, out int bytesRea public static uint WriteKeyValuePair(BinaryWriter bw, KtxKeyValuePair pair) { - int keySpanLength = UTF8.GetByteCount(pair.Key); + var keySpanLength = UTF8.GetByteCount(pair.Key); Span keySpan = stackalloc byte[keySpanLength]; Span valueSpan = pair.Value; - uint totalSize = (uint)(keySpan.Length + 1 + valueSpan.Length); - int paddingBytes = (int)(3 - ((totalSize + 3) % 4)); + var totalSize = (uint)(keySpan.Length + 1 + valueSpan.Length); + var paddingBytes = (int)(3 - (totalSize + 3) % 4); bw.Write(totalSize); bw.Write(keySpan); @@ -274,11 +274,11 @@ public unsafe struct KtxHeader { public fixed byte Identifier[12]; public uint Endianness; - public GLType GlType; + public GlType GlType; public uint GlTypeSize; - public GLFormat GlFormat; + public GlFormat GlFormat; public GlInternalFormat GlInternalFormat; - public GLFormat GlBaseInternalFormat; + public GlFormat GlBaseInternalFormat; public uint PixelWidth; public uint PixelHeight; @@ -291,18 +291,18 @@ public unsafe struct KtxHeader public bool VerifyHeader() { Span id = stackalloc byte[] { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; - for (int i = 0; i < id.Length; i++) + for (var i = 0; i < id.Length; i++) { if (Identifier[i] != id[i]) return false; } return true; } - public static KtxHeader InitializeCompressed(int width, int height, GlInternalFormat internalFormat, GLFormat baseInternalFormat) + public static KtxHeader InitializeCompressed(int width, int height, GlInternalFormat internalFormat, GlFormat baseInternalFormat) { - KtxHeader header = new KtxHeader(); + var header = new KtxHeader(); Span id = stackalloc byte[] { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; - for (int i = 0; i < id.Length; i++) + for (var i = 0; i < id.Length; i++) { header.Identifier[i] = id[i]; } @@ -318,11 +318,11 @@ public static KtxHeader InitializeCompressed(int width, int height, GlInternalFo return header; } - public static KtxHeader InitializeUncompressed(int width, int height, GLType type, GLFormat format, uint glTypeSize, GlInternalFormat internalFormat, GLFormat baseInternalFormat) + public static KtxHeader InitializeUncompressed(int width, int height, GlType type, GlFormat format, uint glTypeSize, GlInternalFormat internalFormat, GlFormat baseInternalFormat) { - KtxHeader header = new KtxHeader(); + var header = new KtxHeader(); Span id = stackalloc byte[] { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; - for (int i = 0; i < id.Length; i++) + for (var i = 0; i < id.Length; i++) { header.Identifier[i] = id[i]; } diff --git a/BCnEnc.Net/Shared/LinearClustering.cs b/BCnEnc.Net/Shared/LinearClustering.cs index 5df2b97..53c9b6e 100644 --- a/BCnEnc.Net/Shared/LinearClustering.cs +++ b/BCnEnc.Net/Shared/LinearClustering.cs @@ -65,25 +65,25 @@ public ClusterCenter(LabXy labxy) public readonly float Distance(LabXy other, float m, float s) { - float dLab = MathF.Sqrt( + var dLab = MathF.Sqrt( MathF.Pow(l - other.l, 2) + MathF.Pow(a - other.a, 2) + MathF.Pow(b - other.b, 2)); - float dXy = MathF.Sqrt( + var dXy = MathF.Sqrt( MathF.Pow(x - other.x, 2) + MathF.Pow(y - other.y, 2)); - return dLab + (m / s) * dXy; + return dLab + m / s * dXy; } public readonly float Distance(ClusterCenter other, float m, float s) { - float dLab = MathF.Sqrt( + var dLab = MathF.Sqrt( (l - other.l) * (l - other.l) + (a - other.a) * (a - other.a) + (b - other.b) * (b - other.b)); - float dXy = MathF.Sqrt( + var dXy = MathF.Sqrt( (x - other.x) * (x - other.x) + (y - other.y) * (y - other.y)); return dLab + m / s * dXy; @@ -131,19 +131,19 @@ public ClusterCenter(LabXy labxy) } //Grid interval S - float S = MathF.Sqrt(pixels.Length / (float)clusters); - int[] clusterIndices = new int[pixels.Length]; + var s = MathF.Sqrt(pixels.Length / (float)clusters); + var clusterIndices = new int[pixels.Length]; var labXys = ConvertToLabXy(pixels, width, height); - Span clusterCenters = InitialClusterCenters(width, height, clusters, S, labXys); + Span clusterCenters = InitialClusterCenters(width, height, clusters, s, labXys); Span previousCenters = new ClusterCenter[clusters]; - float Error = 999; + float error = 999; const float threshold = 0.1f; - int iter = 0; - while (Error > threshold) + var iter = 0; + while (error > threshold) { if (maxIterations > 0 && iter >= maxIterations) { @@ -156,18 +156,18 @@ public ClusterCenter(LabXy labxy) Array.Fill(clusterIndices, -1); // Find closest cluster for pixels - for (int j = 0; j < clusters; j++) + for (var j = 0; j < clusters; j++) { - int xL = Math.Max(0, (int)(clusterCenters[j].x - S)); - int xH = Math.Min(width, (int)(clusterCenters[j].x + S)); - int yL = Math.Max(0, (int)(clusterCenters[j].y - S)); - int yH = Math.Min(height, (int)(clusterCenters[j].y + S)); + var xL = Math.Max(0, (int)(clusterCenters[j].x - s)); + var xH = Math.Min(width, (int)(clusterCenters[j].x + s)); + var yL = Math.Max(0, (int)(clusterCenters[j].y - s)); + var yH = Math.Min(height, (int)(clusterCenters[j].y + s)); - for (int x = xL; x < xH; x++) + for (var x = xL; x < xH; x++) { - for (int y = yL; y < yH; y++) + for (var y = yL; y < yH; y++) { - int i = x + y * width; + var i = x + y * width; if (clusterIndices[i] == -1) { @@ -175,8 +175,8 @@ public ClusterCenter(LabXy labxy) } else { - float prevDistance = clusterCenters[clusterIndices[i]].Distance(labXys[i], m, S); - float distance = clusterCenters[j].Distance(labXys[i], m, S); + var prevDistance = clusterCenters[clusterIndices[i]].Distance(labXys[i], m, s); + var distance = clusterCenters[j].Distance(labXys[i], m, s); if (distance < prevDistance) { clusterIndices[i] = j; @@ -186,7 +186,7 @@ public ClusterCenter(LabXy labxy) } } - Error = RecalculateCenters(clusters, m, labXys, clusterIndices, previousCenters, S, ref clusterCenters); + error = RecalculateCenters(clusters, m, labXys, clusterIndices, previousCenters, s, ref clusterCenters); } if (enforceConnectivity) { @@ -197,20 +197,20 @@ public ClusterCenter(LabXy labxy) } private static float RecalculateCenters(int clusters, float m, LabXy[] labXys, int[] clusterIndices, - Span previousCenters, float S, ref Span clusterCenters) + Span previousCenters, float s, ref Span clusterCenters) { clusterCenters.Clear(); - for (int i = 0; i < labXys.Length; i++) + for (var i = 0; i < labXys.Length; i++) { - int clusterIndex = clusterIndices[i]; + var clusterIndex = clusterIndices[i]; // Sometimes a pixel is out of the range of any cluster, // in that case, find the nearest cluster and add it to it if (clusterIndex == -1) { - int bestCluster = 0; - float bestDistance = previousCenters[0].Distance(labXys[i], m, S); - for (int j = 1; j < clusters; j++) { - float dist = previousCenters[j].Distance(labXys[i], m, S); + var bestCluster = 0; + var bestDistance = previousCenters[0].Distance(labXys[i], m, s); + for (var j = 1; j < clusters; j++) { + var dist = previousCenters[j].Distance(labXys[i], m, s); if (dist < bestDistance) { bestDistance = dist; bestCluster = j; @@ -225,12 +225,12 @@ public ClusterCenter(LabXy labxy) } float error = 0; - for (int i = 0; i < clusters; i++) + for (var i = 0; i < clusters; i++) { if (clusterCenters[i].count > 0) { clusterCenters[i] /= clusterCenters[i].count; - error += clusterCenters[i].Distance(previousCenters[i], m, S); + error += clusterCenters[i].Distance(previousCenters[i], m, s); } } @@ -238,52 +238,52 @@ public ClusterCenter(LabXy labxy) return error; } - private static ClusterCenter[] InitialClusterCenters(int width, int height, int clusters, float S, LabXy[] labXys) + private static ClusterCenter[] InitialClusterCenters(int width, int height, int clusters, float s, LabXy[] labXys) { - ClusterCenter[] clusterCenters = new ClusterCenter[clusters]; + var clusterCenters = new ClusterCenter[clusters]; if (clusters == 2) { - int x0 = (int)MathF.Floor(width * 0.333f); - int y0 = (int)MathF.Floor(height * 0.333f); + var x0 = (int)MathF.Floor(width * 0.333f); + var y0 = (int)MathF.Floor(height * 0.333f); - int x1 = (int)MathF.Floor(width * 0.666f); - int y1 = (int)MathF.Floor(height * 0.666f); + var x1 = (int)MathF.Floor(width * 0.666f); + var y1 = (int)MathF.Floor(height * 0.666f); - int i0 = x0 + y0 * width; + var i0 = x0 + y0 * width; clusterCenters[0] = new ClusterCenter(labXys[i0]); - int i1 = x1 + y1 * width; + var i1 = x1 + y1 * width; clusterCenters[1] = new ClusterCenter(labXys[i1]); }else if(clusters == 3) { - int x0 = (int)MathF.Floor(width * 0.333f); - int y0 = (int)MathF.Floor(height * 0.333f); - int i0 = x0 + y0 * width; + var x0 = (int)MathF.Floor(width * 0.333f); + var y0 = (int)MathF.Floor(height * 0.333f); + var i0 = x0 + y0 * width; clusterCenters[0] = new ClusterCenter(labXys[i0]); - int x1 = (int)MathF.Floor(width * 0.666f); - int y1 = (int)MathF.Floor(height * 0.333f); - int i1 = x1 + y1 * width; + var x1 = (int)MathF.Floor(width * 0.666f); + var y1 = (int)MathF.Floor(height * 0.333f); + var i1 = x1 + y1 * width; clusterCenters[1] = new ClusterCenter(labXys[i1]); - int x2 = (int)MathF.Floor(width * 0.5f); - int y2 = (int)MathF.Floor(height * 0.666f); - int i2 = x2 + y2 * width; + var x2 = (int)MathF.Floor(width * 0.5f); + var y2 = (int)MathF.Floor(height * 0.666f); + var i2 = x2 + y2 * width; clusterCenters[2] = new ClusterCenter(labXys[i2]); } else { - int cIdx = 0; + var cIdx = 0; //Choose initial centers - for (float x = S / 2; x < width; x += S) + for (var x = s / 2; x < width; x += s) { - for (float y = S / 2; y < height; y += S) + for (var y = s / 2; y < height; y += s) { if (cIdx >= clusterCenters.Length) { break; } - int i = (int)x + (int)y * width; + var i = (int)x + (int)y * width; clusterCenters[cIdx] = new ClusterCenter(labXys[i]); cIdx++; } @@ -294,13 +294,13 @@ private static ClusterCenter[] InitialClusterCenters(int width, int height, int private static LabXy[] ConvertToLabXy(ReadOnlySpan pixels, int width, int height) { - LabXy[] labXys = new LabXy[pixels.Length]; + var labXys = new LabXy[pixels.Length]; //Convert pixels to LabXy - for (int x = 0; x < width; x++) + for (var x = 0; x < width; x++) { - for (int y = 0; y < height; y++) + for (var y = 0; y < height; y++) { - int i = x + y * width; + var i = x + y * width; var lab = new ColorLab(pixels[i]); labXys[i] = new LabXy() { @@ -321,23 +321,23 @@ private static int[] EnforceConnectivity(int[] oldLabels, int width, int height, ReadOnlySpan neighborX = new[] { -1, 0, 1, 0 }; ReadOnlySpan neighborY = new[] { 0, -1, 0, 1 }; - int sSquared = (width * height) / clusters; + var sSquared = width * height / clusters; - List clusterX = new List(sSquared); - List clusterY = new List(sSquared); + var clusterX = new List(sSquared); + var clusterY = new List(sSquared); - int adjacentLabel = 0; - int[] newLabels = new int[oldLabels.Length]; - bool[] usedLabels = new bool[clusters]; + var adjacentLabel = 0; + var newLabels = new int[oldLabels.Length]; + var usedLabels = new bool[clusters]; Array.Fill(newLabels, -1); - for (int y = 0; y < height; ++y) + for (var y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) + for (var x = 0; x < width; ++x) { - int xyIndex = x + y * width; + var xyIndex = x + y * width; if (newLabels[xyIndex] < 0) { - int label = oldLabels[xyIndex]; + var label = oldLabels[xyIndex]; newLabels[xyIndex] = label; //New cluster @@ -345,11 +345,11 @@ private static int[] EnforceConnectivity(int[] oldLabels, int width, int height, clusterY.Add(y); //Search neighbors for already completed clusters - for (int i = 0; i < neighborX.Length; ++i) + for (var i = 0; i < neighborX.Length; ++i) { - int nX = x + neighborX[i]; - int nY = y + neighborY[i]; - int nI = nX + nY * width; + var nX = x + neighborX[i]; + var nY = y + neighborY[i]; + var nI = nX + nY * width; if (nX < width && nX >= 0 && nY < height && nY >= 0) { if (newLabels[nI] >= 0) @@ -361,13 +361,13 @@ private static int[] EnforceConnectivity(int[] oldLabels, int width, int height, } //Count pixels in this cluster - for (int c = 0; c < clusterX.Count; ++c) + for (var c = 0; c < clusterX.Count; ++c) { - for (int i = 0; i < neighborX.Length; ++i) + for (var i = 0; i < neighborX.Length; ++i) { - int nX = clusterX[c] + neighborX[i]; - int nY = clusterY[c] + neighborY[i]; - int nI = nX + nY * width; + var nX = clusterX[c] + neighborX[i]; + var nY = clusterY[c] + neighborY[i]; + var nI = nX + nY * width; if (nX < width && nX >= 0 && nY < height && nY >= 0) { if (newLabels[nI] == -1 && label == oldLabels[nI]) @@ -382,11 +382,11 @@ private static int[] EnforceConnectivity(int[] oldLabels, int width, int height, // If this is unusually small cluster or this label is already used, // merge with adjacent cluster - if (clusterX.Count < (sSquared / 4) || usedLabels[label]) + if (clusterX.Count < sSquared / 4 || usedLabels[label]) { - for (int i = 0; i < clusterX.Count; ++i) + for (var i = 0; i < clusterX.Count; ++i) { - newLabels[(clusterY[i] * width + clusterX[i])] = adjacentLabel; + newLabels[clusterY[i] * width + clusterX[i]] = adjacentLabel; } } else { diff --git a/BCnEnc.Net/Shared/MipMapper.cs b/BCnEnc.Net/Shared/MipMapper.cs index 23329e2..65e3919 100644 --- a/BCnEnc.Net/Shared/MipMapper.cs +++ b/BCnEnc.Net/Shared/MipMapper.cs @@ -18,8 +18,8 @@ public static class MipMapper } uint output = 0; for (uint mipLevel = 1; mipLevel < maxNumMipMaps; mipLevel++) { - int mipWidth = Math.Max(1, width / (int)(Math.Pow(2, mipLevel))); - int mipHeight = Math.Max(1, height / (int)(Math.Pow(2, mipLevel))); + var mipWidth = Math.Max(1, width / (int)Math.Pow(2, mipLevel)); + var mipHeight = Math.Max(1, height / (int)Math.Pow(2, mipLevel)); if (mipWidth == 1 && mipHeight == 1) { output = mipLevel + 1; break; @@ -29,7 +29,7 @@ public static class MipMapper } public static List> GenerateMipChain(Image sourceImage, ref uint numMipMaps) { - List> result = new List>(); + var result = new List>(); result.Add(sourceImage.Clone()); if (numMipMaps == 1) { @@ -41,8 +41,8 @@ public static class MipMapper } for (uint mipLevel = 1; mipLevel < numMipMaps; mipLevel++) { - int mipWidth = Math.Max(1, sourceImage.Width / (int)(Math.Pow(2, mipLevel))); - int mipHeight = Math.Max(1, sourceImage.Height / (int)(Math.Pow(2, mipLevel))); + var mipWidth = Math.Max(1, sourceImage.Width / (int)Math.Pow(2, mipLevel)); + var mipHeight = Math.Max(1, sourceImage.Height / (int)Math.Pow(2, mipLevel)); var newImage = sourceImage.Clone(x => x.Resize(mipWidth, mipHeight)); result.Add(newImage); diff --git a/BCnEnc.Net/Shared/OutputFileFormat.cs b/BCnEnc.Net/Shared/OutputFileFormat.cs index 157974f..cc63b8d 100644 --- a/BCnEnc.Net/Shared/OutputFileFormat.cs +++ b/BCnEnc.Net/Shared/OutputFileFormat.cs @@ -3,11 +3,11 @@ public enum OutputFileFormat { /// - /// Khronos texture format https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ + /// Khronos texture Format https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/ /// Ktx, /// - /// Direct draw surface format https://docs.microsoft.com/en-us/windows/win32/direct3ddds/dx-graphics-dds + /// Direct draw surface Format https://docs.microsoft.com/en-us/windows/win32/direct3ddds/dx-graphics-dds /// Dds } diff --git a/BCnEnc.Net/Shared/PcaVectors.cs b/BCnEnc.Net/Shared/PcaVectors.cs index 999e5c8..cd735f3 100644 --- a/BCnEnc.Net/Shared/PcaVectors.cs +++ b/BCnEnc.Net/Shared/PcaVectors.cs @@ -8,12 +8,12 @@ namespace BCnEncoder.Shared { internal static class PcaVectors { - private const int c565_5_mask = 0xF8; - private const int c565_6_mask = 0xFC; + private const int C5655Mask_ = 0xF8; + private const int C5656Mask_ = 0xFC; private static void ConvertToVector4(ReadOnlySpan colors, Span vectors) { - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { vectors[i].X += colors[i].R / 255f; vectors[i].Y += colors[i].G / 255f; @@ -30,7 +30,7 @@ private static Vector4 CalculateMean(Span colors) float b = 0; float a = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { r += colors[i].X; g += colors[i].Y; @@ -48,15 +48,15 @@ private static Vector4 CalculateMean(Span colors) internal static Matrix4x4 CalculateCovariance(Span values, out Vector4 mean) { mean = CalculateMean(values); - for (int i = 0; i < values.Length; i++) + for (var i = 0; i < values.Length; i++) { values[i] -= mean; } //4x4 matrix - Matrix4x4 mat = new Matrix4x4(); + var mat = new Matrix4x4(); - for (int i = 0; i < values.Length; i++) + for (var i = 0; i < values.Length; i++) { mat.M11 += values[i].X * values[i].X; mat.M12 += values[i].X * values[i].Y; @@ -91,9 +91,9 @@ private static Vector4 CalculateMean(Span colors) /// /// internal static Vector4 CalculatePrincipalAxis(Matrix4x4 covarianceMatrix) { - Vector4 lastDa = Vector4.UnitY; + var lastDa = Vector4.UnitY; - for (int i = 0; i < 30; i++) { + for (var i = 0; i < 30; i++) { var dA = Vector4.Transform(lastDa, covarianceMatrix); if(dA.LengthSquared() == 0) { @@ -118,7 +118,7 @@ public static void Create(Span colors, out Vector3 mean, out Vector3 pri ConvertToVector4(colors, vectors); - var cov = CalculateCovariance(vectors, out Vector4 v4Mean); + var cov = CalculateCovariance(vectors, out var v4Mean); mean = new Vector3(v4Mean.X, v4Mean.Y, v4Mean.Z); var pa = CalculatePrincipalAxis(cov); @@ -149,7 +149,7 @@ public static void CreateWithAlpha(Span colors, out Vector4 mean, out Ve float minD = 0; float maxD = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { var colorVec = new Vector3(colors[i].R / 255f, colors[i].G / 255f, colors[i].B / 255f); @@ -159,24 +159,24 @@ public static void CreateWithAlpha(Span colors, out Vector4 mean, out Ve if (d > maxD) maxD = d; } - Vector3 minVec = mean + (principalAxis * minD); - Vector3 maxVec = mean + (principalAxis * maxD); + var minVec = mean + principalAxis * minD; + var maxVec = mean + principalAxis * maxD; - int minR = (int) (minVec.X * 255); - int minG = (int) (minVec.Y * 255); - int minB = (int) (minVec.Z * 255); + var minR = (int) (minVec.X * 255); + var minG = (int) (minVec.Y * 255); + var minB = (int) (minVec.Z * 255); - int maxR = (int) (maxVec.X * 255); - int maxG = (int) (maxVec.Y * 255); - int maxB = (int) (maxVec.Z * 255); + var maxR = (int) (maxVec.X * 255); + var maxG = (int) (maxVec.Y * 255); + var maxB = (int) (maxVec.Z * 255); - minR = (minR >= 0) ? minR : 0; - minG = (minG >= 0) ? minG : 0; - minB = (minB >= 0) ? minB : 0; + minR = minR >= 0 ? minR : 0; + minG = minG >= 0 ? minG : 0; + minB = minB >= 0 ? minB : 0; - maxR = (maxR <= 255) ? maxR : 255; - maxG = (maxG <= 255) ? maxG : 255; - maxB = (maxB <= 255) ? maxB : 255; + maxR = maxR <= 255 ? maxR : 255; + maxG = maxG <= 255 ? maxG : 255; + maxB = maxB <= 255 ? maxB : 255; min = new ColorRgb24((byte)minR, (byte)minG, (byte)minB); max = new ColorRgb24((byte)maxR, (byte)maxG, (byte)maxB); @@ -189,7 +189,7 @@ public static void CreateWithAlpha(Span colors, out Vector4 mean, out Ve float minD = 0; float maxD = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { var colorVec = new Vector3(colors[i].R / 255f, colors[i].G / 255f, colors[i].B / 255f); @@ -203,33 +203,33 @@ public static void CreateWithAlpha(Span colors, out Vector4 mean, out Ve minD *= 15 / 16f; maxD *= 15 / 16f; - Vector3 minVec = mean + (principalAxis * minD); - Vector3 maxVec = mean + (principalAxis * maxD); + var minVec = mean + principalAxis * minD; + var maxVec = mean + principalAxis * maxD; - int minR = (int) (minVec.X * 255); - int minG = (int) (minVec.Y * 255); - int minB = (int) (minVec.Z * 255); + var minR = (int) (minVec.X * 255); + var minG = (int) (minVec.Y * 255); + var minB = (int) (minVec.Z * 255); - int maxR = (int) (maxVec.X * 255); - int maxG = (int) (maxVec.Y * 255); - int maxB = (int) (maxVec.Z * 255); + var maxR = (int) (maxVec.X * 255); + var maxG = (int) (maxVec.Y * 255); + var maxB = (int) (maxVec.Z * 255); - minR = (minR >= 0) ? minR : 0; - minG = (minG >= 0) ? minG : 0; - minB = (minB >= 0) ? minB : 0; + minR = minR >= 0 ? minR : 0; + minG = minG >= 0 ? minG : 0; + minB = minB >= 0 ? minB : 0; - maxR = (maxR <= 255) ? maxR : 255; - maxG = (maxG <= 255) ? maxG : 255; - maxB = (maxB <= 255) ? maxB : 255; + maxR = maxR <= 255 ? maxR : 255; + maxG = maxG <= 255 ? maxG : 255; + maxB = maxB <= 255 ? maxB : 255; // Optimal round - minR = (minR & c565_5_mask) | (minR >> 5); - minG = (minG & c565_6_mask) | (minG >> 6); - minB = (minB & c565_5_mask) | (minB >> 5); + minR = (minR & C5655Mask_) | (minR >> 5); + minG = (minG & C5656Mask_) | (minG >> 6); + minB = (minB & C5655Mask_) | (minB >> 5); - maxR = (maxR & c565_5_mask) | (maxR >> 5); - maxG = (maxG & c565_6_mask) | (maxG >> 6); - maxB = (maxB & c565_5_mask) | (maxB >> 5); + maxR = (maxR & C5655Mask_) | (maxR >> 5); + maxG = (maxG & C5656Mask_) | (maxG >> 6); + maxB = (maxB & C5655Mask_) | (maxB >> 5); min = new ColorRgb565((byte)minR, (byte)minG, (byte)minB); max = new ColorRgb565((byte)maxR, (byte)maxG, (byte)maxB); @@ -243,7 +243,7 @@ public static void CreateWithAlpha(Span colors, out Vector4 mean, out Ve float minD = 0; float maxD = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { var colorVec = new Vector4(colors[i].R / 255f, colors[i].G / 255f, colors[i].B / 255f, colors[i].A / 255f); @@ -253,16 +253,16 @@ public static void CreateWithAlpha(Span colors, out Vector4 mean, out Ve if (d > maxD) maxD = d; } - min = mean + (principalAxis * minD); - max = mean + (principalAxis * maxD); + min = mean + principalAxis * minD; + max = mean + principalAxis * maxD; } public static void GetOptimizedEndpoints565(Span colors, Vector3 mean, Vector3 principalAxis, out ColorRgb565 min, out ColorRgb565 max, float rWeight = 0.3f, float gWeight = 0.6f, float bWeight = 0.1f) { - int length = colors.Length; - Vector3[] vectorColors = new Vector3[length]; - for (int i = 0; i < colors.Length; i++) + var length = colors.Length; + var vectorColors = new Vector3[length]; + for (var i = 0; i < colors.Length; i++) { vectorColors[i] = new Vector3(colors[i].R / 255f, colors[i].G / 255f, colors[i].B / 255f); } @@ -289,12 +289,12 @@ float Distance(Vector3 v, Vector3 p) ; } - float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2, Vector3 f3) + float SelectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2, Vector3 f3) { - float d0 = Distance(selector, f0); - float d1 = Distance(selector, f1); - float d2 = Distance(selector, f2); - float d3 = Distance(selector, f3); + var d0 = Distance(selector, f0); + var d1 = Distance(selector, f1); + var d2 = Distance(selector, f2); + var d3 = Distance(selector, f3); if (d0 < d1 && d0 < d2 && d0 < d3) return d0; if (d1 < d0 && d1 < d2 && d1 < d3) return d1; @@ -305,42 +305,42 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 Vector3 endPoint0; Vector3 endPoint1; - double calculateError() + double CalculateError() { double cumulativeError = 0; - Vector3 ep0 = new Vector3(endPoint0.X / 31, endPoint0.Y / 63, endPoint0.Z / 31); - Vector3 ep1 = new Vector3(endPoint1.X / 31, endPoint1.Y / 63, endPoint1.Z / 31); - Vector3 ep2 = ep0 + ((ep1 - ep0) * 1 / 3f); - Vector3 ep3 = ep0 + ((ep1 - ep0) * 2 / 3f); + var ep0 = new Vector3(endPoint0.X / 31, endPoint0.Y / 63, endPoint0.Z / 31); + var ep1 = new Vector3(endPoint1.X / 31, endPoint1.Y / 63, endPoint1.Z / 31); + var ep2 = ep0 + (ep1 - ep0) * 1 / 3f; + var ep3 = ep0 + (ep1 - ep0) * 2 / 3f; - for (int i = 0; i < length; i++) + for (var i = 0; i < length; i++) { - double distance = selectClosestDistance(vectorColors[i], ep0, ep1, ep2, ep3); + double distance = SelectClosestDistance(vectorColors[i], ep0, ep1, ep2, ep3); cumulativeError += distance; } return cumulativeError; } - for (int i = 0; i < vectorColors.Length; i++) + for (var i = 0; i < vectorColors.Length; i++) { - float d = ProjectPointOnLine(vectorColors[i], mean, principalAxis); + var d = ProjectPointOnLine(vectorColors[i], mean, principalAxis); if (d < minD) minD = d; if (d > maxD) maxD = d; } - endPoint0 = mean + (principalAxis * minD); - endPoint1 = mean + (principalAxis * maxD); + endPoint0 = mean + principalAxis * minD; + endPoint1 = mean + principalAxis * maxD; endPoint0 = new Vector3(MathF.Round(endPoint0.X * 31), MathF.Round(endPoint0.Y * 63), MathF.Round(endPoint0.Z * 31)); endPoint1 = new Vector3(MathF.Round(endPoint1.X * 31), MathF.Round(endPoint1.Y * 63), MathF.Round(endPoint1.Z * 31)); endPoint0 = Clamp565(endPoint0); endPoint1 = Clamp565(endPoint1); - double best = calculateError(); - int increment = 5; - bool foundBetter = true; - int rounds = 0; + var best = CalculateError(); + var increment = 5; + var foundBetter = true; + var rounds = 0; // Variate color and look for better endpoints while (increment > 1 || foundBetter) { @@ -350,7 +350,7 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 var prev = endPoint0; endPoint0 -= principalAxis * increment * 2; endPoint0 = Clamp565(endPoint0); - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -366,7 +366,7 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 var prev = endPoint1; endPoint1 -= principalAxis * increment * 2; endPoint1 = Clamp565(endPoint1); - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -382,7 +382,7 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 var prev = endPoint0; endPoint0 += principalAxis * increment * 2; endPoint0 = Clamp565(endPoint0); - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -398,7 +398,7 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 var prev = endPoint1; endPoint1 += principalAxis * increment * 2; endPoint1 = Clamp565(endPoint1); - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -417,7 +417,7 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 endPoint1 += principalAxis * increment * 2; endPoint0 = Clamp565(endPoint0); endPoint1 = Clamp565(endPoint1); - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -437,7 +437,7 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 endPoint1 -= principalAxis * increment * 2; endPoint0 = Clamp565(endPoint0); endPoint1 = Clamp565(endPoint1); - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -453,9 +453,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 #region G if (endPoint0.Y - increment >= 0) { // decrement ep0 G - float prevY = endPoint0.Y; + var prevY = endPoint0.Y; endPoint0.Y -= increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -469,9 +469,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint1.Y - increment >= 0) { // decrement ep1 G - float prevY = endPoint1.Y; + var prevY = endPoint1.Y; endPoint1.Y -= increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -490,9 +490,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint1.Y + increment <= 63) { // increment ep1 G - float prevY = endPoint1.Y; + var prevY = endPoint1.Y; endPoint1.Y += increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -506,9 +506,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint0.Y + increment <= 63) { // increment ep0 G - float prevY = endPoint0.Y; + var prevY = endPoint0.Y; endPoint0.Y += increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -525,9 +525,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 #region R if (endPoint0.X - increment >= 0) { // decrement ep0 R - float prevX = endPoint0.X; + var prevX = endPoint0.X; endPoint0.X -= increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -541,9 +541,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint1.X - increment >= 0) { // decrement ep1 R - float prevX = endPoint1.X; + var prevX = endPoint1.X; endPoint1.X -= increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -562,9 +562,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint1.X + increment <= 31) { // increment ep1 R - float prevX = endPoint1.X; + var prevX = endPoint1.X; endPoint1.X += increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -578,9 +578,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint0.X + increment <= 31) { // increment ep0 R - float prevX = endPoint0.X; + var prevX = endPoint0.X; endPoint0.X += increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -597,9 +597,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint0.Z - increment >= 0) { // decrement ep0 B - float prevZ = endPoint0.Z; + var prevZ = endPoint0.Z; endPoint0.Z -= increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -613,9 +613,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint1.Z - increment >= 0) { // decrement ep1 B - float prevZ = endPoint1.Z; + var prevZ = endPoint1.Z; endPoint1.Z -= increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -634,9 +634,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint1.Z + increment <= 31) { // increment ep1 B - float prevZ = endPoint1.Z; + var prevZ = endPoint1.Z; endPoint1.Z += increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; @@ -650,9 +650,9 @@ float selectClosestDistance(Vector3 selector, Vector3 f0, Vector3 f1, Vector3 f2 if (endPoint0.Z + increment <= 31) { // increment ep0 B - float prevZ = endPoint0.Z; + var prevZ = endPoint0.Z; endPoint0.Z += increment; - double error = calculateError(); + var error = CalculateError(); if (error < best) { foundBetter = true; diff --git a/BCnEnc.Net/Shared/RawBlocks.cs b/BCnEnc.Net/Shared/RawBlocks.cs index 551e330..decaecc 100644 --- a/BCnEnc.Net/Shared/RawBlocks.cs +++ b/BCnEnc.Net/Shared/RawBlocks.cs @@ -26,7 +26,7 @@ internal struct RawBlock4X4Rgba32 { float error = 0; var pix1 = AsSpan; var pix2 = other.AsSpan; - for (int i = 0; i < pix1.Length; i++) { + for (var i = 0; i < pix1.Length; i++) { var col1 = pix1[i]; var col2 = pix2[i]; @@ -56,7 +56,7 @@ internal struct RawBlock4X4Rgba32 { float crError = 0; var pix1 = AsSpan; var pix2 = other.AsSpan; - for (int i = 0; i < pix1.Length; i++) { + for (var i = 0; i < pix1.Length; i++) { var col1 = new ColorYCbCr(pix1[i]); var col2 = new ColorYCbCr(pix2[i]); @@ -81,7 +81,7 @@ internal struct RawBlock4X4Rgba32 { float alphaError = 0; var pix1 = AsSpan; var pix2 = other.AsSpan; - for (int i = 0; i < pix1.Length; i++) { + for (var i = 0; i < pix1.Length; i++) { var col1 = new ColorYCbCrAlpha(pix1[i]); var col2 = new ColorYCbCrAlpha(pix2[i]); @@ -101,10 +101,10 @@ internal struct RawBlock4X4Rgba32 { } public RawBlock4X4Ycbcr ToRawBlockYcbcr() { - RawBlock4X4Ycbcr rawYcbcr = new RawBlock4X4Ycbcr(); + var rawYcbcr = new RawBlock4X4Ycbcr(); var pixels = AsSpan; var ycbcrPs = rawYcbcr.AsSpan; - for (int i = 0; i < pixels.Length; i++) { + for (var i = 0; i < pixels.Length; i++) { ycbcrPs[i] = new ColorYCbCr(pixels[i]); } return rawYcbcr; @@ -112,7 +112,7 @@ internal struct RawBlock4X4Rgba32 { public bool HasTransparentPixels() { var pixels = AsSpan; - for (int i = 0; i < pixels.Length; i++) { + for (var i = 0; i < pixels.Length; i++) { if (pixels[i].A < 255) return true; } return false; @@ -138,7 +138,7 @@ internal struct RawBlock4X4Ycbcr { float crError = 0; var pix1 = AsSpan; var pix2 = other.AsSpan; - for (int i = 0; i < pix1.Length; i++) { + for (var i = 0; i < pix1.Length; i++) { var col1 = pix1[i]; var col2 = new ColorYCbCr(pix2[i]); diff --git a/BCnEnc.Net/Shared/RgbBoundingBox.cs b/BCnEnc.Net/Shared/RgbBoundingBox.cs index 3e72628..a1743b5 100644 --- a/BCnEnc.Net/Shared/RgbBoundingBox.cs +++ b/BCnEnc.Net/Shared/RgbBoundingBox.cs @@ -14,8 +14,8 @@ internal static class RgbBoundingBox public static void Create565(ReadOnlySpan colors, out ColorRgb565 min, out ColorRgb565 max) { const int colorInsetShift = 4; - const int c565_5_mask = 0xF8; - const int c565_6_mask = 0xFC; + const int c5655Mask = 0xF8; + const int c5656Mask = 0xFC; int minR = 255, minG = 255, @@ -24,7 +24,7 @@ public static void Create565(ReadOnlySpan colors, out ColorRgb565 min, o maxG = 0, maxB = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { var c = colors[i]; @@ -37,9 +37,9 @@ public static void Create565(ReadOnlySpan colors, out ColorRgb565 min, o if (c.B > maxB) maxB = c.B; } - int insetR = (maxR - minR) >> colorInsetShift; - int insetG = (maxG - minG) >> colorInsetShift; - int insetB = (maxB - minB) >> colorInsetShift; + var insetR = (maxR - minR) >> colorInsetShift; + var insetG = (maxG - minG) >> colorInsetShift; + var insetB = (maxB - minB) >> colorInsetShift; // Inset by 1/16th minR = ((minR << colorInsetShift) + insetR) >> colorInsetShift; @@ -50,22 +50,22 @@ public static void Create565(ReadOnlySpan colors, out ColorRgb565 min, o maxG = ((maxG << colorInsetShift) - insetG) >> colorInsetShift; maxB = ((maxB << colorInsetShift) - insetB) >> colorInsetShift; - minR = (minR >= 0) ? minR : 0; - minG = (minG >= 0) ? minG : 0; - minB = (minB >= 0) ? minB : 0; + minR = minR >= 0 ? minR : 0; + minG = minG >= 0 ? minG : 0; + minB = minB >= 0 ? minB : 0; - maxR = (maxR <= 255) ? maxR : 255; - maxG = (maxG <= 255) ? maxG : 255; - maxB = (maxB <= 255) ? maxB : 255; + maxR = maxR <= 255 ? maxR : 255; + maxG = maxG <= 255 ? maxG : 255; + maxB = maxB <= 255 ? maxB : 255; // Optimal rounding - minR = (minR & c565_5_mask) | (minR >> 5); - minG = (minG & c565_6_mask) | (minG >> 6); - minB = (minB & c565_5_mask) | (minB >> 5); + minR = (minR & c5655Mask) | (minR >> 5); + minG = (minG & c5656Mask) | (minG >> 6); + minB = (minB & c5655Mask) | (minB >> 5); - maxR = (maxR & c565_5_mask) | (maxR >> 5); - maxG = (maxG & c565_6_mask) | (maxG >> 6); - maxB = (maxB & c565_5_mask) | (maxB >> 5); + maxR = (maxR & c5655Mask) | (maxR >> 5); + maxG = (maxG & c5656Mask) | (maxG >> 6); + maxB = (maxB & c5655Mask) | (maxB >> 5); min = new ColorRgb565((byte)minR, (byte)minG, (byte)minB); max = new ColorRgb565((byte)maxR, (byte)maxG, (byte)maxB); @@ -74,8 +74,8 @@ public static void Create565(ReadOnlySpan colors, out ColorRgb565 min, o public static void Create565AlphaCutoff(ReadOnlySpan colors, out ColorRgb565 min, out ColorRgb565 max, int alphaCutoff = 128) { const int colorInsetShift = 4; - const int c565_5_mask = 0xF8; - const int c565_6_mask = 0xFC; + const int c5655Mask = 0xF8; + const int c5656Mask = 0xFC; int minR = 255, minG = 255, @@ -84,7 +84,7 @@ public static void Create565AlphaCutoff(ReadOnlySpan colors, out ColorRg maxG = 0, maxB = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { var c = colors[i]; if (c.A < alphaCutoff) continue; @@ -97,9 +97,9 @@ public static void Create565AlphaCutoff(ReadOnlySpan colors, out ColorRg if (c.B > maxB) maxB = c.B; } - int insetR = (maxR - minR) >> colorInsetShift; - int insetG = (maxG - minG) >> colorInsetShift; - int insetB = (maxB - minB) >> colorInsetShift; + var insetR = (maxR - minR) >> colorInsetShift; + var insetG = (maxG - minG) >> colorInsetShift; + var insetB = (maxB - minB) >> colorInsetShift; minR = ((minR << colorInsetShift) + insetR) >> colorInsetShift; minG = ((minG << colorInsetShift) + insetG) >> colorInsetShift; @@ -109,32 +109,32 @@ public static void Create565AlphaCutoff(ReadOnlySpan colors, out ColorRg maxG = ((maxG << colorInsetShift) - insetG) >> colorInsetShift; maxB = ((maxB << colorInsetShift) - insetB) >> colorInsetShift; - minR = (minR >= 0) ? minR : 0; - minG = (minG >= 0) ? minG : 0; - minB = (minB >= 0) ? minB : 0; + minR = minR >= 0 ? minR : 0; + minG = minG >= 0 ? minG : 0; + minB = minB >= 0 ? minB : 0; - maxR = (maxR <= 255) ? maxR : 255; - maxG = (maxG <= 255) ? maxG : 255; - maxB = (maxB <= 255) ? maxB : 255; + maxR = maxR <= 255 ? maxR : 255; + maxG = maxG <= 255 ? maxG : 255; + maxB = maxB <= 255 ? maxB : 255; - minR = (minR & c565_5_mask) | (minR >> 5); - minG = (minG & c565_6_mask) | (minG >> 6); - minB = (minB & c565_5_mask) | (minB >> 5); + minR = (minR & c5655Mask) | (minR >> 5); + minG = (minG & c5656Mask) | (minG >> 6); + minB = (minB & c5655Mask) | (minB >> 5); - maxR = (maxR & c565_5_mask) | (maxR >> 5); - maxG = (maxG & c565_6_mask) | (maxG >> 6); - maxB = (maxB & c565_5_mask) | (maxB >> 5); + maxR = (maxR & c5655Mask) | (maxR >> 5); + maxG = (maxG & c5656Mask) | (maxG >> 6); + maxB = (maxB & c5655Mask) | (maxB >> 5); min = new ColorRgb565((byte)minR, (byte)minG, (byte)minB); max = new ColorRgb565((byte)maxR, (byte)maxG, (byte)maxB); } - public static void Create565a(ReadOnlySpan colors, out ColorRgb565 min, out ColorRgb565 max, out byte minAlpha, out byte maxAlpha) + public static void Create565A(ReadOnlySpan colors, out ColorRgb565 min, out ColorRgb565 max, out byte minAlpha, out byte maxAlpha) { const int colorInsetShift = 4; const int alphaInsetShift = 5; - const int c565_5_mask = 0xF8; - const int c565_6_mask = 0xFC; + const int c5655Mask = 0xF8; + const int c5656Mask = 0xFC; int minR = 255, minG = 255, @@ -145,7 +145,7 @@ public static void Create565a(ReadOnlySpan colors, out ColorRgb565 min, maxB = 0, maxA = 0; - for (int i = 0; i < colors.Length; i++) + for (var i = 0; i < colors.Length; i++) { var c = colors[i]; if (c.R < minR) minR = c.R; @@ -160,10 +160,10 @@ public static void Create565a(ReadOnlySpan colors, out ColorRgb565 min, } - int insetR = (maxR - minR) >> colorInsetShift; - int insetG = (maxG - minG) >> colorInsetShift; - int insetB = (maxB - minB) >> colorInsetShift; - int insetA = (maxA - minA) >> alphaInsetShift; + var insetR = (maxR - minR) >> colorInsetShift; + var insetG = (maxG - minG) >> colorInsetShift; + var insetB = (maxB - minB) >> colorInsetShift; + var insetA = (maxA - minA) >> alphaInsetShift; minR = ((minR << colorInsetShift) + insetR) >> colorInsetShift; minG = ((minG << colorInsetShift) + insetG) >> colorInsetShift; @@ -175,23 +175,23 @@ public static void Create565a(ReadOnlySpan colors, out ColorRgb565 min, maxB = ((maxB << colorInsetShift) - insetB) >> colorInsetShift; maxA = ((maxA << alphaInsetShift) - insetA) >> alphaInsetShift; - minR = (minR >= 0) ? minR : 0; - minG = (minG >= 0) ? minG : 0; - minB = (minB >= 0) ? minB : 0; - minA = (minA >= 0) ? minA : 0; + minR = minR >= 0 ? minR : 0; + minG = minG >= 0 ? minG : 0; + minB = minB >= 0 ? minB : 0; + minA = minA >= 0 ? minA : 0; - maxR = (maxR <= 255) ? maxR : 255; - maxG = (maxG <= 255) ? maxG : 255; - maxB = (maxB <= 255) ? maxB : 255; - maxA = (maxA <= 255) ? maxA : 255; + maxR = maxR <= 255 ? maxR : 255; + maxG = maxG <= 255 ? maxG : 255; + maxB = maxB <= 255 ? maxB : 255; + maxA = maxA <= 255 ? maxA : 255; - minR = (minR & c565_5_mask) | (minR >> 5); - minG = (minG & c565_6_mask) | (minG >> 6); - minB = (minB & c565_5_mask) | (minB >> 5); + minR = (minR & c5655Mask) | (minR >> 5); + minG = (minG & c5656Mask) | (minG >> 6); + minB = (minB & c5655Mask) | (minB >> 5); - maxR = (maxR & c565_5_mask) | (maxR >> 5); - maxG = (maxG & c565_6_mask) | (maxG >> 6); - maxB = (maxB & c565_5_mask) | (maxB >> 5); + maxR = (maxR & c5655Mask) | (maxR >> 5); + maxG = (maxG & c5656Mask) | (maxG >> 6); + maxB = (maxB & c5655Mask) | (maxB >> 5); min = new ColorRgb565((byte)minR, (byte)minG, (byte)minB); max = new ColorRgb565((byte)maxR, (byte)maxG, (byte)maxB); diff --git a/BCnEncTests/Bc7BlockTests.cs b/BCnEncTests/Bc7BlockTests.cs index 8489102..d933884 100644 --- a/BCnEncTests/Bc7BlockTests.cs +++ b/BCnEncTests/Bc7BlockTests.cs @@ -294,8 +294,8 @@ public class Bc7BlockTests KtxFile output = new KtxFile( KtxHeader.InitializeCompressed(numWidthBlocks * 8 * 4, numHeightBlocks * 8 * 4, - GlInternalFormat.GL_COMPRESSED_RGBA_BPTC_UNORM_ARB, - GLFormat.GL_RGBA)); + GlInternalFormat.GlCompressedRgbaBptcUnormArb, + GlFormat.GlRgba)); Span type0 = new Span(outputBlocks, 0 , 64); diff --git a/BCnEncTests/DdsReadTests.cs b/BCnEncTests/DdsReadTests.cs index 3e94ff2..4ba15d7 100644 --- a/BCnEncTests/DdsReadTests.cs +++ b/BCnEncTests/DdsReadTests.cs @@ -18,14 +18,14 @@ public class DdsReadTests public void ReadRgba() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_rgba.dds"); DdsFile file = DdsFile.Load(fs); - Assert.Equal(DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM, file.Header.ddsPixelFormat.DxgiFormat); - Assert.Equal(file.Header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length); + Assert.Equal(DxgiFormat.DxgiFormatR8G8B8A8Unorm, file.header.ddsPixelFormat.DxgiFormat); + Assert.Equal(file.header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length); BcDecoder decoder = new BcDecoder(); var images = decoder.DecodeAllMipMaps(file); - Assert.Equal((uint)images[0].Width, file.Header.dwWidth); - Assert.Equal((uint)images[0].Height, file.Header.dwHeight); + Assert.Equal((uint)images[0].Width, file.header.dwWidth); + Assert.Equal((uint)images[0].Height, file.header.dwHeight); for (int i = 0; i < images.Length; i++) { using FileStream outFs = File.OpenWrite($"decoding_test_dds_rgba_mip{i}.png"); @@ -38,15 +38,15 @@ public class DdsReadTests public void ReadBc1() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc1.dds"); DdsFile file = DdsFile.Load(fs); - Assert.Equal(DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM, file.Header.ddsPixelFormat.DxgiFormat); - Assert.Equal(file.Header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length); + Assert.Equal(DxgiFormat.DxgiFormatBc1Unorm, file.header.ddsPixelFormat.DxgiFormat); + Assert.Equal(file.header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length); BcDecoder decoder = new BcDecoder(); var images = decoder.DecodeAllMipMaps(file); - Assert.Equal((uint)images[0].Width, file.Header.dwWidth); - Assert.Equal((uint)images[0].Height, file.Header.dwHeight); + Assert.Equal((uint)images[0].Width, file.header.dwWidth); + Assert.Equal((uint)images[0].Height, file.header.dwHeight); for (int i = 0; i < images.Length; i++) { using FileStream outFs = File.OpenWrite($"decoding_test_dds_bc1_mip{i}.png"); @@ -59,16 +59,16 @@ public class DdsReadTests public void ReadBc1a() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc1a.dds"); DdsFile file = DdsFile.Load(fs); - Assert.Equal(DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM, file.Header.ddsPixelFormat.DxgiFormat); - Assert.Equal(file.Header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length); + Assert.Equal(DxgiFormat.DxgiFormatBc1Unorm, file.header.ddsPixelFormat.DxgiFormat); + Assert.Equal(file.header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length); BcDecoder decoder = new BcDecoder(); - decoder.InputOptions.ddsBc1ExpectAlpha = true; + decoder.InputOptions.DdsBc1ExpectAlpha = true; var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.dwWidth); - Assert.Equal((uint)image.Height, file.Header.dwHeight); + Assert.Equal((uint)image.Width, file.header.dwWidth); + Assert.Equal((uint)image.Height, file.header.dwHeight); if (!image.TryGetSinglePixelSpan(out var pixels)) { throw new Exception("Cannot get pixel span."); diff --git a/BCnEncTests/DdsWritingTests.cs b/BCnEncTests/DdsWritingTests.cs index 0037918..590eeb9 100644 --- a/BCnEncTests/DdsWritingTests.cs +++ b/BCnEncTests/DdsWritingTests.cs @@ -15,10 +15,10 @@ public class DdsWritingTests var image = ImageLoader.testLenna; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.RGBA; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Rgba; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_rgba.dds"); encoder.Encode(image, fs); @@ -30,10 +30,10 @@ public class DdsWritingTests var image = ImageLoader.testLenna; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC1; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc1; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_bc1.dds"); encoder.Encode(image, fs); @@ -45,10 +45,10 @@ public class DdsWritingTests var image = ImageLoader.testAlpha1; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC2; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc2; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_bc2.dds"); encoder.Encode(image, fs); @@ -60,10 +60,10 @@ public class DdsWritingTests var image = ImageLoader.testAlpha1; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC3; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc3; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_bc3.dds"); encoder.Encode(image, fs); @@ -75,10 +75,10 @@ public class DdsWritingTests var image = ImageLoader.testHeight1; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC4; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc4; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_bc4.dds"); encoder.Encode(image, fs); @@ -90,10 +90,10 @@ public class DdsWritingTests var image = ImageLoader.testRedGreen1; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC5; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc5; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_bc5.dds"); encoder.Encode(image, fs); @@ -105,10 +105,10 @@ public class DdsWritingTests var image = ImageLoader.testLenna; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC7; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc7; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_bc7.dds"); encoder.Encode(image, fs); @@ -120,10 +120,10 @@ public class DdsWritingTests var images = ImageLoader.testCubemap; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC1; - encoder.OutputOptions.fileFormat = OutputFileFormat.Dds; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc1; + encoder.OutputOptions.FileFormat = OutputFileFormat.Dds; using FileStream fs = File.OpenWrite("encoding_dds_cubemap_bc1.dds"); encoder.EncodeCubeMap(images[0],images[1],images[2],images[3],images[4],images[5], fs); diff --git a/BCnEncTests/DecodingTests.cs b/BCnEncTests/DecodingTests.cs index 3cf65e7..9e69aed 100644 --- a/BCnEncTests/DecodingTests.cs +++ b/BCnEncTests/DecodingTests.cs @@ -14,14 +14,14 @@ public class DecodingTests public void Bc1Decode() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc1.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc1.png"); image.SaveAsPng(outFs); @@ -31,14 +31,14 @@ public class DecodingTests public void Bc1AlphaDecode() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc1a.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc1a.png"); image.SaveAsPng(outFs); @@ -48,14 +48,14 @@ public class DecodingTests public void Bc2Decode() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc2.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc2.png"); image.SaveAsPng(outFs); @@ -65,14 +65,14 @@ public class DecodingTests public void Bc3Decode() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc3.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc3.png"); image.SaveAsPng(outFs); @@ -82,14 +82,14 @@ public class DecodingTests public void Bc4Decode() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc4_unorm.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc4.png"); image.SaveAsPng(outFs); @@ -99,14 +99,14 @@ public class DecodingTests public void Bc5Decode() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc5_unorm.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc5.png"); image.SaveAsPng(outFs); @@ -116,14 +116,14 @@ public class DecodingTests public void Bc7DecodeRgb() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc7_rgb.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc7_rgb.png"); image.SaveAsPng(outFs); @@ -133,14 +133,14 @@ public class DecodingTests public void Bc7DecodeUnorm() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc7_unorm.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc7_unorm.png"); image.SaveAsPng(outFs); @@ -150,14 +150,14 @@ public class DecodingTests public void Bc7DecodeEveryBlockType() { using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc7_types.ktx"); KtxFile file = KtxFile.Load(fs); - Assert.True(file.Header.VerifyHeader()); - Assert.Equal((uint)1, file.Header.NumberOfFaces); + Assert.True(file.header.VerifyHeader()); + Assert.Equal((uint)1, file.header.NumberOfFaces); BcDecoder decoder = new BcDecoder(); using var image = decoder.Decode(file); - Assert.Equal((uint)image.Width, file.Header.PixelWidth); - Assert.Equal((uint)image.Height, file.Header.PixelHeight); + Assert.Equal((uint)image.Width, file.header.PixelWidth); + Assert.Equal((uint)image.Height, file.header.PixelHeight); using FileStream outFs = File.OpenWrite("decoding_test_bc7_types.png"); image.SaveAsPng(outFs); diff --git a/BCnEncTests/EncodingTest.cs b/BCnEncTests/EncodingTest.cs index 1cc3240..8c8c4c1 100644 --- a/BCnEncTests/EncodingTest.cs +++ b/BCnEncTests/EncodingTest.cs @@ -24,7 +24,7 @@ public void Bc1GradientBestQuality() var image = ImageLoader.testGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.BestQuality, "encoding_bc1_gradient_bestQuality.ktx", output); @@ -37,7 +37,7 @@ public void Bc1GradientBalanced() TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.Balanced, "encoding_bc1_gradient_balanced.ktx", output); @@ -49,7 +49,7 @@ public void Bc1GradientFast() var image = ImageLoader.testGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.Fast, "encoding_bc1_gradient_fast.ktx", output); @@ -73,7 +73,7 @@ public void Bc1DiffuseBestQuality() var image = ImageLoader.testDiffuse1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.BestQuality, "encoding_bc1_diffuse_bestQuality.ktx", output); @@ -85,7 +85,7 @@ public void Bc1DiffuseBalanced() var image = ImageLoader.testDiffuse1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.Balanced, "encoding_bc1_diffuse_balanced.ktx", output); @@ -97,7 +97,7 @@ public void Bc1DiffuseFast() var image = ImageLoader.testDiffuse1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.Fast, "encoding_bc1_diffuse_fast.ktx", output); @@ -122,7 +122,7 @@ public void Bc1BlurBestQuality() var image = ImageLoader.testBlur1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.BestQuality, "encoding_bc1_blur_bestQuality.ktx", output); @@ -134,7 +134,7 @@ public void Bc1BlurBalanced() var image = ImageLoader.testBlur1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.Balanced, "encoding_bc1_blur_balanced.ktx", output); @@ -146,7 +146,7 @@ public void Bc1BlurFast() var image = ImageLoader.testBlur1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1, + CompressionFormat.Bc1, CompressionQuality.Fast, "encoding_bc1_blur_fast.ktx", output); @@ -171,7 +171,7 @@ public void Bc1aSpriteBestQuality() var image = ImageLoader.testTransparentSprite1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1WithAlpha, + CompressionFormat.Bc1WithAlpha, CompressionQuality.BestQuality, "encoding_bc1a_sprite_bestQuality.ktx", output); @@ -183,7 +183,7 @@ public void Bc1aSpriteBalanced() var image = ImageLoader.testTransparentSprite1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1WithAlpha, + CompressionFormat.Bc1WithAlpha, CompressionQuality.Balanced, "encoding_bc1a_sprite_balanced.ktx", output); @@ -195,7 +195,7 @@ public void Bc1aSpriteFast() var image = ImageLoader.testTransparentSprite1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC1WithAlpha, + CompressionFormat.Bc1WithAlpha, CompressionQuality.Fast, "encoding_bc1a_sprite_fast.ktx", output); @@ -220,7 +220,7 @@ public void Bc2GradientBestQuality() var image = ImageLoader.testAlphaGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC2, + CompressionFormat.Bc2, CompressionQuality.BestQuality, "encoding_bc2_gradient_bestQuality.ktx", output); @@ -232,7 +232,7 @@ public void Bc2GradientBalanced() var image = ImageLoader.testAlphaGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC2, + CompressionFormat.Bc2, CompressionQuality.Balanced, "encoding_bc2_gradient_balanced.ktx", output); @@ -244,7 +244,7 @@ public void Bc2GradientFast() var image = ImageLoader.testAlphaGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC2, + CompressionFormat.Bc2, CompressionQuality.Fast, "encoding_bc2_gradient_fast.ktx", output); @@ -269,7 +269,7 @@ public void Bc3GradientBestQuality() var image = ImageLoader.testAlphaGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC3, + CompressionFormat.Bc3, CompressionQuality.BestQuality, "encoding_bc3_gradient_bestQuality.ktx", output); @@ -281,7 +281,7 @@ public void Bc3GradientBalanced() var image = ImageLoader.testAlphaGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC3, + CompressionFormat.Bc3, CompressionQuality.Balanced, "encoding_bc3_gradient_balanced.ktx", output); @@ -293,7 +293,7 @@ public void Bc3GradientFast() var image = ImageLoader.testAlphaGradient1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC3, + CompressionFormat.Bc3, CompressionQuality.Fast, "encoding_bc3_gradient_fast.ktx", output); @@ -318,7 +318,7 @@ public void Bc4RedBestQuality() var image = ImageLoader.testHeight1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC4, + CompressionFormat.Bc4, CompressionQuality.BestQuality, "encoding_bc4_red_bestQuality.ktx", output); @@ -330,7 +330,7 @@ public void Bc4RedBalanced() var image = ImageLoader.testHeight1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC4, + CompressionFormat.Bc4, CompressionQuality.Balanced, "encoding_bc4_red_balanced.ktx", output); @@ -342,7 +342,7 @@ public void Bc4RedFast() var image = ImageLoader.testHeight1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC4, + CompressionFormat.Bc4, CompressionQuality.Fast, "encoding_bc4_red_fast.ktx", output); @@ -367,7 +367,7 @@ public void Bc5RedGreenBestQuality() var image = ImageLoader.testRedGreen1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC5, + CompressionFormat.Bc5, CompressionQuality.BestQuality, "encoding_bc5_red_green_bestQuality.ktx", output); @@ -379,7 +379,7 @@ public void Bc5RedGreenBalanced() var image = ImageLoader.testRedGreen1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC5, + CompressionFormat.Bc5, CompressionQuality.Balanced, "encoding_bc5_red_green_balanced.ktx", output); @@ -391,7 +391,7 @@ public void Bc5RedGreenFast() var image = ImageLoader.testRedGreen1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC5, + CompressionFormat.Bc5, CompressionQuality.Fast, "encoding_bc5_red_green_fast.ktx", output); @@ -415,7 +415,7 @@ public void Bc7RgbBestQuality() var image = ImageLoader.testRgbHard1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.BestQuality, "encoding_bc7_rgb_bestQuality.ktx", output); @@ -427,7 +427,7 @@ public void Bc7RgbBalanced() var image = ImageLoader.testRgbHard1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.Balanced, "encoding_bc7_rgb_balanced.ktx", output); @@ -439,7 +439,7 @@ public void Bc7LennaBalanced() var image = ImageLoader.testLenna; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.Balanced, "encoding_bc7_lenna_balanced.ktx", output); @@ -451,7 +451,7 @@ public void Bc7RgbFast() var image = ImageLoader.testRgbHard1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.Fast, "encoding_bc7_rgb_fast.ktx", output); @@ -475,7 +475,7 @@ public void Bc7RgbaBestQuality() var image = ImageLoader.testAlpha1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.BestQuality, "encoding_bc7_rgba_bestQuality.ktx", output); @@ -487,7 +487,7 @@ public void Bc7RgbaBalanced() var image = ImageLoader.testAlpha1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.Balanced, "encoding_bc7_rgba_balanced.ktx", output); @@ -499,7 +499,7 @@ public void Bc7RgbaFast() var image = ImageLoader.testAlpha1; TestHelper.ExecuteEncodingTest(image, - CompressionFormat.BC7, + CompressionFormat.Bc7, CompressionQuality.Fast, "encoding_bc7_rgba_fast.ktx", output); @@ -517,9 +517,9 @@ public void WriteCubeMapFile() string filename = "encoding_bc1_cubemap.ktx"; BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = CompressionQuality.Fast; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = CompressionFormat.BC1; + encoder.OutputOptions.Quality = CompressionQuality.Fast; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = CompressionFormat.Bc1; using FileStream fs = File.OpenWrite(filename); encoder.EncodeCubeMap(images[0],images[1],images[2],images[3],images[4],images[5], fs); diff --git a/BCnEncTests/RawTests.cs b/BCnEncTests/RawTests.cs index 9e0c5d5..e5dd478 100644 --- a/BCnEncTests/RawTests.cs +++ b/BCnEncTests/RawTests.cs @@ -19,13 +19,13 @@ public void Decode() var originalImage = decoder.Decode(ktx); var rawBytes = encoder.EncodeToRawBytes(originalImage); - var recodedImage = decoder.DecodeRaw(rawBytes[0], CompressionFormat.BC1, originalImage.Width, originalImage.Height); + var recodedImage = decoder.DecodeRaw(rawBytes[0], CompressionFormat.Bc1, originalImage.Width, originalImage.Height); originalImage.TryGetSinglePixelSpan(out var originalPixels); recodedImage.TryGetSinglePixelSpan(out var recodedPixels); var psnr=ImageQuality.PeakSignalToNoiseRatio(originalPixels, recodedPixels); - if (encoder.OutputOptions.quality == CompressionQuality.Fast) + if (encoder.OutputOptions.Quality == CompressionQuality.Fast) { Assert.True(psnr > 25); } diff --git a/BCnEncTests/TestHelper.cs b/BCnEncTests/TestHelper.cs index e99bbd2..e08e2db 100644 --- a/BCnEncTests/TestHelper.cs +++ b/BCnEncTests/TestHelper.cs @@ -33,9 +33,9 @@ public static class TestHelper public static void ExecuteEncodingTest(Image image, CompressionFormat format, CompressionQuality quality, string filename, ITestOutputHelper output) { BcEncoder encoder = new BcEncoder(); - encoder.OutputOptions.quality = quality; - encoder.OutputOptions.generateMipMaps = true; - encoder.OutputOptions.format = format; + encoder.OutputOptions.Quality = quality; + encoder.OutputOptions.GenerateMipMaps = true; + encoder.OutputOptions.Format = format; using FileStream fs = File.OpenWrite(filename); encoder.Encode(image, fs);