|Issue 2821||Incomplete, progressive JPEG image appears black when opened|
|Starred by 4 users||Reported by s.anu...@gmail.com, Aug 11 2014||Back to list|
What steps will reproduce the problem? 1. Copy the attached image to the device 2. Open the image What is the expected output? What do you see instead? View the image properly. Black/grey image displayed. If the image is corrupted, a message should be displayed informing the user What version of the product are you using? On what operating system? Nexus 5 (Android 4.4.4) Please provide any additional information below. Suspect a jpeg image decoding issue
Aug 11 2014,
Reproduced on 4.4.4, Moto X, although when accessing the file, prior to download, I did get an "unable to access document" error where I normally get to view the jpeg, so the system reported something was wrong with the file. (I could still force the download, open with gallery and make the black display happen.)
Aug 11 2014,
Confirmed code is reporting decoding issue. Hal helped out with some quick libjpeg analysis/testing, seems to work on Linux/Mac viewers use of libjpeg, with Chrome's use of libjpeg-turbo, but the version of the library we pull in (or our use of it).
Sep 22 2014,
Nov 10 2014,
jpeg_start_decompress returns false, although I haven't found a description of what the return value means. While debugging, though, it stream->isAtEnd() returned true, so it appears we reached the end of the stream during that function. This means our later calls would have nothing to read. I haven't figured out how other decoders successfully decode this image. (FWIW, I believe on Android we use libjpeg-turbo as well.)
May 14 2015,
Re: #4: Android does *not* use libjpeg-turbo; I was mistaken. Reassigning to Matt, who is investigating switching to libjpeg-turbo and generally looking into jpeg bugs.
Oct 23 2015,
This is an incomplete, progressive jpeg image. Notice, how the bottom 3/4 of the image appears very blurry. That is because the end of the jpeg file (with more information on these pixels) is missing. SkImageDecoder_libjpeg and SkJpegCodec choose not to decode progressive images progressively. jpeg_start_decompress() will perform all of the entropy decoding upfront and then we will finish the decode line-by-line using jpeg_read_scanlines(). In this case, jpeg_start_decompress() cannot complete the entropy decoding because the image is truncated. It will therefore, never allow us to enter the SCANNING state and begin decoding scanlines. This is consistent with Leon's note above (#4) that indicates that jpeg_start_decompress() returns false. Chromium (and most other decoders, it appears) try to decode progressive images progressively (in buffered_image mode). This allows them to perform the entropy decoding as they go. Therefore, they will not fail until the final pass, and the output will look somewhat reasonable. We could adopt this strategy for progressive images but it would require using the libjpeg-turbo API differently for progressive images. I am hesitant about this - it's not a great fit for Skia's scanline decoder API (it would look very similar to how we handle interlaced pngs). IMO, jpeg_start_decompress() shouldn't fail even if it can't completely finish the entropy decode for progressive images. I locally patched libjpeg-turbo to change this behavior. It's a one line patch that I doubt they would accept. And the output is still underwhelming compared most other decoders. I am attaching it. A more significant, tricky (and likely unacceptable) patch could probably allow us to duplicate the behavior of chromium decoder. Right now this seems low priority to me. I'm not sure exactly what the best fix for us is.
Oct 23 2015,
Oct 26 2016,
I suspect that Leon will fix this when he adds incremental decoding support to SkJpegCodec.
> I suspect that Leon will fix this when he adds incremental > decoding support to SkJpegCodec. cblume@ is now looking to switch SkJpegCodec to incremental decoding. This will be a good test case.
|► Sign in to add a comment|