From e2dad3e15e40636ad58c4db0d7d6071bc0971291 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Thu, 7 May 2026 10:14:42 +0100 Subject: [PATCH 1/3] Update OSS-Fuzz build script --- Source/Fuzzers/build.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Fuzzers/build.sh b/Source/Fuzzers/build.sh index 5a2d588e7..de1da602a 100755 --- a/Source/Fuzzers/build.sh +++ b/Source/Fuzzers/build.sh @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # ---------------------------------------------------------------------------- -# Copyright 2020-2021 Arm Limited +# Copyright 2020-2026 Arm Limited # Copyright 2020 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may not @@ -20,12 +20,12 @@ # This script is invoked by oss-fuzz from /Source/ -# Generate a dummy version header (normally built by CMake variable expansion) +# Generate a dummy version header (normally built by CMake) echo "#pragma once" > astcenccli_version.h echo "#define VERSION_STRING \"0.0.0\"" >> astcenccli_version.h echo "#define YEAR_STRING \"2021\"" >> astcenccli_version.h -# Build the core project for fuzz tests to link against +# Build codec library for source in ./*.cpp; do BASE="${source##*/}" BASE="${BASE%.cpp}" @@ -36,20 +36,20 @@ for source in ./*.cpp; do -DASTCENC_SSE=0 \ -DASTCENC_AVX=0 \ -DASTCENC_POPCNT=0 \ - -I. -std=c++14 -mfpmath=sse -msse2 -fno-strict-aliasing -O0 -g \ + -I. -std=c++17 -mfpmath=sse -msse2 -fno-strict-aliasing -g \ $source \ -o ${BASE}.o done ar -qc libastcenc.a *.o -# Build project local fuzzers +# Build fuzzers for fuzzer in ./Fuzzers/fuzz_*.cpp; do $CXX $CXXFLAGS \ -DASTCENC_SSE=0 \ -DASTCENC_AVX=0 \ -DASTCENC_POPCNT=0 \ - -I. -std=c++14 $fuzzer $LIB_FUZZING_ENGINE ./libastcenc.a \ + -I. -std=c++17 $fuzzer $LIB_FUZZING_ENGINE ./libastcenc.a \ -o $OUT/$(basename -s .cpp $fuzzer) done From e843b853a25c8fb0b21781c065812b2df8b06c27 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Thu, 7 May 2026 10:32:00 +0100 Subject: [PATCH 2/3] Update OSS-Fuzz usage notes --- Docs/Testing.md | 5 +-- Docs/TestingOSSFuzz.md | 69 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 Docs/TestingOSSFuzz.md diff --git a/Docs/Testing.md b/Docs/Testing.md index 246161881..a6d8f0446 100644 --- a/Docs/Testing.md +++ b/Docs/Testing.md @@ -134,13 +134,14 @@ Run test commands through Valgrind: valgrind --tool=memcheck --track-origins=yes -# OSS Fuzz +# OSS-Fuzz ASTC-Encoder has been integrated into the Google OSS-Fuzz program, which performs API fuzz testing on a Google-hosted CI infrastructure. Our OSS-Fuzz test harnesses can be found in the -[/Source/Fuzzers](../Source/Fuzzers/) directory. +[/Source/Fuzzers](../Source/Fuzzers/) directory, and we have some short +[documentation](TestingOSSFuzz.md) about how to run the fuzzers locally. The OSS-Fuzz Project is hosted on GitHub at [google/oss-fuzz][1]. diff --git a/Docs/TestingOSSFuzz.md b/Docs/TestingOSSFuzz.md new file mode 100644 index 000000000..f0114aefe --- /dev/null +++ b/Docs/TestingOSSFuzz.md @@ -0,0 +1,69 @@ +# Testing OSS-Fuzz + +ASTC-Encoder has been integrated into the Google OSS-Fuzz program, which +performs API fuzz testing on a Google-hosted CI infrastructure. + +This page is a set of summary instructions explaining how to locally reproduce +failures reported by OSS-Fuzz on a Linux machine. Full documentation is +provided by the OSS-Fuzz project [documentation pages][1]. + +[1]: https://google.github.io/oss-fuzz/ + +## Prerequisites + +Install Docker: + +```sh +sudo apt install docker.io +sudo usermod -aG docker $USER +``` + +You will need to log out and log in again for the group changes to take effect. + +# Running Python-based CLI functional tests + +Checkout the OSS-Fuzz project: + +```sh +git clone --depth=1 https://github.com/google/oss-fuzz.git +cd oss-fuzz +``` + +Download the standard Docker images with the tools pre-integrated: + +```sh +python3 infra/helper.py pull_images +``` + +Build the Docker image and the fuzzers for astcenc. + +> [!NOTE] +> Fuzzers are built for a specific sanitizer, so you will need to build and run +> the fuzzers multiple times if you want coverage of both ASAN and UBSAN. + +```sh +python3 infra/helper.py build_image astc-encoder + +# Build using clean checkout in the container +python3 infra/helper.py build_fuzzers astc-encoder + +# Build using local checkout mounted into the container +python3 infra/helper.py build_fuzzers astc-encoder /mnt/c/work/projects/astcenc/Source --sanitizer +``` + +Run a reproducer testcase downloaded from OSS Fuzz: + +```sh +python3 infra/helper.py reproduce astc-encoder +``` + +Sometimes reproducers are intermittent and do not always reproduce. Running the +the test scenario in a loop can be a useful way to try and make it reproduce. + +```sh +while python3 infra/helper.py reproduce astc-encoder ; do :; done +``` + +- - - + +_Copyright © 2026, Arm Limited and contributors._ From 840d3c752ab6dda6ac4073e43e142b371f8970ee Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Thu, 7 May 2026 10:32:15 +0100 Subject: [PATCH 3/3] Clamp negative texel values when storing to unorm8 output Prior to this change decompressing a HDR void-extent block that contained a negative color would produce a corrupt color output when stored into a unorm8 output image. Other HDR block types are unaffected, because they cannot encode negative values. This changes clamps negative values to zero before storing them when the output format is unorm8. Fixes #611. --- Docs/ChangeLog-5x.md | 12 ++++++++++++ Source/astcenc_image.cpp | 13 ++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Docs/ChangeLog-5x.md b/Docs/ChangeLog-5x.md index d9ed6ce2d..eedf9c46f 100644 --- a/Docs/ChangeLog-5x.md +++ b/Docs/ChangeLog-5x.md @@ -6,6 +6,18 @@ release of the 5.x series. All performance data on this page is measured on an Intel Core i5-9600K clocked at 4.2 GHz, running `astcenc` using AVX2 and 6 threads. + +## 5.5.0 + +**Status:** In development. + +The 5.5.0 release is a minor maintenance release. + +* **General:** + * **Bug fix:** Add missing low-clamp when storing decompressed HDR data into + a UNORM8 image. Prior to this fix, output colors would be incorrect if a + HDR void-extent block contained a negative FP16 color value. + ## 5.4.0 diff --git a/Source/astcenc_image.cpp b/Source/astcenc_image.cpp index 079f69f19..b55a6f8eb 100644 --- a/Source/astcenc_image.cpp +++ b/Source/astcenc_image.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 // ---------------------------------------------------------------------------- -// Copyright 2011-2024 Arm Limited +// Copyright 2011-2026 Arm Limited // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy @@ -388,10 +388,13 @@ void store_image_block( vfloat data_b(blk.data_b + idx); vfloat data_a(blk.data_a + idx); - vint data_ri = float_to_int_rtn(min(data_r, 1.0f) * 255.0f); - vint data_gi = float_to_int_rtn(min(data_g, 1.0f) * 255.0f); - vint data_bi = float_to_int_rtn(min(data_b, 1.0f) * 255.0f); - vint data_ai = float_to_int_rtn(min(data_a, 1.0f) * 255.0f); + // Clamp values to [0.0, 1.0] range before unorm conversion + // - Values > 1.0 are possible for all HDR blocks + // - Values < 0.0 are possible for HDR void-extent blocks + vint data_ri = float_to_int_rtn(clampzo(data_r) * 255.0f); + vint data_gi = float_to_int_rtn(clampzo(data_g) * 255.0f); + vint data_bi = float_to_int_rtn(clampzo(data_b) * 255.0f); + vint data_ai = float_to_int_rtn(clampzo(data_a) * 255.0f); if (needs_swz) {