Opened 2 years ago

Closed 20 months ago

Last modified 7 months ago

#9673 closed defect (fixed)

ffmpeg not reading color information from JPEG ICC profile

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

Description

ffmpeg / ffprobe is not reading color information from the ICC profile in JPEG. Somewhat related to #9672 (where it also fails to write it to JPEG), for proper support of wide color gamut it's important to be able to both read and write color information properly. This ticket focuses on the reading part.

Attached is an example image in P3 color space (which needs a P3 capable display to render properly). ffprobe is not able to read the ICC color information from this, but it can be read by for example exiftool

Steps to reproduce.

  1. Download the attached test.jpg
  1. Can confirm the ICC profile info with exiftool
exiftool test.jpg

Profile Description             : Display P3

additional output of exiftool is omitted for brevity

  1. Check ffprobe color information
ffprobe -show_streams test.jpg | grep color

color_range=pc
color_space=bt470bg
color_transfer=unknown
color_primaries=unknow

Expected values are color primaries smpte432, color trc iec61966-2-1

Attachments (1)

test.jpg (251.9 KB ) - added by Cosmin Stejerean 2 years ago.

Download all attachments as: .zip

Change History (26)

by Cosmin Stejerean, 2 years ago

Attachment: test.jpg added

comment:1 by Niklas Haas, 2 years ago

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

comment:2 by Niklas Haas, 2 years ago

As of 2cb0cebd11eb90dfcccac5c258af1003bd4f17d2, ffmpeg is capable of parsing embedded ICC profiles and inferring the colorimetry tags. Currently, this is not automatic, but must be manually requested by inserting a -vf iccdetect filter.

Note that this relies on reasonably well-behaved ICC profiles - if the ICC profile deviates too strongly from the set of known primaries and transfer curve, the tags will remain as 'undefined'.

All ICC profiles used in practice should be well-behaved in this regard, but YMMV.

comment:3 by Niklas Haas, 2 years ago

All ICC profiles used in practice should be well-behaved in this regard, but YMMV.

Oh, actually, it's worth pointing out that the test image attached to OP is *not* actually a Display P3 profile, despite the profile comment seemingly claiming otherwise. (It's actually a profile with an sRGB tone curve and custom primaries)

in reply to:  3 comment:4 by Balling, 2 years ago

Replying to haasn:

All ICC profiles used in practice should be well-behaved in this regard, but YMMV.

Oh, actually, it's worth pointing out that the test image attached to OP is *not* actually a Display P3 profile, despite the profile comment seemingly claiming otherwise. (It's actually a profile with an sRGB tone curve and custom primaries)

You are absolutely wrong. Display P3 is Apple profile that uses sRGB EOTF and P3-D65 primaries, not custom primaries, of course in ICCv4 adapted to D50, so you need to chromatically adapt the primaries first. They are not custom or whatever.

But then again, you also believed that CLL cannot change in mp4 file, I proved you wrong.

Profile Description : Display P3
Profile Copyright : Copyright Apple Inc., 2015
Media White Point : 0.95045 1 1.08905
Red Matrix Column : 0.51512 0.2412 -0.00105
Green Matrix Column : 0.29198 0.69225 0.04189
Blue Matrix Column : 0.1571 0.06657 0.78407
Chromatic Adaptation : 1.04788 0.02292 -0.0502 0.02959 0.99048 -0.01706 -0.00923 0.01508 0.75168

these primaries perfectly describe P3-D65 after you apply Chromatic Adaptation matrix.

Red Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Blue Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 32 bytes, use -b option to extract)

These values describe sRGB curve using "para" encoding per every component above:

0 2.399994
1 0.947861
2 0.052139
3 0.077393
4 0.040451

This is the same as reference sRGB curve.

Last edited 2 years ago by Balling (previous) (diff)

comment:6 by Balling, 2 years ago

