-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Black crush and color deviations with some ICC profiles #2815
Comments
OK, every color space conversion, by its very essence, requires two color spaces. But in my terminology, an intermediate color space would be a space that is neither the source nor the target space (nor, strictly speaking, the PCS that is used in all non “device link” conversions). So clearly, if the video material is in BT.709, BT.709 is no intermediate space in the way I used the terminology. (It would be if you used it for all video material, BT.709 or not).
No I wasn’t, although, now you say it, this might at least work better than using BT.2020 for this purpose. But I still think the optimal solution would be a dedicated 3DLUT for a specific video color space – monitor profile combination. Just as a (well-constructed) device link profile is superior to two profiles connected via PCS.
Probably – just like my test with Pro Photo RGB as the monitor profile, where everything worked fine. |
There are many different conversions going on here, each one of the spaces that is not at the very beginning or very end of the pipeline is an “intermediate” space in my books. During typical video playback, the source video will undergo the following color spaces:
I have highlighted steps 5 which is where CMS begins and step 9 which is what gets fed into the 3DLUT. We could use a different set of conversions here. |
Yep, it seems so.
Which confirms that it’s two issues. |
Repeating the experiments with BT.709 gamma 1.961 (uploaded in the previous thread), which uses a simple power function for the transfer curve. I am reading native values. This test also measures color.
|
Ah, OK. But then I would differentiate between primaries conversions and TRC conversions. From my experience, the critical conversions are the primaries conversions. So if we focus on these, your list becomes: BT.709 From this POV, there is one intermediate space, and this is BT.2020. This should remain BT.709, so that we get BT.709 i.e. no intermediate space in this sense.
Uhm, the highlighted steps were 5 and 9? |
Concerning the pipeline I just outlined, I have some two important observations to make: The majority of these conversions are done using exact computations with 32 bit precision, so the margin of error is negligible both in theory and in practice. The video gets rounded and clipped while in some spaces, due to various reasons: 1: inherently clipped to 8-10 bit precision (input video depth) Of these operations, the most significant are the two 8-bit precision clips. That's most likely a big part of the reason why we are introducing so much distortion, because clipping to 8-bit BT.709 values and then again to 8-bit BT.2020 values reduces the overall bit depth below 8 bits because the “round numbers” are not aligned. (There is another 8-bit clip in step 10 but this is less significant since it's dithered, so we retain much of the precision) So if we want to minimize distortion, we have to make sure that space 9 and space 1 are as close as possible, to eliminate the effects of “double clipping”. This is the idea behind using a profile similar to the video source as the intermediate space. (Basically, it would be the same as in step 2) But looking at this pipeline it seems obvious to me that we could eliminate distortion even more by going all the way back to the space used in step 1 - the input space - and generate the 3DLUT against this. That way the 3DLUT would essentially be a mapping from source Y'CbCr to monitor RGB. (The internal calculations are performed with 64-bit floating point precision by LittleCMS, so the extra conversion inside LittleCMS should be essentially free) |
Yes, exactly. |
Clearly, from the evidence in this discussion, the TRC selection matters just as much as the selection of the primaries - that's what's causing the black crush.
Oops, I had duplicates in my numbering while editing and GitHub automatically changed them to count consistently. |
How much does this patch improve things? (haasn@2ed5e5a) diff --git a/video/out/opengl/lcms.c b/video/out/opengl/lcms.c
index c956127..db93e08 100644
--- a/video/out/opengl/lcms.c
+++ b/video/out/opengl/lcms.c
@@ -197,7 +197,7 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d)
// because we may change the parameter in the future or make it
// customizable, same for the primaries.
char *cache_info = talloc_asprintf(tmp,
- "ver=1.1, intent=%d, size=%dx%dx%d, gamma=2.4, prim=bt2020\n",
+ "ver=1.1, intent=%d, size=%dx%dx%d, gamma=1.961, prim=bt709\n",
p->opts.intent, s_r, s_g, s_b);
uint8_t hash[32];
@@ -242,9 +242,9 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d)
if (!profile)
goto error_exit;
- // We always generate the 3DLUT against BT.2020, and transform into this
+ // We always generate the 3DLUT against BT.709, and transform into this
// space inside the shader if the source differs.
- struct mp_csp_primaries csp = mp_get_csp_primaries(MP_CSP_PRIM_BT_2020);
+ struct mp_csp_primaries csp = mp_get_csp_primaries(MP_CSP_PRIM_BT_709);
cmsCIExyY wp = {csp.white.x, csp.white.y, 1.0};
cmsCIExyYTRIPLE prim = {
@@ -253,9 +253,9 @@ bool gl_lcms_get_lut3d(struct gl_lcms *p, struct lut3d **result_lut3d)
.Blue = {csp.blue.x, csp.blue.y, 1.0},
};
- // 2.4 is arbitrarily used as a gamma compression factor for the 3DLUT,
+ // 1.961 is arbitrarily used as a gamma compression factor for the 3DLUT,
// reducing artifacts due to rounding errors on wide gamut profiles
- cmsToneCurve *tonecurve = cmsBuildGamma(cms, 2.4);
+ cmsToneCurve *tonecurve = cmsBuildGamma(cms, 1.961);
cmsHPROFILE vid_profile = cmsCreateRGBProfileTHR(cms, &wp, &prim,
(cmsToneCurve*[3]){tonecurve, tonecurve, tonecurve});
cmsFreeToneCurve(tonecurve);
diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c
index d13cd30..3a0c2c4 100644
--- a/video/out/opengl/video.c
+++ b/video/out/opengl/video.c
@@ -1768,9 +1768,9 @@ static void pass_colormanage(struct gl_video *p, enum mp_csp_prim prim_src,
enum mp_csp_prim prim_dst = p->opts.target_prim;
if (p->use_lut_3d) {
- // The 3DLUT is hard-coded against BT.2020's gamut during creation, and
+ // The 3DLUT is hard-coded against BT.709's gamut during creation, and
// we never want to adjust its output (so treat it as linear)
- prim_dst = MP_CSP_PRIM_BT_2020;
+ prim_dst = MP_CSP_PRIM_BT_709;
trc_dst = MP_CSP_TRC_LINEAR;
}
@@ -1800,10 +1800,10 @@ static void pass_colormanage(struct gl_video *p, enum mp_csp_prim prim_src,
}
if (p->use_lut_3d) {
gl_sc_uniform_sampler(p->sc, "lut_3d", GL_TEXTURE_3D, TEXUNIT_3DLUT);
- // For the 3DLUT we are arbitrarily using 2.4 as input gamma to reduce
+ // For the 3DLUT we are arbitrarily using 1.961 as input gamma to reduce
// the severity of quantization errors.
GLSL(color.rgb = clamp(color.rgb, 0.0, 1.0);)
- GLSL(color.rgb = pow(color.rgb, vec3(1.0/2.4));)
+ GLSL(color.rgb = pow(color.rgb, vec3(1.0/1.961));)
GLSL(color.rgb = texture3D(lut_3d, color.rgb).rgb;)
}
if (need_gamma) It's not the full idea I proposed (using the input space), but for BT.709 videos this should be similar, perhaps. |
With haasn/mp@2ed5e5a. First with BT.709 gamma 1.961. I am measuring native values.
With iMac color profile.
With BT.709 gamma 1.961, your patch improves color accuracy significantly. With iMac color profile, your patch improves color accuracy, but less so, since the recent build wasn't too bad with this profile in the first place. Still, an improvement. Black crush is not improved by your patch; of course, this is expected, since the problem is in LittleCMS, or with LittleCMS interaction which was not changed by your patch. |
Wasn't black crush improved when using an sRGB input curve for the 3DLUT as well? Another thing I would like to try is generating the 3DLUT against your monitor profile (i.e. extract a gamut and TRC from the profile and use that) - if that has similar performance, we could consider just doing that. That would have the benefit of preserving the status quo of “one 3DLUT per ICC profile”. We can also test generating it against XYZ or Lab, but I doubt this is going to improve black crush at all. |
In haasn/mp@114f69a? No, that made black crush slightly worse. |
I rebased my DCI-P3 patch on haasn/mp@2ed5e5a, and now Of course it's not usable because this uses gamma=1.961 which is not right for my display (in other words P3 gamma 1.961 doesn't match my display, nor the "real" Display P3.icc). My patch is at 4ad/mpv-colorfix@dbed5e0. |
This does not surprise me, since in the absence of a 3dlut all operations are done with 16-32 bit precision, which is more than enough to meet the 8-bit requirement you gave it. (In fact, due to mpv's good dithering, the mpv result will be virtually exact overall) |
A possibility that is somewhat far out there but possibly worth consideration in general is to use the 3DLUT for less and do more with exact shader computations - e.g. we could implement parts of the ICC spec in mpv directly, such as the bits concerning the transfer characteristics. (Theoretically it would be possible to implement all of ICC in pure shader code and get a virtually perfect result that way, but the implementation overhead of such a feat would be monstrous - and the potential for errors due to bugs or negligence far greater.) |
Hmm, I have an interesting result. So, I added target-trc=DCI-P3. Now, I don't have access to the standard, so I implemented the complex parametric transfer function by looking inside the color profile. In other words, I read the transfer function from the profile, just like LittleCMS does! And guess what, the result is the same, I get black crush. In other words, with the Display P3.icc color profile, My code is here 4ad/mpv-colorfix@5711136. |
@4ad Maybe the correct result of a transformation through that profile results in crushed blacks even in theory? It's not impossible that QuickTime is the one that gets this particular profile “wrong” - or that they have some extra logic that goes beyond simply transforming it in order to actively mitigate black crush. |
I don't think so. On 1-Black Clipping.mp4 I should see 17-25 flashing, but I only see 19-25 flashing. Plus, in real movies, mpv is lacking shadow detail (not noise, genuine detail) that is visible in QuickTime. |
And here we are again at the important distinction between “looking good” and being a correct implementation of the spec. Sure, I don't doubt that crushed blacks are bad. But if that's the way your profile was generated, and if Little CMS correctly implements the standard, then this is the result we would and should expect. Since you have independently extracted the transfer curve from the profile, implemented, and gotten the same result - I'm inclined to believe the problem here is not LittleCMS but the profile. |
Well, the profile contains both a parametric tone response curve, and a 3*1024 point LUT called the "tone response code". Maybe they don't match, and LittleCMS uses the parametric curve, while QuickTime uses the LUT? |
That would be a good thing to investigate. Inconsistencies like these often arise when different programs decide to use different versions of what should be redundant data, but isn't (e.g. due to bad profile generation). Edit: Though I think the 3x1 “tone response code” might be for per-channel adjustments independent of the parametric tone response curve. |
Well that's why I want to get the real standard. |
QuickTime Player, mpv, ColorSync and Little CMSIn the following I’m trying to more clearly locate the root of the deviations we see in the reproduction of the dark patches. Video PlayersFor mpv, I’m using my “working version” in this test that has no BT.2020 intermediate space and of which we know that it reproduces the colors very close to QuickTime Player (which it again did in my following tests). So I’m concentrating on the dark patches. Specifically, I look at the 9th patch which we can assume is RGB 8-8-8 in BT.709 gamma 1.961. I use the DigitalColor Meter to measure the colors. CMMsTo evaluate the ColorSync and Little CMS CMMs which QuickTime Player and mpv use, respectively, I calculate the conversion from 8-8-8 in BT.709 gamma 1.961 to the tested monitor space using the Calculator in the ColorSync Utility application included with OS X for ColorSync and the transicc command line utility included with Little CMS for Little CMS. Monitor ProfilesI have tried to use a representative collection of monitor profiles. I will list native monitor RGB values, since we are interested in the (relative) differences between the color values obtained in the four different ways, not the absolute values. Using native monitor RGB values minimizes the required calculations and focuses on what we want to know. The absolute values in the following table do not matter, only the differences. I have omitted profiles with simple tone response curves, as we know that these work well. We have not much discussed yet that when it comes to complex transfer curves, there are still two different variants: matrix profiles with such curves, and LUT profiles. Note that as soon as we deal with LUT monitor profiles, rendering intents become relevant (whereas for matrix monitor profiles, only the chromatic adaptation of the absolute colorimetric intent might make a difference). In the table, I use p = perceptual, r = relative colorimetric, a = absolute colorimetric. Here’s the rationale for the monitor profiles I used: ICCv2, Matrix, complex tone response curvesRGB (well known ICCv2 standard profile) ICCv4, Matrix, complex tone response curveP3 (taken from OS X El Capitan, ICCv4 standard profile) outside of ICCv2/ICCv4 spec, Matrix, complex tone response curveiMac (tagged as ICCv2, using ICCv4 features, real life relevance as it’s default profile in recent iMacs) ICCv2 LUT profilespring-LED.LUT (individual profile created with Quato iColor Display) ICCv4 LUT profileLED ipLUT (individual profile created with X-Rite i1 Profiler) Test Results for the dark patch with RGB 8-8-8 (BT.709 gamma 1.961)
Comments
SummaryFor matrix profiles with complex tone response curves, it simply seems that Little CMS does not handle dark tones too gracefully, and that there is little mpv can do. The only thing I can think of is to replace Little CMS with ColorSync for the Mac platform, which would be technically possible, but of course a huge platform specific deviation. For LUT profiles, the possible differences in behavior are baffling. The options for fine tuning that mpv offers (rendering intent, black point compensation) become much more relevant here than I would have thought. Perceptual might be a better default rendering intent than relative colorimetric (but this would need further confirmation). |
Regarding comment nr. 1 above: Assuming that, for whatever reason, it is the 8th (not the 9th) patch in the test movie that has RGB 8-8-8, the table would look as follows (different values for QuickTime Player and mpv):
|
Why are you listing mpv under pr and nowhere else? mpv's default intent is relative colorimetric, and you can choose your own. Regarding perceptual vs colorimetric, I use a LUT-based profile (created by ArgyllCMS) and I see no difference whatsoever between the two intents. |
Does this patch improve things? diff --git a/video/out/opengl/video_shaders.c b/video/out/opengl/video_shaders.c
index a083364..1b01d87 100644
--- a/video/out/opengl/video_shaders.c
+++ b/video/out/opengl/video_shaders.c
@@ -251,8 +251,18 @@ void pass_linearize(struct gl_shader_cache *sc, enum mp_csp_trc trc)
pow((color.rgb + vec3(0.055))/vec3(1.055), vec3(2.4)),
lessThan(vec3(0.04045), color.rgb));)
break;
- case MP_CSP_TRC_BT_1886:
- GLSL(color.rgb = pow(color.rgb, vec3(1.961));)
+ case MP_CSP_TRC_BT_1886: {
+ double white = 1.0;
+ double black = 0.05 / 120; // 0.05cd/m² blacks on a 120 cd/m² display
+ double gamma = 1.961;
+
+ double dif = pow(white, 1/gamma) - pow(black, 1/gamma);
+ double gain = pow(dif, gamma);
+ double lift = pow(black, 1/gamma) / dif;
+
+ GLSLF("color.rgb = %f * pow(color.rgb + %f, vec3(%f));\n",
+ gain, lift, gamma);
+ }
break;
case MP_CSP_TRC_GAMMA18:
GLSL(color.rgb = pow(color.rgb, vec3(1.8));) The idea is to implement the “full” BT.1886 spec, by simulating a device with a real black point (one which the user could possible tune directly in the further). That way we basically get our own “black point compensation” into mpv. Note that you can get a similar result by playing with the “brightness” and “contrast” controls in mpv, i.e. making the overall image slightly darker or brighter. That method actually has the benefit of preserving image values that were technically below the minimum, i.e. “super-blacks”, if your source has any. |
A good test-pattern for testing both black and white clipping at the same time is https://github.com/haasn/cms/raw/8286d4ed3b4a00e5a44e086e931bd2eae669921c/MP4-2c/Basic%20Settings/2-APL%20Clipping.mp4 |
It certainly changes things, but doesn't improve them. With iMac color profile and measured native values.
I also changed the black level to various values between 1/700 to 1/15000, the best for black#7 and black#8 seems to be around 1/5000, but #black15 is way off. |
Well, the idea behind this change is only to raise the black levels overall in order to prevent black crush, it's not to make the transfer curve exactly match QuickTimes. As far as we can tell, mpv's transfer curve for this profile was fine in theory, but the black crush caused problems in practice. This patch fixes those practical problems. |
But with simple color profiles, QuickTime and mpv agree, and we agree that it's producing correct output. This patch not only changes output with complex profile, it changes output with simple profiles too. So if they were right before, now with this patch it means that they must be wrong. Also, while this patch changes black levels, I don't think the changes are correct. I compare mpv and QuickTime on sRGB-like monitor, with simple profile. I'm watching a real movie, shadow-detail seems good, and consistent between mpv and QuickTime. Now I watch the same movie on the iMac. Shadow detail is missing (quite obviously I must add, people unaware of this bug here have complained to me about the shadows missing!). When I add your patch (with blacks set to 1/5000), something changes, however, it doesn't look like the output on the sRGB monitor, while the QuickTime output does look the same as mpv and QuickTime on the sRGB monitor. Also if the problem is related to black-point compensation, surely that must be addressed in the final transformation from the intermediary color space (now BT.709) to the target display space, and not in the intermediary space, no? |
This commit refactors the 3DLUT loading mechanism to build the 3DLUT against the original source characteristics of the file. This allows us, among other things, to use a real BT.1886 profile for the source. This also allows us to actually use perceptual mappings. Finally, this reduces errors on standard gamut displays (where the previous 3DLUT target of BT.2020 was unreasonably wide). This also improves the overall accuracy of the 3DLUT due to eliminating rounding errors where possible, and allows for more accurate use of LUT-based ICC profiles. The current code is somewhat more ugly than necessary, because the idea was to implement this commit in a working state first, and then maybe refactor the profile loading mechanism in a later commit. Fixes mpv-player#2815.
The easiest/most straightforward way to facilitate something like this (if desired) is probably to add support for ICC devicelink profiles via LittleCMS. This approach could possibly also used as a general way to cache transforms to disk (as devicelinks) ie. using cmsTransform2DeviceLink to turn the transform into a devicelink which can then be stored for later (re-)use. |
I’m afraid this would collide with Slope Limiting (contrary to 3DLUTs). I doubt there is a way to encode such behavior into an ICC device link profile, is it? |
A parametric tone curve that incorporates the slope limit should work. Of course if the slope limit were to be implemented directly in littleCMS then this wouldn't be needed. |
You mean additional profiles in the profile chain for the device link, or as as a replacement for the original TRCs of the profiles in the profile chain?
But how could a CMM apply slope limiting to an existing device link profile? The slope limit algorithm is applied to the conversions to and from the PCS, but there is no PCS in device link profiles. Because of this, my Slope Limit patch for Little CMS ignores device link profiles so far. |
Yes, a replacement for the original source profile TRC (with the only difference being the slope limit).
Alright, that wouldn't be possible. |
This commit refactors the 3DLUT loading mechanism to build the 3DLUT against the original source characteristics of the file. This allows us, among other things, to use a real BT.1886 profile for the source. This also allows us to actually use perceptual mappings. Finally, this reduces errors on standard gamut displays (where the previous 3DLUT target of BT.2020 was unreasonably wide). This also improves the overall accuracy of the 3DLUT due to eliminating rounding errors where possible, and allows for more accurate use of LUT-based ICC profiles. The current code is somewhat more ugly than necessary, because the idea was to implement this commit in a working state first, and then maybe refactor the profile loading mechanism in a later commit. Fixes mpv-player#2815.
That was my first approach to the slope limit issue, but unfortunately, from what I can see, it only works in specific cases that we cannot assume. (Which is why in the end I decided to patch Little CMS.) To build a replacement TRC for a parametric or a gamma TRC is certainly possible. But what do you do if a profile uses a 1DLUT for its TRC? While you could try to translate it to a parametric curve, this is neither trivial nor guaranteed to produce a precise result, whereas the slope limit algorithm I used in Little CMS leaves the original TRC completely untouched apart from the dark area where it intentionally intervenes. So I think the solution I used is more robust and produces superior results, but unfortunately, it does not lend itself to your suggestion with the device link profiles. |
I see. Yes, that case is not easily supported if you don't know exactly how the original 1D LUT was arrived at. |
(Surely instead of trying to reconstruct a parametric response curve from the 1D LUT and adding slope limiting to that, you can just directly modify the 1D LUT to incorporate the slope limiting?) |
True, but by then a simple one liner to incorporate slope limiting has become an unwieldy amount of code – recalculate and replace gamma curves, parametric curves, and 1DLUTs, for v2 and v4 ICC profiles … I don’t think that’s worth it just to be able to use device link profiles to be able to write 3DLUTs to disk in ICC format. (And it would be less probable that such an amount of code would make it into the official Little CMS code base.) |
(This is the wrong issue for this and offtopic, deleting posts.) |
I am back after some work-related absence. So what is the state regarding Adobe CMM emulation in LittleCMS? In other words, do we have a way to fix the black crush problem? |
@4ad The new BT.1886 emulation should fix black crush for the majority of profiles. (It would still fail if the profiles don't contain accurate reverse tables, since then the code can't estimate the display's black point accurately) I'm not sure what to do in that situation |
First of all, sorry for the long silence; unfortunately, I have very little time currently. I have now checked the most recent mpv build for its new color management implementation. First, again the reference image from Melancholia with which it all started. Above is the reference still image, below is mpv: To little surprise, the mpv image is again too dark/has too much contrast; but of course, this is what you would expect from a BT.1886 implementation that implies a contrast enhancement. Second, the QuickTime test movie (QuickTime Player above, mpv below): If anything, the current implementation makes the black crush issue worse; it certainly does not fix it. I have no interest in rekindling the ideological debates about color management again. Maybe it’s a question of semantics:
If you use the term “color management” in the second way (as I do), then the only way to adjust contrast for a dim viewing environment would be to use a color appearance aware display profile which would be used by both applications alike. Of course, all this isn’t surprising; it’s what I’ve said all along. Let’s just say that those who understand the term “color management” in the second way and want to make sure the black crush issue is fixed need a different option in mpv which does not exist yet. This option would have to be a emulation of the QuickTime behavior, i.e. a source gamma of 1.961 and LittleCMS with a slope limit of 16. I will report on that in my next post. |
Seems like your profile has inaccurate reverse tables. mpv relies on them being accurate in order to map black to black. A profile with accurate reverse tables should have no black crush almost by definition.
This in itself is a good reason to provide compatibility / emulation modes where appropriate, but I can't help but wonder whether it's mpv that should be emulating QuickTime or QuickTime that should be emulating mpv. A priori, mpv follows the BT.1886 spec, QuickTime follows some made-up Apple/Adobe spec, so to match them either one of the two would have to implement support for emulating the other. But I guess it's not like we can change QuickTime either way, so the best we can hope to provide is implement a compatibility mode inside mpv. |
It’s a matrix profile which has no tables at all. |
That's a problem, the profile must have reverse tables for mpv to be able to figure out what the display's black point is. I'm not sure how to work around this. Pure matrix profiles like yours contain no information whatsoever about the target device's contrast, do they? Edit: Well, I could still add an option like |
Slope limiting. 😎
No, they don’t. But they are the most common type of display profile (and for good reasons: they are efficient – important for all moving content –, and tables are not really needed for display profiles where non-linearities can be dealt with in the video card LUT). |
Yes. Now comes the bad news: Marti Maria (the author of LittleCMS) does not want to incorporate the patch. The “core patch” is as simple and clean as it gets, but to propagate the user option setting to the function that implements the patch, several other functions must be modified, which Marti dislikes. But that’s not the main point. The main point is – I can hardly believe it – patents. Marti is afraid that this extremely simple formula might be patent encumbered. He used to work for HP, who supported him in such matters (figuring out the legal situation for him), but does not work there anymore. Therefore, he asked me to use a plug-in for the implementation instead. I still don’t think that’s fully possible, but promised him to try. Unfortunately, because of my current time restraints, I haven’t gotten too far with it, yet. But of course, this would only relocate the possible patent issue. It would not be in LittleCMS anymore, but it would be in the plug-in. I would think that a project like mpv had already have to deal with patent related questions. Is there some kind of “standard procedure” how to proceed in cases like this? Anyway, this leaves us with a situation with (if I get it correctly) the following alternatives:
Have I forgotten anything? Oh well … what should we do? |
But in the Melancholia image comparison, the still image is not displayed by QuickTime Player, but by a color managed image editing application (which itself is completely consistent with all other OS X applications which handle still images, and with spectrometers). The point with QuickTime’s approach is that it provides this consistency for moving images, too.
Purely for the sake of simplicity, I suggest the following terminology: color management for color reproduction in one specific application (point 1. above) Using this terminology, my argument has always been that the BT.1886 approach is not applicable to ICC color management because it displaces the contrast enhancement for a dim viewing environment from the display profile (where it belongs architecturally in ICC color management) to the source application. So from this perspective, QuickTime clearly is the rule and BT.1886 the exception. |
But how can the user know this value? This reintroduces the guesswork that color management is supposed to remove. |
I remember a previous patch that had a I posted previous measurements earlier in this thread. To recap, at realistic contrast ratios it made the problem imperceptibly worse, and at ridiculous contrast ratios (1:10000), black crush was solved at the expense of huge deviations of midtones. |
Why can't we implement slope limiting by editing the LUT generated by LittleCMS? |
I would assume that once a LUT is created, it’s opaque and hardly editable, but I’m no expert on that. Anyway, we do have the correct implementation that emulates ColorSync’s behavior perfectly and in every situation. It seems to be more of a (potentially) legal issue, and I would assume this would apply to LUT editing as well. |
Oh boy, please disregard the previous message (deleted). I am very tired. It was intended for a very different project. |
It would be doable but complicated. Inside the 3DLUT there are three steps:
Slope limiting needs access to information from step 2. Specifically, the algorithm does something like Anyway, to replicate the algorithm we would probably need to reimplement LittleCMS' desaturation algorithm, although we could theoretically get away with it due to the fact that it only matters for things close to black (which are very desaturated either way). |
Slope limiting applies to both directions, and depends on the direction (F = slope limit factor): for the RGB to PCS direction:
for the PCS to RGB direction:
It is the RGB to PCS direction where the black crush is prevented. |
Continuation of the discussion in #534.
Some ICC profiles are experiencing black crush when used in mpv, in particular ones that use complex transfer curves rather than simple pure powers.
Proposed solutions including reworking the 3DLUT/lcms mechanism to pick a connection space more gracefully.
The text was updated successfully, but these errors were encountered: