Repository navigation
Conversation
The preprocessor stored the chroma of the top-left pixel of each subsampling window (point sampling), which aliases and shifts chroma by half a pixel from the centered siting that JFIF (and decoders) assume. Average the window instead if the input has full chroma resolution and Cb and Cr have the same sampling. On four 4096x4096 orthophotos (q95, 4:2:0, decoded by libjpeg-turbo with fancy upsampling) this improves PSNR by 0.17-0.49 dB, the JPEG is 0.4-0.6 % smaller and the preprocessor kernel takes ~0.01 ms longer. The previous behavior can be selected by GPUJPEG_ENC_OPT_CHROMA_FILTER_BOOL.
The postprocessor replicated 4:2:0, 4:2:2 and 4:4:0 chroma. For
full-resolution output, interpolate it with the triangle filter that
libjpeg uses by default ("fancy upsampling", same weights and rounding).
Other layouts (dynamic kernels) and subsampled output formats are
unchanged. Unlike libjpeg, no exception is made for chroma width <= 2.
Decoding libjpeg-turbo q95 4:2:0 JPEGs of four 4096x4096 orthophotos, PSNR
improves by 0.32-0.70 dB (now equal to libjpeg-turbo), the postprocessor
kernel takes ~0.01 ms longer.
The previous behavior can be selected by GPUJPEG_DEC_OPT_CHROMA_FILTER_BOOL.
Compares the encoder's chroma planes and the decoder's full-resolution output with a CPU reference for 4:2:0, 4:2:2, 4:4:0 and 4:1:1 with the filters on and off, and the option change without reinitialization.
Check also the default (filter on) and the option change on the same coders for each layout (instead of only 4:2:0); express the 4:2:0 reference with the plain 9/3/3/1 weights.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
when we tried to adopt GPU jpeg for our project, I realised that it has slightly worse encoding quality compared to jpeg turbo. so I tasked Claude to look for and fix the issue. codex conducted a review.
I also have some other fixes, but I don't know what your LLM policy is, so I'm starting with this one. I'm happy to iterate on it, you can take it or close it :)
this is the llm summary:
Summary
Improve JPEG colour fidelity by filtering chroma during encoding and decoding.
4:2:2 and 4:4:0 chroma when producing full-resolution output.
previous behaviour.
Evidence
Measured on four real 4096×4096 RGB orthophoto tiles at quality 95, 4:2:0,
using an RTX 4090. RGB PSNR is measured against source pixels.
across the four tiles—equivalent to 14–27% lower mean squared error.
to 0.03–0.06 dB.
postprocessing per 4096×4096 image.
CTest passes all three suites. CUDA memcheck reports no errors or leaks,
and targeted chroma-kernel racecheck reports no hazards. Tests cover
sampling layouts, odd dimensions, padded input, default-on behaviour,
and toggling the filters between calls.