strukturag / libheif

libheif is an HEIF and AVIF file format decoder and encoder.
Other
1.76k stars 302 forks source link

Question about color profile support #119

Open Jehan opened 5 years ago

Jehan commented 5 years ago

Hi!

I just implemented color profile saving/loading for HEIF in the GIMP plug-in with your new API on libheif 1.4.0 (on master branch only), but I have a question:

the heif_color_profile_type has a heif_color_profile_type_rICC and a heif_color_profile_type_prof. What is the difference? Looking how you use the API in example files of your repo, you seem to use "prof" as meaning ICC profiles.

In particular, in examples/heif_enc.cc, you set twice heif_image_set_raw_color_profile(image, "prof" […]) while using ICC raw data.

And well, while I am here, can I ask what is a "nclx" profile? A web search or Wikipedia don't seem to know about this!

farindk commented 5 years ago

prof seems to be the usual ICC profile. rICC is a reduced ICC profile (whatever that means, I also do not know; have not seen one yet). nclx is defined in ISO/IEC 29199-2.

prof

therahedwig commented 4 years ago

Hey, so I have been doing some research, and bothered some people, and now finally know what ricc is: They're matrix shaper icc profiles, and were first defined in the jpeg2000 spec:

http://wiki.opf-labs.org/download/attachments/11337762/15444-1annexi.pdf?version=1&modificationDate=1324478641000 check section I.3.2 Restricted ICC profile method.

It seems like they must be matrix shaper, either grayscale or three component, and be of the 'input' type, though it seems the 'display' type is accepted these days as well? This means that for example, a cLut icc profile (which are made for cmyk or sometimes for rgb displays) is considered inappropriate for this, but all of Elle Stone's working profiles are fine.

For those of us who use LCMS, we can just load the ricc as a regular profile. I am not 100% sure on this, but for saving, it seems like best practice is to do a check whether a profile is...

and if all of these check out, to save it as an ricc profile (and otherwise save into 'prof').

As for nclx, it seems there's some ongoing discussion about whether this one(or cicp?) shouldn't always be saved as having the colorants handy is useful for YUV conversions. (As nclx seems to define a matrix shaper profile as well)

Regardless, it seems wise to document somewhere... I have to admit I wish specs were a little clearer about the workflow of this at times :D

farindk commented 4 years ago

Thanks @therahedwig for researching this background information.

Concerning nclx: I have made the change that an libheif image can store both an nclx and an ICC profile (a84730bf06c). If both are present, the ICC goes into the colr box and the nclx is encoded in the h265 or AV1 bitstreams. If only a nclx profile is present, it is saved into both the colr box and the compressed image bitstreams.

therahedwig commented 4 years ago

I actually have a bit more background info, but this time about nclx. For one, they were first defined in QuickTime specs:

https://developer.apple.com/library/archive/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG10

(They are called nclc inside quicktime, and nclx outside of it) Not huge, but it's nice to have a version that actually explains what the values are (esp. the matrix coefficients).

So, from what I gather, with nclx, it's best practice, to, if your icc profile matches a profile that can be described in nclx to try and also construct a nclx and store that? Is there a best practice regarding icc profiles that don't have a corresponding nclx? (Though, admittedly, maybe we should just warn end-users to convert for situations like that, as, if they're doing something so specialized, I doubt conversion is the only pre-export step they have to take...)

farindk commented 4 years ago

The definitive reference for the values in the nclx is h.273: https://www.itu.int/rec/T-REC-H.273/en The h.273 standard is also copied in large parts to other standards (e.g. h.265) as the same information can also be coded in the bitstream.

Converting between nclx and ICC is probably a bit too much. ICC by itself it too complex to integrate in a codec library. It's better to handle the ICC externally with lcms2, for example.

therahedwig commented 4 years ago

Converting between nclx and ICC is probably a bit too much. ICC by itself it too complex to integrate in a codec library. It's better to handle the ICC externally with lcms2, for example.

You misunderstood me, I meant for someone who is using this library? Like, graphics programs that use LCMS2 need to convert nclx to icc when there's no icc present anyway, because nclx says the file is encoded in adobe rgb we should be making an adobe rgb icc profile, because otherwise the colors of the image are misrepresented. My question was, if we let the user export, should the graphics program that uses lcms2 be both storing an icc profile, and try to get an nclx and store it if the icc profile can also be represented in nclx (such as the case for adobe rgb)?