CieLCH seems to be the best option but also the most complicated color space conversion algorithm.
For me this is a new field to explore and have to learn a lot more to understand it fully.
Looking forward to see your CieLCH routine when finished. :t
Found this paper:
http://jcgt.org/published/0002/02/01/paper.pdfIn my own logic, I always try to understand algorithms by working my way backwards.
Then I try to simplify the calculations if possible.
In the case of color space conversion you can precalculate the coefficients for a dot3 matrix routine.
Once you know the 3*3 matrix coefficients for the "forward" RGB -> XYZ calculations,
you can use the inverse of the 3*3 matrix coefficients to compute the "backwards" XYZ -> RGB.
This way, the "backwards" results will always be correct.
Bruce Lindbloom has done some of the coefficients math for us to compute the RGB -> XYZ and XYZ -> RGB matrices.
http://www.brucelindbloom.com/Eqn_RGB_XYZ_Matrix.htmlThere is a CIE Color Calculator on his site:
http://www.brucelindbloom.com/ColorCalculator.htmlMy routines are not finished yet but I will post them when ready, then we can check if it is done right.
Here is the dot3 color conversion routine I wrote, the one is used in the example above in reply #70.
I wrote it in SSE2 instructions so it can be used on older computers as well. ( so no fancy byte shuffles in this one. )
Adjusted the 3*3 matrix transpose routine to handle 4 row elements preserving alpha
; B G R A
CIERGB2XYZ real4 0.2006017, 0.3106803, 0.4887180, 0.0 ; X
real4 0.0108109, 0.8129847, 0.1762044, 0.0 ; Y
real4 0.9897952, 0.0102048, 0.0000000, 1.0 ; Z ( AZ must be 1.0 )
ALPHA_mask dd -1,-1,-1,0
align 4
ColorConversionInt2Float proc uses ebx esi edi BitmapWidth:DWORD,BitmapHeight:DWORD,pSourceMem:DWORD,pDestinationMem:DWORD,pConversionType:DWORD
mov esi,pSourceMem
mov edi,pDestinationMem
mov edx,pConversionType
mov ecx,BitmapWidth
imul ecx,BitmapHeight
shr ecx,2
pxor xmm5,xmm5 ; Empty the source operand, to zero the integer high parts,
; in the "punpcklbw", "punpcklwd" instructions
align 16
LoadFourPixels:
mov ebx,4
movdqa xmm6,oword ptr [esi] ; Load 4 ARGB pixels at once
FourPixelLP:
movq xmm0,xmm6 ; 1 pixel
punpcklbw xmm0,xmm5 ; Convert 4 bytes to 4 words
punpcklwd xmm0,xmm5 ; Convert 4 words to 4 dwords
cvtdq2ps xmm0,xmm0 ; Convert 4 dwords to 4 real4 values
movaps xmm1,xmm0 ; [B G R A]
movaps xmm2,xmm0 ; [B G R A]
mulps xmm0,oword ptr [edx] ; [BX GX RX --] Multiply Color X conversion coefficients
mulps xmm1,oword ptr [edx+16] ; [BY GY RY --] Multiply Color Y conversion coefficients
mulps xmm2,oword ptr [edx+32] ; [BZ GZ RZ AZ] Multiply Color Z conversion coefficients
; Color conversion using an adjusted SSE2 4*3 matrix transposition routine ( preserving Alpha_Z)
; Now we can run a fast Dot3 ( 3-component vector ) calculation on the
; 12 color components and 12 color coefficients ( 9 of each + 3 Alpha components )
; Calculations are in parallel, 3 muls and 2 adds
movaps xmm3,xmm0 ; [BX GX RX --]
movaps xmm4,xmm2 ; [BZ GZ RZ AZ]
unpcklps xmm3,xmm1 ; [BX BY GX GY]
unpcklps xmm4,xmm4 ; [BZ BZ GZ GZ]
movhlps xmm4,xmm3 ; [GX GY GZ GZ]
movlhps xmm3,xmm2 ; [BX BY BZ GZ]
unpckhps xmm0,xmm1 ; [RX RY -- --]
shufps xmm0,xmm2,Shuffle(3,2,1,0) ; [RX RY RZ AZ]
shufps xmm6,xmm6,Shuffle(0,3,2,1) ; pre-load next ARGB pixel
addps xmm3,xmm4 ; [BX+GX BY+GY BZ+GZ GZ+GZ]
andps xmm3,oword ptr ALPHA_mask ; [BX+GX BY+GY BZ+GZ --]
addps xmm0,xmm3 ; [RX+BX+GX RY+BY+GY RZ+BZ+GZ AZ]
; result: BGRA
movaps oword ptr [edi],xmm0 ; Store BGRA Pixel in Real4 format
add edi,16
dec ebx
jnz FourPixelLP
add esi,16
dec ecx
jnz LoadFourPixels
ret
ColorConversionInt2Float endp