Opened 2 years ago

Closed 21 months ago

#9672 closed defect (fixed)

ffmpeg not writing ICC profiles in images

Reported by: Cosmin Stejerean Owned by: Niklas Haas
Priority: normal Component: undetermined
Version: unspecified Keywords:
Cc: mirh, Niklas Haas Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description

For image output formats, primarily JPEG (but PNG and WebP would also be nice to have) it appears the latest FFmpeg 5 does not support writing ICC profiles, even with color primaries/space/trc parameters are specified.

Example: this should produce JPEG in the sRGB color space but no ICC profile is found in the output. This can be confirmed by running exiftool on the output

ffmpeg -filter_complex color=red:s=640x480 -frames 1 -q:v 1 -color_primaries bt709 -colorspace bt470bg -color_range pc -color_trc iec61966-2-1 -pix_fmt yuv420p red.jpg

This should output JPEG in Display P3 color space

ffmpeg -filter_complex color=red:s=640x480 -frames 1 -q:v 1 -color_primaries smpte432 -colorspace bt470bg -color_range pc -color_trc iec61966-2-1 -pix_fmt yuv420p red.jpg

Separately reading color information from ICC profiles is also not working as expected, but will file a separate ticket for that.

Change History (8)

comment:1 by Balling, 2 years ago

PNG does write cHRM and gAMA. But of course even sRGB cannot be written with gAMA chunk, because sRGB is not 2.2 gamma.

comment:2 by mirh, 2 years ago

Cc: mirh added

comment:3 by Niklas Haas, 2 years ago

Cc: Niklas Haas added
Owner: set to Niklas Haas
Status: newopen

comment:4 by Niklas Haas, 2 years ago

As of e254af31549ce6b4964936b3fe2124c3a18e69f8, FFmpeg will now *write* ICC profiles to both PNG and JPG. As such, if you open a image with an embedded ICC profile for transcoding, the ICC profile will be preserved.

That doesn't technically cover the entirety of this issue, which as written also requires generating ICC profiles from scratch. But it does mean that the combination of #9672+#9673 works as intended, as long as you ignore that the ICC profile is only present in the form of side data (rather than colorspace tags).

I will also submit a separate patch for ICC profile generation and reading down the line, but for the time being, does this solve your use case?

comment:5 by Cosmin Stejerean, 2 years ago

Reading ICC profile from the input and getting it passed to the output via side data is a good first step that will help in some limited cases. The most important usecase however is generating matching thubmails from a video sequence, and for that we really need the ability to generate the proper ICC profile from the video color information.

comment:6 by Niklas Haas, 2 years ago

As of 5cfeaeef0c2e0970f64d3188375a525c17f4621b you can now also generate ICC profiles from scratch, using a new video filter, vf_iccgen. (Requires ffmpeg built with support for lcms2)

In the case you describe (i.e. transcoding a video with known primaries) you can simply add a -vf iccgen somewhere in your video chain. It will automatically generate an ICC profile for the tagged video color space. (And is, by default, a no-op for files which already have embedded ICC profiles in them)

For the example in the OP, you would either need to manually tag the video stream (vf_setparams or using input options), or specify the explicit color space you want as options to vf_iccgen.

I may reconsider my opinion on whether or not the png/jpeg encoders should automatically generate ICC profiles on encoding, but for the time being I think a video filter is a good compromise.

comment:7 by Cosmin Stejerean, 2 years ago

I think this could work for the short term and solve the underlying problem, although it still feels more cumbersome than it should be. This feels like the kind of behavior that should happen automatically (if not as of 5.1 then perhaps as of ffmpeg 6.0). Instead of manually injecting a filter any chance we could enable this behavior with a flag, which can be say opt-in for ffmpeg 5.1 to give folks a chance to kick the tires on it, and assuming there's no major problems found it can become opt out in ffmpeg 6.0

comment:8 by Niklas Haas, 21 months ago

Resolution: fixed
Status: openclosed

Instead of manually injecting a filter any chance we could enable this behavior with a flag, which can be say opt-in for ffmpeg 5.1 to give folks a chance to kick the tires on it, and assuming there's no major problems found it can become opt out in ffmpeg 6.0

This is now implemented on master. You can specify -flags2 icc_profiles to enable the experimental functionality.

(Example taken from OP)
$ ffmpeg -flags2 icc_profile -filter_complex color=red:s=640x480 -frames 1 -q:v 1 -color_primaries bt709 -colorspace bt470bg -color_range pc -color_trc iec61966-2-1 -pix_fmt yuv420p red.jpg
$ exiftool red.jpg
...
Profile Description : RGB built-in
Profile Copyright : No copyright, use freely
Media White Point : 0.9642 1 0.82491
Chromatic Adaptation : 1.04788 0.02292 -0.05022 0.02959 0.99048 -0.01707 -0.00925 0.01508 0.75168
Red Matrix Column : 0.43604 0.22249 0.01392
Blue Matrix Column : 0.14305 0.06061 0.71391
Green Matrix Column : 0.38512 0.7169 0.09706
...

Closing this issue, as now it's merely a matter of time and (eventually) enabling the new functionality as default.

Note: See TracTickets for help on using tickets.