-
Notifications
You must be signed in to change notification settings - Fork 608
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
PNG alpha premultiplied in texture color space or linear color space? #4314
Comments
Proposed fix in #4315 |
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this issue
Jun 27, 2024
…dation#4315) TL;DR: when turning unassociated alpha into associated for gamma-corrected PNG images, we got the exponent wrong for the linearization step, and when doing the same for sRGB images, we didn't linearize at all. WARNING: will change appearance of PNG files with partial alpha. Details: Ugh, two separate problems related to how we associate alpha (i.e. premultiply the colors) for PNG pixels with partial alpha. The correct thing to do is linearize the unassociated pixel value first, then associate, then go back to the nonlinear space. First problem: PNGs have three possible transfer functions: gamma correction (with a particular gamma), no gamma correction / linear, and explicitly sRGB. Guess what? We were neglecting the case of pngs tagged as sRGB and not doing the linearize/delinearize round trip for those images. But if that's not enough, also for the gamma case, we were, ugh, swapping the gamma and 1/gamma, resulting in those partial alpha pixels ending up a whole lot darker than they should have been. None of this affected most ordinary PNGs with no alpha channel, or where alpha was 1.0. It only affected "edge" or "partially transparent" pixels with 0 < alpha < 1. But it was definitely wrong before, for which I apologize and hope you'll understand why those pixels are going to change now (hopefully, always always for the better). While I was at it, I also made the color space handling a little more robust -- instead of just a straight string compare for color space names, use the ColorConfig to check `equivalent`, which should make us a lot more robust against aliases and whatnot. Fixes AcademySoftwareFoundation#4314 Closes AcademySoftwareFoundation#4054 --------- Signed-off-by: Larry Gritz <lg@larrygritz.com>
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this issue
Jun 27, 2024
…dation#4315) TL;DR: when turning unassociated alpha into associated for gamma-corrected PNG images, we got the exponent wrong for the linearization step, and when doing the same for sRGB images, we didn't linearize at all. WARNING: will change appearance of PNG files with partial alpha. Details: Ugh, two separate problems related to how we associate alpha (i.e. premultiply the colors) for PNG pixels with partial alpha. The correct thing to do is linearize the unassociated pixel value first, then associate, then go back to the nonlinear space. First problem: PNGs have three possible transfer functions: gamma correction (with a particular gamma), no gamma correction / linear, and explicitly sRGB. Guess what? We were neglecting the case of pngs tagged as sRGB and not doing the linearize/delinearize round trip for those images. But if that's not enough, also for the gamma case, we were, ugh, swapping the gamma and 1/gamma, resulting in those partial alpha pixels ending up a whole lot darker than they should have been. None of this affected most ordinary PNGs with no alpha channel, or where alpha was 1.0. It only affected "edge" or "partially transparent" pixels with 0 < alpha < 1. But it was definitely wrong before, for which I apologize and hope you'll understand why those pixels are going to change now (hopefully, always always for the better). While I was at it, I also made the color space handling a little more robust -- instead of just a straight string compare for color space names, use the ColorConfig to check `equivalent`, which should make us a lot more robust against aliases and whatnot. Fixes AcademySoftwareFoundation#4314 Closes AcademySoftwareFoundation#4054 --------- Signed-off-by: Larry Gritz <lg@larrygritz.com>
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this issue
Jun 27, 2024
…dation#4315) TL;DR: when turning unassociated alpha into associated for gamma-corrected PNG images, we got the exponent wrong for the linearization step, and when doing the same for sRGB images, we didn't linearize at all. WARNING: will change appearance of PNG files with partial alpha. Details: Ugh, two separate problems related to how we associate alpha (i.e. premultiply the colors) for PNG pixels with partial alpha. The correct thing to do is linearize the unassociated pixel value first, then associate, then go back to the nonlinear space. First problem: PNGs have three possible transfer functions: gamma correction (with a particular gamma), no gamma correction / linear, and explicitly sRGB. Guess what? We were neglecting the case of pngs tagged as sRGB and not doing the linearize/delinearize round trip for those images. But if that's not enough, also for the gamma case, we were, ugh, swapping the gamma and 1/gamma, resulting in those partial alpha pixels ending up a whole lot darker than they should have been. None of this affected most ordinary PNGs with no alpha channel, or where alpha was 1.0. It only affected "edge" or "partially transparent" pixels with 0 < alpha < 1. But it was definitely wrong before, for which I apologize and hope you'll understand why those pixels are going to change now (hopefully, always always for the better). While I was at it, I also made the color space handling a little more robust -- instead of just a straight string compare for color space names, use the ColorConfig to check `equivalent`, which should make us a lot more robust against aliases and whatnot. Fixes AcademySoftwareFoundation#4314 Closes AcademySoftwareFoundation#4054 --------- Signed-off-by: Larry Gritz <lg@larrygritz.com>
lgritz
added a commit
to lgritz/OpenImageIO
that referenced
this issue
Jul 16, 2024
…dation#4315) TL;DR: when turning unassociated alpha into associated for gamma-corrected PNG images, we got the exponent wrong for the linearization step, and when doing the same for sRGB images, we didn't linearize at all. WARNING: will change appearance of PNG files with partial alpha. Details: Ugh, two separate problems related to how we associate alpha (i.e. premultiply the colors) for PNG pixels with partial alpha. The correct thing to do is linearize the unassociated pixel value first, then associate, then go back to the nonlinear space. First problem: PNGs have three possible transfer functions: gamma correction (with a particular gamma), no gamma correction / linear, and explicitly sRGB. Guess what? We were neglecting the case of pngs tagged as sRGB and not doing the linearize/delinearize round trip for those images. But if that's not enough, also for the gamma case, we were, ugh, swapping the gamma and 1/gamma, resulting in those partial alpha pixels ending up a whole lot darker than they should have been. None of this affected most ordinary PNGs with no alpha channel, or where alpha was 1.0. It only affected "edge" or "partially transparent" pixels with 0 < alpha < 1. But it was definitely wrong before, for which I apologize and hope you'll understand why those pixels are going to change now (hopefully, always always for the better). While I was at it, I also made the color space handling a little more robust -- instead of just a straight string compare for color space names, use the ColorConfig to check `equivalent`, which should make us a lot more robust against aliases and whatnot. Fixes AcademySoftwareFoundation#4314 Closes AcademySoftwareFoundation#4054 --------- Signed-off-by: Larry Gritz <lg@larrygritz.com>
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Discussed in #4054
Originally posted by jimenea November 17, 2023
Hello,
I am trying to understand why PNG files with alpha are not giving us the expected results. The issue seems to be down to how OpenImageIO premultiplies the alpha when loading this texture. Is it done in the texture color space or the linear color space? Our results seem to indicate the former.
I have attached a single-pixel texture, cropped from the original texture, which shows this very clearly. This texture contains the pixel color (1, 1, 1, 0.5). We get that value correctly when checking with "oiiotool --dumpdata -no-autopremult", but when we take out the "-no-autopremult" option, we get "55 55 55 127 (0.21568629 0.21568629 0.21568629 0.49803925)". Notice how this value is suspiciously close to the expected value in linear space with gamma 2.2 applied (0.5 ^ 2.2 = 0.2176).
After reading https://www.realtimerendering.com/blog/a-png-puzzle/, I think we should be getting something like (187, 187, 187, 128). Am I correct? Is there anything else I should be doing? Maybe I am missing an option to change this behaviour?
Thanks in advance.
Regards,
Angel
test.png.zip
The text was updated successfully, but these errors were encountered: