Author Topic: AdaptColorSpace Function  (Read 574 times)

guga

  • Moderator
  • Member
  • *****
  • Posts: 1074
  • Assembly is a state of art.
    • RosAsm
AdaptColorSpace Function
« on: January 26, 2019, 09:32:06 AM »
AdaptColorSpace -  This function converts a RGB Working Space Matrices onto another one. When you are playing with perceptual color spaces such as CieLab, CieLCH, XYZ etc, you end up using the proper matrices related to a given  RGB space such as: Adobe RGB (1998), Apple RGB, ColorMatch, Lab Gamut, sRGB, CIE RGB etc.
Each one of them works on their own Reference Whites (D65, D50, E, C, etc etc).
This function can easily port from one RGB space onto another one, transforming a Apple RGB with a D65 white reference onto a Apple RGB with a D50 reference etc etc, so you can easily port from RGB to Lab and vice-versa, or RGB to XYZ, XYZ to RGB etc using the proper matrices.
The matrix is nothing more then a structure composed of 9 double FPU (Real8) data to be used on the fuctions to convert colorspaces (RGB to Lab etc etc)

Code: [Select]
Proc AdaptColorSpace:
    Arguments @pInWorkSpaceMatrix, @pOutAdapted, @pOutInverted, @WhiteRefFrom, @WhiteRefTo, @Method
    Structure @TempData 72, @pAdaptedMatrixDis 0
    Uses ebx

    lea ebx D@pAdaptedMatrixDis
    call GetChromaticAdaptationMatrix ebx, D@WhiteRefFrom, D@WhiteRefTo, D@Method
    On eax <> &TRUE, ExitP ; The return value in eax is not TRUE (meaning it ended with an error), exit the function.
    call MultiplyMatrix3x3_Double ebx, D@pInWorkSpaceMatrix, D@pOutAdapted
    If D@pOutInverted <> 0
        call InvertMatrix_3x3_Double D@pOutAdapted, D@pOutInverted
    End_If

EndP

