Decoded fruit.png (which contains a strong gamma value in a gAMA chunk).
Encoded back to result.png.
Opened result.png in a gAMA-aware viewer (Chromium)
What did you expect to see?
What did you see instead?
I understand (after reading file reader_test.go and part of the PNG spec) that handling ancillary chunks (e.g. gAMA) is not a requirement for a PNG decoder. I also understand that implementing it would require some (unknown to me) amount of work. So, the question boils down to "would it be a good idea or not to take the gAMA chunk into account?".
The text was updated successfully, but these errors were encountered:
It would be a good idea, but it's also non-trivial. The right solution would probably be to add some concept to the image/color package to represent color spaces (e.g. sRGB vs Adobe RGB), including the concept of gamma. Designing that new API is probably a substantial amount of work, and not something I have time for any time soon. Sorry.
See also #11420 "x/image/draw: color space-correct interpolation".
Though my example involved Decode and Encode, I was more concerned about what happens in Decode, when the gAMA is encountered and ignored. How about "modifying the color values of each pixel at the end of Decode", i.e. "applying" the custom gamma, and then forget about gamma concepts?
Acknowledged, this is not the same thing as (and would be less thorough than) introducing color spaces concepts to the std image and color packages.
I'm wary of making a short-term workaround like that. If, for example, we shipped that in Go 1.10, then maintaining backwards compatibility might constrain us in doing the right solution for a later Go 1.x version.
I have implemented the gAMA, cHRM, and sRGB chunks in PNG's writer.go. I added constants for rendering intent, and parameters in Encoder.
// sRGB rendering intent: (https://www.w3.org/TR/PNG/#11cHRM 184.108.40.206)
type RenderingIntent byte
// Perceptual: images preferring good adaptation to the output device
// gamut at the expense of colorimetric accuracy, such as photographs.
Perceptual RenderingIntent = 0
// Relative colorimetric: images requiring colour appearance matching
// (relative to the output device white point), such as logos.
Relative RenderingIntent = 1
// Saturation: images preferring preservation of saturation at the expense
// of hue and lightness, such as charts and graphs.
Saturation RenderingIntent = 2
// Absolute: images requiring preservation of absolute colorimetry, such
// as previews of images destined for a different output device (proofs).
Absolute RenderingIntent = 3
However, this is write-only and does not change any pixel values, it simply allows the user to have the output PNG represent the nature of the data; any gamma-encoding must have already been done before the image was supplied to the encoder. I could add the read side if desired.
It is dangerous to to the gamma encode in that commonly 8-bit components commonly need to be companded to a larger size and there is no natural place for that here. That said, I do have the code handy...