ARM-software/astc-encoder

Question about bizarre differences between `-ts` vs `-ds`

Closed this issue · 3 comments

Hi, I am working on implementing my custom ASTC decoder for a special purpose and comparing my results against the output of astcenc. After fixing a bunch of bit manipulation errors I caused, I got stuck investigating 0.1% of the blocks that decode to non-sense colors. I narrowed the problem to the fact that the astcenc -ts option produces a slightly different .png result than astcenc -ds. These are the scenarios:

src=src.png
dst_astc=ref.astc
dst_ref=ref.png

# This works. My decoder output is bit-exact.
astcenc -cs $src $dst_astc 8x8 -thorough -j 1
astcenc -ds $dst_astc $dst_ref -j 1

# This does not work. My decoder output differs by 0.1% of the time.
astcenc -ts $src $dst_ref 8x8 -thorough -j 1

My decoder takes dst_astc as an input and compares the decoded result against dst_ref.

I printf'd const uint8_t* bp = data + offset; in astcenc_entry.cpp and occasionally -ts flag produces random-looking bytes. Meanwhile, the output of the -ds option matches exactly what my decoder read from the .astc file.

I pulled and built astcenc from b0ca5831326683176a041c0f1d29afbaf8d447b3 (Jan 1, 2024).

(Edited for clarity)

To make astcenc return the same value for both -ts and -cs, you will need to run the -cs pass with the -decode_unorm8 option specified. Without this you will get LSB rounding differences in the alpha channel. The decode_unorm8 mode is automatically inferred for -ts because it knows the decompressed output is an 8-bit png, but we can't do that inference for -cs so it's defaulting to decode_float16 unless you provide the option.

If you still have issues after that please provide a failing image that reproduces the issue and I can take a look. The behavior above should only cause LSB bit differences, so "totally random-looking bytes" sounds like a different problem.

Footnote: The fact that sRGB alpha is specified to decode to decode_float16, when RGB decodes to decode_unorm8, is likely a bug in the Khronos Data Format specification. We currently implement the specified behavior, but the upstream spec may change here (so alpha would become decode_unorm8 by default for sRGB images).

Resolved offline - not a compressor issue.