I’m not sure what you mean by “where imprecision in sRGB ICC comes from”? I can think of two very different interpretations:

One possible interpretation is "How to deal with rounding when making an sRGB ICC profile, at the point where the calculated XYZ values are saved as s15Fixed16Number, and the TRC is saved as either V4 parametric curve or a point curve or a V2 “gamma” curve, assuming the profile maker actually did read the specs and then used the correct input values. This interpretation assumes that the profile maker:

actually read the relevant color space and ICC specs and used the right D65 values for the source white point and the right D50 values for the destination white point

used Bradford adaptation, which is the conventional if not required choice, and used the proper values for the adaptation matrix

used the right xy values for the source color space RGB values

and the sole source of “imprecision” is the choices made during the actual saving to disk of the ICC profile using the specified number types.

Another interpretation is “Why there are so many different sRGB profile variations floating around in cyberspace?” which question deals with all the ways the profile maker can and do go wrong even when selecting the input values, at which point rounding while saving the actual ICC profile to disk is fairly far down the list of reasons why there can be considerable variation between “sRGB profiles”.

@Elle, I’d be particularly interested in your thoughts, as it seems you’re the person who has spent the most time researching this. I’m quite confident in my numbers, but it’s always good to get another set of eyes on the math.

calculation of TRC are made in “live” with an old program (part of Dcraw), I modified 6 yers ago

5 values are calculated in function of slope and gamma, with thes values we can elaborate : direct gamma and inverse gamma
For sRGB TRC , we must differentiate, ICC specification and internal usage to RT - for internal (conversion RGB, curves, etc.)- it is important (we work wirh real and not integer) not to have “jump”

I list after some settings possible with no “jump” for inverse

g=2.39990 slope=12.92 x=0.039289 delta = 0.055

g=2.40000 slope=12.92 x=0.039293 delta = 0.055011

g=2.40000 slope=12.92310 x = 0.039286 delta = 0.055

I used LCMS and my skill !
For LCMS I used LUT with 4096 points, but I have modified call with 7 parameters
“cmsBuildParametricToneCurve(nullptr, X, Parameters)”, by increasing X with 2 values with 0, now there is 7
This leads to smooth the result - I don’t know why !

the result with ICC directly incorporate (FOIP) -Free Output Incorporate Profile - in file instead of load it with an ICC profile, is much better (when I compare with Histogrammar)

result with FOIP is similar to v4 ICC and seems very good

result with v2 ICC is less good

We can elaborate all FOIP and V2 and V4 for :

all “primaries” used in internal by RT : AdobeRGB, BestRGB, BetarGB, BruceRGB, Prophoto, Rec2020, sRGB, Widegamut

any gamma between 1.0 to 3.5 with precision 5 zero

any slope between 0.0 to 15.0 with precsion 5 zero
By defaut choice is

Third step
Presentation of Histogrammar (Guillermo Luijk - 2012). This software - very good is old, and not up todate. you need for use, to chnage the date of your computer…
You can see histogram, and zoom X and zoom Y, so ou can look principally at the beginning (left part) where TRC are actives - linear part of sRGB TRC

First I show an image with all histogram (quasi), you can see around stat

Four step
I have load always the same image (NEF I take in turkey in 2007),
I used profile with primarie sRGB and LUT srgb with 212 points
I zoom on the begining of the histogram X=1/16x Y=32x

@jdc - slightly off-topic, but thank you! for showing Histogrammer screenshots. Guillermo Luijk is a genius and I had completely forgotten about his Histogrammer. Well, it’s Windows only and I haven’t had a Windows machine in many years. I don’t even have Wine installed, but does anyone know if Histogrammer runs under Wine?

It would be wonderful to have such a tool available for free/libre software. Do you know if Guillermo ever supplied the source code under an appropriate license? Is it perhaps incorporated in the Perfect Raw code?

In your article, there is a typo (? - but the “typo” links to the Babel proprietary software website) and incorrect link:

In his writeup on the sRGBz profile, Øyvind Kolås (Pippin) mentioned generating new colorant tag values from Babel with improved accuracy.

I was a bit surprised to see “Øyvind Kolås (Pippin)” and “Babel” proprietary software in the same sentence given Pippin’s commitment to using free/libre software . Looking through Pippin’s write-up on sRGBz (http://pippin.gimp.org/sRGBz/), indeed “Babel” software isn’t mentioned. He was actually referring to his own “babl” software:

So the quantizing for the 212-point profile shown by Histogrammer is obviously a bad thing. The question is whether the quantizing is from Histogrammer not doing a linear interpolation between the profile TRC points (the ICC does specify to use linear interpolation between the points). We can’t check without access to the Histogrammer software source code.

What happens to the histogram when you use cctiff (https://www.argyllcms.com/doc/cctiff.html) to convert from my V4 sRGB profile to the 212-point profile? What happens to the histogram when you do the same thing using LCMS’s tificc (https://github.com/mm2/Little-CMS/blob/master/utils/tificc/tificc.c)? I guess it’s not possible to tell using Histogrammer, if Histogrammer indeed does not interpolate between the points? Maybe do a round-trip for each conversion back to my V4 version of sRGB, and then check using Histogrammer? Or maybe use Imagemagick to count the number of colors in the image “before” and “after” converting and/or after simply assigning the different versions of sRGB?

If a “failure to interpolate between the points” happens in various softwares, that alone is a reason to confine the use of “small” sRGB profiles to 8-bit images displayed on the web.

@saucecontrol - is your final version of the small sRGB profile available for download? If it was given in your Part 3, I didn’t see it, but I was scanning for the main lines of your argument, rather than for a download link.

Regarding your proposed values for the sRGB profile’s RGB XYZ tags, I see where you are going with your line of reasoning. Here’s my understanding so far, so please correct me if I misunderstand:

It’s not enough to use the correct source and destination white points and the correct source xy values, and then “nudge” to get well-behaved primaries in the profile that is saved to disk.

In addition, one must make sure the resulting primaries are invertible, to get back to the xy values in the spec.

These invertible primaries - at least for the sRGB ICC profile - are actually in the sRGB specs and/or in the ICC’s recommendations for making an sRGB profile.

No-one ever, anywhere, ever - including Graham Gill (my sRGB primaries match Graham Gill’s sRGB.icm by design), HP, and the ICC - has ever actually produced a correct sRGB ICC profile.

And because of the way the source white point is calculated, all true V2 ICC profiles (including I presume AdobeRGB1998) that have ever been made for a color space with a D65 source white point - or at least the ones I included in my various surveys - all of these profiles have incorrect white point tags.

I haven’t had a hex editor installed on my system since iccXml was released, so first I want to install a hex editor (or maybe 3 or 4 hex editors ), and then reread through your Part 3. So clarifications on where I might have misunderstood Part 3 are greatly appreciated. A link to your proposed replacement sRGB profile also would be nice!

If I understand Histogrammar, it does the same thing (in best ==> zoom and so on), than an normal histogram.

An normal histogram works in general in 8 bits ==> 256 colors for red, 256 colors for green, 256 colors fo blue, and for each color we count the number of pixels, and put them in Y ordonate, and in X value of R, G or B

In this case Guiilermo (I am quasi sure,even I am an old man!) works in 16 bits ==> 65536 colors for red, 65536 colors for green, 65536 colors for blue
The only “interpolation” is round of float values to integer, eg 32123,34 ==> 32123, I think negligeable

@jdc thanks for posting your test findings. I’ve been considering different ways to test and had settled on using tiffcc in 8-bit and 16-bit modes with the V4 profile as a reference. I’ll check out Histogrammar and see if I can figure out how it does its thing

@Elle thanks for the tip on the babel/babl typo. I knew that didn’t look right, and then it was late when I was adding links to my post, so I didn’t think about it as much as I should have.

I do believe that’s enough to get a well-behaved profile, according to neutral grey axis definition. In fact, you can choose completely wrong whitepoints and primaries and get a well-behaved profile too, as long as the primary values balance out so that they add to exactly the value of white. It was easy for me to see this in looking at the hex values, since the granularity becomes one hex digit. Trying to figure it out in increments of 0.000015 in decimal form makes it a bit harder.

This, I think, is an important part of adhering to the spec. If the spec only gave the values for the R’G’B’->XYZ matrix, I think you could calculate those values with any level of precision you want (as long as it was at least what’s specified). But the sRGB spec also give the XYZ->R’G’B’ matrix values, and in order to match those, the profile matrix has to be invertible. The fact that those numbers were revised between the draft spec and the final spec is key for me. sRGB is meant to be easy to implement and get right. If you use the XYZ values published in the spec, you follow the spec. Attempting to calculate the intended numbers from xy is not only more difficult, it also breaks compatibility with software that did actually follow the spec.

Yes, and yes. I’m sure you’ve looked at more profiles than I have, but I couldn’t find one myself. I find it very odd that the ICC publishes what I believe to be the correct numbers in their spec extension but doesn’t distribute a profile with them,

I don’t think this is right. The D65 value in the white point tag should match the value that was used to adapt to D50. My understanding is that the wtpt tag is only used in Absolute Colorimetric Intent conversions, and it’s used to undo the chromatic adaptation to the profile white point. That means its value should match the one that was used to create the original D65->D50 adaptation matrix. sRGB is very clear that the value of D65 is [X=0.9505,Y=1,Z=1.0890], and using that number keeps everything in balance because it is the exact sum of their rounded primary values given in the R’G’B’->XYZ matrix.

I’ve only just started looking at the Adobe RGB spec, but they give the XYZ value of D65 as [X=0.9505,Y=1,Z=1.0891], so by that definition, they should have a different wtpt tag in their profiles.

Interestingly, Adobe gives 5 decimals of precision their R’G’B’->XYZ matrix, and their values total to [X=0.95046,Y=0.99999,Z=1.08906]. Those totals are closer to the correct value of D65 as calculated from their given D65 chromaticity of x=0.3127, y=0.3290. Calculating XYX from those xy values gives [X=0.950455927051672, Y=1, Z=1.08905775075988].

Anyway, what’s correct for that value depends entirely on what was used to calculate the primary color values. I found that if those values are kept in balance with their defined white and the Bradford adaptation matrix uses that same defined white, the values always come out well-behaved. It would stand to reason that the value stored in the wtpt tag would also allow a reverse Bradford matrix to be created that would allow its output to be well-behaved too.

I haven’t done all the testing I want to with that profile and the other variants I want to try, but you’re welcome to put it through its paces and see if you can find a weakness.

Yes, as long as one’s only goal is producing a well-behaved (neutral gray axis) ICC profile, it doesn’t matter what source or destination white point or even what xy values for the primaries you choose. As long as the resulting XYZ values are properly “nudged” (which ArgyllCMS does do, and LCMS does not do), the resulting profile is “well-behaved”. Well, most profiles with D50 source white points don’t need nudging, and not even all the color spaces wtih non-D50 white points need nudging.

As a complete aside, I’m guessing there are practical limits to what can be used as source color space RGB xy values. For example, what happens if you choose three primaries that are all on the spectral red and yellow side of any normal white point, and not including a primary on the other side of any actually “white” white point? For such a color space, it would be odd to speak of a neutral gray axis. In another thread this type of profile was suggested, but I never did take the time to make such a special-purpose profile (and I’m not sure my profile-making code would even be able to make such a profile). If you are curious, here’s the thread:

I am very happy - thrilled actually - that so many people on this forum and in this thread are taking the time to read the ICC specs and also even read color space specs.

Like @saucecontrol, I’m not willing to spend money to get copies of the various official latest color space specs. But if anyone uses exiftool to examine my ICC profiles, I do give the link to the version of the spec that I did use, right inside one of the ICC profile tags.

Thanks! And also thanks much! for clarifying regarding the D65 white point.

To me, this is the really cool thing about XYZ colors… it doesn’t matter. Imagine you’re in a room with a red light and you’re wearing white shoes. If you look at your shoes, they’re red… as is everything else. There is no neutral grey in such a room. In fact, the only color in that room’s gamut with 0 a* and b* values is black (if even that exists). I guess that gives it a neutral axis, which just happens to be a neutral point instead of a line.

All of that seems perfectly legit, but you wouldn’t want to do work in that room that required you to be able to accurately compare colors. So it would make a valid color space but not a good working space. And it would be silly to define an RGB space in that way since there’s no green or blue light to represent. On a chromaticity diagram, red, green, and blue would all be red. Still valid, I suppose

Hi,
I’m afraid I’m not convinced that your sRGB primaries are more accurate. From my reading of your blog post, you seem to be trying to make the matrix values match the rounded values in the sRGB specification. I don’t think that’s a valid goal. If one starts with the primary x,y values as given, then the equivalent matrices have to have infinite precision in order to match the original x,y values. If you truncate the matrices to 4 dp precision, then you are taking them as canonical, instead of the primary x,y values.
To put it another way, I take the sRGB spec matrix values as illustrative or implementation convenience values, not canonical, and instead compute the ICC tag values (equivalent to the RGB to XYZ matrix) from first principals to be the the best rounded values consistent with the spec. x,y values, and the goal that the primaries should sum exactly to the white point.

From a pragmatic point of view, I use the (quantized) header values thru-out ArgyllCMS. Once again I assume that the published 4 dp values have been rounded to meet the Scientific publishing convention of not showing more precision than can be justified. To take the decimal values as canonical would result in an impossible to reconcile and unnecessary loss of precision in the CMS implementation.