Additional function -  MultiplyMatrix3x3_Double
Code: [Select]
;;
    MultiplyMatrix3x3_Double
   
    This function multiplies a 3x3 matrix with another one of the same size
   
        Parameters:
       
            Matrix1 - A pointer to a 3x3 matrix to be multiplied to the next one. The elements on the matrix must be in a Real8 (Double FPU) format.
                      So, the maximum size of the matrix is 72 (9*8) bytes.
            Matrix1 - A pointer to a 3x3 matrix to be multiplied to the previous one. The elements on the matrix must be in a Real8 (Double FPU) format.
                      So, the maximum size of the matrix is 72 (9*8) bytes.
            Output - A pointer to a buffer to receive the multiplied data.
                     The size of the buffer must be at least 72 bytes corresponding to 9 Real8 (Double FPU) data.

            Return Values: This function does not return any value.

            Example of usage:

            [TesteMAtrix1: R$ 1, 2, 3,
                              4, 5, 6,
                              7, 8, 9]

            [TesteMAtrix2: R$ 10, 11, 12,
                              13, 14, 15,
                              16, 17, 18]

            [MyMatrixBuffer: R$ 0 #9]

                call MultiplyMatrix3x3_Double TesteMAtrix1, TesteMAtrix2, MyMatrixBuffer

                The resultant values stored in MyMatrixBuffer will be:

                [MyMatrixBuffer: R$ 84, 90, 96,
                                    201, 216, 231,
                                    318, 342, 366]

;;

Proc MultiplyMatrix3x3_Double:
    Arguments @pMatrix1, @pMatrix2, @pOutput
    Uses edi, ebx, edx

    finit

    mov edi D@pMatrix1
    mov ebx D@pMatrix2
    mov edx D@pOutput

;;
 FloatMatrices.M1Dis    FloatMatrices.M2Dis     FloatMatrices.M3Dis
 FloatMatrices.M4Dis    FloatMatrices.M5Dis     FloatMatrices.M6Dis
 FloatMatrices.M7Dis    FloatMatrices.M8Dis     FloatMatrices.M9Dis

;;

    fld R$edi+FloatMatrices.M1Dis | fmul R$ebx+FloatMatrices.M1Dis | fld R$edi+FloatMatrices.M2Dis | fmul R$ebx+FloatMatrices.M4Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M3Dis | fmul R$ebx+FloatMatrices.M7Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M1Dis
    fld R$edi+FloatMatrices.M1Dis | fmul R$ebx+FloatMatrices.M2Dis | fld R$edi+FloatMatrices.M2Dis | fmul R$ebx+FloatMatrices.M5Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M3Dis | fmul R$ebx+FloatMatrices.M8Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M2Dis
    fld R$edi+FloatMatrices.M1Dis | fmul R$ebx+FloatMatrices.M3Dis | fld R$edi+FloatMatrices.M2Dis | fmul R$ebx+FloatMatrices.M6Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M3Dis | fmul R$ebx+FloatMatrices.M9Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M3Dis

    fld R$edi+FloatMatrices.M4Dis | fmul R$ebx+FloatMatrices.M1Dis | fld R$edi+FloatMatrices.M5Dis | fmul R$ebx+FloatMatrices.M4Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M6Dis | fmul R$ebx+FloatMatrices.M7Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M4Dis
    fld R$edi+FloatMatrices.M4Dis | fmul R$ebx+FloatMatrices.M2Dis | fld R$edi+FloatMatrices.M5Dis | fmul R$ebx+FloatMatrices.M5Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M6Dis | fmul R$ebx+FloatMatrices.M8Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M5Dis
    fld R$edi+FloatMatrices.M4Dis | fmul R$ebx+FloatMatrices.M3Dis | fld R$edi+FloatMatrices.M5Dis | fmul R$ebx+FloatMatrices.M6Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M6Dis | fmul R$ebx+FloatMatrices.M9Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M6Dis

    fld R$edi+FloatMatrices.M7Dis | fmul R$ebx+FloatMatrices.M1Dis | fld R$edi+FloatMatrices.M8Dis | fmul R$ebx+FloatMatrices.M4Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M9Dis | fmul R$ebx+FloatMatrices.M7Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M7Dis
    fld R$edi+FloatMatrices.M7Dis | fmul R$ebx+FloatMatrices.M2Dis | fld R$edi+FloatMatrices.M8Dis | fmul R$ebx+FloatMatrices.M5Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M9Dis | fmul R$ebx+FloatMatrices.M8Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M8Dis
    fld R$edi+FloatMatrices.M7Dis | fmul R$ebx+FloatMatrices.M3Dis | fld R$edi+FloatMatrices.M8Dis | fmul R$ebx+FloatMatrices.M6Dis | faddp ST1 ST0 | fld R$edi+FloatMatrices.M9Dis | fmul R$ebx+FloatMatrices.M9Dis | faddp ST1 ST0 | fstp R$edx+FloatMatrices.M9Dis

EndP

For complete documentation on the usage of this function, see the attached file.

For the others additional functions GetChromaticAdaptationMatrix and  InvertMatrix_3x3_Double, please see them at: http://masm32.com/board/index.php?topic=7644.0



I´m currently building a better "RGB to CieLCH" function (And the reverted back) that can use any of those transformations and also i´ll plan to put all of those matrixes on a single structure to be configured automatically with very few user intervention. A configuration function is usefull to make the RGBtoCieLCH function works faster since all necessary data (gamma, offset, slope, white reference and the matrices) will be already precalculated, so, no need to insert extra functions to compute all of them whenever you need to use the RGB to CieLCH converter :)

If i succeed you will be able to use about 720 different variations on each color space model, like Adobe RGB 1998. Since i´ll  also insert the other models (About 25 different models/colorspaces, such as: BetaRGB, Bruce, Ekta, NTSC, PAL, ProPhoto, Cie, HDTV etc), it means you may be able to build somethign around 18000 (720*25) different models/colorspaces to play with  :greensml: :greensml: :greensml: :greensml:
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com