Merge pull request #380 from zeux/fix-exrwarn

Fix gcc's calloc-transposed-args warning
tree: 135e45e4fb27cac338176dd7d2ac04cc8c913bbb
  1. .reuse/
  2. bin/
  3. build/
  4. contrib/
  5. encoder/
  6. encoder_lib/
  7. example/
  8. LICENSES/
  9. OpenCL/
  10. test_files/
  11. transcoder/
  12. webgl/
  13. zstd/
  14. .gitignore
  15. appveyor.yml
  16. basisu.manifest
  17. basisu.sln
  18. basisu.vcxproj
  19. basisu.vcxproj.filters
  20. basisu_tool.cpp
  21. CMakeLists.txt
  22. CppProperties.json
  23. encoder_lvl_vs_perf.png
  24. format.sh
  25. LICENSE
  26. README.md
README.md

basis_universal

An LDR/HDR portable GPU compressed texture transcoding system.

Build status


Intro

Basis Universal is an open source supercompressed LDR/HDR GPU compressed texture interchange system from Binomial LLC that supports two intermediate file formats: the .KTX2 open standard from the Khronos Group, and our own “.basis” file format. These file formats support rapid transcoding to virtually any compressed GPU texture format released in the past ~25 years.

Our overall goal with this project is to simplify the encoding and efficient distribution of portable LDR and HDR GPU texture, image, and texture video content in a way that is compatible with any GPU or rendering/graphics API.

The system supports three modes: ETC1S, UASTC LDR, and UASTC HDR. The C/C++ encoder and transcoder libaries can be compiled to native code or WebAssembly, and all encoder/transcoder features can be accessed from Javascript.

Links

Supported LDR GPU Texture Formats

ETC1S and UASTC LDR files can be transcoded to:

  • ASTC LDR 4x4 L/LA/RGB/RGBA 8bpp
  • BC1-5 RGB/RGBA/X/XY
  • BC7 RGB/RGBA
  • ETC1 RGB, ETC2 RGBA, and ETC2 EAC R11/RG11
  • PVRTC1 4bpp RGB/RGBA and PVRTC2 RGB/RGBA
  • ATC RGB/RGBA and FXT1 RGB
  • Uncompressed LDR raster image formats: 8888/565/4444

Supported HDR GPU Texture Formats

UASTC HDR files can be transcoded to:

  • ASTC HDR 4x4 RGB 8bpp
  • BC6H RGB
  • Uncompressed HDR raster image formats: RGB_16F/RGBA_16F (half float/FP16 RGB, 48 or 64bpp), 32-bit shared exponent RGB_9E5

Supported Texture Compression Modes

  1. ETC1S: A roughly .3-3bpp low to medium quality supercompressed mode based off a subset of ETC1 called “ETC1S”. This mode supports variable quality vs. file size levels (like JPEG), alpha channels, built-in compression, and texture arrays optionally compressed as a video sequence using skip blocks (Conditional Replenishment). This mode can be rapidly transcoded to all of the supported LDR texture formats.

  2. UASTC LDR: An 8 bits/pixel LDR high quality mode. UASTC LDR is a 19 mode subset of the standard ASTC LDR 4x4 (8bpp) texture format, but with a custom block format containing transcoding hints. Transcoding UASTC LDR to ASTC LDR and BC7 are particularly fast and simple, because UASTC LDR is a common subset of both BC7 and ASTC. The transcoders for the other texture formats are accelerated by several format-specific hint bits present in each UASTC LDR block.

This mode supports an optional Rate-Distortion Optimizated (RDO) post-process stage that conditions the encoded UASTC LDR texture data in the .KTX2/.basis file so it can be more effectively LZ compressed. More details here.

Here is the UASTC LDR specification document.

  1. UASTC HDR: An 8 bits/pixel HDR high quality mode. This is a 24 mode subset of the standard ASTC HDR 4x4 (8bpp) texture format. It‘s designed to be high quality, supporting the 27 partition patterns in common between BC6H and ASTC, and fast to transcode with very little loss (typically a fraction of a dB PSNR) to the BC6H HDR texture format. Notably, UASTC HDR data is 100% standard ASTC texture data, so no transcoding at all is required on devices or API’s supporting ASTC HDR. This mode can also be transcoded to various 32-64bpp uncompressed HDR texture/image formats.

Here is the UASTC HDR specification document, and some compressed example images.

Other Features

