diff --git a/src/ImageSharp.Textures/Compression/Astc/AstcDecoder.cs b/src/ImageSharp.Textures/Compression/Astc/AstcDecoder.cs
index 66496cf7..7a19d64f 100644
--- a/src/ImageSharp.Textures/Compression/Astc/AstcDecoder.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/AstcDecoder.cs
@@ -16,10 +16,7 @@ namespace SixLabors.ImageSharp.Textures.Compression.Astc;
///
/// Image data is streamed from a source of ASTC blocks to a destination of pixels, one
/// block-row band at a time, so peak memory is independent of the image height.
-/// The decoder returns raw decoded values and does not apply any gamma or color-space
-/// transform. Callers loading ASTC data from an sRGB-tagged container (e.g. a KTX file
-/// with an *_SRGB_BLOCK format) are responsible for applying sRGB-to-linear conversion
-/// downstream if they need linear values.
+/// The decoder returns raw decoded values and does not apply an sRGB-to-linear transform.
///
public static class AstcDecoder
{
@@ -56,16 +53,24 @@ private interface IBandSerializer
/// Image width in pixels.
/// Image height in pixels.
/// The ASTC block footprint.
+ /// LDR decode mode — linear (default) or sRGB endpoint expansion.
///
/// Thrown if contains fewer bytes than the footprint requires.
///
- public static void DecompressImage(Stream source, Stream destination, int width, int height, Footprint footprint)
+ public static void DecompressImage(Stream source, Stream destination, int width, int height, Footprint footprint, LdrDecodeMode mode = LdrDecodeMode.Linear)
{
Guard.NotNull(source);
Guard.NotNull(destination);
ValidateStreamDecodeArgs(width, height);
- DecodeToStream(source, destination, width, height, footprint);
+ if (mode == LdrDecodeMode.Srgb)
+ {
+ DecodeToStream, byte, ByteBandSerializer>(source, destination, width, height, footprint);
+ }
+ else
+ {
+ DecodeToStream, byte, ByteBandSerializer>(source, destination, width, height, footprint);
+ }
}
///
@@ -77,19 +82,22 @@ public static void DecompressImage(Stream source, Stream destination, int width,
/// Image width in pixels.
/// Image height in pixels.
/// The ASTC block footprint.
+ /// LDR decode mode — linear (default) or sRGB endpoint expansion.
/// Token to cancel the operation.
/// A task that completes when the decode has finished.
///
/// Thrown if contains fewer bytes than the footprint requires.
///
public static Task DecompressImageAsync(
- Stream source, Stream destination, int width, int height, Footprint footprint, CancellationToken cancellationToken = default)
+ Stream source, Stream destination, int width, int height, Footprint footprint, LdrDecodeMode mode = LdrDecodeMode.Linear, CancellationToken cancellationToken = default)
{
Guard.NotNull(source);
Guard.NotNull(destination);
ValidateStreamDecodeArgs(width, height);
- return DecodeToStreamAsync(source, destination, width, height, footprint, cancellationToken);
+ return mode == LdrDecodeMode.Srgb
+ ? DecodeToStreamAsync, byte, ByteBandSerializer>(source, destination, width, height, footprint, cancellationToken)
+ : DecodeToStreamAsync, byte, ByteBandSerializer>(source, destination, width, height, footprint, cancellationToken);
}
///
diff --git a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/FusedLdrBlockDecoder.cs b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/FusedLdrBlockDecoder.cs
index 8126891e..37fccc8a 100644
--- a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/FusedLdrBlockDecoder.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/FusedLdrBlockDecoder.cs
@@ -19,10 +19,12 @@ internal static class FusedLdrBlockDecoder
///
/// Fused LDR decode to a contiguous buffer.
/// Only handles single-partition, non-dual-plane, LDR blocks.
+ /// selects linear vs sRGB decode (ASTC spec §C.2.19).
///
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
- internal static void DecompressBlockFusedLdr(UInt128 bits, in BlockInfo info, Footprint footprint, Span buffer)
- => DecompressBlock(
+ internal static void DecompressBlockFusedLdr(UInt128 bits, in BlockInfo info, Footprint footprint, Span buffer)
+ where TMode : struct, ILdrColorMode
+ => DecompressBlock(
bits,
in info,
footprint,
@@ -34,9 +36,10 @@ internal static void DecompressBlockFusedLdr(UInt128 bits, in BlockInfo info, Fo
///
/// Fused LDR decode writing directly to image buffer at strided positions.
/// Only handles single-partition, non-dual-plane, LDR blocks.
+ /// selects linear vs sRGB decode (ASTC spec §C.2.19).
///
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
- internal static void DecompressBlockFusedLdrToImage(
+ internal static void DecompressBlockFusedLdrToImage(
UInt128 bits,
in BlockInfo info,
Footprint footprint,
@@ -44,7 +47,8 @@ internal static void DecompressBlockFusedLdrToImage(
int dstBaseY,
int imageWidth,
Span imageBuffer)
- => DecompressBlock(
+ where TMode : struct, ILdrColorMode
+ => DecompressBlock(
bits,
in info,
footprint,
@@ -54,7 +58,7 @@ internal static void DecompressBlockFusedLdrToImage(
dstRowStride: imageWidth * BlockInfo.ChannelsPerPixel);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void DecompressBlock(
+ private static void DecompressBlock(
UInt128 bits,
in BlockInfo info,
Footprint footprint,
@@ -62,20 +66,22 @@ private static void DecompressBlock(
int dstBaseX,
int dstBaseY,
int dstRowStride)
+ where TMode : struct, ILdrColorMode
{
// Up to 12×12 = 144 ints (576 bytes) for the largest 2D footprint per spec §C.2.4.
Span texelWeights = stackalloc int[footprint.PixelCount];
ColorEndpointPair endpointPair = FusedBlockDecoder.DecodeFusedCore(bits, in info, footprint, texelWeights);
- WriteLdrPixels(buffer, footprint, dstBaseX, dstBaseY, dstRowStride, in endpointPair, texelWeights);
+ WriteLdrPixels(buffer, footprint, dstBaseX, dstBaseY, dstRowStride, in endpointPair, texelWeights);
}
///
/// Writes a footprint-sized block of LDR pixels into at position
/// (, ) with the given row stride.
- /// Uses SIMD where hardware-accelerated; scalar otherwise.
+ /// Uses SIMD where hardware-accelerated; scalar otherwise.
+ /// selects linear vs sRGB decode (ASTC spec §C.2.19).
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void WriteLdrPixels(
+ private static void WriteLdrPixels(
Span buffer,
Footprint footprint,
int dstBaseX,
@@ -83,6 +89,7 @@ private static void WriteLdrPixels(
int dstRowStride,
in ColorEndpointPair endpointPair,
Span texelWeights)
+ where TMode : struct, ILdrColorMode
{
int lowR = endpointPair.LdrLow.R, lowG = endpointPair.LdrLow.G, lowB = endpointPair.LdrLow.B, lowA = endpointPair.LdrLow.A;
int highR = endpointPair.LdrHigh.R, highG = endpointPair.LdrHigh.G, highB = endpointPair.LdrHigh.B, highA = endpointPair.LdrHigh.A;
@@ -107,7 +114,7 @@ private static void WriteLdrPixels(
texelWeights[texelIndex + 1],
texelWeights[texelIndex + 2],
texelWeights[texelIndex + 3]);
- SimdHelpers.Write4PixelLdr(
+ SimdHelpers.Write4PixelLdr(
buffer,
dstRowOffset + (pixelX * BlockInfo.ChannelsPerPixel),
lowR,
@@ -124,7 +131,7 @@ private static void WriteLdrPixels(
for (; pixelX < footprintWidth; pixelX++)
{
- SimdHelpers.WriteSinglePixelLdr(
+ SimdHelpers.WriteSinglePixelLdr(
buffer,
dstRowOffset + (pixelX * BlockInfo.ChannelsPerPixel),
lowR,
diff --git a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPipeline.cs b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPipeline.cs
index 6a7797a1..fc106e5b 100644
--- a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPipeline.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPipeline.cs
@@ -9,9 +9,11 @@ namespace SixLabors.ImageSharp.Textures.Compression.Astc.BlockDecoding;
///
/// implementation for the LDR (byte RGBA) decode profile
/// (ASTC spec §C.2.5 "LDR Mode"). HDR-mode blocks are reserved in the LDR profile per §C.2.25
-/// and produce the error colour (magenta) per §C.2.19, §C.2.24.
+/// and produce the error colour (magenta) per §C.2.19, §C.2.24.
+/// selects linear vs sRGB decode (ASTC spec §C.2.19).
///
-internal readonly struct LdrPipeline : IBlockPipeline
+internal readonly struct LdrPipeline : IBlockPipeline
+ where TMode : struct, ILdrColorMode
{
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -38,17 +40,17 @@ public void WriteErrorColorClipped(
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FusedToImage(UInt128 blockBits, in BlockInfo info, Footprint footprint, int dstBaseX, int dstBaseY, int imageWidth, Span imageBuffer)
- => FusedLdrBlockDecoder.DecompressBlockFusedLdrToImage(blockBits, in info, footprint, dstBaseX, dstBaseY, imageWidth, imageBuffer);
+ => FusedLdrBlockDecoder.DecompressBlockFusedLdrToImage(blockBits, in info, footprint, dstBaseX, dstBaseY, imageWidth, imageBuffer);
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FusedToScratch(UInt128 blockBits, in BlockInfo info, Footprint footprint, Span decodedPixels)
- => FusedLdrBlockDecoder.DecompressBlockFusedLdr(blockBits, in info, footprint, decodedPixels);
+ => FusedLdrBlockDecoder.DecompressBlockFusedLdr(blockBits, in info, footprint, decodedPixels);
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void LogicalWrite(UInt128 blockBits, in BlockInfo info, Footprint footprint, Span decodedPixels)
- => LogicalBlock.DecodeToBytes(blockBits, in info, footprint, decodedPixels);
+ => LogicalBlock.DecodeToBytes(blockBits, in info, footprint, decodedPixels);
///
/// Spec §C.2.19 error colour: opaque magenta (0xFF, 0x00, 0xFF, 0xFF) as UNORM8 RGBA.
diff --git a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPixelWriter.cs b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPixelWriter.cs
index 434def5f..78dd8361 100644
--- a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPixelWriter.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LdrPixelWriter.cs
@@ -9,12 +9,14 @@ namespace SixLabors.ImageSharp.Textures.Compression.Astc.BlockDecoding;
///
/// LDR — writes UNORM8 RGBA bytes via the scalar SIMD helpers.
+/// selects linear vs sRGB decode (ASTC spec §C.2.19).
///
-internal readonly struct LdrPixelWriter : IPixelWriter
+internal readonly struct LdrPixelWriter : IPixelWriter
+ where TMode : struct, ILdrColorMode
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WritePixel(Span buffer, int offset, in ColorEndpointPair endpoint, int weight)
- => SimdHelpers.WriteSinglePixelLdr(
+ => SimdHelpers.WriteSinglePixelLdr(
buffer,
offset,
endpoint.LdrLow.R,
@@ -35,7 +37,7 @@ public void WritePixelDualPlane(
int primaryWeight,
int dualPlaneChannel,
int dualPlaneWeight)
- => SimdHelpers.WriteSinglePixelLdrDualPlane(
+ => SimdHelpers.WriteSinglePixelLdrDualPlane(
buffer,
offset,
endpoint.LdrLow.R,
diff --git a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LogicalBlock.cs b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LogicalBlock.cs
index 04663cca..55902d51 100644
--- a/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LogicalBlock.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/BlockDecoding/LogicalBlock.cs
@@ -18,10 +18,12 @@ internal static class LogicalBlock
///
/// Decodes a block to its UNORM8 RGBA pixels. HDR-endpoint blocks must not reach this
/// method: the LDR entry points in reject HDR content per
- /// ASTC spec §C.2.19, so every partition's endpoint here is LDR.
+ /// ASTC spec §C.2.19, so every partition's endpoint here is LDR.
+ /// selects linear vs sRGB decode (ASTC spec §C.2.19).
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void DecodeToBytes(UInt128 bits, in BlockInfo info, Footprint footprint, Span pixels)
+ public static void DecodeToBytes(UInt128 bits, in BlockInfo info, Footprint footprint, Span pixels)
+ where TMode : struct, ILdrColorMode
{
if (!info.IsValid)
{
@@ -30,7 +32,7 @@ public static void DecodeToBytes(UInt128 bits, in BlockInfo info, Footprint foot
if (info.DualPlane.Enabled && !info.IsVoidExtent)
{
- DecodeDualPlane(bits, in info, footprint, pixels);
+ DecodeDualPlane, byte>(bits, in info, footprint, pixels);
return;
}
@@ -38,7 +40,7 @@ public static void DecodeToBytes(UInt128 bits, in BlockInfo info, Footprint foot
Span weights = stackalloc int[footprint.PixelCount];
DecodedBlockState state = DecodeSinglePlane(bits, in info, footprint, weights);
- WriteAllPixels(footprint, pixels, in state);
+ WriteAllPixels, byte>(footprint, pixels, in state);
}
///
@@ -295,7 +297,7 @@ private static void WriteAllPixelsDualPlane(
///
/// Inline storage for up to 4 per-partition values
/// (spec §C.2.10 caps partition count at 4). Used as a stack-local buffer to hold the
- /// decoded endpoints during a single / call.
+ /// decoded endpoints during a single / call.
///
[InlineArray(BlockInfo.MaxPartitionCount)]
private struct EndpointBuffer
diff --git a/src/ImageSharp.Textures/Compression/Astc/Core/Interpolation.cs b/src/ImageSharp.Textures/Compression/Astc/Core/Interpolation.cs
index 8d9264dd..5d823ad2 100644
--- a/src/ImageSharp.Textures/Compression/Astc/Core/Interpolation.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/Core/Interpolation.cs
@@ -21,13 +21,15 @@ public static int BlendWeighted(int p0, int p1, int weight)
=> ((p0 * (64 - weight)) + (p1 * weight) + 32) / 64;
///
- /// LDR-to-UNORM16 blend: each 8-bit endpoint is bit-replicated to 16 bits
- /// ((p << 8) | p) per §C.2.19 before the weighted blend. Every LDR decode
- /// path that produces 16-bit intermediate values goes through this primitive.
+ /// LDR-to-UNORM16 blend with linear bit-replication (§C.2.19).
///
+ ///
+ /// Used by the HDR output path where LDR channels always expand linearly. The LDR-output path
+ /// expands per channel via before calling .
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int BlendLdrReplicated(int p0, int p1, int weight)
- => BlendWeighted((p0 << 8) | p0, (p1 << 8) | p1, weight);
+ => BlendWeighted(LinearExpand.Expand(p0), LinearExpand.Expand(p1), weight);
///
/// Normalises a UNORM16 value (clamped to [0, 0xFFFF]) to the [0.0, 1.0] float range.
diff --git a/src/ImageSharp.Textures/Compression/Astc/Core/LdrChannelExpansion.cs b/src/ImageSharp.Textures/Compression/Astc/Core/LdrChannelExpansion.cs
new file mode 100644
index 00000000..cfe4b218
--- /dev/null
+++ b/src/ImageSharp.Textures/Compression/Astc/Core/LdrChannelExpansion.cs
@@ -0,0 +1,82 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Textures.Compression.Astc.Core;
+
+#pragma warning disable SA1201 // Readability: keep each expansion strategy adjacent to the interface it implements.
+#pragma warning disable SA1649 // Multiple small, tightly-related expansion strategies share one file.
+
+///
+/// Linear LDR expansion (ASTC spec §C.2.19). Used for every channel in linear decode mode, for the
+/// alpha channel in every mode, and for LDR channels borrowed by the HDR output path.
+///
+internal readonly struct LinearExpand
+{
+ ///
+ /// Expands an 8-bit component to its 16-bit form.
+ ///
+ /// The 8-bit component value.
+ /// The 16-bit expanded value.
+ public static int Expand(int c) => (c << 8) | c;
+}
+
+///
+/// sRGB LDR expansion (ASTC spec §C.2.19). Used for the R, G, and B channels in sRGB decode mode.
+///
+internal readonly struct SrgbExpand
+{
+ ///
+ /// Expands an 8-bit component to its 16-bit form.
+ ///
+ /// The 8-bit component value.
+ /// The 16-bit expanded value.
+ public static int Expand(int c) => (c << 8) | 0x80;
+}
+
+///
+/// An LDR decode mode's per-channel endpoint expansion (ASTC spec §C.2.19).
+///
+internal interface ILdrColorMode
+{
+ ///
+ /// Expands an 8-bit R, G, or B endpoint component to 16 bits.
+ ///
+ /// The 8-bit colour component value.
+ /// The 16-bit expanded value.
+ public static abstract int ExpandColor(int c);
+
+ ///
+ /// Expands an 8-bit alpha endpoint component to 16 bits.
+ ///
+ /// The 8-bit alpha component value.
+ /// The 16-bit expanded value.
+ public static abstract int ExpandAlpha(int c);
+}
+
+///
+/// Linear LDR decode mode
+///
+internal readonly struct LinearMode : ILdrColorMode
+{
+ ///
+ public static int ExpandColor(int c) => LinearExpand.Expand(c);
+
+ ///
+ public static int ExpandAlpha(int c) => LinearExpand.Expand(c);
+}
+
+///
+/// sRGB LDR decode mode: R, G, B use ; alpha stays .
+/// ASTC spec §C.2.19, only the colour channels take the sRGB low byte.
+///
+internal readonly struct SrgbMode : ILdrColorMode
+{
+ ///
+ public static int ExpandColor(int c) => SrgbExpand.Expand(c);
+
+ ///
+ public static int ExpandAlpha(int c) => LinearExpand.Expand(c);
+}
+
+#pragma warning restore SA1201
+#pragma warning restore SA1649
diff --git a/src/ImageSharp.Textures/Compression/Astc/Core/SimdHelpers.cs b/src/ImageSharp.Textures/Compression/Astc/Core/SimdHelpers.cs
index fcd78841..7a804dcb 100644
--- a/src/ImageSharp.Textures/Compression/Astc/Core/SimdHelpers.cs
+++ b/src/ImageSharp.Textures/Compression/Astc/Core/SimdHelpers.cs
@@ -13,21 +13,24 @@ internal static class SimdHelpers
private static readonly Vector128 Vec255 = Vector128.Create(255);
///
- /// Interpolates one channel for 4 pixels simultaneously.
- /// All 4 pixels share the same endpoint values but have different weights.
- /// Returns 4 byte results packed into the lower bytes of a .
+ /// Interpolates one channel for 4 pixels simultaneously from two already-expanded 16-bit
+ /// endpoints (ASTC spec §C.2.19).
///
+ ///
+ /// Callers apply the per-channel expansion (linear or sRGB) to /
+ /// first. All 4 pixels share the same endpoints but have different weights.
+ ///
+ /// 4 byte results packed into the lower bytes of a
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector128 Interpolate4ChannelPixels(int p0, int p1, Vector128 weights)
+ public static Vector128 Interpolate4ExpandedPixels(int c0, int c1, Vector128 weights)
{
- // Bit-replicate endpoint bytes to 16-bit
- Vector128 c0 = Vector128.Create((p0 << 8) | p0);
- Vector128 c1 = Vector128.Create((p1 << 8) | p1);
+ Vector128 v0 = Vector128.Create(c0);
+ Vector128 v1 = Vector128.Create(c1);
// Vectorised form of the ASTC spec §C.2.19 weighted blend (see Interpolation.BlendWeighted).
// NOTE: >> 6 rather than / 64 — Vector128 has no hardware division and decomposes to scalar ops.
Vector128 w64 = Vec64 - weights;
- Vector128 c = ((c0 * w64) + (c1 * weights) + Vec32) >> 6;
+ Vector128 c = ((v0 * w64) + (v1 * weights) + Vec32) >> 6;
// Spec §C.2.19 (Weight Application): for LDR-mode UNORM8 output the final
// 8-bit result is the top 8 bits of the UNORM16 interpolation. Mask
@@ -37,11 +40,12 @@ public static Vector128 Interpolate4ChannelPixels(int p0, int p1, Vector128
}
///
- /// Writes 4 LDR pixels directly to output buffer using SIMD.
- /// Processes each channel across 4 pixels in parallel, then interleaves to RGBA output.
+ /// Writes 4 LDR pixels directly to output buffer using SIMD. R, G, and B expand via
+ /// 's colour expansion. Processes each channel across 4 pixels in parallel,
+ /// then interleaves to RGBA output.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Write4PixelLdr(
+ public static void Write4PixelLdr(
Span output,
int offset,
int lowR,
@@ -53,11 +57,12 @@ public static void Write4PixelLdr(
int highB,
int highA,
Vector128 weights)
+ where TMode : struct, ILdrColorMode
{
- Vector128 r = Interpolate4ChannelPixels(lowR, highR, weights);
- Vector128 g = Interpolate4ChannelPixels(lowG, highG, weights);
- Vector128 b = Interpolate4ChannelPixels(lowB, highB, weights);
- Vector128 a = Interpolate4ChannelPixels(lowA, highA, weights);
+ Vector128 r = Interpolate4ExpandedPixels(TMode.ExpandColor(lowR), TMode.ExpandColor(highR), weights);
+ Vector128 g = Interpolate4ExpandedPixels(TMode.ExpandColor(lowG), TMode.ExpandColor(highG), weights);
+ Vector128 b = Interpolate4ExpandedPixels(TMode.ExpandColor(lowB), TMode.ExpandColor(highB), weights);
+ Vector128 a = Interpolate4ExpandedPixels(TMode.ExpandAlpha(lowA), TMode.ExpandAlpha(highA), weights);
// Pack 4 RGBA pixels into 16 bytes via vector OR+shift.
// Each int element has its channel value in bits [0:7].
@@ -68,11 +73,11 @@ public static void Write4PixelLdr(
}
///
- /// Scalar single-pixel LDR interpolation, writing directly to buffer.
- /// No Rgba32 allocation.
+ /// Scalar single-pixel LDR interpolation, writing directly to buffer. R, G, and B expand via
+ /// 's colour expansion. No Rgba32 allocation.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteSinglePixelLdr(
+ public static void WriteSinglePixelLdr(
Span output,
int offset,
int lowR,
@@ -84,18 +89,20 @@ public static void WriteSinglePixelLdr(
int highB,
int highA,
int weight)
+ where TMode : struct, ILdrColorMode
{
- output[offset + 0] = (byte)InterpolateChannelScalar(lowR, highR, weight);
- output[offset + 1] = (byte)InterpolateChannelScalar(lowG, highG, weight);
- output[offset + 2] = (byte)InterpolateChannelScalar(lowB, highB, weight);
- output[offset + 3] = (byte)InterpolateChannelScalar(lowA, highA, weight);
+ output[offset + 0] = (byte)InterpolateColorScalar(lowR, highR, weight);
+ output[offset + 1] = (byte)InterpolateColorScalar(lowG, highG, weight);
+ output[offset + 2] = (byte)InterpolateColorScalar(lowB, highB, weight);
+ output[offset + 3] = (byte)InterpolateAlphaScalar(lowA, highA, weight);
}
///
- /// Scalar single-pixel dual-plane LDR interpolation, writing directly to buffer.
+ /// Scalar single-pixel dual-plane LDR interpolation, writing directly to buffer. R, G, and B
+ /// expand via 's colour expansion.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void WriteSinglePixelLdrDualPlane(
+ public static void WriteSinglePixelLdrDualPlane(
Span output,
int offset,
int lowR,
@@ -109,31 +116,40 @@ public static void WriteSinglePixelLdrDualPlane(
int weight,
int dpChannel,
int dpWeight)
+ where TMode : struct, ILdrColorMode
{
- output[offset + 0] = (byte)InterpolateChannelScalar(
+ output[offset + 0] = (byte)InterpolateColorScalar(
lowR,
highR,
dpChannel == 0 ? dpWeight : weight);
- output[offset + 1] = (byte)InterpolateChannelScalar(
+ output[offset + 1] = (byte)InterpolateColorScalar(
lowG,
highG,
dpChannel == 1 ? dpWeight : weight);
- output[offset + 2] = (byte)InterpolateChannelScalar(
+ output[offset + 2] = (byte)InterpolateColorScalar(
lowB,
highB,
dpChannel == 2 ? dpWeight : weight);
- output[offset + 3] = (byte)InterpolateChannelScalar(
+ output[offset + 3] = (byte)InterpolateAlphaScalar(
lowA,
highA,
dpChannel == 3 ? dpWeight : weight);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static int InterpolateChannelScalar(int p0, int p1, int weight)
- {
- // Spec §C.2.19 (Weight Application): for LDR-mode UNORM8 output the final
- // 8-bit result is the top 8 bits of the UNORM16 interpolation.
- int c = Interpolation.BlendLdrReplicated(p0, p1, weight);
- return (c >> 8) & 0xFF;
- }
+ private static int InterpolateColorScalar(int p0, int p1, int weight)
+ where TMode : struct, ILdrColorMode
+ => TopByte(Interpolation.BlendWeighted(TMode.ExpandColor(p0), TMode.ExpandColor(p1), weight));
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static int InterpolateAlphaScalar(int p0, int p1, int weight)
+ where TMode : struct, ILdrColorMode
+ => TopByte(Interpolation.BlendWeighted(TMode.ExpandAlpha(p0), TMode.ExpandAlpha(p1), weight));
+
+ ///
+ /// Spec §C.2.19 (Weight Application): for LDR-mode UNORM8 output the final 8-bit result is the
+ /// top 8 bits of the UNORM16 interpolation.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static int TopByte(int unorm16) => (unorm16 >> 8) & 0xFF;
}
diff --git a/src/ImageSharp.Textures/Compression/Astc/LdrDecodeMode.cs b/src/ImageSharp.Textures/Compression/Astc/LdrDecodeMode.cs
new file mode 100644
index 00000000..744f5404
--- /dev/null
+++ b/src/ImageSharp.Textures/Compression/Astc/LdrDecodeMode.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+namespace SixLabors.ImageSharp.Textures.Compression.Astc;
+
+///
+/// Selects how the LDR decode path expands and outputs color (ASTC spec §C.2.19, §C.2.5).
+///
+public enum LdrDecodeMode
+{
+ ///
+ /// Linear decode. Each 8-bit endpoint component is bit-replicated to 16 bits before interpolation.
+ ///
+ Linear,
+
+ ///
+ /// sRGB decode. The R, G, and B endpoint components are expanded, alpha is unchanged.
+ ///
+ Srgb,
+}
diff --git a/src/ImageSharp.Textures/Formats/Ktx/KtxProcessor.cs b/src/ImageSharp.Textures/Formats/Ktx/KtxProcessor.cs
index 6a87acc4..4ae867de 100644
--- a/src/ImageSharp.Textures/Formats/Ktx/KtxProcessor.cs
+++ b/src/ImageSharp.Textures/Formats/Ktx/KtxProcessor.cs
@@ -95,47 +95,61 @@ public MipMap[] DecodeMipMaps(Stream stream, int width, int height, uint count)
case GlInternalPixelFormat.CompressedRgb8Etc2:
return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc4x4Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc4x4Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc4x4Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc5x4Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x4Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x4Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc5x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x5Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x5Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc6x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x5Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x5Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc6x6Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x6Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x6Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc8x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x5Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x5Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc8x6Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x6Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x6Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc8x8Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x8Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x8Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc10x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x5Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x5Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc10x6Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x6Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x6Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc10x8Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x8Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x8Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc10x10Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x10Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x10Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc12x10Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x10Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x10Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
case GlInternalPixelFormat.CompressedRgbaAstc12x12Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x12Khr:
return this.AllocateMipMaps(stream, width, height, count);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x12Khr:
+ return this.AllocateMipMaps(stream, width, height, count);
}
break;
@@ -234,47 +248,61 @@ public CubemapTexture DecodeCubeMap(Stream stream, int width, int height)
case GlInternalPixelFormat.CompressedRgb8Etc2:
return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc4x4Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc4x4Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc4x4Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc5x4Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x4Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x4Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc5x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x5Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc5x5Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc6x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x5Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x5Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc6x6Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x6Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc6x6Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc8x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x5Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x5Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc8x6Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x6Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x6Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc8x8Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x8Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc8x8Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc10x5Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x5Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x5Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc10x6Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x6Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x6Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc10x8Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x8Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x8Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc10x10Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x10Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc10x10Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc12x10Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x10Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x10Khr:
+ return this.AllocateCubeMap(stream, width, height);
case GlInternalPixelFormat.CompressedRgbaAstc12x12Khr:
- case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x12Khr:
return this.AllocateCubeMap(stream, width, height);
+ case GlInternalPixelFormat.CompressedSrgb8Alpha8Astc12x12Khr:
+ return this.AllocateCubeMap(stream, width, height);
}
break;
diff --git a/src/ImageSharp.Textures/Formats/Ktx2/Ktx2Processor.cs b/src/ImageSharp.Textures/Formats/Ktx2/Ktx2Processor.cs
index 59b0198a..6f2a6d5e 100644
--- a/src/ImageSharp.Textures/Formats/Ktx2/Ktx2Processor.cs
+++ b/src/ImageSharp.Textures/Formats/Ktx2/Ktx2Processor.cs
@@ -168,47 +168,61 @@ public MipMap[] DecodeMipMaps(Stream stream, int width, int height, LevelIndex[]
case VkFormat.VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
+ return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
return AllocateMipMaps(memoryStream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
@@ -379,47 +393,61 @@ public CubemapTexture DecodeCubeMap(Stream stream, int width, int height, LevelI
case VkFormat.VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
- case VkFormat.VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
+ case VkFormat.VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
+ return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK:
return AllocateCubeMap(stream, width, height, levelIndices);
case VkFormat.VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK:
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/AstcDecoder.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/AstcDecoder.cs
index 2b417add..5580b750 100644
--- a/src/ImageSharp.Textures/TextureFormats/Decoding/AstcDecoder.cs
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/AstcDecoder.cs
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
+using SixLabors.ImageSharp.Textures.Compression.Astc;
using SixLabors.ImageSharp.Textures.Compression.Astc.Core;
namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
@@ -27,6 +28,7 @@ internal static class AstcDecoder
/// The height of the block footprint.
/// The number of compressed bytes per block. Must equal
/// (16).
+ /// LDR decode mode — linear or sRGB endpoint expansion
/// The decompressed UNORM8 RGBA pixel data.
/// Thrown if is null.
/// Thrown if dimensions or block parameters are invalid.
@@ -38,7 +40,8 @@ public static byte[] DecompressImage(
int height,
int blockWidth,
int blockHeight,
- byte compressedBytesPerBlock)
+ byte compressedBytesPerBlock,
+ LdrDecodeMode mode = LdrDecodeMode.Linear)
{
long expectedDataLength = GetExpectedBlockStreamLength(width, height, blockWidth, blockHeight, compressedBytesPerBlock);
long totalPixels = (long)width * height;
@@ -58,7 +61,7 @@ public static byte[] DecompressImage(
// KTX/KTX2 mip-level slices may be over-sized; trim to the exact block stream the real decoder expects.
using MemoryStream source = new(blockData, 0, (int)expectedDataLength, writable: false);
using MemoryStream destination = new(decompressedData, writable: true);
- Compression.Astc.AstcDecoder.DecompressImage(source, destination, width, height, footprint);
+ Compression.Astc.AstcDecoder.DecompressImage(source, destination, width, height, footprint, mode);
return decompressedData;
}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x10.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x10.cs
new file mode 100644
index 00000000..053186f3
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x10.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 10x10
+///
+internal readonly struct RgbaAstcSrgb10X10 : IBlock
+{
+ public static Size BlockSize => new(10, 10);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 10;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x5.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x5.cs
new file mode 100644
index 00000000..fa6bb8b8
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x5.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 10x5
+///
+internal readonly struct RgbaAstcSrgb10X5 : IBlock
+{
+ public static Size BlockSize => new(10, 5);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 10;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x6.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x6.cs
new file mode 100644
index 00000000..8f88498e
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x6.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 10x6
+///
+internal readonly struct RgbaAstcSrgb10X6 : IBlock
+{
+ public static Size BlockSize => new(10, 6);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 10;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x8.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x8.cs
new file mode 100644
index 00000000..52dabcfe
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb10x8.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 10x8
+///
+internal readonly struct RgbaAstcSrgb10X8 : IBlock
+{
+ public static Size BlockSize => new(10, 8);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 10;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb12x10.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb12x10.cs
new file mode 100644
index 00000000..e8609847
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb12x10.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 12x10
+///
+internal readonly struct RgbaAstcSrgb12X10 : IBlock
+{
+ public static Size BlockSize => new(12, 10);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 12;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb12x12.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb12x12.cs
new file mode 100644
index 00000000..18676d72
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb12x12.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 12x12
+///
+internal readonly struct RgbaAstcSrgb12X12 : IBlock
+{
+ public static Size BlockSize => new(12, 12);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 12;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb4x4.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb4x4.cs
new file mode 100644
index 00000000..a22ee8e9
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb4x4.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 4x4
+///
+internal readonly struct RgbaAstcSrgb4X4 : IBlock
+{
+ public static Size BlockSize => new(4, 4);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 4;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb5x4.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb5x4.cs
new file mode 100644
index 00000000..954be459
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb5x4.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 5x4
+///
+internal readonly struct RgbaAstcSrgb5X4 : IBlock
+{
+ public static Size BlockSize => new(5, 4);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 5;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb5x5.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb5x5.cs
new file mode 100644
index 00000000..9a52da5e
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb5x5.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 5x5
+///
+internal readonly struct RgbaAstcSrgb5X5 : IBlock
+{
+ public static Size BlockSize => new(5, 5);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 5;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb6x5.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb6x5.cs
new file mode 100644
index 00000000..c2220488
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb6x5.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 6x5
+///
+internal readonly struct RgbaAstcSrgb6X5 : IBlock
+{
+ public static Size BlockSize => new(6, 5);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 6;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb6x6.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb6x6.cs
new file mode 100644
index 00000000..8c74666c
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb6x6.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 6x6
+///
+internal readonly struct RgbaAstcSrgb6X6 : IBlock
+{
+ public static Size BlockSize => new(6, 6);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 6;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x5.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x5.cs
new file mode 100644
index 00000000..82939b37
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x5.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 8x5
+///
+internal readonly struct RgbaAstcSrgb8X5 : IBlock
+{
+ public static Size BlockSize => new(8, 5);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 8;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x6.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x6.cs
new file mode 100644
index 00000000..f7011189
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x6.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 8x6
+///
+internal readonly struct RgbaAstcSrgb8X6 : IBlock
+{
+ public static Size BlockSize => new(8, 6);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 8;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x8.cs b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x8.cs
new file mode 100644
index 00000000..fea09628
--- /dev/null
+++ b/src/ImageSharp.Textures/TextureFormats/Decoding/RgbaAstcSrgb8x8.cs
@@ -0,0 +1,40 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.Textures.Compression.Astc;
+
+namespace SixLabors.ImageSharp.Textures.TextureFormats.Decoding;
+
+///
+/// Texture compressed with the sRGB variant of ASTC 8x8
+///
+internal readonly struct RgbaAstcSrgb8X8 : IBlock
+{
+ public static Size BlockSize => new(8, 8);
+
+ ///
+ public int BitsPerPixel => 128 / (BlockSize.Width * BlockSize.Height);
+
+ ///
+ public byte PixelDepthBytes => 4;
+
+ ///
+ public byte DivSize => 8;
+
+ ///
+ public byte CompressedBytesPerBlock => 16;
+
+ ///
+ public bool Compressed => true;
+
+ ///
+ public Image GetImage(byte[] blockData, int width, int height)
+ {
+ byte[] decompressedData = this.Decompress(blockData, width, height);
+ return Image.LoadPixelData(decompressedData, width, height);
+ }
+
+ ///
+ public byte[] Decompress(byte[] blockData, int width, int height) =>
+ AstcDecoder.DecompressImage(blockData, width, height, BlockSize.Width, BlockSize.Height, this.CompressedBytesPerBlock, LdrDecodeMode.Srgb);
+}
diff --git a/tests/ImageSharp.Textures.Benchmarks/AstcDecodingBenchmark.cs b/tests/ImageSharp.Textures.Benchmarks/AstcDecodingBenchmark.cs
index 7cea20db..a577aecc 100644
--- a/tests/ImageSharp.Textures.Benchmarks/AstcDecodingBenchmark.cs
+++ b/tests/ImageSharp.Textures.Benchmarks/AstcDecodingBenchmark.cs
@@ -49,7 +49,7 @@ public int Partitioning()
BlockInfo info = BlockModeDecoder.Decode(bits);
Footprint footprint = Footprint.FromFootprintType(FootprintType.Footprint4x4);
Span pixels = stackalloc byte[footprint.PixelCount * 4];
- LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
+ LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
return pixels[0];
}
}
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Astc/AstcStreamCodec.cs b/tests/ImageSharp.Textures.Tests/Formats/Astc/AstcStreamCodec.cs
index 51c42458..034dda00 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Astc/AstcStreamCodec.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Astc/AstcStreamCodec.cs
@@ -24,6 +24,18 @@ public static byte[] DecodeLdr(ReadOnlySpan astcData, int width, int heigh
public static byte[] DecodeLdr(ReadOnlySpan astcData, int width, int height, FootprintType footprint)
=> DecodeLdr(astcData, width, height, Footprint.FromFootprintType(footprint));
+ public static byte[] DecodeLdrSrgb(ReadOnlySpan astcData, int width, int height, Footprint footprint)
+ {
+ using MemoryStream source = new(astcData.ToArray());
+ using MemoryStream destination = new();
+ AstcDecoder.DecompressImage(source, destination, width, height, footprint, LdrDecodeMode.Srgb);
+
+ return destination.ToArray();
+ }
+
+ public static byte[] DecodeLdrSrgb(ReadOnlySpan astcData, int width, int height, FootprintType footprint)
+ => DecodeLdrSrgb(astcData, width, height, Footprint.FromFootprintType(footprint));
+
public static float[] DecodeHdr(ReadOnlySpan astcData, int width, int height, Footprint footprint)
{
using MemoryStream source = new(astcData.ToArray());
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Astc/LogicalAstcBlockTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Astc/LogicalAstcBlockTests.cs
index 2a7c3932..17edf4d7 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Astc/LogicalAstcBlockTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Astc/LogicalAstcBlockTests.cs
@@ -28,7 +28,7 @@ public void DecodeToBytes_WithErrorBlock_ShouldLeaveBufferUntouched()
byte[] pixels = new byte[footprint.PixelCount * 4];
Array.Fill(pixels, (byte)0xCC);
- LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
+ LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
// Invalid blocks short-circuit without touching the output buffer.
Assert.All(pixels, b => Assert.Equal(0xCC, b));
@@ -43,7 +43,7 @@ public void DecodeToBytes_WithVoidExtentBlock_ShouldFillUniformPixels()
Footprint footprint = Footprint.FromFootprintType(FootprintType.Footprint8x8);
byte[] pixels = new byte[footprint.PixelCount * 4];
- LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
+ LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
Assert.All(pixels, b => Assert.Equal(0, b));
}
@@ -91,7 +91,7 @@ public void DecodeToBytes_WithStandardBlock_Succeeds()
Footprint footprint = Footprint.FromFootprintType(FootprintType.Footprint6x5);
byte[] pixels = new byte[footprint.PixelCount * 4];
- LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
+ LogicalBlock.DecodeToBytes(bits, in info, footprint, pixels);
// Block carries valid LDR data and decodes without throwing; we don't pin specific
// pixel values here — those are covered by the image roundtrip tests below.
@@ -147,7 +147,7 @@ private static Image DecodeAstcBlocksToImage(Footprint footprint, byte[]
BlockInfo info = BlockModeDecoder.Decode(bits);
Assert.True(info.IsValid);
- LogicalBlock.DecodeToBytes(bits, in info, footprint, blockPixels);
+ LogicalBlock.DecodeToBytes(bits, in info, footprint, blockPixels);
for (int y = 0; y < blockHeight; ++y)
{
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/AstcReferenceDecoder.cs b/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/AstcReferenceDecoder.cs
index f71b2ac2..fd452da6 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/AstcReferenceDecoder.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/AstcReferenceDecoder.cs
@@ -65,6 +65,55 @@ public static byte[] DecompressLdr(ReadOnlySpan blocks, int w, int h, int
}
}
+ ///
+ /// Decompress ASTC blocks to sRGB RGBA32 (LDR sRGB profile) using the ARM reference decoder.
+ ///
+ ///
+ /// The RGB channels are expanded via the sRGB rule (fixed 0x80 low byte, ASTC spec
+ /// §C.2.19); alpha stays linear. The output is the sRGB-encoded 8-bit values, no
+ /// sRGB-to-linear transform is applied.
+ ///
+ public static byte[] DecompressLdrSrgb(ReadOnlySpan blocks, int w, int h, int blockX, int blockY)
+ {
+ AstcencError error = Astcenc.AstcencConfigInit(
+ AstcencProfile.AstcencPrfLdrSrgb,
+ (uint)blockX,
+ (uint)blockY,
+ 1,
+ Astcenc.AstcencPreFastest,
+ AstcencFlags.DecompressOnly,
+ out AstcencConfig config);
+ ThrowOnError(error, "ConfigInit(LDR_SRGB)");
+
+ error = Astcenc.AstcencContextAlloc(ref config, 1, out AstcencContext context);
+ ThrowOnError(error, "ContextAlloc(LDR_SRGB)");
+
+ try
+ {
+ int pixelCount = w * h;
+ byte[] outputBytes = new byte[pixelCount * 4]; // RGBA32
+
+ AstcencImage image = new()
+ {
+ dimX = (uint)w,
+ dimY = (uint)h,
+ dimZ = 1,
+ dataType = AstcencType.AstcencTypeU8,
+ data = outputBytes,
+ };
+
+ byte[] blocksCopy = blocks.ToArray();
+ error = Astcenc.AstcencDecompressImage(context, blocksCopy, ref image, IdentitySwizzle, 0);
+ ThrowOnError(error, "DecompressImage(LDR_SRGB)");
+
+ return outputBytes;
+ }
+ finally
+ {
+ Astcenc.AstcencContextFree(context);
+ }
+ }
+
///
/// Decompress ASTC blocks to FP16 RGBA (HDR) using the ARM reference decoder.
///
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/ReferenceDecoderTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/ReferenceDecoderTests.cs
index a6713e26..0d745ec6 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/ReferenceDecoderTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Astc/Reference/ReferenceDecoderTests.cs
@@ -227,6 +227,89 @@ public void DecompressLdr_VoidExtentBlock_ShouldMatch()
CompareRgba8(actual, expected, blockX, blockY, "VoidExtent");
}
+ [Theory]
+ [MemberData(nameof(AllFootprintTypes))]
+ public void DecompressLdrSrgb_SolidColor_ShouldMatch(FootprintType footprintType)
+ {
+ (int blockX, int blockY) = AstcReferenceDecoder.ToBlockDimensions(footprintType);
+ int width = blockX;
+ int height = blockY;
+
+ byte[] pixels = new byte[width * height * 4];
+ for (int index = 0; index < width * height; index++)
+ {
+ pixels[(index * 4) + 0] = 128; // R
+ pixels[(index * 4) + 1] = 64; // G
+ pixels[(index * 4) + 2] = 200; // B
+ pixels[(index * 4) + 3] = 255; // A
+ }
+
+ byte[] compressed = AstcReferenceDecoder.CompressLdr(pixels, width, height, blockX, blockY);
+ Footprint footprint = Footprint.FromFootprintType(footprintType);
+
+ byte[] expected = AstcReferenceDecoder.DecompressLdrSrgb(compressed, width, height, blockX, blockY);
+ byte[] actual = AstcStreamCodec.DecodeLdrSrgb(compressed, width, height, footprint);
+
+ CompareRgba8(actual, expected, width, height, $"Srgb_SolidColor_{footprintType}");
+ }
+
+ [Theory]
+ [MemberData(nameof(AllFootprintTypes))]
+ public void DecompressLdrSrgb_Gradient_ShouldMatch(FootprintType footprintType)
+ {
+ (int blockX, int blockY) = AstcReferenceDecoder.ToBlockDimensions(footprintType);
+
+ int width = blockX * 2;
+ int height = blockY * 2;
+
+ byte[] pixels = new byte[width * height * 4];
+ for (int row = 0; row < height; row++)
+ {
+ for (int col = 0; col < width; col++)
+ {
+ int idx = ((row * width) + col) * 4;
+ pixels[idx + 0] = (byte)(255 * col / (width - 1));
+ pixels[idx + 1] = (byte)(255 * row / (height - 1));
+ pixels[idx + 2] = (byte)(255 - (255 * col / (width - 1)));
+ pixels[idx + 3] = 255;
+ }
+ }
+
+ byte[] compressed = AstcReferenceDecoder.CompressLdr(pixels, width, height, blockX, blockY);
+ Footprint footprint = Footprint.FromFootprintType(footprintType);
+
+ byte[] expected = AstcReferenceDecoder.DecompressLdrSrgb(compressed, width, height, blockX, blockY);
+ byte[] actual = AstcStreamCodec.DecodeLdrSrgb(compressed, width, height, footprint);
+
+ CompareRgba8(actual, expected, width, height, $"Srgb_Gradient_{footprintType}");
+ }
+
+ [Theory]
+ [MemberData(nameof(AllFootprintTypes))]
+ public void DecompressLdrSrgb_RandomNoise_ShouldMatch(FootprintType footprintType)
+ {
+ (int blockX, int blockY) = AstcReferenceDecoder.ToBlockDimensions(footprintType);
+
+ int width = blockX * 2;
+ int height = blockY * 2;
+
+ Random rng = new(42);
+ byte[] pixels = new byte[width * height * 4];
+ rng.NextBytes(pixels);
+ for (int index = 3; index < pixels.Length; index += 4)
+ {
+ pixels[index] = byte.MaxValue;
+ }
+
+ byte[] compressed = AstcReferenceDecoder.CompressLdr(pixels, width, height, blockX, blockY);
+ Footprint footprint = Footprint.FromFootprintType(footprintType);
+
+ byte[] expected = AstcReferenceDecoder.DecompressLdrSrgb(compressed, width, height, blockX, blockY);
+ byte[] actual = AstcStreamCodec.DecodeLdrSrgb(compressed, width, height, footprint);
+
+ CompareRgba8(actual, expected, width, height, $"Srgb_RandomNoise_{footprintType}");
+ }
+
///
/// Compare RGBA32 output from both decoders. The ASTC spec (Khronos Data Format
/// §C.2.18–§C.2.19) defines the entire LDR pipeline bit-exactly — endpoint and
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Ktx/KtxAstcDecoderFlatTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Ktx/KtxAstcDecoderFlatTests.cs
index c7f4e02e..0658e7a2 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Ktx/KtxAstcDecoderFlatTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Ktx/KtxAstcDecoderFlatTests.cs
@@ -20,8 +20,8 @@ public class KtxAstcDecoderFlatTests
private static readonly KtxDecoder KtxDecoder = new();
[Theory]
- [WithFile(TestTextureFormat.Ktx, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx.Astc.Rgb32_8x8)]
- public void CanDecode_Rgba32_Blocksizes(TestTextureProvider provider)
+ [WithFile(TestTextureFormat.Ktx, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx.Astc.Rgba32_8x8)]
+ public void CanDecode_Rgba32_Srgb(TestTextureProvider provider)
{
using Texture texture = provider.GetTexture(KtxDecoder);
provider.SaveTextures(texture);
@@ -88,7 +88,7 @@ public void CanDecode_Rgba32_Unorm(TestTextureProvider provider)
[WithFile(TestTextureFormat.Ktx, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx.Astc.Rgb32_sRgb_10x10)]
[WithFile(TestTextureFormat.Ktx, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx.Astc.Rgb32_sRgb_12x10)]
[WithFile(TestTextureFormat.Ktx, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx.Astc.Rgb32_sRgb_12x12)]
- public void CanDecode_Rgba32_Srgb(TestTextureProvider provider)
+ public void CanDecode_Rgb32_Srgb(TestTextureProvider provider)
{
string blockSize = BlockSizeExtractor.FromFileName(provider.InputFile);
using Texture texture = provider.GetTexture(KtxDecoder);
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcArrayDecoderTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcArrayDecoderTests.cs
index 1cfb946a..bd392e83 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcArrayDecoderTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcArrayDecoderTests.cs
@@ -35,7 +35,7 @@ public class Ktx2AstcArrayDecoderTests
/// array-layer support lands.
///
[Theory]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Array, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Array.Rgb32_Srgb_6x6_MipMap)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Array, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Array.Rgba32_sRgb_6x6_MipMap)]
public void CanDecode_MipMaps(TestTextureProvider provider)
{
int mipMapLevel = 0;
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderCubemapTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderCubemapTests.cs
index 0f258b67..e1171cdb 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderCubemapTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderCubemapTests.cs
@@ -20,7 +20,7 @@ public class Ktx2AstcDecoderCubemapTests
private static readonly Ktx2Decoder KtxDecoder = new();
[Theory]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Cubemap, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Cubemap.Rgb32_Srgb_6x6)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Cubemap, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Cubemap.Rgba32_sRgb_6x6)]
public void CanDecode_All_Faces(TestTextureProvider provider)
{
using Texture texture = provider.GetTexture(KtxDecoder);
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderFlatTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderFlatTests.cs
index 5bee5b6c..453c5034 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderFlatTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcDecoderFlatTests.cs
@@ -20,21 +20,21 @@ public class Ktx2AstcDecoderFlatTests
private static readonly Ktx2Decoder KtxDecoder = new();
[Theory]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_4x4)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_5x4)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_5x5)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_6x5)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_6x6)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_8x5)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_8x6)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_8x8)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_10x5)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_10x6)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_10x8)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_10x10)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_12x10)]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_12x12)]
- public void CanDecode_Rgba32_Blocksizes(TestTextureProvider provider)
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_4x4)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_5x4)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_5x5)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_6x5)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_6x6)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_8x5)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_8x6)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_8x8)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_10x5)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_10x6)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_10x8)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_10x10)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_12x10)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_12x12)]
+ public void CanDecode_Rgba32_Srgb(TestTextureProvider provider)
{
string blockSize = BlockSizeExtractor.FromFileName(provider.InputFile);
using Texture texture = provider.GetTexture(KtxDecoder);
@@ -102,7 +102,7 @@ public void CanDecode_Rgba32_Unorm(TestTextureProvider provider)
[WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgb32_sRgb_10x10)]
[WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgb32_sRgb_12x10)]
[WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgb32_sRgb_12x12)]
- public void CanDecode_Rgba32_Srgb(TestTextureProvider provider)
+ public void CanDecode_Rgb32_Srgb(TestTextureProvider provider)
{
string blockSize = BlockSizeExtractor.FromFileName(provider.InputFile);
using Texture texture = provider.GetTexture(KtxDecoder);
@@ -121,7 +121,7 @@ public void CanDecode_Rgba32_Srgb(TestTextureProvider provider)
}
[Theory]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgb32_Srgb_Large)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_sRgb_10x5_Large)]
public void CanDecode_Rgba32_Srgb_Large(TestTextureProvider provider)
{
using Texture texture = provider.GetTexture(KtxDecoder);
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrDecoderFlatTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrDecoderFlatTests.cs
index c6cc0d0e..f44ff702 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrDecoderFlatTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrDecoderFlatTests.cs
@@ -57,7 +57,7 @@ public void CanDecode_Astc_Sfloat_Blocksizes(TestTextureProvider provider)
/// error colour (magenta) for every texel.
///
[Theory]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Astc4x4_HdrInUnorm)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_4x4_HdrInUnorm)]
public void Decode_HdrBlocksInUnormContainer_EmitsErrorColor(TestTextureProvider provider)
{
using Texture texture = provider.GetTexture(Ktx2Decoder);
diff --git a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrInUnormTests.cs b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrInUnormTests.cs
index 16af4dd6..00b1c2b7 100644
--- a/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrInUnormTests.cs
+++ b/tests/ImageSharp.Textures.Tests/Formats/Ktx2/Ktx2AstcHdrInUnormTests.cs
@@ -25,7 +25,7 @@ public class Ktx2AstcHdrInUnormTests
private static readonly Ktx2Decoder Ktx2Decoder = new();
[Theory]
- [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Astc4x4_HdrInUnorm)]
+ [WithFile(TestTextureFormat.Ktx2, TestTextureType.Flat, TestTextureTool.ToKtx, TestImages.Ktx2.Astc.Rgba32_4x4_HdrInUnorm)]
public void Decode_HdrBlocksInUnormContainer_EmitsErrorColor(TestTextureProvider provider)
{
using Texture texture = provider.GetTexture(Ktx2Decoder);
diff --git a/tests/ImageSharp.Textures.Tests/TestImages.cs b/tests/ImageSharp.Textures.Tests/TestImages.cs
index 54278fe4..9523264a 100644
--- a/tests/ImageSharp.Textures.Tests/TestImages.cs
+++ b/tests/ImageSharp.Textures.Tests/TestImages.cs
@@ -14,7 +14,7 @@ public static class Ktx
public static class Astc
{
- public const string Rgb32_8x8 = "Flat/Astc/rgba32-srgb-8x8.ktx";
+ public const string Rgba32_8x8 = "Flat/Astc/rgba32-srgb-8x8.ktx";
public const string Rgb32_sRgb_4x4 = "Flat/Astc/rgba32-srgb-4x4-valid.ktx";
public const string Rgb32_sRgb_5x4 = "Flat/Astc/rgba32-srgb-5x4-valid.ktx";
@@ -67,20 +67,20 @@ public static class Ktx2
public static class Astc
{
// Flat textures with various block sizes
- public const string Rgba32_4x4 = "Flat/Astc/rgba32-srgb-4x4.ktx2";
- public const string Rgba32_5x4 = "Flat/Astc/rgba32-srgb-5x4.ktx2";
- public const string Rgba32_5x5 = "Flat/Astc/rgba32-srgb-5x5.ktx2";
- public const string Rgba32_6x5 = "Flat/Astc/rgba32-srgb-6x5.ktx2";
- public const string Rgba32_6x6 = "Flat/Astc/rgba32-srgb-6x6.ktx2";
- public const string Rgba32_8x5 = "Flat/Astc/rgba32-srgb-8x5.ktx2";
- public const string Rgba32_8x6 = "Flat/Astc/rgba32-srgb-8x6.ktx2";
- public const string Rgba32_8x8 = "Flat/Astc/rgba32-srgb-8x8.ktx2";
- public const string Rgba32_10x5 = "Flat/Astc/rgba32-srgb-10x5.ktx2";
- public const string Rgba32_10x6 = "Flat/Astc/rgba32-srgb-10x6.ktx2";
- public const string Rgba32_10x8 = "Flat/Astc/rgba32-srgb-10x8.ktx2";
- public const string Rgba32_10x10 = "Flat/Astc/rgba32-srgb-10x10.ktx2";
- public const string Rgba32_12x10 = "Flat/Astc/rgba32-srgb-12x10.ktx2";
- public const string Rgba32_12x12 = "Flat/Astc/rgba32-srgb-12x12.ktx2";
+ public const string Rgba32_sRgb_4x4 = "Flat/Astc/rgba32-srgb-4x4.ktx2";
+ public const string Rgba32_sRgb_5x4 = "Flat/Astc/rgba32-srgb-5x4.ktx2";
+ public const string Rgba32_sRgb_5x5 = "Flat/Astc/rgba32-srgb-5x5.ktx2";
+ public const string Rgba32_sRgb_6x5 = "Flat/Astc/rgba32-srgb-6x5.ktx2";
+ public const string Rgba32_sRgb_6x6 = "Flat/Astc/rgba32-srgb-6x6.ktx2";
+ public const string Rgba32_sRgb_8x5 = "Flat/Astc/rgba32-srgb-8x5.ktx2";
+ public const string Rgba32_sRgb_8x6 = "Flat/Astc/rgba32-srgb-8x6.ktx2";
+ public const string Rgba32_sRgb_8x8 = "Flat/Astc/rgba32-srgb-8x8.ktx2";
+ public const string Rgba32_sRgb_10x5 = "Flat/Astc/rgba32-srgb-10x5.ktx2";
+ public const string Rgba32_sRgb_10x6 = "Flat/Astc/rgba32-srgb-10x6.ktx2";
+ public const string Rgba32_sRgb_10x8 = "Flat/Astc/rgba32-srgb-10x8.ktx2";
+ public const string Rgba32_sRgb_10x10 = "Flat/Astc/rgba32-srgb-10x10.ktx2";
+ public const string Rgba32_sRgb_12x10 = "Flat/Astc/rgba32-srgb-12x10.ktx2";
+ public const string Rgba32_sRgb_12x12 = "Flat/Astc/rgba32-srgb-12x12.ktx2";
public const string Rgb32_sRgb_4x4 = "Flat/Astc/rgba32-srgb-4x4-valid.ktx2";
public const string Rgb32_sRgb_5x4 = "Flat/Astc/rgba32-srgb-5x4-valid.ktx2";
@@ -112,7 +112,7 @@ public static class Astc
public const string Rgb32_Unorm_12x10 = "Flat/Astc/rgba32-unorm-12x10-valid.ktx2";
public const string Rgb32_Unorm_12x12 = "Flat/Astc/rgba32-unorm-12x12-valid.ktx2";
- public const string Rgb32_Srgb_Large = "Flat/Astc/rgba32-10x5-flighthelmet-basecolor.ktx2";
+ public const string Rgba32_sRgb_10x5_Large = "Flat/Astc/rgba32-10x5-flighthelmet-basecolor.ktx2";
// Supercompressed textures (ZLIB)
public const string Rgb32_Unorm_4x4_Zlib1 = "Flat/Astc/Supercompressed/rgba32-unorm-4x4-zlib-1-valid.ktx2";
@@ -144,18 +144,18 @@ public static class Astc
// ASTC blocks encoded with HDR endpoint modes but wrapped in a UNORM container.
// Spec allows this; the decoder should clamp HDR output to UNORM8 range.
- public const string Astc4x4_HdrInUnorm = "Flat/Astc/Hdr/rgba32-4x4-hdr-in-unorm.ktx2";
+ public const string Rgba32_4x4_HdrInUnorm = "Flat/Astc/Hdr/rgba32-4x4-hdr-in-unorm.ktx2";
public static class Array
{
// LDR sRGB ASTC array texture with mipmaps
- public const string Rgb32_Srgb_6x6_MipMap = "Array/Astc/rgba32-6x6-mipmap.ktx2";
+ public const string Rgba32_sRgb_6x6_MipMap = "Array/Astc/rgba32-6x6-mipmap.ktx2";
}
public static class Cubemap
{
// LDR sRGB ASTC cubemap
- public const string Rgb32_Srgb_6x6 = "Cubemap/Astc/rgba32-6x6.ktx2";
+ public const string Rgba32_sRgb_6x6 = "Cubemap/Astc/rgba32-6x6.ktx2";
// HDR uncompressed cubemaps
public const string R32_Sfloat = "Cubemap/Hdr/r32-sfloat.ktx2";
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x10.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x10.png
new file mode 100644
index 00000000..951a4382
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x10.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:672be4b2816422dbfb260d503b5bfd59aa8719dd7fe5a6ad10bf7e92349d3d86
+size 428
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x5.png
new file mode 100644
index 00000000..2ba90c5f
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05c8053c5fd386c54e074a191e613782ee8ec68f21a560069fd5058ef8a468ac
+size 308
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x6.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x6.png
new file mode 100644
index 00000000..622af179
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:32fcfb523c0a6d5ef2b9f02541336ce16bd4b3b8bdc337982b8f924dedc1f0cc
+size 349
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x8.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x8.png
new file mode 100644
index 00000000..51a25dca
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:41e304f6abc15b18501d0122196fa12e3225d996cd8d155e61454f2770921980
+size 367
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x10.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x10.png
new file mode 100644
index 00000000..3b516d14
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x10.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:52d43782053bb16cc586c6a73602a77b52b7e48c1ec0651ae9bb7d565c102b53
+size 417
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x12.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x12.png
new file mode 100644
index 00000000..99f4ff44
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x12.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e041e95896786c2071b6cc8a59eea7807eaabfb1e2bd6b2fcaac9b89a2e1698e
+size 387
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_4x4.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_4x4.png
new file mode 100644
index 00000000..b4e122ab
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_4x4.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0a7266e665c5964bce2c0ebc8dc5a6787545850277c39c057d415a9aef42e315
+size 347
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x4.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x4.png
new file mode 100644
index 00000000..4e1e48ea
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x4.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:19ab251ba9aa4b6ef76a66ee644a3df73eabd4fe4952bf43d605b3db1a3a2771
+size 436
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x5.png
new file mode 100644
index 00000000..4ba54f4e
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fbba4b7017662f47d4aeb04f6cacff94b35af69cf50e8456735f05e69ba24b45
+size 358
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x5.png
new file mode 100644
index 00000000..c7590bc9
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3170c9800d1f53feddaf21234089ad159e7877636014a37bda46077cd4e71969
+size 352
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x6.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x6.png
new file mode 100644
index 00000000..04abd0a1
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:649646029fbf17cea56a2e945ca687b6771daed1cc8c99bc245f921fdbee7545
+size 331
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x5.png
new file mode 100644
index 00000000..12cb7c52
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a069b267fb8217e01362e2b2c62e4b197c7c98afcd6cd23a8281438863af96cf
+size 294
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x6.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x6.png
new file mode 100644
index 00000000..ab17ecec
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8d27d6f6fc559f12551c6488e2903502c4ee52323222dcf3d2ed2e79a33b7a52
+size 382
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x8.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x8.png
new file mode 100644
index 00000000..2fb4d9e7
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9426418902832ecd0f6a6a29288613a1e7f08b54857329aff9f90349558764db
+size 321
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb.png
new file mode 100644
index 00000000..a8b748b0
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9571a45fd52a93e0cf6cc8094b24642c5d503b5cd2eae330835bd6db5ef5a91e
+size 82278
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png
deleted file mode 100644
index a5285512..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:eb604cac3ad29ce767ae9054d72fb5fe431a7c864c037d569511db63e860dec5
-size 430
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png
deleted file mode 100644
index 3a8b8be4..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:023184c99624b412fe9989509222e75f861c890d68972f3764cc9f0dd42e48f1
-size 310
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png
deleted file mode 100644
index dd4e32ab..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d91d6178b73d37fc91d61523002fd9f24428dc22347076fe5b91d99109b50034
-size 350
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png
deleted file mode 100644
index f8d8bb4e..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:336338bdca897ffeb70b2dfd6f44fcb215e234ae48d50c7d0d84e5f0d8ab6f5d
-size 373
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png
deleted file mode 100644
index 43b205c9..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3084bcf59ef7f423d6b01a7896a1d6f5ce912067678caa15bac0020d060af096
-size 422
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png
deleted file mode 100644
index c508b7f4..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:fed612c92b1bbba3aea038a672d4ddbd7f6c2bd12f02d9da4ea23d71aa4a83c0
-size 372
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png
deleted file mode 100644
index b5883c0b..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:c43ebde41d94c67c6a3fb2dd71fc12852d0c889cd755b64abf7ce9b08131d364
-size 358
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png
deleted file mode 100644
index 0e5b8fd3..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:af8672ada2e64ea02a9902372139130f641cd92f9ffac57da1293474f7b9527a
-size 441
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png
deleted file mode 100644
index 04a36c94..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:41600fa42571dfdb2a790c1afcfa4a0a6714ed27290f5301f732310fee436894
-size 354
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png
deleted file mode 100644
index 42b247e5..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:a481fc7dc3fb0531b061af3da9f5db84016cfa297d37672b68e7732fc3501099
-size 347
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png
deleted file mode 100644
index a72993ac..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3630216ba8c328036e3349a91df4716b705fde4edd680c28c7cbb2b71209bebc
-size 341
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png
deleted file mode 100644
index 17479a2a..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:9b9efa23cf5d6d078c3e610299246d951c1ab8d02aa700baef7dc97cce745a9d
-size 292
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png
deleted file mode 100644
index 4167013b..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:6ff941eb5e5378740897a98d9bf253e4b04694cb8dd8be7c1110b15cf08c6d3c
-size 385
diff --git a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png b/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png
deleted file mode 100644
index be8bd493..00000000
--- a/tests/Images/ReferenceOutput/Ktx/KtxAstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7a2a25957c869e4ffed4962c3d4912907804bdc7fbc44a2c78e4bf35aea58834
-size 328
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negX.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negX.png
index 1d648941..dbde494b 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negX.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negX.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7ecb8859ddf59de30003bcf0183dda89af75103a195db09d61027d222ce503cf
+oid sha256:a4296744239a10d990369fc366415901ca5cc767f8b58bf2004e5e0b2835d5ac
size 4456250
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negY.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negY.png
index 926d79da..653b279e 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negY.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negY.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:25ab0d83c9a0bd320a6a42ff3c767933b02814dc57e16c01de9a2a9b8a027c1d
-size 4519750
+oid sha256:8615a15cfbac32d0c440520e70af99bd1af3c64b6651f4dffe990007afe470d5
+size 4520170
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negZ.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negZ.png
index 64e30172..49286a16 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negZ.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_negZ.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:5d339200edcaff4225ecf17d292ec45329b37220f65e37a69d4de2187b7211cf
-size 4181844
+oid sha256:2685be16e227bd073226a723de98e43ae88d637825fdeba5ea8b51408bd0cfd0
+size 4188564
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posX.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posX.png
index eaf11b74..27afd652 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posX.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posX.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1142e18ea017435fd9dc2290937f1a7c66e5e31644e5c6ac9fee918d900bdf20
+oid sha256:fca3cb243546b93d03b2915bb8aacad79356ea94e6b310eb69519c3b67423973
size 4451226
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posY.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posY.png
index 76b5a710..03064d85 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posY.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posY.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c4ab628c5050ec7f6508cd33f769efe1efc5f568a1f113833670c22d9aa2873e
-size 2786250
+oid sha256:ab4da315d9108628612732ebff930439253d3ac31509a4fb058a9f333b508c33
+size 2820362
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posZ.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posZ.png
index e1f5511e..87673d5f 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posZ.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderCubemapTests/CanDecode_All_Faces_posZ.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:96bbd22a1f253371343ec204ef0b2aae6150b83a53d499cea470ecbb259334c0
-size 3902912
+oid sha256:d8c8d2fc2845c320370edd8ee4abf819809b82a8ce8f1d44b1afd644b9091c8d
+size 3910606
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x10.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x10.png
new file mode 100644
index 00000000..951a4382
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x10.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:672be4b2816422dbfb260d503b5bfd59aa8719dd7fe5a6ad10bf7e92349d3d86
+size 428
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x5.png
new file mode 100644
index 00000000..2ba90c5f
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:05c8053c5fd386c54e074a191e613782ee8ec68f21a560069fd5058ef8a468ac
+size 308
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x6.png
new file mode 100644
index 00000000..622af179
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:32fcfb523c0a6d5ef2b9f02541336ce16bd4b3b8bdc337982b8f924dedc1f0cc
+size 349
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x8.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x8.png
new file mode 100644
index 00000000..51a25dca
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_10x8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:41e304f6abc15b18501d0122196fa12e3225d996cd8d155e61454f2770921980
+size 367
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x10.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x10.png
new file mode 100644
index 00000000..3b516d14
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x10.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:52d43782053bb16cc586c6a73602a77b52b7e48c1ec0651ae9bb7d565c102b53
+size 417
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x12.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x12.png
new file mode 100644
index 00000000..99f4ff44
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_12x12.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e041e95896786c2071b6cc8a59eea7807eaabfb1e2bd6b2fcaac9b89a2e1698e
+size 387
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_4x4.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_4x4.png
new file mode 100644
index 00000000..b4e122ab
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_4x4.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0a7266e665c5964bce2c0ebc8dc5a6787545850277c39c057d415a9aef42e315
+size 347
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x4.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x4.png
new file mode 100644
index 00000000..4e1e48ea
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x4.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:19ab251ba9aa4b6ef76a66ee644a3df73eabd4fe4952bf43d605b3db1a3a2771
+size 436
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x5.png
new file mode 100644
index 00000000..4ba54f4e
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_5x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fbba4b7017662f47d4aeb04f6cacff94b35af69cf50e8456735f05e69ba24b45
+size 358
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x5.png
new file mode 100644
index 00000000..c7590bc9
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3170c9800d1f53feddaf21234089ad159e7877636014a37bda46077cd4e71969
+size 352
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x6.png
new file mode 100644
index 00000000..04abd0a1
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_6x6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:649646029fbf17cea56a2e945ca687b6771daed1cc8c99bc245f921fdbee7545
+size 331
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x5.png
new file mode 100644
index 00000000..12cb7c52
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a069b267fb8217e01362e2b2c62e4b197c7c98afcd6cd23a8281438863af96cf
+size 294
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x6.png
new file mode 100644
index 00000000..ab17ecec
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8d27d6f6fc559f12551c6488e2903502c4ee52323222dcf3d2ed2e79a33b7a52
+size 382
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x8.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x8.png
new file mode 100644
index 00000000..2fb4d9e7
--- /dev/null
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgb32_Srgb_8x8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9426418902832ecd0f6a6a29288613a1e7f08b54857329aff9f90349558764db
+size 321
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x10.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x10.png
deleted file mode 100644
index 3e12fe9f..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x10.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:9aa909cd938fd48c16e7130f049bce4a7c408bd21bfe7c3585ad793878ba2aa6
-size 91793
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x5.png
deleted file mode 100644
index ad1fe5bf..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d60af65486078f1c34bb39a94447e3b573e3f8d5a575470bda96100f8385bea2
-size 112255
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x6.png
deleted file mode 100644
index 7e39476f..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x6.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2992323d4e2711850d3b52afd044c88a66ff9ec4c370b17ff00702ca5d9752b6
-size 108706
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x8.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x8.png
deleted file mode 100644
index 819a0c03..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_10x8.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2ba31fb3375ff7b24fe9646c5d71c11842e652899275641139435c40ece2ec26
-size 104952
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_12x10.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_12x10.png
deleted file mode 100644
index 0803e324..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_12x10.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:493f03cd85b3c56e86b9bb8e72970c896c349bf3f0dd84b9affdf1c9dbdafd81
-size 89471
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_12x12.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_12x12.png
deleted file mode 100644
index c5898254..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_12x12.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2c9720ed8162a296c721ed1d76f1fc9ff45371a391ba569f8ba3cf3bbf4ccd23
-size 85067
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_4x4.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_4x4.png
deleted file mode 100644
index e45b50f7..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_4x4.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:25cfff9e30323cdb774c934484b0326456f4625dccca6241561dce0d40483f85
-size 146099
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_5x4.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_5x4.png
deleted file mode 100644
index d592680b..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_5x4.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:055de2e70185b4f709734b246c4bd5e0fe119f4f30df2370ff6d0e93d56c72cc
-size 139970
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_5x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_5x5.png
deleted file mode 100644
index 03834add..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_5x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:210d53ec40cc946f56d30f6bffd1b67645fa6f31c0ef93d750df710a8d84faa3
-size 136175
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_6x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_6x5.png
deleted file mode 100644
index 617da2d9..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_6x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:91fdb99f06874e13c6f38e705294ead2ff436d807f38f481da317b9512101d40
-size 127969
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_6x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_6x6.png
deleted file mode 100644
index ca12dbc1..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_6x6.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:325a10403bab9a0d73fbcc6bae3ec20844038decc52886e510fbf75ba93458ce
-size 127785
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x5.png
deleted file mode 100644
index 3f509ee8..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x5.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b013f2db1e6e98dc78464ae4fb65e848ecb3805b4d91413f350fc8c11eca681c
-size 119823
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x6.png
deleted file mode 100644
index 97a99702..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x6.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:4145368bd16baa5aad373468057473a9c1c8cd9c32a889c27c4dbbd6b86a92b1
-size 114913
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x8.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x8.png
deleted file mode 100644
index 34c720f1..00000000
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Blocksizes_8x8.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:2ab0112b118611e9121c687b5115f21c6a2f467d659f0c96a919036e6a9e9d81
-size 110451
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png
index a5285512..29092b8e 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x10.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:eb604cac3ad29ce767ae9054d72fb5fe431a7c864c037d569511db63e860dec5
-size 430
+oid sha256:aea57b2a37ec125848a0a9ad49103e0ccea51bc617697ba1af1d659c9fa9a6f2
+size 91192
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png
index 3a8b8be4..bc69d093 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x5.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:023184c99624b412fe9989509222e75f861c890d68972f3764cc9f0dd42e48f1
-size 310
+oid sha256:5af59471945997a8f2ba46b9f41b7bb53d3fcd2d3a04787deb256ddf1411b375
+size 111984
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png
index dd4e32ab..44b6c446 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x6.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d91d6178b73d37fc91d61523002fd9f24428dc22347076fe5b91d99109b50034
-size 350
+oid sha256:466b704a55288c08f96e66312929ae395589ed44de95c7e34a47dc443a85c9bf
+size 108511
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png
index f8d8bb4e..d0a06e44 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_10x8.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:336338bdca897ffeb70b2dfd6f44fcb215e234ae48d50c7d0d84e5f0d8ab6f5d
-size 373
+oid sha256:e9681af274af66cf7fee75de3e7420e532195155ec77c7e42dd7a799eb38534b
+size 104550
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png
index 43b205c9..256d6c7d 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x10.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3084bcf59ef7f423d6b01a7896a1d6f5ce912067678caa15bac0020d060af096
-size 422
+oid sha256:1013d9fa5275dd0265276f7ba30f42c070b888ed02c6e1fa5096fd4d97096a59
+size 89166
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png
index c508b7f4..003172d9 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_12x12.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fed612c92b1bbba3aea038a672d4ddbd7f6c2bd12f02d9da4ea23d71aa4a83c0
-size 372
+oid sha256:327f6b3712b21c90a0c0e3e8228404b900fab5caa9dbb9ccf44912efb8f2b380
+size 84813
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png
index b5883c0b..fb0cc376 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_4x4.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c43ebde41d94c67c6a3fb2dd71fc12852d0c889cd755b64abf7ce9b08131d364
-size 358
+oid sha256:ed667f473aa9a831e23f3d50913007ba9e5bf71e1505225742ffc166d03b1c93
+size 145825
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png
index 0e5b8fd3..43b1c2b3 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x4.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:af8672ada2e64ea02a9902372139130f641cd92f9ffac57da1293474f7b9527a
-size 441
+oid sha256:796f1fc7688d86175f6ef5efaa3367d9872b3cf6301a9cee8bfaf15eec443d35
+size 139510
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png
index 04a36c94..f4d5bb2c 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_5x5.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:41600fa42571dfdb2a790c1afcfa4a0a6714ed27290f5301f732310fee436894
-size 354
+oid sha256:d3816117e59f07096d9dcd0aa9993d84fffd1aaed2b0dd0862002272fc66094e
+size 135833
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png
index 42b247e5..02927c88 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x5.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a481fc7dc3fb0531b061af3da9f5db84016cfa297d37672b68e7732fc3501099
-size 347
+oid sha256:ad6c84703c2cd928011772d7307a5c7263b6c5d57d0008bbcf9baf4420191366
+size 127606
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png
index a72993ac..9c818fa6 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_6x6.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3630216ba8c328036e3349a91df4716b705fde4edd680c28c7cbb2b71209bebc
-size 341
+oid sha256:5df4127981d416d6e02d50d233532a6811e800afcd2240b68724678af3f321c8
+size 127408
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png
index 17479a2a..726b0a82 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x5.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9b9efa23cf5d6d078c3e610299246d951c1ab8d02aa700baef7dc97cce745a9d
-size 292
+oid sha256:324e6fbbe483a0117558c6c179936d2dad2e3800938b591f5ff8b1a1270318ea
+size 119358
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png
index 4167013b..f6cd1d24 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x6.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:6ff941eb5e5378740897a98d9bf253e4b04694cb8dd8be7c1110b15cf08c6d3c
-size 385
+oid sha256:8c858980b43944441c4a4e1a83f37dec79fe0d3bd391b2b336b54de54addc54d
+size 114463
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png
index be8bd493..b5d7a138 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_8x8.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7a2a25957c869e4ffed4962c3d4912907804bdc7fbc44a2c78e4bf35aea58834
-size 328
+oid sha256:3fe064e5fd524238b3b00e50b1dd839dcd32726a68d69f8ee1965d97eacbaa21
+size 110185
diff --git a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_Large.png b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_Large.png
index 06c534f0..c3d4a6a3 100644
--- a/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_Large.png
+++ b/tests/Images/ReferenceOutput/Ktx2/Ktx2AstcDecoderFlatTests/CanDecode_Rgba32_Srgb_Large.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:43894d08390a5fee9a75e0f1846c37c2027af566d1bced1d3593a9ed58eab73f
+oid sha256:7ec550e3dc2007ac6c075a2fe46670734d95ad08acbe13e1b3aea5085aba1082
size 1450642