strukturag / libheif

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

Problem with saving NCLX profile #995

Open bigcat88 opened 1 year ago

bigcat88 commented 1 year ago

Currently do not know to reproduce it with heif-enc (I can not find how to save nclx profile with it), still searching was what changed in libheif itself related to this.

I remember our discussion https://github.com/strukturag/libheif/discussions/931 but there was no talks that some breaking change will appear.

I used heif_image_set_nclx_color_profile to set profile and set macOS_compatibility_workaround_no_nclx_profile to False, but for some reason with last version no NCLX profile get saved.

Can someone point me right place what changes was in 1.17.0 to this?

bigcat88 commented 1 year ago

https://github.com/strukturag/libheif/blob/18d4e550ad7ee114fb95ba2256ee3e756174e92d/libheif/context.cc#L2573

I think this is due to this new line of code.

Here does not count that NCLX profile can be set before with heif_image_set_nclx_color_profile and not be passed in the options.

farindk commented 1 year ago

First, note that heif_image_set_nclx_color_profile sets the nclx profile of the input image. This is not necessarily the same as the nclx profile in the output image. The profile to be used in the output is specified in heif_encoding_options::output_nclx_profile. libheif now does the correct color conversion between these two profiles. If no custom output profile is specified, the input profile is used, though.

If the input image contains an ICC profile, libheif writes only this ICC profile to the output MP4 container as the first version of HEIF said that only one color profile may be saved. In this case, the nclx profile is stored in the compressed bitstream (at least for heic and avif) and also read from there during decoding. I assume that this is what confused you.

In the HEIF v2 standard, it is now allowed to store multiple color profiles in the MP4 container (e.g. ICC and nclx). This can be enabled with heif_encoding_options::save_two_colr_boxes_when_ICC_and_nclx_available.

bigcat88 commented 1 year ago

First, note that heif_image_set_nclx_color_profile sets the nclx profile of the input image. This is not necessarily the same as the nclx profile in the output image. The profile to be used in the output is specified in heif_encoding_options::output_nclx_profile. libheif now does the correct color conversion between these two profiles. If no custom output profile is specified, the input profile is used, though.

thanks for clarification, I will rewrite code today and post the result

farindk commented 1 year ago

https://github.com/strukturag/libheif/blob/18d4e550ad7ee114fb95ba2256ee3e756174e92d/libheif/context.cc#L2573

I think this is due to this new line of code.

Yes, right. I guess when no ICC is preset, we could save the nclx also in the MP4 container. Actually, it is then twice in the file and would enlarge it slightly, but it would be easier to access. Not really sure yet what the best method would be, but I agree that the current situation (save it only when specified in encoding options) is somehow inconsistent.

farindk commented 1 year ago

I propose the following libheif change:

bigcat88 commented 1 year ago

In discussion you also mentioned this situation:

"input is RGB no nclx specified in options -> convert to YCbCr with default nclx parameters and save those parameters"

will it be covered? Cause that line prevents it.

P.S:

The profile to be used in the output is specified in heif_encoding_options::output_nclx_profile.

Tested and it works, if I specify profile in output_nclx_profile it got saved.

bigcat88 commented 1 year ago

In theory, this issue can be closed, because I am completely satisfied with the explanations and how the latest version works with NCLX. I was able to make it work very nice in python, providing a different ways to people to use it(I hope).