# astcenc ships instruction-set binaries, and SVE builds must match the CPU

> astcenc is Arm's command line compressor and codec library for the ASTC texture format, used across OpenGL, OpenGL ES and Vulkan. What matters in the README is not the format description but the distribution model: separate binaries per SIMD level on Windows and Linux, a universal binary on macOS, and a warning that the Arm SVE builds are not length-agnostic and must match the host CPU.

**ARM-software/astc-encoder** — The Arm ASTC Encoder, a compressor command line tool and codec library for the Adaptive Scalable Texture Compression image format.

- Repository: https://github.com/ARM-software/astc-encoder
- Website: https://developer.arm.com/mobile-graphics-and-gaming
- Stars: 1,304 · Forks: 289
- Language: C++
- License: Apache-2.0
- Published: 2026-10-17 · Updated: 2026-10-17 · Language: en
- Canonical page: https://hysenlabs.com/projects/arm-software-astc-encoder

## The format is the reason the tool has presets

ASTC was developed by Arm and AMD and has been adopted as an official extension to the OpenGL, OpenGL ES and Vulkan graphics APIs. The README's argument for it is two-dimensional: image quality at a given bitrate, and the format and bitrate flexibility available to content creators.

That flexibility is the important half. ASTC does not define one compression format with one bitrate. It defines a family of block footprints, and the content creator picks one. The encoder supports all of the ASTC block sizes and compression modes, ranging from 0.89 bits per pixel up to 8 bits per pixel.

So the decision an artist makes is not file format but bits per pixel, expressed as a footprint like 6x6. The example in the README compresses an image with a 6x6 footprint, which the README states works out to 3.56 bits per pixel. A 5x5 footprint, used in the quality measurement example, is cheaper again and visibly lossier.

That is why a dedicated encoder exists at all. Choosing the footprint per asset, normal maps and UI atlases do not want the same number of bits per pixel, and a game that bakes one setting for everything either wastes memory or loses quality.

The format also has profile layers, and the encoder supports all three the specification allows: a 2D low dynamic range profile, a 2D low and high dynamic range profile, and a full profile covering 2D and 3D in both. Input formats span BMP, JPEG, PNG and TGA for low dynamic range and EXR and HDR for high, with a subset of image data wrapped in DDS and KTX containers accepted and KTX as an output format.

## Four compression modes and a mirrored set for decoding

The mode flags are where most mistakes happen, because there are four of them and they encode two independent choices.

Compression uses `-cl`, `-cs`, `-ch` or `-cH`. The `-cl` mode uses the linear LDR color profile and `-cs` uses the sRGB LDR color profile. The `-ch` mode uses the HDR color profile tuned for HDR RGB and LDR alpha, while `-cH` uses the HDR profile tuned for HDR RGBA.

The `l` and `s` modes select linear or sRGB LDR, while `h` and `H` select two HDR profiles with different alpha handling.

Decompression mirrors it with a `d` prefix: `-dl`, `-ds`, `-dh` and `-dH`.

A single image is compressed with a profile flag, a footprint and a preset:

```
astcenc -cl example.png example.astc 6x6 -medium
```

Decompression takes the profile flag and an output format instead:

```
astcenc -dh example.astc example.exr
```

The README notes something about the decode modes that is worth knowing before you script around them. The modes mirror the compression options but use a `d` prefix, and for decompression there is no difference between the two HDR modes: both are provided simply to maintain symmetry across operations.

That is a good example of a tool documenting its own inconsistency rather than leaving you to discover that `-dh` and `-dH` are interchangeable.

There is also a related flag for precision. If the decoded result will be limited to UNORM8 by the decode mode extensions, the README recommends adding `-decode_unorm8`, because it makes the compressor use the correct rounding rules when choosing encodings.

## Quality presets and the PSNR number

The compression time and quality tradeoff is controlled by six named presets: `exhaustive`, `verythorough`, `thorough`, `medium`, `fast` and `fastest`.

The names are unusual in that they mix a quality word with a speed word in one identifier, which takes a moment to parse. `exhaustive` is the slowest and presumably best, `fastest` is the other end. The README's guidance is that `-medium` gives reasonable image quality for relatively fast compression speed and is a good starting point.

Then there is the measurement, which is the feature that separates this from a simple texture converter. The encoder reports the compression time and the Peak Signal-to-Noise Ratio between the input image and the compressed output, and the quality review modes mirror the compression and decoding flags with a `t` prefix:

```
astcenc -tl example.png example.tga 5x5 -thorough
```

That example is described as equivalent to using the LDR color profile and a 5x5 block size to compress, so it produces a compressed output to measure rather than a deliverable.

This is what makes astcenc usable in an asset pipeline. Anyone can produce an ASTC file. Compression-time and PSNR reporting lets creators compare changes to a footprint deliberately across a project.

