diff --git a/BCnEnc.Net/BCnEncoder.csproj b/BCnEnc.Net/BCnEncoder.csproj index 624a44d..da61c8d 100644 --- a/BCnEnc.Net/BCnEncoder.csproj +++ b/BCnEnc.Net/BCnEncoder.csproj @@ -12,7 +12,7 @@ MIT OR Unlicense false - 1.2.2 + 1.2.3 Nominom BCnEncoder.Net @@ -31,7 +31,7 @@ Supported formats are: git BCn BC BC1 BC2 BC3 BC4 BC5 BC7 BPTC RGTC S3TC DXT1 DXT3 DXT5 ktx dds texture compression encoding decoding decompression image gpu https://github.com/Nominom/BCnEncoder.NET - Changed EncodingQuality to CompressionQuality. + Upgraded ImageSharp dependency from 1.0.0 beta 7 to version 1.0.1 @@ -44,7 +44,7 @@ Supported formats are: - + diff --git a/BCnEnc.Net/Decoder/BcDecoder.cs b/BCnEnc.Net/Decoder/BcDecoder.cs index 2b50ee1..d768a85 100644 --- a/BCnEnc.Net/Decoder/BcDecoder.cs +++ b/BCnEnc.Net/Decoder/BcDecoder.cs @@ -260,7 +260,9 @@ public Image Decode(KtxFile file) var image = new Image((int)pixelWidth, (int)pixelHeight); var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); - var pixels = image.GetPixelSpan(); + if (!image.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); return image; @@ -299,7 +301,9 @@ public Image[] DecodeAllMipMaps(KtxFile file) var image = new Image((int)pixelWidth, (int)pixelHeight); var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); - var pixels = image.GetPixelSpan(); + if (!image.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); images[mip] = image; @@ -345,7 +349,9 @@ public Image Decode(DdsFile file) var image = new Image((int)pixelWidth, (int)pixelHeight); var output = decoder.Decode(data, (int)pixelWidth, (int)pixelHeight); - var pixels = image.GetPixelSpan(); + if (!image.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); return image; @@ -393,7 +399,9 @@ public Image[] DecodeAllMipMaps(DdsFile file) var image = new Image((int) pixelWidth, (int) pixelHeight); var output = decoder.Decode(data, (int) pixelWidth, (int) pixelHeight); - var pixels = image.GetPixelSpan(); + if (!image.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } output.CopyTo(pixels); images[mip] = image; diff --git a/BCnEnc.Net/Encoder/BcEncoder.cs b/BCnEnc.Net/Encoder/BcEncoder.cs index e8f8982..3424d55 100644 --- a/BCnEnc.Net/Encoder/BcEncoder.cs +++ b/BCnEnc.Net/Encoder/BcEncoder.cs @@ -189,7 +189,10 @@ public KtxFile EncodeToKtx(Image inputImage) } else { - encoded = uncompressedEncoder.Encode(mipChain[i].GetPixelSpan()); + 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, @@ -264,7 +267,10 @@ public DdsFile EncodeToDds(Image inputImage) } else { - encoded = uncompressedEncoder.Encode(mipChain[mip].GetPixelSpan()); + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) { + throw new Exception("Cannot get pixel span."); + } + encoded = uncompressedEncoder.Encode(mipPixels); } if (mip == 0) @@ -334,7 +340,10 @@ public List EncodeToRawBytes(Image inputImage) } else { - encoded = uncompressedEncoder.Encode(mipChain[i].GetPixelSpan()); + if (!mipChain[i].TryGetSinglePixelSpan(out var mipPixels)) { + throw new Exception("Cannot get pixel span."); + } + encoded = uncompressedEncoder.Encode(mipPixels); } output.Add(encoded); @@ -400,7 +409,10 @@ public byte[] EncodeToRawBytes(Image inputImage, int mipLevel, out int m } else { - encoded = uncompressedEncoder.Encode(mipChain[mipLevel].GetPixelSpan()); + if (!mipChain[mipLevel].TryGetSinglePixelSpan(out var mipPixels)) { + throw new Exception("Cannot get pixel span."); + } + encoded = uncompressedEncoder.Encode(mipPixels); } mipWidth = mipChain[mipLevel].Width; @@ -506,7 +518,10 @@ public KtxFile EncodeCubeMapToKtx(Image right, Image left, Image } else { - encoded = uncompressedEncoder.Encode(mipChain[i].GetPixelSpan()); + if (!mipChain[i].TryGetSinglePixelSpan(out var mipPixels)) { + throw new Exception("Cannot get pixel span."); + } + encoded = uncompressedEncoder.Encode(mipPixels); } if (f == 0) @@ -603,7 +618,10 @@ public DdsFile EncodeCubeMapToDds(Image right, Image left, Image } else { - encoded = uncompressedEncoder.Encode(mipChain[mip].GetPixelSpan()); + if (!mipChain[mip].TryGetSinglePixelSpan(out var mipPixels)) { + throw new Exception("Cannot get pixel span."); + } + encoded = uncompressedEncoder.Encode(mipPixels); } if (mip == 0) diff --git a/BCnEnc.Net/Shared/ImageToBlocks.cs b/BCnEnc.Net/Shared/ImageToBlocks.cs index 2285ebf..fb8b7bb 100644 --- a/BCnEnc.Net/Shared/ImageToBlocks.cs +++ b/BCnEnc.Net/Shared/ImageToBlocks.cs @@ -13,7 +13,10 @@ 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]; - Span pixels = image.GetPixelSpan(); + + if (!image.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } for (int y = 0; y < image.Height; y++) { @@ -75,7 +78,10 @@ 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); - Span pixels = output.GetPixelSpan(); + + if (!output.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } for (int y = 0; y < output.Height; y++) { @@ -102,7 +108,10 @@ 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); - Span pixels = output.GetPixelSpan(); + + if (!output.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } for (int y = 0; y < output.Height; y++) { diff --git a/BCnEncTests/BC1Tests.cs b/BCnEncTests/BC1Tests.cs index 189f9ac..77492f4 100644 --- a/BCnEncTests/BC1Tests.cs +++ b/BCnEncTests/BC1Tests.cs @@ -35,10 +35,10 @@ public void Decode() { block[15] = 0; var raw = block.Decode(false); - Assert.Equal(Rgba32.Black, raw.p00); - Assert.Equal(Rgba32.Black, raw.p10); - Assert.Equal(Rgba32.Black, raw.p20); - Assert.Equal(Rgba32.Black, raw.p30); + Assert.Equal(new Rgba32(0, 0, 0), raw.p00); + Assert.Equal(new Rgba32(0, 0, 0), raw.p10); + Assert.Equal(new Rgba32(0, 0, 0), raw.p20); + Assert.Equal(new Rgba32(0, 0, 0), raw.p30); Assert.Equal(new Rgba32(85, 85, 85), raw.p01); Assert.Equal(new Rgba32(85, 85, 85), raw.p11); @@ -50,10 +50,10 @@ public void Decode() { Assert.Equal(new Rgba32(170, 170, 170), raw.p22); Assert.Equal(new Rgba32(170, 170, 170), raw.p32); - Assert.Equal(Rgba32.White, raw.p03); - Assert.Equal(Rgba32.White, raw.p13); - Assert.Equal(Rgba32.White, raw.p23); - Assert.Equal(Rgba32.White, raw.p33); + Assert.Equal(new Rgba32(255, 255, 255), raw.p03); + Assert.Equal(new Rgba32(255, 255, 255), raw.p13); + Assert.Equal(new Rgba32(255, 255, 255), raw.p23); + Assert.Equal(new Rgba32(255, 255, 255), raw.p33); } [Fact] @@ -89,20 +89,20 @@ public void DecodeBlack() { Assert.Equal(new Rgba32(206, 203, 206), raw.p20); Assert.Equal(new Rgba32(206, 203, 206), raw.p30); - Assert.Equal(Rgba32.Black, raw.p01); - Assert.Equal(Rgba32.Black, raw.p11); - Assert.Equal(Rgba32.Black, raw.p21); - Assert.Equal(Rgba32.Black, raw.p31); + Assert.Equal(new Rgba32(0, 0, 0), raw.p01); + Assert.Equal(new Rgba32(0, 0, 0), raw.p11); + 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(Rgba32.White, raw.p03); - Assert.Equal(Rgba32.White, raw.p13); - Assert.Equal(Rgba32.White, raw.p23); - Assert.Equal(Rgba32.White, raw.p33); + Assert.Equal(new Rgba32(255, 255, 255), raw.p03); + Assert.Equal(new Rgba32(255, 255, 255), raw.p13); + Assert.Equal(new Rgba32(255, 255, 255), raw.p23); + Assert.Equal(new Rgba32(255, 255, 255), raw.p33); } [Fact] @@ -148,10 +148,10 @@ public void DecodeAlpha() { Assert.Equal(new Rgba32(230, 228, 230), raw.p22); Assert.Equal(new Rgba32(230, 228, 230), raw.p32); - Assert.Equal(Rgba32.White, raw.p03); - Assert.Equal(Rgba32.White, raw.p13); - Assert.Equal(Rgba32.White, raw.p23); - Assert.Equal(Rgba32.White, raw.p33); + Assert.Equal(new Rgba32(255, 255, 255), raw.p03); + Assert.Equal(new Rgba32(255, 255, 255), raw.p13); + Assert.Equal(new Rgba32(255, 255, 255), raw.p23); + Assert.Equal(new Rgba32(255, 255, 255), raw.p33); } } diff --git a/BCnEncTests/BlockTests.cs b/BCnEncTests/BlockTests.cs index 7cfd6e1..2213ed6 100644 --- a/BCnEncTests/BlockTests.cs +++ b/BCnEncTests/BlockTests.cs @@ -38,9 +38,11 @@ public void PaddingColor() { using Image testImage = new Image(13, 13); - var pixels = testImage.GetPixelSpan(); + if (!testImage.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } for (int i = 0; i < pixels.Length; i++) { - pixels[i] = Rgba32.Aquamarine; + pixels[i] = new Rgba32(0, 125, 125); } var blocks = ImageToBlocks.ImageTo4X4(testImage.Frames[0], out var blocksWidth, out var blocksHeight); @@ -52,7 +54,7 @@ public void PaddingColor() for (int x = 0; x < blocksWidth; x++) { for (int y = 0; y < blocksHeight; y++) { foreach (var color in blocks[x + y * blocksWidth].AsSpan) { - Assert.Equal(Rgba32.Aquamarine, color); + Assert.Equal(new Rgba32(0, 125, 125), color); } } } @@ -64,7 +66,9 @@ public void BlocksToImage() Random r = new Random(0); using Image testImage = new Image(16, 16); - var pixels = testImage.GetPixelSpan(); + if (!testImage.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } for (int i = 0; i < pixels.Length; i++) { pixels[i] = new Rgba32( (byte)r.Next(255), @@ -80,7 +84,10 @@ public void BlocksToImage() Assert.Equal(4, blocksHeight); using var output = ImageToBlocks.ImageFromRawBlocks(blocks, blocksWidth, blocksHeight); - var pixels2 = output.GetPixelSpan(); + + if (!output.TryGetSinglePixelSpan(out var pixels2)) { + throw new Exception("Cannot get pixel span."); + } Assert.Equal(pixels.Length, pixels2.Length); for (int i = 0; i < pixels.Length; i++) { diff --git a/BCnEncTests/ClusterTests.cs b/BCnEncTests/ClusterTests.cs index dbd5ab8..26e613c 100644 --- a/BCnEncTests/ClusterTests.cs +++ b/BCnEncTests/ClusterTests.cs @@ -16,7 +16,11 @@ public class ClusterTests [Fact] public void Clusterize() { using var testImage = ImageLoader.testBlur1.Clone(); - var pixels = testImage.GetPixelSpan(); + + if (!testImage.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } + int numClusters = (testImage.Width / 32) * (testImage.Height / 32); var clusters = LinearClustering.ClusterPixels(pixels, testImage.Width, testImage.Height, numClusters, 10, 10); diff --git a/BCnEncTests/DdsReadTests.cs b/BCnEncTests/DdsReadTests.cs index d1423ef..3e94ff2 100644 --- a/BCnEncTests/DdsReadTests.cs +++ b/BCnEncTests/DdsReadTests.cs @@ -70,7 +70,10 @@ public void ReadBc1a() { Assert.Equal((uint)image.Width, file.Header.dwWidth); Assert.Equal((uint)image.Height, file.Header.dwHeight); - Assert.Contains(image.GetPixelSpan().ToArray(), x => x.A == 0); + if (!image.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } + Assert.Contains(pixels.ToArray(), x => x.A == 0); using FileStream outFs = File.OpenWrite($"decoding_test_dds_bc1a.png"); image.SaveAsPng(outFs); diff --git a/BCnEncTests/TestHelper.cs b/BCnEncTests/TestHelper.cs index 42cf292..e99bbd2 100644 --- a/BCnEncTests/TestHelper.cs +++ b/BCnEncTests/TestHelper.cs @@ -20,8 +20,13 @@ public static float DecodeCheckPSNR(string filename, Image original) { var ktx = KtxFile.Load(fs); var decoder = new BcDecoder(); using var img = decoder.Decode(ktx); - var pixels = original.GetPixelSpan(); - var pixels2 = img.GetPixelSpan(); + + if (!original.TryGetSinglePixelSpan(out var pixels)) { + throw new Exception("Cannot get pixel span."); + } + if (!img.TryGetSinglePixelSpan(out var pixels2)) { + throw new Exception("Cannot get pixel span."); + } return ImageQuality.PeakSignalToNoiseRatio(pixels, pixels2, true); }