saucecontrol / Compact-ICC-Profiles

Minimal ICC Profiles intended for embedding in image files
Creative Commons Zero v1.0 Universal
195 stars 7 forks source link

v4 TRC 'para' values off by a bit? #17

Closed nico closed 1 year ago

nico commented 1 year ago

Apologies, me again.

sRGB-v4.icc contains for the RTCs:

70617261 00000000 00030000 00026669 0000F2A7 00000D59 000013D0 00000A5B

That's 4 byte tag ("para"), 4 bytes reserved (0), 2 byte curve type (3), another 2 bytes reserved (0), and then 5 s15Fixed16Number at 4 bytes each. The 5 numbers encode g, a, b, c, d in the equation

Y = (a*X + b)**g       if X >= d
  =  c*X               else

s15Fixed16Number per ICC spec:

"4.6 s15Fixed16Number An s15Fixed16Number is a fixed signed 4-byte (32-bit) quantity which has 16 fractional bits as shown in Table 4."

Table 4 for example contains "1.0 encoded as 0001_0000h".

The conversion from an int32_t encoding such a number to a floating point value an be done with:

double f = i / (double)0x1'0000;
int i = round(f * 0x1_0000);

The sRGB TRC uses g = 2.4 per https://en.wikipedia.org/wiki/SRGB#From_sRGB_to_CIE_XYZ

>>> hex(round(2.4 * 0x1_0000))
'0x26666'

Rounding vs truncating doesn't make a difference:

>>> hex(int(2.4 * 0x1_0000))
'0x26666'

The file instead contains 00026669.

>>> 0x00026669 / 0x1_0000
2.4000396728515625

Which one is closer to the true value 2.4?

>>> (0x00026669 / 0x1_0000) - 2.4
3.967285156258882e-05
>>> (0x00026666 / 0x1_0000) - 2.4
-6.103515624911182e-06

Am I missing something?

(I haven't looked at the other 4 parameters in detail yet, but they're also a bit different than what I get when I convert {2.4, 1/1.055, 0.055/1.055, 1/12.92, 0.04045} to s15Fixed16Numbers.)

saucecontrol commented 1 year ago

There was a previous discussion on that in https://github.com/saucecontrol/Compact-ICC-Profiles/issues/6

The short answer is that naive rounding of all parameters to s15Fixed16Number results in both the a and g values rounding down, which gives a less accurate match for the true sRGB curve than the adjusted values used in my profile. The adjusted values halve the total error.

nico commented 1 year ago

Sorry for missing it! Closing as a dupe. Thanks for the quick reply!