-
-
Notifications
You must be signed in to change notification settings - Fork 851
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
Pixeldata not correct when reading certain JPEG #245
Comments
Aha, didn't do a good enough check through the open issues then, my apologies for that :). Do you know the piece of code/class that is most likely to cause this issue? I could also do some investigation to see if I can find out anything. |
You're additional info is very important so don't worry. 😄 Tbh understanding jpeg eludes me. We're going wrong somewhere but I'm not sure where. |
@devedse in the best case this might be caused by rounding inaccuracy in In the worst case we need a deep refactor of the codebase to fix this; introducing an elegant management of Speed <-> Memory <-> Quality tradeoffs (see #192). |
@antonfirsov I had a look at the rounding there and we probably should be adding The error must be elsewhere, I just don't know where that is. We're sometimes showing an error of +-3 per color component. |
In the JpegDecoderCore I added a breakpoint if Pixel 5990, 3992 was being handled. I manually entered the YUV values in an online YUV to RGB converted and saw the same values as the ones that came out of your conversion function: Website: For this specific pixel it seems that: When I print out the surrounding values of the Y table for X values: My next question would be, where does it fill the this.ycbcrImage.YChannel table? |
@devedse Thanks for clarifying the conversion accuracy. The channel is populated here. https://github.com/JimBobSquarePants/ImageSharp/blob/b165c54bb5c3a0c17cf6ce45f0f47fee9ff980fb/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegPixelArea.cs#L109 |
@devedse quick advice: VS supports conditional breakpoints. Just right click on it and add the condition from the if statement. This way you can debug without manipulating the code. |
@Toxantron, I know, I just don't like the way they work. This works easier for me ^.^ |
I also did some tests using the following C++ script to see what the result would be of YUV to RGB conversion:
This also resulted in the same values for RGB: Obtained from: https://stackoverflow.com/questions/9098881/convert-from-yuv-to-rgb-in-c-android-ndk This really leads me to think that the issue should be in or before the CopyColorsTo method |
@devedse your feedback and investigation is really useful! I'm planning to have a deep dive back into the Jpeg decoder in ~4 weeks. I will start by analyzing and TDD-ing the IDCT + color conversion chain based on your observations. |
@JimBobSquarePants I did some more testing and was initially positively surprised that Image1 now returned the right pixel data for pixel X: 5990 Y: 3992. However when I ran the 2 images through the whole compare again it failed on pixel X: 0 Y:0 directly :(. This time pixel1 (from image1) had the correct data, pixel2 (from image2) again differed by a tiny bit. |
I think there's always going to be minor differences in decoders. I've read that System.Drawing even differs slightly on 32 and 64bit machines. |
I've tried to keep casting to an absolute minimum in my test decoder to reduce error. |
I've changed up my library to now first use LibVIPS to convert the image from JPEG to PNG before doing the comparison. Doing that will actually give me equal images again. So basically (pseudo code):
|
@devedse We're in the midst of a complete rewrite of the jpeg decoder which will likely utilise floating point maths throughout (so we can use SIMD). We'll revisit this once we have completed that work. |
I think we've done enough work now to ensure adequate accuracy for our decoder. Different decoders yield different results with varying levels of consistency per image. We're well within acceptable parameters. |
Description
I'm writing a small tool that compares images after doing lossless optimizations on them using another tool: https://encode.ru/threads/1589-FileOptimizer
I took a picture with my own Camera (6000x4000) and ran it through the FileOptimizer. After that I used the tool I created to compare the source and target image to see if there were any pixel differences. The comparison failed on pixel X: 5990 Y: 3992
For image1 the debugger shows: 36, 15, 10, 255 (RGBA)
For image2 the debugger shows: 36, 15, 12, 255 (RGBA)
The strange this is, if I open the same images in Paint.NET the pixel value is: 38, 14, 12, 255 (RGBA). (And it's the same for both images).
I also tested what the pixel value would be of the images saved as BMP. In Paint.NET they read again as the same values we saw before:
Steps to Reproduce
Images that should be equal:
SourceImagesThatShouldBeEqual.zip
Code I'm using to reproduce the bug:
System Configuration
The text was updated successfully, but these errors were encountered: