Uh oh!
There was an error while loading. Please reload this page.
Jpeg compressed tiff: jpeg decoder should handle the conversion from YCbCr to RGB - #2124
Conversation
JimBobSquarePants
commented
May 21, 2022
@brianpopow You're not gonna like this but since it's such a critical bug we'll have to backport this PR to the release/2.1.x branch. |
@brianpopow This looks to be how libjpeg-turbo figures it out. |
brianpopow
commented
May 22, 2022
I think it is working now as it should. I had to change how the jpeg decoder deduces the colorspace. That's why this should be reviewed carefully. It is close to how libjpeg does it, but not exactly the same. libjpeg checks for a JFIF marker first and then concludes it should be YCbCr. We first check for adobe with a color transform and if the component Id's are ASCII R, G, B. The reason for that is, that there is a test image @br3aker if you have time to review this part, your feedback would be very much appreciated. |
br3aker
commented
May 22, 2022
Ups, completely missed this, will review tomorrow! |
There was a problem hiding this comment.
Strictly speaking, oracle docs are not accurate according to jpeg specs. We can have 2 different 'versions' for the jpeg image - jfif and adobe jfif (exif of whatever it's called). So we can have 2 different paths:
- Have jfif marker
- Have app14 adobe marker
But we can't have both at the same time according to the specs. I'd suggest to write it like this:
if(componentCount==1){returngrayscale;}if(componentCount==3){// we prioritize adobe marker over jfif marker// if somebody really encoded this image with redundant adobe marker// then it's most likely an adobe jfif image IMOif(this.adobeMarkeris not null){if(this.adobeMarker.Transform==ycbcr)returnycbcr;elseif(this.adobeMarker.Transform==unknown)returnrgb;// throw if color transform flag has invalid value?}if(this.jfifMarkeris not null){returnycbcr;}// fallback to the id color deductionreturnthis.Components[2].Id==66&&this.Components[1].Id==71&&this.Components[0].Id==82?rgb:ycbcr;}if(componentCount==4){// jfif images don't not support 4 component images// so we only check adobeif(this.adobeMarkeris not null){if(this.adobeMarker.Transform==ycck)returnycck;elseif(this.adobeMarker.Transform==unknown)returncmyk;// throw if color transform flag has invalid value?}// fallback to cmyk as neither of cmyk nor ycck have 'special' component idsreturncmyk;}JpegThrowHelper.ThrowNotSupportedComponentCount(componentCount);returndefault;P.S.
I personally don't like component id color deduction as ids are used to determine components in scans, they have nothing to do with encoding color. AFAIR 'RGB' ASCII ids were proposed by Adobe before jpeg extension via APP14 marker was published.
brianpopow
commented
May 23, 2022
@br3aker thanks for your feedback, I have changed the color deduction accordingly. For |
antonfirsov
commented
May 25, 2022
After merging this PR, we should rebase all the commits in this PR on @JimBobSquarePants I'm not sure what happens after merging the backport PR, is it enough to just tag the merge commit with |
antonfirsov
commented
May 25, 2022
@JimBobSquarePants is faster doing than me talking 😆 |
JimBobSquarePants
commented
May 25, 2022
Haha 😄 Yeah, See #2126 It should be enough to PR against the release branch then create a tagged release via the UI here ensuring we are pointing at the correct branch to create the release from. |
Prerequisites
Description
This PR provides a fix for #2123: If the image uses Jpeg Compression, the jpeg decoder should handle the conversion from YCbCr to RGB and not the Tiff Decoder, See discussion in #2123