Both .basis and .KTX2 files support mipmap levels, texture arrays, cubemaps, cubemap arrays, and texture video, in all three modes. Additionally, .basis files support non-uniform texture arrays, where each image in the file can have a different resolution or number of mipmap levels.

In ETC1S mode, the compressor is able to exploit color and pattern correlations across all the images in the entire file using global endpoint/selector codebooks, so multiple images with mipmaps can be stored efficiently in a single file. The ETC1S mode also supports short video sequences, with skip blocks (Conditional Replenishment) used to not send blocks which haven't changed relative to the previous frame.

The LDR image formats supported for reading are .PNG, .DDS with mipmaps, .TGA, .QOI, and .JPG. The HDR image formats supported for reading are .EXR, .HDR, and .DDS with mipmaps. It can write .basis, .KTX2, .DDS, .KTX (v1), .ASTC, .OUT, .EXR, and .PNG files.

The system now supports loading basic 2D .DDS files with optional mipmaps, but the .DDS file must be in one of the supported uncompressed formats: 24bpp RGB, 32bpp RGBA/BGRA, half-float RGBA, or float RGBA. Using .DDS files allows the user to control exactly how the mipmaps are generated before compression.

Building

The encoding library and command line tool have no required 3rd party dependencies that are not already in the repo itself. The transcoder is a single .cpp source file (in transcoder/basisu_transcoder.cpp) which has no 3rd party dependencies.

We build and test under:

  • Windows x86/x64 using Visual Studio 2019/2022, MSVC, or clang
  • Mac OSX (M1) with clang v15.0
  • Ubuntu Linux with gcc v11.4 or clang v14
  • Arch Linux ARM, on a Pinebook Pro, with gcc v12.1.

Under Windows with Visual Studio you can use the included basisu.sln file. Alternatively, you can use cmake to create new VS solution/project files.

To build, first install cmake, then:

cd build
cmake ..
make

To build with SSE 4.1 support on x86/x64 systems (encoding is roughly 15-30% faster), add -DSSE=TRUE to the cmake command line. Add -DOPENCL=TRUE to build with (optional) OpenCL support. Use -DCMAKE_BUILD_TYPE=Debug to build in debug. To build 32-bit executables, add -DBUILD_X64=FALSE.

After building, the native command line tool used to create, validate, and transcode/unpack .basis/.KTX2 files is bin/basisu.

Testing the Codec

The command line tool includes some automated LDR/HDR encoding/transcoding tests:

cd ../bin
basisu -test
basisu -test_hdr

To test the codec in OpenCL mode (must have OpenCL libs/headers/drivers installed and have compiled OpenCL support in by running cmake with -DOPENCL=TRUE):

basisu -test -opencl

Compressing and Unpacking .KTX2/.basis Files

  • To compress an LDR sRGB PNG/QOI/TGA/JPEG/DDS image to an ETC1S .KTX2 file, at quality level 255 (the highest):

basisu -q 255 x.png

  • For a linear LDR image, in ETC1S mode, at default quality (128):

basisu -linear x.png

  • To compress to UASTC LDR, which is much higher quality than ETC1S:

basisu -uastc x.png

basisu x.exr

Note the .EXR reader we‘re using is TinyEXR's, which doesn’t support all possible .EXR compression modes. Tools like ImageMagick can be used to create .EXR files that TinyEXR can read.

Alternatively, LDR images (such as .PNG) can be compressed to UASTC HDR by specifying -hdr. By default, LDR images, when compressed to UASTC HDR, are first converted from sRGB to linear light before compression. This conversion step can be disabled by specifying -hdr_ldr_no_srgb_to_linear.

Importantly, for best quality, you should supply basisu with original uncompressed source images. Any other type of lossy compression applied before basisu (including ETC1/BC1-5, BC7, JPEG, etc.) will cause multi-generational artifacts to appear in the final output textures.