Yes, Apple profile is quite buggy, it has not perfect chromatic adaption matrix and it has negative red Z, which is prohibited and caused all kinds of problems (not on MacOS) in our chromium and firefox, though is correctly done by Little CMS stealing it from Adobe CMS/Apple. It is not like with V-gamut though in mpv code, that has "wrong" negative values even natively, while red Z negative in Display P3 comes from slightly wrong chromatic adapation done by Apple (it is also xy, not XYZ, see your commit https://github.com/mpv-player/mpv/commit/247ec0cb841c28b97a186675c0ef923a0ede2f40).

Even sRGB para curve can be made slightly better if only you will round correctly. See repo Compact-ICC-Profiles. It also has correct profiles without negative stuff in red Z.

See my comments here: https://github.com/saucecontrol/Compact-ICC-Profiles/issues/7#issuecomment-943567373

Here: https://github.com/saucecontrol/Compact-ICC-Profiles/issues/6

And here: https://github.com/colour-science/colour/discussions/739

Still you need to understand THAT MEDIA WHITE POINT IS NOT the white point of PROFILE CONNECTION SPACE, though apple did a mistake there as well. PCS is ONLY D50, nothing else is supported untill v5. So you can just ignore it (not for printing, complex relationship is described https://github.com/saucecontrol/Compact-ICC-Profiles/issues/7#issuecomment-943567373).

There is also a problem that display profile is used for what should be an input profile, JPEG 2000 part does not allow that, while part two allowed that.

Last edited 2 years ago by Balling (previous) (diff)

comment:7 by Cosmin Stejerean, 2 years ago

This is a great start, but I'm curious what it would take to do this automatically. For example it would be useful to have the color information exposed in ffprobe, and having to inject a filter into the process would make this more cumbersome.

comment:8 by Niklas Haas, 21 months ago

This is a great start, but I'm curious what it would take to do this automatically. For example it would be useful to have the color information exposed in ffprobe, and having to inject a filter into the process would make this more cumbersome.

As with the other issue, -flags2 icc_profiles enables this experimental functionality on master:

$ ffprobe -flags2 icc_profiles -show_frames test.jpg | grep color
...
color_range=pc
color_space=bt470bg
color_primaries=unknown
color_transfer=iec61966-2-1

Note that you need to use -show_frames and not -show_streams as a result of the ICC profile and hence color space metadata being internally a property of the frame, not the container. (I'll continue thinking about ways we could possibly improve that)

Let me know if your use case is solved.

comment:9 by Niklas Haas, 20 months ago

Resolution: fixed
Status: openclosed

comment:10 by Cosmin Stejerean, 10 months ago

The color primaries shouldn't be unknown though, for P3 I believe this should return color_primaries=smpte432

Also if I attempt to create a P3 image through ffmpeg using

./ffmpeg.sh -flags2 icc_profiles -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 red2.jpg
`

then ffprobe recognizes it as smpte432 however exiftool does not show P3. Instead it shows

Profile ID                      : 0
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.51512 0.2412 -0.00105
Blue Matrix Column              : 0.1571 0.06657 0.78407
Green Matrix Column             : 0.29198 0.69225 0.04189

whereas for the P3 image shared above it shows

Profile Creator                 : Apple Computer Inc.
Profile ID                      : ca1a9582257f104d389913d5d1ea1582
Profile Description             : Display P3
Profile Copyright               : Copyright Apple Inc., 2017
Media White Point               : 0.95045 1 1.08905
Red Matrix Column               : 0.51512 0.2412 -0.00105
Green Matrix Column             : 0.29198 0.69225 0.04189
Blue Matrix Column              : 0.1571 0.06657 0.78407

The notable difference here seems to be the media white point.

0.9642 1 0.82491 maps to D50 illuminant
0.95045 1 1.08905 matches D65

I think P3 is supposed to use D65 adapted to D50 in the ICC profile.

comment:11 by Balling, 9 months ago

The color primaries shouldn't be unknown though, for P3 I believe this should return color_primaries=smpte432

That is P3-D65, so yes.

I think P3 is supposed to use D65 adapted to D50 in the ICC profile.

All ICC before v5 are only D50 adapted, so Red matrix, Green, Blue are different from canonical values on wikipedia that are D65 adapted.

in reply to:  10 comment:12 by Niklas Haas, 9 months ago

Replying to Cosmin Stejerean:

then ffprobe recognizes it as smpte432 however exiftool does not show P3.

The 'Profile Description' field is an arbitrary free-form text embedded in the ICC profile. It only says this for the other image because that image's embedded ICC profile has "Display P3" as the description.

comment:13 by Cosmin Stejerean, 9 months ago

ok, perhaps the description doesn't matter (although it would be great if it was correct). However the color_primaries being unknown is definitely an issue. Also it's not just that the display name is an issue, the Media White Point listed is also different from a typical P3 image.

comment:14 by Niklas Haas, 8 months ago

Sorry for the delay in getting to this.

Looking at it again, I'm not entirely sure what needs to be changed, though. We read the profile white point by creating an unadapted observer transformation from the profile to XYZ space and passing (1,1,1) through this transformation.

This is what was recommended upstream by the Little-CMS developer (see https://github.com/mm2/Little-CMS/issues/316)

We could use an adapted observer instead, but I think this would break other profiles (e.g. standard sRGB profile), though I'll re-test it to be sure.

comment:15 by Niklas Haas, 8 months ago

So, with an unadapted absolute colorimetric observer, I get:

white point: 0.277627, 0.296325
red point: 0.676886, 0.323146
green point: 0.258474, 0.682744
blue point: 0.118205, 0.047961

Changing that to use an adapted observer instead get me values which are also incorrect:

white point: 0.312699, 0.329003
red point: 0.679226, 0.322634
green point: 0.277986, 0.668605
blue point: 0.123242, 0.052980

As a reminder, correct Display-P3 values should be:

white point: 0.3127, 0.3290
red point: 0.680, 0.320
green point: 0.265, 0.690
blue point: 0.150, 0.060

Seems no combination of parameters lets me extract the DCI-P3 values from this ICC profile. I'm not sure why it behaves so differently from other ICC profiles, which seem to work fine with the current code. Is it possible that the reverse tables in this profile are just wrong? It also doesn't round trip correctly with itself, which other ICC profiles do.

Out of curiosity, how are you generating this specific ICC profile / what's its source?

Last edited 8 months ago by Niklas Haas (previous) (diff)

comment:16 by Cosmin Stejerean, 8 months ago

Here are some other P3 images that appear to have the same ICC profile as the test sample I shared, from https://webkit.org/blog-files/color-gamut/

https://webkit.org/blog-files/color-gamut/YellowFlower-P3.jpg
https://webkit.org/blog-files/color-gamut/Italy-P3.jpg
https://webkit.org/blog-files/color-gamut/Iceland-P3.jpg
https://webkit.org/blog-files/color-gamut/Webkit-logo-P3.png

for all of these along with the one I shared running exiftool shows

Connection Space Illuminant     : 0.9642 1 0.82491
Profile ID                      : e5bb0e9867bd46cd4bbe446ebd1b7598
Profile Description             : Display P3
Media White Point               : 0.95045 1 1.08905
Red Matrix Column               : 0.51512 0.2412 -0.00105
Green Matrix Column             : 0.29198 0.69225 0.04189
Blue Matrix Column              : 0.1571 0.06657 0.78407

comment:17 by Niklas Haas, 8 months ago

So, I wrote a small demo utility to run the ffprobe logic on a variety of ICC files on my system, here are my results:

ArgyllCMS ICC profiles (v2)

  • ACES_P3.icm: unknown profile:

Red: XYZ 2.1249 1.0 0.0000, Yxy 0.680 0.320
Green: XYZ 0.3841 1.0 0.0652, Yxy 0.265 0.690
Blue: XYZ 2.5000 1.0 13.1669, Yxy 0.150 0.060
White: XYZ 0.9527 1.0 1.0088, Yxy 0.3216819 0.3376689

  • ClayRGB1998.icm: detected primaries: Adobe RGB (1998)
  • DisplayP3.icm: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • EBU3213_PAL.icm: detected primaries: ITU-R Rec. BT.601 (625-line = PAL, SECAM)
  • ProPhoto.icm: detected primaries: ProPhoto RGB (ROMM)
  • ProPhotoLin.icm: detected primaries: ProPhoto RGB (ROMM)
  • Rec2020.icm: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec709.icm: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • SMPTE431_P3.icm: detected primaries: DCI-P3 (Digital Cinema)
  • SMPTE_RP145_NTSC.icm: detected primaries: ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)
  • sRGB.icm: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB

The ACES P3 profile exactly matches the values we'd expect from a profile combining the DCI-P3 gamut with the ACES whitepoint.

krita ICC profiles (mix)

  • ACEScg-elle-V4-g10.icc: detected primaries: ACES Primaries #1
  • ClayRGB-elle-V2-g22.icc: detected primaries: Adobe RGB (1998)
  • ClayRGB-elle-V4-srgbtrc.icc: detected primaries: Adobe RGB (1998)
  • krita25_lcms-builtin-sRGB_g100-truegamma.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • LargeRGB-elle-V2-g22.icc: detected primaries: ProPhoto RGB (ROMM)
  • Rec2020-elle-V4-g10.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • sRGB-elle-V2-g10.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • sRGB-elle-V2-srgbtrc.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • WideRGB-elle-V2-g22.icc: unknown profile:

Red: XYZ 2.7693 1.0 -0.0000, Yxy 0.735 0.265
Green: XYZ 0.1394 1.0 0.0707, Yxy 0.115 0.826
Blue: XYZ 8.8554 1.0 46.6897, Yxy 0.157 0.018
White: XYZ 0.9642 1.0 0.8249, Yxy 0.3457029 0.3585375

Again, all profiles are correctly recognized except for WideRGB which seems to be some custom profile with D65 white point.

colord profiles (v4)

  • AdobeRGB1998.icc: detected primaries: Adobe RGB (1998)
  • AppleRGB.icc: unknown profile:

Red: XYZ 1.8383 1.0 0.1030, Yxy 0.625 0.340
Green: XYZ 0.4706 1.0 0.2101, Yxy 0.280 0.595
Blue: XYZ 2.2144 1.0 11.0724, Yxy 0.155 0.070
White: XYZ 0.9502 1.0 1.0883, Yxy 0.3127148 0.3291147

  • NTSC-RGB.icc: detected primaries: ITU-R Rec. BT.470 M
  • PAL-RGB.icc: detected primaries: ITU-R Rec. BT.601 (625-line = PAL, SECAM)
  • ProPhotoRGB.icc: detected primaries: ProPhoto RGB (ROMM)
  • Rec709.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • SMPTE-C-RGB.icc: detected primaries: ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)
  • sRGB.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB

(I omitted some results corresponding to synthetic/test/obscure profiles)

https://webkit.org/blog-files/color-gamut/

  • Flowers-ProPhoto.icc: detected primaries: ProPhoto RGB (ROMM)
  • Flowers-sRGB.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • Iceland-P3.icc: unknown profile:

Red: XYZ 2.0947 1.0 -0.0001, Yxy 0.677 0.323
Green: XYZ 0.3786 1.0 0.0861, Yxy 0.258 0.683
Blue: XYZ 2.4646 1.0 17.3858, Yxy 0.118 0.048
White: XYZ 0.9369 1.0 1.4378, Yxy 0.2776273 0.2963247

  • Italy-P3.icc: unknown profile:

Red: XYZ 2.0947 1.0 -0.0001, Yxy 0.677 0.323
Green: XYZ 0.3786 1.0 0.0861, Yxy 0.258 0.683
Blue: XYZ 2.4646 1.0 17.3858, Yxy 0.118 0.048
White: XYZ 0.9369 1.0 1.4378, Yxy 0.2776273 0.2963247

  • Rose-AdobeRGB.icc: detected primaries: Adobe RGB (1998)
  • Rose-ProPhoto.icc: detected primaries: ProPhoto RGB (ROMM)
  • Rose-sRGB.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • Shoes-AdobeRGB.icc: detected primaries: Adobe RGB (1998)
  • Sunset-P3.icc: unknown profile:

Red: XYZ 2.0947 1.0 -0.0001, Yxy 0.677 0.323
Green: XYZ 0.3786 1.0 0.0861, Yxy 0.258 0.683
Blue: XYZ 2.4646 1.0 17.3858, Yxy 0.118 0.048
White: XYZ 0.9369 1.0 1.4378, Yxy 0.2776273 0.2963247

Red: XYZ 2.0947 1.0 -0.0001, Yxy 0.677 0.323
Green: XYZ 0.3786 1.0 0.0861, Yxy 0.258 0.683
Blue: XYZ 2.4646 1.0 17.3858, Yxy 0.118 0.048
White: XYZ 0.9369 1.0 1.4378, Yxy 0.2776273 0.2963247

All ICC profiles were extracted from the correspondingly named test images. (Note that the sRGB images do not have an attached color profile)

color.org

  • DCI-P3-D65.icc: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • DCI-P3-DCI.icc: detected primaries: DCI-P3 (Digital Cinema)
  • ITU-RBT709ReferenceDisplay.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • sRGB2014.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB

http://color.support/iccprofiles.html

  • P3D60.icc: unknown profile:

Red: XYZ 2.1249 1.0 0.0000, Yxy 0.680 0.320
Green: XYZ 0.3841 1.0 0.0652, Yxy 0.265 0.690
Blue: XYZ 2.4999 1.0 13.1664, Yxy 0.150 0.060
White: XYZ 0.9526 1.0 1.0088, Yxy 0.3216771 0.3376677

  • P3D65.icc: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • P3DCI.icc: detected primaries: DCI-P3 (Digital Cinema)
  • Rec2020-Rec1886.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec709-Rec1886.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB

https://github.com/saucecontrol/Compact-ICC-Profiles

  • AdobeCompat-v2.icc: detected primaries: Adobe RGB (1998)
  • AdobeCompat-v4.icc: detected primaries: Adobe RGB (1998)
  • DCI-P3-v4.icc: detected primaries: DCI-P3 (Digital Cinema)
  • DisplayP3Compat-v2-magic.icc: unknown profile:

Red: XYZ 2.1250 1.0 0.0061, Yxy 0.679 0.319
Green: XYZ 0.3841 1.0 0.0651, Yxy 0.265 0.690
Blue: XYZ 2.5001 1.0 13.1548, Yxy 0.150 0.060
White: XYZ 0.9505 1.0 1.0891, Yxy 0.3127005 0.3289998

  • DisplayP3Compat-v2-micro.icc: unknown profile:

Red: XYZ 2.1250 1.0 0.0061, Yxy 0.679 0.319
Green: XYZ 0.3841 1.0 0.0651, Yxy 0.265 0.690
Blue: XYZ 2.5001 1.0 13.1548, Yxy 0.150 0.060
White: XYZ 0.9505 1.0 1.0891, Yxy 0.3127005 0.3289998

  • DisplayP3Compat-v4.icc: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • DisplayP3-v2-magic.icc: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • DisplayP3-v2-micro.icc: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • DisplayP3-v4.icc: detected primaries: DCI-P3 (Digital Cinema) with D65 white point
  • ProPhoto-v2-magic.icc: detected primaries: ProPhoto RGB (ROMM)
  • ProPhoto-v2-micro.icc: detected primaries: ProPhoto RGB (ROMM)
  • ProPhoto-v4.icc: detected primaries: ProPhoto RGB (ROMM)
  • Rec2020Compat-v2-magic.icc: unknown profile:

Red: XYZ 2.4246 1.0 0.0098, Yxy 0.706 0.291
Green: XYZ 0.2133 1.0 0.0413, Yxy 0.170 0.797
Blue: XYZ 2.8479 1.0 17.8628, Yxy 0.131 0.046
White: XYZ 0.9505 1.0 1.0891, Yxy 0.3127005 0.3289998

  • Rec2020Compat-v2-micro.icc: unknown profile:

Red: XYZ 2.4246 1.0 0.0098, Yxy 0.706 0.291
Green: XYZ 0.2133 1.0 0.0413, Yxy 0.170 0.797
Blue: XYZ 2.8479 1.0 17.8628, Yxy 0.131 0.046
White: XYZ 0.9505 1.0 1.0891, Yxy 0.3127005 0.3289998

  • Rec2020Compat-v4.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec2020-g24-v4.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec2020-v2-magic.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec2020-v2-micro.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec2020-v4.icc: detected primaries: ITU-R Rec. BT.2020 (UltraHD)
  • Rec601NTSC-v2-magic.icc: detected primaries: ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)
  • Rec601NTSC-v2-micro.icc: detected primaries: ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)
  • Rec601NTSC-v4.icc: detected primaries: ITU-R Rec. BT.601 (525-line = NTSC, SMPTE-C)
  • Rec601PAL-v2-magic.icc: detected primaries: ITU-R Rec. BT.601 (625-line = PAL, SECAM)
  • Rec601PAL-v2-micro.icc: detected primaries: ITU-R Rec. BT.601 (625-line = PAL, SECAM)
  • Rec601PAL-v4.icc: detected primaries: ITU-R Rec. BT.601 (625-line = PAL, SECAM)
  • Rec709-v2-magic.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • Rec709-v2-micro.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • Rec709-v4.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • scRGB-v2.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • sRGB-v2-magic.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • sRGB-v2-micro.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • sRGB-v2-nano.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB
  • sRGB-v4.icc: detected primaries: ITU-R Rec. BT.709 (HD), also sRGB

I removed some less interesting profiles. All of the profiles were correctly detected, with the notable exception of the "Compat" v2 profiles, which the README advises use modified primaries (seems they reduced red primary x/y by ~0.001). That explains why we don't detect them as DCI-P3, even though the detected values are very close.

Conclusion

In conclusion, basically all of the profiles tested above work, except for the ones that don't have corresponding names/enums, including the *other* ICC profiles from the webkit demo page. This includes v2 profiles, v4 profiles, profiles with white points other than D65, wide gamut profiles, standard gamut profiles, and so on. Notably, the DCI-P3 profile I downloaded from color.org, an authoritative source if there ever was one, is detected correctly: https://www.color.org/chardata/rgb/DCIP3.xalter

So in summary, the overwhelming evidence appears to indicate that the code is correct, and the ICC profile extracted from that test page is faulty. I would recommend using one of the other DCI-P3 ICC profiles from the above links, as a replacement, all of which are detected correctly.

Last edited 8 months ago by Niklas Haas (previous) (diff)

comment:18 by Niklas Haas, 7 months ago

So, to recap a quick discussion we had about this at VDD:

  • This ICC profile is the built-in profile Apple use for all its DCI-P3 content
  • The matrix coefficients appear to contain the "correct" values, which is ofc wrong as they're *supposed* to be adapted to D50 by spec (but aren't)
  • We can read out the "correct" coefficients using the D50 adapted observer (and raw white point tag), going against ICC spec but providing one possible way to work around

If we care about detecting this particular profile we could work around it "easily" by using the above considerations to implement a compatibility code path. That said, I will have a look again at the ICCv4 spec and fully dissect this profile to make sure everything I wrote above is correct.

Last edited 7 months ago by Niklas Haas (previous) (diff)

comment:19 by Balling, 7 months ago

Apple use for all its DCI-P3 content

No, P3-D65 with sRGB transfer, together called Display P3.

The matrix coefficients appear to contain the "correct" values, which is ofc wrong as they're *supposed* to be adapted to D50 by spec

No, they are adapted. Except for white point, which is wrongly not adapted. Z for red being negative shows it is adapted.

comment:20 by Niklas Haas, 7 months ago

So, I did some extensive reverse engineering of the Apple DCI-P3 profile and came to the following conclusions:

  1. They (accidentally?) used the D65 Chromatic Adaptation matrix for this profile (as would be correct for Display-P3)
  2. They then used this Chromatic Adaptation matrix on the (correct) DCI-P3 primaries, resulting in the "correct" R/G/B Matrix columns. But, for some reason, Little-CMS does not correctly read these back out, probably because of the white point issue.
  3. They then encoded the *unadapted* white point (D65) into the media white point tag, which violates spec as you're supposed to encode the *adapted* white point (D50) instead. (See sections 6.2.3 and 6.3.2)

So, the tl;dr here is that Apple made a mistake when creating this profile, and I can prove it. (It violates ICCv4 spec)

For further information/cross verification, notice that the Apple DCI-P3 profile almost matches the "DCI-P3-D65.icc" profile from ICC/color.org:

Connection Space Illuminant : 0.9642 1 0.82491
Chromatic Adaptation : 1.04791 0.02293 -0.0502 0.0296 0.99046 -0.01707 -0.00925 0.01506 0.75179
Red Matrix Column : 0.51512 0.2412 -0.00105
Green Matrix Column : 0.29198 0.69225 0.04189
Blue Matrix Column : 0.1571 0.06657 0.78407
Media White Point : 0.96419 1 0.82491

Except that the media white point in the ICC profile is correct (D50), whereas the one in the Apple profile is incorrect (D65).

This does, mean, however, that we could apply a simple work-around in principle: If the profile fails decoding, we can try a second time using the (incorrect) "mediaWhitePointTag" as the white point instead of the (correct) "Inverse(chromaticAdaptationTag) * mediaWhitePointTag". If that produces an exact match, return it.

However, since this is a hack and a work-around for a broken profile, I'd rather hide it behind some sort of extra option or debug flag. I'll have to think about whether this is a preferred solution or not.

Maybe you can work around it on your side instead, by detecting the profile e.g. by its "Profile Description" tag? What do you think?

Last edited 7 months ago by Niklas Haas (previous) (diff)

comment:21 by Balling, 7 months ago

DCI-P3-D65 from https://www.color.org/chardata/rgb/DCIP3.xalter is 2.6 gamma. Did you even look into rTRC of it? It is not really relevant, is it... Its Red Z is -0.00081, so negative, so noncompliant. Why would you think ICC pages will have no bugs? LOL.

Except that the media white point in the ICC profile is correct (D50), whereas the one in the Apple profile is incorrect (D65).

So? I told you that. Who cares. It is not used for color managment. ICCV4 is always USING D50.

instead of the (correct) "Inverse(chromaticAdaptationTag) * mediaWhitePointTag

No. ICCV4 is always USING D50. WHAT?? You do not need this and even chad is not used really, except to make negative Z of R positive.

comment:22 by Cosmin Stejerean, 7 months ago

The ICC profile reading/writing is already behind a flag so I think it's low risk to update this to be more compatible with things that we are likely to find in the wild (and this Apple P3 profile seems quite common). It sounds like ICCv4 not using D50 is a bug, and it seems like it could be a safe fallback to assume D50 when reading ICCv4 (ignore the whitepoint if it's not D50 in v4 as not being spec compliant).

comment:23 by Balling, 7 months ago

ignore the whitepoint if it's not D50 in v4 as not being spec compliant

Yep, indeed any white point chromatically adapted to D50 is just D50. At least if we are talking Plancian locus. But is that the case with DCI white point, that is slightly removed from Plancian locus?

Last edited 7 months ago by Balling (previous) (diff)

comment:24 by Niklas Haas, 7 months ago

The ICC profile reading/writing is already behind a flag so I think it's low risk to update this to be more compatible with things that we are likely to find in the wild (and this Apple P3 profile seems quite common). It sounds like ICCv4 not using D50 is a bug, and it seems like it could be a safe fallback to assume D50 when reading ICCv4 (ignore the whitepoint if it's not D50 in v4 as not being spec compliant).

Yes, that's actually a good idea. I'll try and implement this tomorrow.

comment:25 by Niklas Haas, 7 months ago

I submitted a series implementing this work-around:

http://ffmpeg.org/pipermail/ffmpeg-devel/2023-September/314954.html

$ ./ffprobe -flags2 icc_profiles -show_frames /mem/Webkit-logo-P3.png
[png @ 0x3a16a80] Invalid colorimetric ICCv4 profile media white point tag (expected 0.3457 0.3585, got 0.3127 0.3290)
...
color_range=pc
color_space=gbr
color_primaries=smpte432
color_transfer=iec61966-2-1
chroma_location=unspecified

Last edited 7 months ago by Niklas Haas (previous) (diff)
Note: See TracTickets for help on using tickets.