This commit is contained in:
2026-06-14 19:09:18 +01:00
parent 14bd1a9271
commit 13fa90a0e9
3958 changed files with 999286 additions and 4 deletions
+65
View File
@@ -0,0 +1,65 @@
# SPDX-License-Identifier: Apache-2.0
# ----------------------------------------------------------------------------
# Copyright 2021 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
# of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# CMake configuration
cmake_minimum_required(VERSION 3.15)
include(ExternalProject)
project(astcencoder_example VERSION 1.1.0)
# Add the external project and pull out the project directories we need
# The default build is a native build which supports the highest level of SIMD
# exposed by the compiler when using default compiler flags. Add a single
# SIMD enable to the CMAKE_CACHE_ARGS option to force something specific, but
# remember to change the link library in target_link_libraries() to match.
#
# * Add "-DASTCENC_ISA_SSE2:String=ON" and link against "astcenc-sse2-static"
# * Add "-DASTCENC_ISA_SSE41:String=ON" and link against "astcenc-sse4.1-static"
# * Add "-DASTCENC_ISA_AVX2:String=ON" and link against "astcenc-avx2-static"
# * Add "-DASTCENC_ISA_NEON:String=ON" and link against "astcenc-neon-static"
ExternalProject_Add(astcencoder
GIT_REPOSITORY https://github.com/ARM-software/astc-encoder
GIT_TAG main
CMAKE_CACHE_ARGS -DASTCENC_CLI:STRING=OFF -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
INSTALL_COMMAND "")
ExternalProject_Get_property(astcencoder
SOURCE_DIR)
ExternalProject_Get_property(astcencoder
BINARY_DIR)
# Build the command line
add_executable(astcenc_example astc_api_example.cpp)
# ... with astcencoder as a dependency
add_dependencies(astcenc_example astcencoder)
# ... with astcencoder Source dir on the include path
target_include_directories(astcenc_example
PRIVATE
${SOURCE_DIR}/Source)
# ... with astcencoder Binary dir on the library path and as a library dep
target_link_directories(astcenc_example
PRIVATE
${BINARY_DIR}/Source)
target_link_libraries(astcenc_example
PRIVATE
astcenc-native-static)
+55
View File
@@ -0,0 +1,55 @@
# Library usage example
This is a minimal example of using the astcenc codec as a library in another
project. This sample shows:
* How to include astcenc as an external project CMake dependency.
* How to use the API to compress and decompress an image.
For sake of simplicity the example application uses fixed compression settings,
reading an uncompressed LDR image, compressing using 6x6 blocks at medium
quality, and then decompressing and writing the decompressed image back to disk
as a PNG file.
## Building
:warning: For sake of simplicity the example CMake project uses the CMake
`ExternalProject` mechanism to import the astcenc project from GitHub. This is
trivial to integrate, but requires network access during the build to pull the
astcenc project.
Most users will want to store a copy of astcenc in a project sub-directory,
e.g. by using git submodules, and then use `add_subdirectory()` to include the
project in their build. This allows the user to directly use the astcenc core
library as a link requirement via `target_link_libraries()`, without the
additional plumbing that `ExternalProject` requires.
### Linux and macOS
From the `./Utils/Example` directory.
```
mkdir build
cd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release ..
make -j8
```
### Windows
From the `./Utils/Example` directory, in a Visual Studio command prompt.
```
mkdir build
cd build
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release ..
nmake
```
## Running
From the build directory above.
```
astcenc_example <input.png> <output.png>
```
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2021-2024 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
// of the License at:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// ----------------------------------------------------------------------------
// This is a minimal example of using the astcenc library.
//
// This sample shows how to include the astcenc library in your CMake project
// as an external dependency, and how to compress and decompress images using
// the C library API.
//
// For sake of clarity the command line exposed by the sample is minimalistic,
// and the compression uses a fixed set of options, but the code is commented
// to indicate where extension would be possible. Errors handling points are
// detected and logged, but resources are not cleaned up on error paths to keep
// the sample control path simple, so resources will leak on error.
#include <stdio.h>
#include "astcenc.h"
#define STB_IMAGE_IMPLEMENTATION
#include "ThirdParty/stb_image.h"
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "ThirdParty/stb_image_write.h"
int main(int argc, char **argv)
{
// Parse command line
if (argc != 3)
{
printf("Usage:\n"
" %s <source> <dest>\n\n"
" <source> : Uncompressed LDR source image.\n"
" <dest> : Uncompressed LDR destination image (png).\n"
, argv[0]);
return 1;
}
// ------------------------------------------------------------------------
// For the purposes of this sample we hard-code the compressor settings
static const unsigned int thread_count = 1;
static const unsigned int block_x = 6;
static const unsigned int block_y = 6;
static const unsigned int block_z = 1;
static const astcenc_profile profile = ASTCENC_PRF_LDR;
static const float quality = ASTCENC_PRE_MEDIUM;
static const astcenc_swizzle swizzle {
ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A
};
// ------------------------------------------------------------------------
// Load input image, forcing 4 components
int image_x, image_y, image_c;
uint8_t *image_data = (uint8_t*)stbi_load(argv[1], &image_x, &image_y, &image_c, 4);
if (!image_data)
{
printf("Failed to load image \"%s\"\n", argv[1]);
return 1;
}
// Compute the number of ASTC blocks in each dimension
unsigned int block_count_x = (image_x + block_x - 1) / block_x;
unsigned int block_count_y = (image_y + block_y - 1) / block_y;
// ------------------------------------------------------------------------
// Initialize the default configuration for the block size and quality
astcenc_config config;
astcenc_error status;
status = astcenc_config_init(profile, block_x, block_y, block_z, quality, 0, &config);
if (status != ASTCENC_SUCCESS)
{
printf("ERROR: Codec config init failed: %s\n", astcenc_get_error_string(status));
return 1;
}
// ... power users can customize any config settings after calling
// config_init() and before calling context alloc().
// ------------------------------------------------------------------------
// Create a context based on the configuration
astcenc_context* context;
status = astcenc_context_alloc(&config, thread_count, &context);
if (status != ASTCENC_SUCCESS)
{
printf("ERROR: Codec context alloc failed: %s\n", astcenc_get_error_string(status));
return 1;
}
// ------------------------------------------------------------------------
// Compress the image
astcenc_image image;
image.dim_x = image_x;
image.dim_y = image_y;
image.dim_z = 1;
image.data_type = ASTCENC_TYPE_U8;
uint8_t* slices = image_data;
image.data = reinterpret_cast<void**>(&slices);
// Space needed for 16 bytes of output per compressed block
size_t comp_len = block_count_x * block_count_y * 16;
uint8_t* comp_data = new uint8_t[comp_len];
status = astcenc_compress_image(context, &image, &swizzle, comp_data, comp_len, 0);
if (status != ASTCENC_SUCCESS)
{
printf("ERROR: Codec compress failed: %s\n", astcenc_get_error_string(status));
return 1;
}
// ... the comp_data array contains the raw compressed data you would pass
// to the graphics API, or pack into a wrapper format such as a KTX file.
// If using multithreaded compression to sequentially compress multiple
// images you should reuse the same context, calling the function
// astcenc_compress_reset() between each image in the series.
// ------------------------------------------------------------------------
// Decompress the image
// Note we just reuse the image structure to store the output here ...
status = astcenc_decompress_image(context, comp_data, comp_len, &image, &swizzle, 0);
if (status != ASTCENC_SUCCESS)
{
printf("ERROR: Codec decompress failed: %s\n", astcenc_get_error_string(status));
return 1;
}
// If using multithreaded decompression to sequentially decompress multiple
// images you should reuse the same context, calling the function
// astcenc_decompress_reset() between each image in the series.
// ------------------------------------------------------------------------
// Store the result back to disk
stbi_write_png(argv[2], image_x, image_y, 4, image_data, 4 * image_x);
// ------------------------------------------------------------------------
// Cleanup library resources
stbi_image_free(image_data);
astcenc_context_free(context);
delete[] comp_data;
return 0;
}