Some Useful Command Line Options

  • -fastest (which is equivalent to -uastc_level 0) puts the UASTC LDR/HDR encoders in their fastest (but lower quality) modes.

  • -slower puts the UASTC LDR/HDR encoders in higher quality but slower modes (equivalent to -uastc_level 3). The default level is 1, and the highest is 4 (which is quite slow).

  • -q X, where X ranges from [1,255], controls the ETC1S mode's quality vs. file size tradeoff level. 255 is the highest quality, and the default is 128.

  • -debug causes the encoder to print internal and developer-oriented verbose debug information.

  • -stats to see various quality (PSNR) statistics.

  • -linear: ETC1S defaults to sRGB colorspace metrics, UASTC LDR currently always uses linear metrics, and UASTC HDR defaults to weighted RGB metrics (with 2,3,1 weights). If the input is a normal map, or some other type of non-sRGB (non-photographic) texture content, be sure to use -linear to avoid extra unnecessary artifacts. (Angular normal map metrics for UASTC LDR/HDR are definitely doable and on our TODO list.)

  • Specifying -opencl enables OpenCL mode, which currently only accelerates ETC1S encoding.

  • The compressor is multithreaded by default, which can be disabled using the -no_multithreading command line option. The transcoder is currently single threaded, although it is thread safe (i.e. it supports decompressing multiple texture slices in parallel).

More Example Command Lines

  • To compress an sRGB PNG/QOI/TGA/JPEG/DDS image to an RDO (Rate-Distortion Optimization) UASTC LDR .KTX2 file with mipmaps:

basisu -uastc -uastc_rdo_l 1.0 -mipmap x.png

-uastc_rdo_l X controls the RDO (Rate-Distortion Optimization) quality setting. The lower this value, the higher the quality, but the larger the compressed file size. Good values to try are between .2-3.0. The default is 1.0.

  • To add automatically generated mipmaps to a ETC1S .KTX2 file, at a higher than default quality level (which ranges from [1,255]):

basisu -mipmap -q 200 x.png

There are several mipmap options to change the filter kernel, the filter colorspace for the RGB channels (linear vs. sRGB), the smallest mipmap dimension, etc. The tool also supports generating cubemap files, 2D/cubemap texture arrays, etc. To bypass the automatic mipmap generator, you can create LDR or HDR uncompressed .DDS texture files and feed them to the compressor.

  • To create a slightly higher quality ETC1S .KTX2 file (one with higher quality endpoint/selector codebooks) at the default quality level (128) - note this is much slower to encode:

basisu -comp_level 2 x.png

On some rare images (ones with blue sky gradients come to bind), you may need to increase the ETC1S -comp_level setting, which ranges from 1,6. This controls the amount of overall effort the encoder uses to optimize the ETC1S codebooks and the compressed data stream. Higher comp_level's are significantly slower.

  • To manually set the ETC1S codebook sizes (instead of using -q), with a higher codebook generation level (this is useful with texture video):

basisu x.png -comp_level 2 -max_endpoints 16128 -max_selectors 16128

  • To tonemap an HDR .EXR or .HDR image file to multiple LDR .PNG files at different exposures, using the Reinhard tonemap operator:

basisu -tonemap x.exr

  • To compare two LDR images and print PSNR statistics:

basisu -compare a.png b.png

  • To compare two HDR .EXR/.HDR images and print FP16 PSNR statistics:

basisu -compare_hdr a.exr b.exr

See the help text for a complete listing of the tool's command line options. The command line tool is just a thin wrapper on top of the encoder library.

Unpacking .KTX2/.basis files to .PNG/.EXR/.KTX/.DDS files

You can either use the command line tool or call the transcoder directly from JavaScript or C/C++ code to decompress .KTX2/.basis files to GPU texture data or uncompressed image data. To unpack a .KTX2 or.basis file to multiple .png/.exr/.ktx/.dds files:

basisu x.ktx2

Use the -no_ktx and -etc1_only/-format_only options to unpack to less files.

-info and -validate will just display file information and not output any files.

The written mipmapped, cubemap, or texture array .KTX/.DDS files will be in a wide variety of compressed GPU texture formats (PVRTC1 4bpp, ETC1-2, BC1-5, BC7, etc.), and to our knowledge there is unfortunately (as of 2024) still no single .KTX or .DDS viewer tool that correctly and reliably supports every GPU texture format that we support. BC1-5 and BC7 files are viewable using AMD‘s Compressonator, ETC1/2 using Mali’s Texture Compression Tool, and PVRTC1 using Imagination Tech's PVRTexTool. RenderDoc has a useful texture file viewer for many formats. The Mac OSX Finder supports previewing .EXR and .KTX files in various GPU formats. The Windows 11 Explorer can preview .DDS files. The online OpenHDR Viewer is useful for viewing .EXR/.HDR image files.

WebGL Examples

The ‘WebGL’ directory contains four simple WebGL demos that use the transcoder and compressor compiled to WASM with emscripten. These demos are online here. See more details in the readme file here.

Screenshot of texture example running in a browser.