New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 874939 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Oct 11
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Feature

Blocked on:
issue 839034



Sign in to add a comment

Support e-sRGB 16 bit PNG in ImageDecoder

Project Member Reported by zakerinasab@chromium.org, Aug 16

Issue description


16 bit PNGs in e-sRGB color space decode fine to 8888, but fail to decode to F16, hence they are excluded from PNGImageDecoder unit tests. 

Apparently, in case of e-sRGB, ImageDecoder falls into color transformation code path, which is not the case for other color spaces when ColorBehavior is set to kTag.

 
Cc: brianosman@chromium.org mtklein@chromium.org
The IsTag section of ImageDecoder::ColorTransform() says

    // This will most likely be equal to the |src_profile|.
    // In that case, we skip the xform when we check for equality below.

It sounds like for the other color spaces, we ended up able to skip the transform, but e-sRGB is going to require one.
The problem is not with e-sRGB, it is with the profile of the images color converted in Adobe Photoshop 18. 

Source image in sRGB: https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/images/resources/png-16bit/2x2_16bit_sRGB_opaque.png

Converted to e-sRGB using Photoshop 18:
https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/images/resources/png-16bit/2x2_16bit_e-sRGB_opaque.png

Skia fiddle that shows skcms_Parse() successfully(?) parses the embedded profile but SkColorSpace::Make(profile) fails to return a valid color space.

I'll generate some 16 bit e-sRGB samples with SkEncoder and I expect them to pass the tests. Still I think we need to fix this since Photoshop can be an important source of e-sRGB images.
Yeah, that image has a profile that Skia cannot work with (or even represent with an SkColorSpace), but skcms can take it as an input.  I think you might want to check for these situations and use skcms to transform to a known good SkColorSpace.

Here's the skcms iccdump for that profile:

~/skcms (public↑1|✔) $ out/clang/iccdump ~/Desktop/2x2_16bit_e-sRGB_opaque.png
Profile name from .png: 'e-sRGB'
                Size : 0x00001D24 : 7460
    Data color space : 0x52474220 : 'RGB '
                 PCS : 0x58595A20 : 'XYZ '
           Tag count : 0x0000000B : 11

 Tag    : Type   : Size   : Offset
 ------ : ------ : ------ : --------
 'cprt' : 'mluc' :    110 : 264
 'desc' : 'mluc' :     40 : 376
 'wtpt' : 'XYZ ' :     20 : 416
 'bkpt' : 'XYZ ' :     20 : 436
 'chad' : 'sf32' :     44 : 456
 'A2B0' : 'mAB ' :   1688 : 500
 'A2B2' : 'mAB ' :   1688 : 500
 'A2B1' : 'mAB ' :   1688 : 2188
 'B2A0' : 'mBA ' :   1792 : 3876
 'B2A2' : 'mBA ' :   1792 : 3876
 'B2A1' : 'mBA ' :   1792 : 5668

 A2B : "M", Matrix, "B"
 "M" : 3 inputs
  M0 : 16-bit table with 256 entries
  ~= : 2.360165, 0.04138637, 0.2936969, 1.290439, 0.05490196, 0.01433209, 0 (Max error: 15.9174) (D-gap: -2.75224e-05)
  M1 : 16-bit table with 256 entries
  ~= : 2.360165, 0.04138637, 0.2936969, 1.290439, 0.05490196, 0.01433209, 0 (Max error: 15.9174) (D-gap: -2.75224e-05)
  M2 : 16-bit table with 256 entries
  ~= : 2.360165, 0.04138637, 0.2936969, 1.290439, 0.05490196, 0.01433209, 0 (Max error: 15.9174) (D-gap: -2.75224e-05)
Mtrx : | 0.959396958 0.847338140 0.314814538 -0.503105104 |
       | 0.489433438 1.577521086 0.133390293 -0.521812081 |
       | 0.030578148 0.213589266 1.570868373 -0.430443883 |
 "B" : 3 outputs
  B0 : 1, 1, 0, 0, 0, 0, 0 (~Identity)
  B1 : 1, 1, 0, 0, 0, 0, 0 (~Identity)
  B2 : 1, 1, 0, 0, 0, 0, 0 (~Identity)
252 random bytes transformed to linear XYZD50 bytes:
	003012 e8ff0c 335505 00000c 000032 5a3300 2d9d18
	8c3b0f 000000 884609 dcd000 274100 0c230c 3510c0
	da9ed9 4255b8 7a8838 213706 000041 ae7b00 cd60e5
	ac4e06 000012 ffff67 a327c2 a9ff22 00008a 41762b
	24240e 150b1e 000028 96983f bcff76 bc577c 2d7f00
	759ca3 192d05 430000 4bc020 000000 00006a 07073b
	000093 000000 395b77 000000 051300 4a2400 b165bb
	ffe249 e87eff 6a3305 236514 56a826 000000 86ff10
	519615 8a5b00 010006 160d00 000011 000000 281403
	57456b 4a245b 215600 2a004c 000000 0e0d39 4b51b0
	0f2201 220ea4 00000e 590b00 5ec900 000000 4a46ef
	84fe0a 31130c 151f18 633206 53b228 492302 424da1
IIUC, the check is already there and we fall back to sRGB: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/image-decoders/image_decoder.cc?l=621

Still it appears that skcms reads the embedded color profile as something different than sRGB, causing skcmsTransform to change the pixels even though the source image does not have any values outside [0,1]:

(this is what PNGImageReader reads)
      0.6414435035, 0.6857862211, 0.747005417,  1,   // Top left pixel
      0.877347982,  0.8382848859, 0.6494087129, 1,   // Top right pixel
      0.735194934,  0.9353933013, 0.9374380102, 1,   // Bottom left pixel
      0.9209277485, 0.9575799191, 0.9264515145, 1    // Bottom right pixel
Right, that's not a profile that we can recognize as sRGB.  Eyeballing the 3D overlap between this profile and sRGB, it's not entirely clear to me that we'd want to.

In general I don't think it makes much sense to think of A2B profiles like this in the context of extending past [0,1], at least not without matching them against  if we have to go through a table lookup anywhere, that kind of defeats "extending" past the table range.

Looking at this a little more closely, this is a somewhat unusual A2B profile that I think could actually be backported to be a TRC+XYZ profile.  Let me run through that math and hopefully that'll let me compare against sRGB a little more sensibly.
err, that should be "...without matching them against a parametric form.  If we have to ..."
Oops, I was mistaken about being able to backport that profile to TRC+XYZ for comparison.  But, it still stands that there are colors in sRGB that this profile cannot represent, and colors this profile can represent that are outside sRGB.

That conversion in photoshop doesn't appear to have preserved the colors.  Here's what the two files you uploaded look like on my screen, the original sRGB on the left and the e-sRGB on the right.
Screen Shot 2018-10-09 at 2.53.30 PM.png
248 KB View Download
Status: Fixed (was: Assigned)
I replaced the e-sRGB files created with Adobe Photoshop with new samples
created using SkPngEncoder. Everything works fine now.


https://chromium-review.googlesource.com/c/chromium/src/+/1276885

Sign in to add a comment