Skip to content

Implement ASTC decoding with integrated decoder#37

Open
Erik-White wants to merge 6 commits intoSixLabors:mainfrom
Erik-White:implement-astc-decoding
Open

Implement ASTC decoding with integrated decoder#37
Erik-White wants to merge 6 commits intoSixLabors:mainfrom
Erik-White:implement-astc-decoding

Conversation

@Erik-White
Copy link
Contributor

@Erik-White Erik-White commented Feb 27, 2026

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

Adds support for decoding ASTC compressed KTX and KTX2 textures, including both LDR and HDR modes. Implementing an ASTC decoder was a major challenge, but I was able to base a lot of it on existing C++ implementations from ARM and Khronos.

ASTC is very complex, with different combinations of modes, block sizes and partitions, so I'm afraid that the diff is very large.

I have added tests that compare the output vs the ARM C++ implementation to ensure correctness (see ImageSharp.Textures.Astc.Reference.Tests), however this had to be a separate test project because the C# bindings wrapper (AstcEncoderCSharp) only supports .NET10.

Decoding speed compares favorably to the reference decoder, but I couldn't include those benchmarks here, again due to the .NET10 issue. You can find some comparison benchmarks in my separate implementation: https://github.com/Erik-White/AstcSharp

KTX1 has support for ASTC, but I couldn't find a tool to create test images and had a difficult time sourcing test data. So the tests are quite limited for v1, but much better for KTX2.

Limitations

  • No support for 3D ASTC block types (4x4x4 etc)
  • No encoding

Test data

Everything used is either created by myself, or sourced from
https://github.com/KhronosGroup/KTX-Software (Apache 2.0 license)
https://github.com/KhronosGroup/KTX-Software-CTS (Apache 2.0 license)
https://github.com/ARM-software/astc-encoder (Apache-2.0 license)

@Erik-White Erik-White marked this pull request as draft February 27, 2026 13:00
@Erik-White Erik-White marked this pull request as ready for review February 27, 2026 16:56
*.dds filter=lfs diff=lfs merge=lfs -text
*.ktx filter=lfs diff=lfs merge=lfs -text
*.ktx2 filter=lfs diff=lfs merge=lfs -text
*.astc filter=lfs diff=lfs merge=lfs -text
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This keeps getting overwritten by a target that copies gitattributes from the shared project, so I will need to update it there as well

return (ulong)FloatHelper.PackFloatToFloat16(vector.X)
| ((ulong)FloatHelper.PackFloatToFloat16(vector.Y) << 16)
| ((ulong)FloatHelper.PackFloatToFloat16(vector.Z) << 32)
| ((ulong)FloatHelper.PackFloatToFloat16(vector.W) << 48);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting to unit could result in an overflow when shifting. Widening to a long allows for correct shifting without overflow

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AstcEncoderCSharp only supports .NET10 so I kept this in a separate test project. It is very useful to be able to compare output directly with the ARM implementation.

using SixLabors.ImageSharp.Textures.Tests.TestUtilities.Attributes;
using SixLabors.ImageSharp.Textures.Tests.TestUtilities.TextureProviders;

namespace SixLabors.ImageSharp.Textures.Tests.Formats.Astc.HDR;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't quite sure whether to use uppercase or title case (HDR vs Hdr) for this namespace. Title case is mostly used elsewhere, but there are some excepts like IO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant