-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JPEG decoding yields discolored image (basic 8-bit YUV 444 JPEG with no / GIMP default sRGB color profile). #249
Comments
Sorry, for delay in reply. It is probably the cause, will rewrite it to use integer intrinsics |
If you or anyone has some time tho, you can use the impl from stb for inspiration @https://github.com/nothings/stb/blob/5c205738c191bcb0abc65c4febfa9bd25ff35234/stb_image.h#L3690-L3746 |
He already tried transformation using floating point see I wrote few hundreds of Yuv conversions. I may do PR with fast high precision transform(probably exact with libjpeg-turbo), better than yours with low precision, or mixed precision as in stb, but probably not the exact same as stb. However, YUV transforms even in low precision usually do not produce this effect, there is likely issue with DCT coefficients or with something else. |
Nice if you have time that would be appreciated. libjpeg-turbo matching is better than stb. |
So after we've made YUV conversion is almost loseless brightness gain decoded correctly and images became a way better. SSIM: dssim ./assets/bench.jpg v_new.png libjpeg-turbo The "greenish effect" became less noticeable because the image brightness is at least not changing. However, it is still present. Here are the images I tested. |
Any other reasons you suspect that the dsism is that high compared to libjpeg-turbo? |
YUV conversion in 14 bit is almost loseless, so the issue somewhere in other place. Let's check the statistics.
identify -verbose /Users/radzivon/RustroverProjects/moxcms/v_new.png Channel statistics: identify -verbose /Users/radzivon/RustroverProjects/moxcms/assets/bench.jpg Channel statistics: |
I'd bet that Cb coeffiecient delivered from DCT is incorrect. It also have contribution to Green channel that mean it delivers error in 2 channels at the time. I'll recheck my coefficients, but I think they're correct. |
Also there is might also be another option, it may explain why coefficients in libjpeg-turbo looks unnatural and it is not clear how to reproduce them: someone might adjusted Yuv coefficients by hands to compensate errors from DCT, by simplex method, brute forcing or something. I’m not sure this is real. I’ll try their coefficients |
Another problem might be problems with the upsampling step. I choose a different algorithm for sampling |
So, I tried theirs YUV coefficients: Ours: libjpeg-turbo: That means there is no any magic in libjpeg-turbo coefficients, perhaps I just used more precise software.\ Here is original coefficients that I made with MPFR 150 bits of precision. Inverse CbCrInverseTransform { y_coef: 1.0000000000000000000000000000000000000000000000, cr_coef: 1.4020000100135803222656250000000000000000000000, cb_coef: 1.7719999998807907104492187500000000000000000000, g_coeff_1: 7.1413627332466104295757259219925233487803202950e-1, g_coeff_2: 3.4413628345745065477397884219925233487803202915e-1 }
Inverse CbCrInverseTransform { y_coef: 1.0, cr_coef: 1.402, cb_coef: 1.772, g_coeff_1: 0.7141363, g_coeff_2: 0.3441363 }
Inverse Numeric CbCrInverseTransform { y_coef: 16384, cr_coef: 22970, cb_coef: 29032, g_coeff_1: 11700, g_coeff_2: 5638 }; We could change it if any doubts, recompute with Wolfram or any other arbitrary precision tools. But atm I think they are correct: https://github.com/libjpeg-turbo/libjpeg-turbo/blob/adbb328159b5558e846690c49f9458deccbb0f43/src/jdcolor.c#L54 |
etemesi254 thank you for looking into this. I never coded DCT so I couldn't/cannot comment on the DCT coeff part without learning it.
My image starting this issue was YUV444 so there should be no upsampling involved as far as I understand the decoding. |
If there was no upsampling, then its good. Will investigate further.
Thanks for taking time to report too
…On Sat, 1 Mar 2025 at 22:21, Gergő Sályi ***@***.***> wrote:
etemesi254 thank you for looking into this. I never coded DCT so I
couldn't/cannot comment on the DCT coeff part without learning it.
Another problem might be problems with the upsampling step.
My image was YUV444 so there should be no upsampling involved as far as I
understand the decoding.
—
Reply to this email directly, view it on GitHub
<#249 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AFZRVE6I4ZON23PEXDNY3L32SICC3AVCNFSM6AAAAABWGJUNHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOJSGM3TIOBSGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
[image: gergo-salyi]*gergo-salyi* left a comment
(etemesi254/zune-image#249)
<#249 (comment)>
etemesi254 thank you for looking into this. I never coded DCT so I
couldn't/cannot comment on the DCT coeff part without learning it.
Another problem might be problems with the upsampling step.
My image was YUV444 so there should be no upsampling involved as far as I
understand the decoding.
—
Reply to this email directly, view it on GitHub
<#249 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AFZRVE6I4ZON23PEXDNY3L32SICC3AVCNFSM6AAAAABWGJUNHCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDMOJSGM3TIOBSGU>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I'm relaying this from my issue at the
image
crate using zune-jpg for JPEG decoding: image-rs/image#2411Tested on Linux with x86_64 CPU (i5-1035G4) 10th gen Intel having AVX2, etc...
# Convert with ImageMagick for reference magick start.jpg good.png
start.jpg
:good.png
:bad.png
:Lower half of
bad.png
is visibly more green thenstart.jpg
orgood.png
. E.g. pixel at index(150, 200)
became#131910
instead of#151811
. I expect the the JPEG decoder to yield identical result to ImageMagick.Not sure about the cause, but I suspect a YCbCr -> RGB conversion problem.
zune-jpeg
does this:zune-image/crates/zune-jpeg/src/color_convert/avx.rs
Lines 16 to 18 in c9f333d
This integer approximation is known to have caused problems elsewhere in the past, see: https://en.wikipedia.org/wiki/YCbCr#Approximate_8-bit_matrices_for_BT.601
The JPEG File Interchange Format Version 1.02 spec defines on page 3:
These formulas don't have +-1/255 error. Again I'm not 100% sure that YCbCr -> RGB conversion is the cause of the discoloration, but I have this suspicion seeing the sloppy integer math.
Being off by +-1 in a 0-255 ranged 8-bit color intensity (in a non-random / non-dithered way) is a visually significant error, basically JPEG images which are supposed to be visually lossless (encoded with quality 90 in the above example) are completely violated in their usage intent.
Please also see image-rs/image#2411 , the maintainer there posted some statistical measurements about the above images.
The text was updated successfully, but these errors were encountered: