Jpegli Documentation

repository·main·Indexed 18 days ago

https://github.com/google/jpegli

Jpegli is an improved JPEG encoder and decoder implementation designed as a drop-in replacement for libjpeg62, maintaining API and ABI compatibility. It features high-precision input/output (16-bit unsigned and 32-bit floating point), a floating-point pipeline for color space conversions and DCT, distance-based quality control, adaptive dead-zone quantization, and XYB colorspace support. The project includes command-line tools cjpegli and djpegli for encoding and decoding.

Tokens
13.4K
Snippets
63
Records
69
Agent score
63%

What's inside Jpegli

  1. Overview of Jpegli encoder and decoder improvements

    main

    Jpegli provides several technical improvements over standard JPEG implementations:

    Encoder Improvements

    • High-precision input: Supports 16-bit unsigned and 32-bit floating point input buffers.
    • Floating-point pipeline: Color space conversions, chroma subsampling, and DCT are performed in floating-point precision.
    • Distance-based quality: Quality is controlled by a distance parameter (analogous to JPEG XL) which selects quantization tables based on distance and chroma subsampling mode.
    • Adaptive dead-zone quantization: Adjusts quantization thresholds for zero coefficients based on image noise levels.
    • XYB colorspace support: Efficiently compresses JPEGs with an ICC profile representing the XYB colorspace by using specialized quantization tables for X, Y, and B channels instead of converting to YCbCr.

    Decoder Improvements

    • High-precision output: Supports 16-bit unsigned and 32-bit floating point output buffers.
    • Statistical dequantization: Non-zero DCT coefficients are dequantized to the expectation value of their quantization intervals (assuming a Laplacian distribution).
    • Floating-point pipeline: Inverse DCT, chroma upsampling, and color space conversions are performed in floating-point precision, with integer conversion occurring only in the final output phase.
  2. Write fuzzer-friendly code with asserts

    main

    To help fuzzers detect programming errors (like out-of-bounds access or undefined behavior), use the following assertion macros:

    • JPEGLI_DASSERT: Enabled in Debug builds (including ASan, MSan, and UBSan). Use these for general logic checks. Avoid complex checks that run multiple times per pixel to maintain fuzzing performance.
    • JPEGLI_CHECK_IMAGE_INITIALIZED(image, rect): Specifically for MSan builds. Use this to explicitly check that a portion of an image is expected to be initialized. This helps catch errors earlier in the decoding/encoding process.
  3. Understand MSYS2 Build Environments

    main

    MSYS2 provides different environments targeting different runtimes and compilers. Crucially, all package installations and updates must be performed from within the MSYS environment, not the specific build environment. After installing packages, you must exit all terminals and restart your desired build environment.

    • MINGW32: For 32-bit Windows builds. Package prefix: mingw-w64-i686.
    • MINGW64: The primary environment for 64-bit Windows using the MSVCRT runtime. Package prefix: mingw-w64-x86_64.
    • UCRT64: Uses the Universal C Runtime (UCRT) used by modern Visual Studio. Best for interoperability with Visual Studio projects. Package prefix: mingw-w64-ucrt-x86_64.
    • CLANG64: Supports the clang compiler, but gimp packages are not available here. Package prefix: mingw-w64-clang-x86_64.
  4. Handle uninitialized memory in MSan builds

    main

    In MSan builds, using uninitialized memory in a way that affects program flow (e.g., in an if statement or a ternary operator) triggers an error. Simple arithmetic or memcpy over uninitialized memory is generally not an error.

    Dealing with SIMD padding

    When performing vectorized operations, you often operate over uninitialized padding memory at the end of a row/region. To prevent MSan errors when these values are used in operations like NearestInt(), use the following pattern:

    1. Use msan::UnpoisonMemory on the portion of the last SIMD vector being processed.
    2. Use msan::PoisonMemory on the corresponding output values after processing.
    3. Add a comment explaining why this is safe (e.g., no cross-lane computation is involved).

    Note: Do not simply initialize all padding memory in all builds; this can hide logic bugs and incur performance penalties.

  5. Use Jpegli as a drop-in replacement for libjpeg62

    main
    Jpegli is designed to be API and ABI compatible with libjpeg62. When built, it produces a shared library named lib/jpegli/libjpeg.so.62.3.0. This allows it to be used as a drop-in replacement for existing system libraries that depend on libjpeg62 without requiring code changes to the consuming applications.
  6. Build jpegli and run unit tests

    main

    To perform a standard release build and execute the project's unit tests, use the release command via the ci.sh script.

    By default, build commands like release and opt will automatically run tests. If you wish to build without running tests, set the SKIP_TEST environment variable to 1.

    ./ci.sh release
  7. Install minimum build dependencies on Debian/Ubuntu

    main

    To build jpegli on a Debian or Ubuntu-based system, you must install the core build tools and dependencies. Ensure your default clang compiler is at least version 6.

    If you have a newer version installed (e.g., clang-7) but the default clang --version reports an older version, use update-alternatives to set the correct default.

    Note: This list excludes dependencies already located in the third_party directory.

    # Install core dependencies
    sudo apt install clang cmake doxygen graphviz ninja-build libpng-dev
    
    # If clang is outdated, update the defaults (example for clang-7)
    sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-7 100
    sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-7 100
  8. Install dependencies for Jpegli on macOS

    main

    To build Jpegli on macOS, you must first install several dependencies using Homebrew. Note that OSX builds are provided on a "best effort" basis and may have incomplete test coverage or excluded sub-projects.

    1. Ensure brew doctor reports no serious problems and that you have an up-to-date version of Xcode installed.
    2. Install llvm (this may take several hours).
    3. Install the required libraries and build tools.

    Note: You must ensure that which clang points to the Homebrew-installed version (/usr/local/opt/llvm/bin/clang) rather than the Xcode default. If it does not, update your PATH environment variable.

    brew install llvm
    brew install coreutils cmake giflib jpeg-turbo libpng ninja zlib
  9. Build and Install the GIMP Plugin

    main

    To build the GIMP plugin for jpegli:

    1. Install the relevant gimp package from the MSYS environment (e.g., mingw-w64-x86_64-gimp).
    2. If using clang, use ./ci.sh. Otherwise, use cmake within a build directory:
      cd build
      rm -r CM*
      cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
         -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF \
         -DJPEGLI_ENABLE_BENCHMARK=OFF -DJPEGLI_ENABLE_MANPAGES=OFF \
         -DJPEGLI_FORCE_SYSTEM_GTEST=ON ..
    3. Once built, install the plugin into GIMP:
      • Download and install GIMP (e.g., version 2.10.24).
      • Create the directory: C:\Program Files\GIMP 2\lib\gimp\2.0\plug-ins\file-jxl
      • Copy build/plugins/gimp/file-jxl.exe into that folder.
    cd build
    rm -r CM*
    cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
       -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF \
       -DJPEGLI_ENABLE_BENCHMARK=OFF -DJPEGLI_ENABLE_MANPAGES=OFF \
       -DJPEGLI_FORCE_SYSTEM_GTEST=ON ..
  10. Rebase your branch to stay up to date with upstream

    main

    If git branch -vv shows that your branch is "behind" origin/main, you should rebase your changes on top of the latest upstream commits to maintain a linear history.

    To perform a fetch and a rebase in a single step, use:

    git pull -r

    Alternatively, if you have already fetched, you can run git rebase to apply your current branch's commits on top of the tracking branch.

  11. Build jpegli using the clang compiler

    main

    To use clang, first install the appropriate packages from the MSYS environment (e.g., for x86_64):

    mingw-w64-x86_64-clang
    mingw-w64-x86_64-clang-tools-extra
    mingw-w64-x86_64-clang-compiler-rt

    Once installed, you can build jpegli using the ./ci.sh script:

    ./ci.sh opt -DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF \
        -DJPEGLI_ENABLE_BENCHMARK=OFF -DJPEGLI_ENABLE_MANPAGES=OFF \
        -DJPEGLI_FORCE_SYSTEM_GTEST=ON