Skip to content

djpegli rejects real-world progressive JPEGs with empty DHT segments #248

Description

@ternaus

Summary

djpegli rejects progressive JPEGs containing empty DHT segments (FF C4 00 02). These files are accepted by several widely used libjpeg-turbo-based decoders. This was previously reported in libjxl/libjxl#3597, but it still reproduces in the standalone Jpegli repository.

I understand that a DHT segment with no tables is not conforming to the JPEG syntax. This is a compatibility request for real-world files that other common decoders handle: treat an empty DHT segment as a no-op that preserves previously defined tables, or provide an equivalent tolerant decoding mode.

Reproduction on current main

I built djpegli from 031a007 on macOS 26.4.1 arm64 with AppleClang 21.0.0:

$ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DJPEGLI_ENABLE_TOOLS=ON
$ cmake --build build --target djpegli -j 8
$ build/tools/djpegli photo_2024-05-21_21-56-01.jpg output.png
Read 85012 compressed bytes.
jpegli decoding failed

The public reproducer is attached to libjxl/libjxl#3597: https://github.com/libjxl/libjxl/files/15393696/photo_2024-05-21_21-56-01.zip

Its JPEG has SHA-256 caeb422c07ff7b134a03c4d8a5727ca0aab998ac70a07a263e135b85a17d7c77 and contains two FF C4 00 02 sequences.

The current source still reports an error when a DHT segment contains no tables:

void ProcessDHT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
size_t pos = 2;
if (pos == len) {
JPEGLI_ERROR("DHT marker: no Huffman table found");
}

Real-world scope

I encountered this while auditing the exact common-support exclusions in a JPEG decoder benchmark based on the Forchheim Image Database (FODB). All 276 excluded files have the same characteristics:

  • 276/276 are progressive WhatsApp variants, spanning 23 devices and 12 scenes;
  • 276/276 contain exactly two empty DHT segments (FF C4 00 02);
  • 276/276 fail in Jpegli with DHT marker: no Huffman table found;
  • 276/276 decode successfully and materialize RGB output with simplejpeg 1.9.0, OpenCV 5.0.0, and torchvision 0.28.0.

One representative FODB file is 1600x1201 and has SHA-256 5e97e82ee53716360d21d02298ac76a1a7112b65e3bbe3c154ce0c806bf84b93. I am not attaching the FODB image because the dataset's redistribution terms should be respected; the public reproducer above triggers the same behavior.

The Python binding ajpegli==1.0.0, which pins Jpegli commit 7cdf212790241868c77dca777dbee14e98128cba, exposes the underlying error as:

ajpegli.errors.DecodeError: jpegli decode failed: lib/jpegli/decode_marker.cc:288: DHT marker: no Huffman table found

Expected behavior

Jpegli decodes these files in a compatibility mode, ideally with a regression test using the existing public reproducer. If strict rejection is intentional, an explicit tolerant option would still allow applications to match the behavior of common JPEG decoders.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions