Re: Erroneous color transformations with Apple CMM
# Re: Erroneous color transformations with Apple CMM

**Subject**: **Re: Erroneous color transformations with Apple CMM**
- From: Klaus Karcher <email@hidden>
- Date: Thu, 28 Jan 2010 06:10:00 +0100

`Marco Ugolini wrote:
`I don't follow what exactly these numbers are measuring. What is the
procedure? What is being compared? And which DeltaE formula?

It's the result of a round-trip-test with 100000 random RGB values and
very, very simple matrix profiles. I used three different methods to
convert the values with Apples ColorSync API (different API functions
and data structures) and -- for comparison -- one method independent of
ColorSync or any other CMM (simply based on linear algebra).
These are the gamma values of the test profile:
Rgamma: 2.234375
Ggamma: 2.234375
Bgamma: 2.234375

They are encoded as single gamma values in order to avoid
table interpolation or inversion issues.

These are the primaries of the profile:
Red: X: 0.478958, Y: 0.275146, Z: 0.049362
Green: X: 0.350143, Y: 0.618881, Z: 0.130112
Blue: X: 0.135101, Y: 0.105972, Z: 0.645432

(Typo in the source code corrected: printed Z value for Blue was wrong)

This is the number of random RGB values tested:
Number of tests: 100000

And this is the procedure:

Test Data preparation:
======================

1.) create random RGB values

`2.) Convert them to XYZ as described in the ICC Spec
<http://www.color.org/ICC34.pdf>,`

Chapter 6.3.2.2 RGB Display Profiles (Page 29)

(no ColorSync API functions required thus far)
`3.) Convert the XYZ values to Lab`

using Apple's ColorSync API function "CMConvertXYZFloatBitmap"

see
<http://developer.apple.com/mac/library/technotes/tn/tn2035.html#TNTAG80>
4.) Convert the Lab values back to XYZ
using "CMConvertXYZFloatBitmap"

`We have plausible, corresponding XYZ and Lab data as input for the tests
now.`
`CMConvertXYZFloatBitmap seems to work as expected, there are no
significant errors thus far.`
All values are encoded as floating point numbers.

Test 1:
=======

Invert Step 2, i.e. Convert XYZ back to RGB
as described in the ICC Spec
Chapter 6.3.2.2 RGB Display Profiles (Page 29 + 30)

`This requires to solve a system of linear equations (in other words to
invert the 3x3 matrix of the profile and solve for RGB).`

As the profile matrix /has/ to be invertible, the system has a single,
unique RGB solution for every XYZ.
`I used the well-proven CLAPACK Linear Algebra package to solve the
system (see <http://en.wikipedia.org/wiki/Lapack>)`

and calculated with single precision floating point numbers.
`Clapac routines used:
<http://www.physics.oregonstate.edu/~rubin/nacphy/lapack/routines/sgetrs.html>
and`

<http://www.physics.oregonstate.edu/~rubin/nacphy/lapack/routines/sgetrf.html>
No ColorSync API functions are involved in this test.

Test 2:
=======

Convert Lab to RGB using Apple's ColorSync API function "CMMatchFloatBitmap"
<http://developer.apple.com/mac/library/technotes/tn/tn2035.html#TNTAG100>

`CMMatchFloatBitmap also uses single precision floating point numbers,
i.e. the precision should be just as high as with CLAPAC.`
Test 3:
=======

`Convert Lab to RGB using Apple's ColorSync API function "CWMatchColors"`

CWMatchColors uses 16bit integers. The integer range 0..65535 maps to L*
0..100, a* or b* -128..127.996 and R, G, or B 0..1 and might cause clipping.
Test 4:
=======

`Convert XYZ to RGB using Apple's ColorSync API function
"CMMatchFloatBitmap" (single precision floating point)`

`I converted the RGB results of all 4 test cases back to Lab in the same
way as in steps 2 and 3 of the data preparation.`
`We have now round trip results for 100000 colors converted with 4
different methods and can compare the CIELAB values before and after the
round trip (CIEDE76):`
Delta E avg / max lapack: 0.00 / 0.02
Delta E avg / max float Lab: 1.24 / 9.18
Delta E avg / max fixed: 1.25 / 9.18
Delta E avg / max float XYZ: 5.40 / 27.29

Summary:

- the LAPAC results are as precise as expected.

- the ColorSync API results starting with CIELAB data
are surprisingly bad. There is no significant difference between
16bit integer and 32 bit float conversions, i.e. the errors can
neither be explained by clipping to the UInt16 range nor
by rounding errors.