The documentation pointer is split in two: a format overview for a quick introduction and the Khronos Data Format Specification for all the details. The encoder's own change log is in `Docs/ChangeLog-5x.md`.

## Seven binaries on Windows and Linux, one on macOS

The binary distribution is unusual and worth reading carefully, because the wrong choice is a crash or a large performance loss rather than an error message.

On Windows and Linux the builds are provided as multiple binaries, each tuned for a specific SIMD instruction set. For x86-64 there are three, in order of increasing performance: `astcenc-sse2` using SSE2, `astcenc-sse4.1` using SSE4.1 and POPCNT, and `astcenc-avx2` using AVX2, SSE4.2, POPCNT and F16C.

The SSE2 build works on every x86-64 machine but is the slowest of the three. The other two require instruction sets that are not universally available, and each step gains about 15% more performance.

For Arm there are three more, in increasing order: `astcenc-sve_256` using 256-bit SVE, `astcenc-sve_128` using 128-bit SVE, and `astcenc-neon` using NEON.

Then comes the caveat that decides which one you run on a server. The Arm Scalable Vector Extensions allow CPUs to have a variable vector length, and the astcenc implementation is not written in a length-agnostic style, so it requires the binary to match the vector length on the host CPU.

That is a real constraint on any fleet. A fleet of Arm machines with different vector widths needs the matching binary for each machine.

macOS avoids the problem by shipping a single universal binary called `astcenc`, which lets the OS automatically use the correct variant for the host. Three architecture slices are provided: `x86_64` uses the SSE4.1 build, `x86_64h` uses the AVX2 build, and `arm64` uses the NEON build.

The `x86_64h` slice is the one to notice because it uses the AVX2 build.

## Pick a release tag, not main

The repository branches section is short and unusually candid about what each branch is for.

The `main` branch is an active development branch for the compressor. It aims to be stable for the latest major release series, but since it is used for ongoing development, the README says to expect some volatility and recommends using the latest stable release tag for production development.

The `4.x` branch is the older stable line, no longer under active development, but still supported and still receiving back-ported bug fixes.

Older releases are no longer available as a release branch, though official releases remain available by git tag, and developers on an older version are advised to migrate to the latest 5.x stable tag.

Any other branches are development branches for new features or optimisations, described as interesting to play with but transient and unstable.

That is a clear support policy stated in five sentences, and it tells you two things. There is a maintained back-port line, which matters if you are on 4.x and cannot move. And `main` is not the place to pin.

The release history matches the current line: 5.5.0 on 2026-06-09, 5.6.0 on 2026-07-01 and 5.7.0 on 2026-07-31, with the last push on 2026-10-15. So the 5.x line is actively developed and `main` is ahead of it.

Prebuilt binaries for the stable releases are on the GitHub Releases page, 64-bit only, for Windows, macOS and Linux. The licence is Apache 2.0, and the README states that downloading any component from the repository means you accept the terms in LICENSE.txt.

## Conclusion

Adopt astcenc if you are shipping GPU textures and want to choose the block footprint and quality preset yourself, since that choice is the whole point of the format. Skip it if you only need one-time asset compression through an engine's own pipeline. Verify first which binary matches your CPU, because the Windows and Linux builds are separate executables per instruction set and each Arm SVE binary must match the host CPU's vector length.

## FAQ

### How do I compress an image with astcenc?

Use one of the compression modes `-cl`, `-cs`, `-ch` or `-cH`, then the input, output, block footprint and a quality preset, for example `astcenc -cl example.png example.astc 6x6 -medium`. The four modes cover linear LDR, sRGB LDR, and two HDR profiles differing in how alpha is handled.

### Which astcenc binary should I use?

On Windows and Linux pick the build matching your CPU. The x86-64 choices are `astcenc-sse2`, `astcenc-sse4.1` and `astcenc-avx2`; the Arm choices, in increasing performance order, are `astcenc-sve_256`, `astcenc-sve_128` and `astcenc-neon`. SVE builds must match the host CPU vector length. macOS ships one universal `astcenc` binary.

### How do I know whether compression hurt image quality?

Use the `-tl`, `-ts`, `-th` or `-tH` measurement modes, for example `astcenc -tl example.png example.tga 5x5 -thorough`. The encoder reports the compression time and the PSNR between the input and the compressed output, and the quality presets range from `exhaustive` to `fastest`.

## Sources

- [ARM-software/astc-encoder on GitHub](https://github.com/ARM-software/astc-encoder)
- [License: Apache-2.0](https://github.com/ARM-software/astc-encoder/blob/main/LICENSE)
- [Project website](https://developer.arm.com/mobile-graphics-and-gaming)
- [README](https://github.com/ARM-software/astc-encoder/blob/main/README.md)
- [Releases](https://github.com/ARM-software/astc-encoder/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/arm-software-astc-encoder
