TinyEXR

repository·release·Indexed 21 days ago

https://github.com/syoyo/tinyexr

A lightweight, high-performance library for loading and saving OpenEXR (.exr) images. Designed for easy embedding, it features runtime-dispatched SIMD kernels (SSE2, AVX2, NEON) and supports various codecs including RLE, ZIP, PIZ, and HTJ2K. The library includes a comprehensive benchmark suite for measuring throughput and correctness, with optional integration of the libdeflate backend for improved performance.

Tokens
34.9K
Snippets
109
Records
167
Agent score
74%

What's inside tinyexr

  1. Overview of the WASM EXR Viewer features

    release

    The TinyEXR v3 WASM Viewer is a browser-based tool that decodes EXR files entirely in WebAssembly and renders them using WebGL2.

    Key capabilities include:

    • Streaming Decoding: Uses the v3 streaming block API (exr_reader_num_blocks, exr_reader_block_info, exr_reader_decode_block) to decode files one scanline-block or tile at a time, allowing for progress bar updates.
    • Live HDR Rendering: Instant GPU-based adjustments for exposure (EV), gamma / sRGB curves, and channel isolation (RGB, R, G, B, A, or luminance).
    • Deep Image Support: Renders deep (deepscanline/deeptiled) parts as a 3D point cloud where samples are placed at their (x, y) coordinates and Z (depth), colorable by depth or RGB.
    • Non-RGB Data Handling: Automatically renders non-RGB parts (like depth Z or masks) by mapping them to grayscale or using false-color (viridis) heatmaps.
    • Advanced Navigation: Supports zoom (wheel), pan (drag), region-of-interest selection (shift-drag), and a pixel picker to read raw float R/G/B/A values.
  2. Overview of texcomp tools and codecs

    release

    texcomp is a pure-C11 GPU block-compression library. It is part of a suite of tools designed to bridge the gap between scene-linear EXRs and GPU-samplable textures.

    • texcomp: Block compression/decompression (BC1/3/5/6H/7, ETC2, EAC, ASTC, and uni).
    • tir: Content-aware image resizing.
    • texpipe: Mip chains, alpha coverage, cube LOD, and KTX2/DDS container management.
    • envmap: Equirectangular to cubemap/octahedral reprojection and spherical harmonics.

    Supported Codecs

    codecbppchannelstarget
    BC14RGBdesktop, colour
    BC38RGBAdesktop, colour + alpha
    BC58RGdesktop, normal maps (UNORM and SNORM)
    BC6H8RGB HDRdesktop, HDR / IBL (uf16 + sf16)
    BC78RGBAdesktop, best LDR quality
    ETC2 RGB / RGBA4 / 8RGB / RGBAmobile
    EAC R11 / RG114 / 8R / RGmobile, masks and normal maps
    ASTC0.9–8RGBAmobile + desktop, variable block size
    ASTC HDR8RGB HDRmobile HDR
    uni8RGBAprivate ASTC-backed intermediate

    Note on uni: This is a native carrier. You encode once and convert on load to the target device format (e.g., BC7 for desktop, ASTC/ETC2 for mobile). It is not the Basis UASTC representation.

  3. Overview of texpipe

    release

    texpipe — resize-aware texture compression

    texpipe is a tool that integrates two standalone libraries—tir (content-aware image resizing) and texcomp (block compression)—to build content-aware mip chains and serialize them into multi-mip GPU texture containers like DDS and KTX2.

    It is written in pure C11. While the library (libtexpipe) is designed for integration, the texpipe_cli provides a command-line interface for file I/O and batch processing.

  4. Overview of nanozlib

    release

    nanozlib is a nanoscale, secure zlib decoding and encoding library written in portable C/C++. It is designed for embedding zlib support into C/C++ applications where security and robustness are priorities.

    Key characteristics:

    • Decoding: Uses Wuffs std/zlib for highly secure decoding. It is designed to be resistant to corrupted or malicious zlib data, avoiding asserts, C++ exceptions, and segmentation faults.
    • Encoding: Uses stb_zlib for somewhat secure compression.
    • Limitations: Supports up to 2GB and adds approximately 50 KB or more to the compiled binary size (even with -Os).
  5. License for TinyEXR texcomp

    release

    The TinyEXR texcomp texture-compression suite (located under tools/texcomp/) is licensed under the Apache License, Version 2.0.

    Note that this is a specific licensing choice for the texcomp subcomponent; the rest of the TinyEXR project uses the BSD-3-Clause license. The Apache-2.0 license is compatible with BSD-3-Clause for combined or redistributed works.

  6. Use the tocio OpenColorIO engine

    release

    tocio is a pure-C11 OpenColorIO (OCIO) configuration engine and code generator. It parses OCIO YAML subsets and resolves color transforms into CPU (SSE2/AVX2, NEON) or GPU (GLSL, Metal) execution paths.

    Key Features

    • ACES 2.0 Support: Includes SDR, HDR, and D60-simulation variants, along with various input/output encodings (ACEScg, sRGB, PQ, etc.).
    • Execution Modes: CPU interpreter, AOT C source generation, GLSL/Metal shader generation, and JIT (x86-64/AArch64).
    • Supported Formats: OCIO YAML, Iridas .cube, Sony .spi1d/.spi3d, and ACES CLF LUT files.

    Build Commands

    make tocio-lib         # Build build/libtocio.a
    make tocio-test        # Run unit tests
    make tocio-validate    # Numerical validation against PyOpenColorIO
  7. Core features of miniz

    release

    Miniz provides several high-performance data compression and archive capabilities:

    • zlib/Deflate Compatibility: Acts as a drop-in replacement for the most commonly used zlib APIs. It is a completely independent implementation, so zlib licensing does not apply.
    • Streaming/Coroutine API: Supports stream-based processing. The low-level tdefl (compressor) and tinfl (decompressor) APIs use simple state structs that can be saved/restored via memcpy. These low-level APIs do not use the heap.
    • Archive Manipulation: Includes a set of APIs for reading, writing, and appending .ZIP format archives, designed for embedded, mobile, or game development.
    • PNG Support: Contains simple functions for writing .PNG format image files.
    • Portability: Written in plain C, tested with GCC, clang, and Visual Studio, and can be easily tuned or trimmed using preprocessor defines.
  8. Compare TinyEXR performance against OpenEXR

    release

    TinyEXR v3 performance varies significantly depending on the codec used and whether the libdeflate backend is enabled.

    Single-threaded Performance

    • TinyEXR wins on uncompressed (none) and RLE codecs.
    • OpenEXR leads on the DEFLATE family (ZIP, PXR24, ZIPS, PIZ) and HTJ2K due to its tuned implementations.
    • TinyEXR with libdeflate (DEFLATE=auto) matches or beats OpenEXR on the DEFLATE family (e.g., ZIP decode is ~1.4× faster).

    Multi-threaded Performance

    TinyEXR supports opt-in parallel encode and decode. At 16 threads, TinyEXR (in-tree) out-decodes OpenEXR on RLE, ZIP, ZIPS, and B44. When using the libdeflate backend, TinyEXR leads the entire DEFLATE family by a wide margin.

    Compression Size

    Lossless and standard codecs are interoperable between libraries. Only ZIP and HTJ2K show differences due to encoder tuning, not format changes.

  9. Understanding the HTJ2K entropy decoder SIMD implementation status

    release

    As of the current documentation, SIMD acceleration for the HTJ2K cleanup-pass entropy decoder (specifically the MagSgn magnitude/sign reconstruction step) is not yet implemented and is currently in the scoping phase.

    While research into AVX2 implementations (1-quad and 2-quad batching) was conducted, they were found to be either break-even or slower than the optimized scalar implementation (JphQuadMs) due to the overhead of window fetches and the efficiency of the scalar lazy-loading approach.

    Current Status: The project has decided to stick with the optimized scalar JphQuadMs (commit a4cb990) as the primary implementation for the entropy decode workload, as it minimizes bitstream fetches and provides the best performance-to-complexity ratio on current hardware.

  10. Handle errors in TinyEXR V3

    release

    TinyEXR V3 provides detailed error reporting with context (including byte positions).

    C++ API

    Errors are returned via Result<T>. You can iterate over result.errors to get descriptive strings.

    C API

    Use exr_context_get_last_error to retrieve an ExrErrorInfo struct containing the error message and the byte position where the error occurred.

    // C++ API
    auto result = decoder.parse_header();
    if (!result) {
        for (const auto& err : result.errors) {
            std::cerr << err.to_string() << "\n";
        }
    }
    
    // C API
    ExrErrorInfo error;
    if (exr_context_get_last_error(ctx, &error) == EXR_SUCCESS) {
        printf("Error: %s at byte %llu\n", error.message, error.byte_position);
    }
  11. Use xbc7 for supercompressed BC7

    release

    The xbc7 format is a texcomp-native implementation of the XBC7 concept (windowed RDO + entropy coding of BC7).

    • It is not bitstream-compatible with Basis XBC7.
    • It uses zstd for entropy coding the BC7 stream.
    • It transcodes directly to standard BC7.
  12. HTJ2K MagSgn reconstruction: int32 vs int64 paths

    release

    The HTJ2K decoding process distinguishes between two paths for MagSgn (magnitude/sign) reconstruction:

    • int32 path (jph_decode_block): This is the high-value, common case where missing_msbs < 30 and kmax <= 30. In this path, a quad's 4 samples consume $\le 124$ bits, meaning a single 128-bit fetch per quad is sufficient. This is the primary target for potential future SIMD optimization.
    • int64 path (jph_decode_block64_cleanup): Used for float/32-bit data where samples can be up to 62 bits. Because a quad can exceed 128 bits in this mode, the decoder remains scalar to match the behavior of OpenJPH and ensure correctness.