- the ColorSync API results starting with XYZ data are corrupted
and completely useless IMHO.

`I checked my code and repeated the tests several times with various
profiles. The results are always very similar as long as the colors fit
into the Lab encoding range, otherwise the max. errors for the Lab-based
tests increase (more examples below).`
`I can't find any other explanation than bugs in Apple's ColorSync API.
It well may be that I am wrong as I am anything but a versed programmer
-- but as the issue concerns fundamental functions of the operating
system and the errors are grave, I think it's high time that someone
with better programming skills grapples with my findings and tries to
verify or rebut my results.`
Klaus

---

additional examples:

Profile: testRGB
Rgamma: 1.800781
Ggamma: 1.800781
Bgamma: 1.800781
Red: X: 0.650284, Y: 0.320297, Z: 0.000000
Green: X: 0.178040, Y: 0.602036, Z: 0.067825
Blue: X: 0.135880, Y: 0.077667, Z: 0.757065

Number of tests: 100000

Delta E avg / max lapack: 0.01 / 0.02
Delta E avg / max float Lab: 1.10 / 11.23
Delta E avg / max fixed: 1.10 / 11.23
Delta E avg / max float XYZ: 4.84 / 33.54

---

Profile: test3
Rgamma: 2.230469
Ggamma: 2.230469
Bgamma: 2.230469
Red: X: 0.476410, Y: 0.273361, Z: 0.049042
Green: X: 0.352661, Y: 0.620819, Z: 0.130707
Blue: X: 0.135132, Y: 0.105820, Z: 0.645142

Number of tests: 100000

Delta E avg / max lapack: 0.00 / 0.02
Delta E avg / max float Lab: 1.24 / 8.25
Delta E avg / max fixed: 1.25 / 8.25
Delta E avg / max float XYZ: 5.40 / 26.90

---

Profile: test4
Rgamma: 1.000000
Ggamma: 1.000000
Bgamma: 1.000000
Red: X: 0.476410, Y: 0.273361, Z: 0.049042
Green: X: 0.352661, Y: 0.620819, Z: 0.130707
Blue: X: 0.135132, Y: 0.105820, Z: 0.645142

Number of tests: 100000

Delta E avg / max lapack: 0.00 / 0.02
Delta E avg / max float Lab: 1.16 / 8.64
Delta E avg / max fixed: 1.16 / 5.46
Delta E avg / max float XYZ: 2.53 / 28.40

---

Profile: test5
Rgamma: 2.234375
Ggamma: 2.234375
Bgamma: 2.234375
Red: X: 0.478958, Y: 0.275146, Z: 0.049362
Green: X: 0.350143, Y: 0.618881, Z: 0.130112
Blue: X: 0.135101, Y: 0.105972, Z: 0.645432

Number of tests: 100000

Delta E avg / max lapack: 0.00 / 0.02
Delta E avg / max float Lab: 1.25 / 9.21
Delta E avg / max fixed: 1.25 / 9.21
Delta E avg / max float XYZ: 5.40 / 27.09

---

two Roundtrip examples with Profile test5:

IN:
RGB 0.03571 0.11186 0.03757
Lab 4.39 -6.87 4.88

1) lapack:
RGB 0.03571 0.11186 0.03757
LAB 4.39 -6.87 4.88
DE 0.00

2) floatLab:
RGB 0.04395 0.08698 0.05966
Lab 2.79 -3.20 1.44
DE 5.28

3) fixedLab:
RGB 0.04393 0.08695 0.05965
Lab 2.79 -3.20 1.44
DE 5.28

4) floatXYZ:
RGB 0.01543 0.02255 0.00000
Lab 0.14 0.02 -0.05
DE 9.48

--

IN:
RGB 0.07623 0.22080 0.05524
Lab 16.61 -19.42 18.06

1) lapack:
RGB 0.07627 0.22084 0.05519
LAB 16.62 -19.42 18.06
DE 0.01

2) floatLab:
RGB 0.08121 0.22112 0.06194
Lab 16.73 -18.97 17.64
DE 0.62

3) fixedLab:
RGB 0.08118 0.22112 0.06191
Lab 16.73 -18.98 17.65
DE 0.61

4) floatXYZ:
RGB 0.06777 0.10036 0.02969
LAB 3.93 -3.69 4.63
DE 24.26

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Colorsync-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
`This email sent to email@hidden
`