Referring to "Procedural Elements for Computer Graphics" by David F. Rogers (1985) the ipp headers list the transformation matrix for RGB to XYZ as follows
X = 0.412453 * R + 0.35758 * G + 0.180423 * B
Y = 0.212671 * R + 0.71516 * G + 0.072169 * B
Z = 0.019334 * R + 0.119193* G + 0.950227 * B
This is listed as the transformation matrix from HDTV (Rec. 709) RGB to CIE XYZ.
Wikipedia shows https://en.wikipedia.org/wiki/CIE_1931_color_space another transformation matrix, which is from CIE RGB to CIE XYZ. Clearly, the RGB to XYZ transformation (and vice versa) depends on the ICC profile of the image. This is true for RGB to LUV and RGB to LAB too, as ipp uses RGB to XYZ as part of those transformations.
Can you confirm the above and is there a special reason why the HDTV color space was chosen ? It seems a logical choice for movies, rather than still images. However, the much used sRGB color space was derived (and is nearly identical) to the HDTV color space.
Adriaan van Os
In fact, the RGB to XYZ matrix to be used can simply be calculated from the x and y chromaticities that are stored with the ICC profile of an image (see e.g. http://www.brucelindbloom.com/index.html and docs-hoffmann.de/ciexyz29082000.pdf). That matrix can then be used with ippiColorTwist and ippiColorTwist32f to do an RGB to XYZ transformation that is more precise than the rather arbitrary (HDTV-only) transformation used by ippiRGBToXYZ.
Unfortunately, ippiRGBToLUV and ippiRGBToLab are based on ippiRGBToXYZ and therefore are HDTV-only.
To solve this dilemma, I suggest to add ippiXYZtoLab, ippiLabToXYZ, ippiXYZtoLUV and ippiLUVtoXYZ functions to IPP (and also ippiXYZtoYxy and ippiYxytoXYZ).
Adriaan van Os
Another issue. The comment in the ipp headers with ippRGBtoXYZ says:
Equations are given above in assumption that the X,Y,Z,R,G, and B values are in the range [0..1].
Y, C1, C2, R, G, B - are scaled to the range:
[0..1] for the 32f depth,
[0..IPP_MAX_8u] for the 8u depth,
[0..IPP_MAX_16u] for the 16u depth,
[IPP_MIN_16s..IPP_MAX_16s] for the 16s depth.
This is not correct. First, there are no Y, C1 and C2 values here, but X, Y and Z values. Second, by comparing the result with ippiColorTwist32f, I checked that ippiRGBtoXYZ actually applies the given matrix w i t h o u t normalizing the resulting X, Y and Z to 0..1. Consequently, the X, Y and Z entry values of ippiXYZto RGB are not in the range 0..1, but in a range that sets the resulting R, G and B to be in the range 0..1. Which X, Y and Z values these are, can be found by adding the row values of the given (HDTV) RGB to XYZ matrix.
I draw your attention again to the complexity (http://www.argyllcms.com/doc/ArgyllCMS_arts_tag.html) of the RGB to XYZ conversion as this is a device to device-independent conversion. The device to device conversions are unproblematic: between RGB, HSL and HSV. Also, the device-independent conversions are unproblematic (but unfortunately missing in IPP): between XYZ, Lab, LUV and xyY. Direct conversions between RGB and Lab, LUV are not recommended, but should instead use the RGB to XYZ conversion as an extra step.
Compare this with the device to device and device-independent conversions available with ColorSync https://developer.apple.com/documentation/applicationservices/colorsync_manager/1805133-cmconvertxyz...
Adriaan van Os
And another (related) issue. The headers for ippiGammaFwd and ippiGammaInv say:
Purpose: Performs gamma-correction of an RGB image (ippiGammaFwd); converts a gamma-corrected RGB image back to the original (ippiGammaInv).
In general, this is not true. The mentioned gamma function is the gamma correction specified by ITU-R Recommendation BT.709, https://en.wikipedia.org/wiki/Rec._709 for HDTV. The related sRGB color space https://en.wikipedia.org/wiki/SRGB uses another gamma correction. No other still image color space uses this gamma correction, so for still images, these functions are of no use.
I think this should at least be mentioned in the headers and the documentation.
Also unmentioned is the fact that RGB to XYZ conversions (see my comments above) require inverse gamma companding first, see http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
Adriaan van Os
Sorry for long delay, but I still don't know what to reply. The IPP library has long history and the significant part of functions were implemented by some customer requests with fixed matrices of coefficients. It is not a really bug(crash, wrong result and so on). Adding new function to IPP requires some effort from our team(not big) and it means that we cannot add something else in next IPP release. Could you please estimate how it is important for software community to have these new optimized functions ippiXYZtoLab, ippiLabToXYZ, ippiXYZtoLUV and ippiLUVtoXYZ? Also what about new API ippiRGBToLab_Twist_8u_C3R(...,const Ipp32f twist)? May be it will be more appropriate?
In my software, I use a long list of IPP functions, among them
I relied on these functions doing what they suggest. However, I recently had a better look at the internals of color conversions. And discovered that some of the ippi functions do not do what they should do (or at least not what the docs and the function names suggest they do).
I think there are two possibilities
1. clearly document what the limitations of the current IPP functions are, by describing what they do and especially what they do not do
2. reorganise the IPP color conversion functions to something that is useful and makes sense
I think (1.) is absolute necessary, the documentation for the functions, as they are now, is misleading.
With regard to (2.) this is for Intel to decide. I can only say
- I would use the redesigned functions in my software
- the RGBToXYZ, RGBToLUV and RGBToLab conversions (and back) in the current form only make sense for HDVideo, not for still images
- the same is true for the curremt gamma correction functions in IPP, they only make sense for HDVideo, not for still images
As for the technical aspects
- RGB, HSV and HLS are device color spaces, so conversions between them are unproblematic
- XYZ, LUV, Lab and Yxy are device-independent color spaces, so conversions between them are unproblematic
- RGB to XYZ (and back) is very tricky. It is a device to device-indepent color conversion, dependent on the characteristics of the device, given by an ICC-profile, that is not always unambiguous http://www.argyllcms.com/doc/ArgyllCMS_arts_tag.html. Not to mention that ICC <http://www.color.org> is now promoting LUT-based profiles for workspace color space, which is completely nuts. Image editors, I think, use matrix-based workspaces internally. And not to mention color space white-point conversions, like from D65 to D50 .....
- besides, the conversion from RGB to XYZ requires gamma-corrected RGB, So, an un-gamma function must first be applied to the pixmap RGB. Such a function is (unfortunately) not part of IPP, the gamma function in IPP is for HD video only. Note that sRGB uses a special gamma function of its own <https://en.wikipedia.org/wiki/Gamma_correction>.
So, well, what can I say more to answer your question ? Please follow up if something is not clear. I will be pleased to help to describe or implement new functions or to correct the current documentation.
Adriaan van Os
The headers for ippiRGBToLUV, ippiLUVToRGB, ippiRGBToLab and ippiLabToRGB document that these conversions are a two step process, first from RGB to XYZ and then from XYZ to LUV or Lab. Same for the reverse operations. I can't look into the IPP source code, but this suggests that ippiXYZToLUV, ippiLUVToXYZ, ippiXYZToLab and ippiLabToXYZ are already part of the internals of IPP. If so, it would just be a matter of making these functions available as global calls.
Adriaan van Os