nothings / stb

stb single-file public domain libraries for C/C++
https://twitter.com/nothings
Other
26.68k stars 7.71k forks source link

stb_image supported 16-bpc file formats should support float/HDR path #227

Open nothings opened 8 years ago

nothings commented 8 years ago

The 16-bpc file formats loaded by stb_image currently (PNG and PSD) just discard the bottom 8-bits, since there's nothing reasonable to do on the 8-bit path. However, they should also support the float "HDR" API path.

But how to transform 16-bit integer to float? API is supposed to be file-format independent, so we should be returning floats in a linear space. But what format are 16-bpc PSD and 16-bpc PNGs in? Are they always linear? Or are they gamma-corrected with more precision? For example, do PNGs need to respect gAMA/sRGB in this case? Research is needed.

(Respecting gAMA/sRGB would be inconsistent with 8-bit, where they're always ignored, but this is intentional because they're often broken in 8-bit, and passing through unaltered respects the original data maximally, as any 8-bit-to-8-bit conversion would lose data. 16-bit-to-float conversion wouldn't lose data and could theoretically be reversed by app if necessary.)

socks-the-fox commented 8 years ago

So far, the 16-bit PNGs I've come across look exactly the same on my computer with gAMA and iCCP chunks stripped out. Granted, they're all from the same person but to my knowledge they're just using their art program's default settings for exporting PNGs (which in this case is Krita).

I think applying gamma and color space corrections should be an optional step users can call themselves, but the way I have in mind would require implementing a new lower level public interface (though the current one could potentially be implemented using it, allowing compatibility with current codebases).

MarkCallow commented 5 years ago

(Respecting gAMA/sRGB would be inconsistent with 8-bit, where they're always ignored, but this is intentional because they're often broken in 8-bit, and passing through unaltered respects the original data maximally,

What do you mean they are often broken? Ignoring them is not "respect(ing) the original data maximally". sRGB/gAMA are a form of perceptually-based encoding (i.e. compression) to make best use of a narrow channel such as an 8-bit channel. The original data is the pre-encoding linear data and by ignoring sRGB/gAMA and not providing a way to query those values via the stb_image API there is no way for users to recover those original values.

As for 16-bit PNGs, they should be linear. There is no need for sRGB/gAMA as 16-bits is more than enough for there to be no steps larger than humans can perceive.

breakin commented 3 years ago

I ran into this recently. I have 16-bit-PNGs and used the float-loading path of stb. A first good step here would be to retain the 16-bit precision. Then the user can apply reverse-gamma at least. As a user it is hard to know if I should do it or not. Perhaps stb could say if it was unsure of its choice and then state its choice... (stb says it applied gamma and that it was unsure).

Note that to how easy it is with single-header libraries I just copied out the three "outer" functions and changed the conversion myself, without having to write any hard code at all.

cesss commented 2 years ago

The 16-bpc file formats loaded by stb_image currently (PNG and PSD) just discard the bottom 8-bits, since there's nothing reasonable to do on the 8-bit path.

Is this still true as of today? Looking at the code, I thought that the full 16 bit were loaded in unsigned shorts if using the 16bit API.