| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 2003-2007, Broadcom Corporation |
|---|
| 3 | * All Rights Reserved |
|---|
| 4 | * Confidential Property of Broadcom Corporation |
|---|
| 5 | * |
|---|
| 6 | * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE |
|---|
| 7 | * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR |
|---|
| 8 | * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 9 | * |
|---|
| 10 | * $brcm_Workfile: bcsc.c $ |
|---|
| 11 | * $brcm_Revision: Hydra_Software_Devel/2 $ |
|---|
| 12 | * $brcm_Date: 6/11/07 6:48p $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: /magnum/commonutils/csc/bcsc.c $ |
|---|
| 19 | * |
|---|
| 20 | * Hydra_Software_Devel/2 6/11/07 6:48p albertl |
|---|
| 21 | * PR31093: Fixed some fixed math errors. |
|---|
| 22 | * |
|---|
| 23 | * Hydra_Software_Devel/1 5/31/07 7:29p albertl |
|---|
| 24 | * PR31093: Initial version. |
|---|
| 25 | * |
|---|
| 26 | ***************************************************************************/ |
|---|
| 27 | #include "bstd.h" /* standard types */ |
|---|
| 28 | #include "bkni.h" /* memcpy calls */ |
|---|
| 29 | #include "bmth_fix.h" |
|---|
| 30 | #include "bcsc.h" |
|---|
| 31 | #include "bdbg.h" |
|---|
| 32 | |
|---|
| 33 | BDBG_MODULE(BCSC); |
|---|
| 34 | |
|---|
| 35 | #define BCSC_P_FIX_MAX_BITS (31) |
|---|
| 36 | |
|---|
| 37 | #define BCSC_P_FIX_CONVERT(x, infract, outfract) \ |
|---|
| 38 | (BMTH_FIX_SIGNED_CONVERT(x, (BCSC_P_FIX_MAX_BITS - infract), infract, (BCSC_P_FIX_MAX_BITS - outfract), outfract)) |
|---|
| 39 | |
|---|
| 40 | /* fixed to integer */ |
|---|
| 41 | #define BCSC_P_FIXTOI(x, infract) \ |
|---|
| 42 | (BMTH_FIX_SIGNED_FIXTOI(x, (BCSC_P_FIX_MAX_BITS - infract), infract)) |
|---|
| 43 | |
|---|
| 44 | /* integer to fixed */ |
|---|
| 45 | #define BCSC_P_ITOFIX(x, outfract) \ |
|---|
| 46 | (BMTH_FIX_SIGNED_ITOFIX(x, (BCSC_P_FIX_MAX_BITS - outfract), outfract)) |
|---|
| 47 | |
|---|
| 48 | /* fixed point operation multiply */ |
|---|
| 49 | #define BCSC_P_FIX_MUL(x, y, fract) \ |
|---|
| 50 | (BMTH_FIX_SIGNED_MUL(x, y, (BCSC_P_FIX_MAX_BITS - fract), fract, \ |
|---|
| 51 | (BCSC_P_FIX_MAX_BITS - fract), fract, \ |
|---|
| 52 | (BCSC_P_FIX_MAX_BITS - fract), fract)) |
|---|
| 53 | |
|---|
| 54 | /* fixed point operation divide */ |
|---|
| 55 | #define BCSC_P_FIX_DIV(x, y, fract) \ |
|---|
| 56 | (BMTH_FIX_SIGNED_DIV(x, y, (BCSC_P_FIX_MAX_BITS - fract), fract, \ |
|---|
| 57 | (BCSC_P_FIX_MAX_BITS - fract), fract, \ |
|---|
| 58 | (BCSC_P_FIX_MAX_BITS - fract), fract)) |
|---|
| 59 | |
|---|
| 60 | typedef struct BCSC_P_Matrix |
|---|
| 61 | { |
|---|
| 62 | uint32_t data[4][4]; |
|---|
| 63 | uint32_t ulSize; |
|---|
| 64 | uint32_t ulFractBits; |
|---|
| 65 | } BCSC_P_Matrix; |
|---|
| 66 | |
|---|
| 67 | typedef struct BCSC_P_Vector |
|---|
| 68 | { |
|---|
| 69 | uint32_t data[4]; |
|---|
| 70 | uint32_t ulSize; |
|---|
| 71 | uint32_t ulFractBits; |
|---|
| 72 | } BCSC_P_Vector; |
|---|
| 73 | |
|---|
| 74 | |
|---|
| 75 | /* Prototypes */ |
|---|
| 76 | void BCSC_P_Matrix_RGBW_To_NPM |
|---|
| 77 | ( uint32_t *pulRGBW, |
|---|
| 78 | uint32_t ulRGBWFractBits, |
|---|
| 79 | BCSC_P_Matrix *pNPM, |
|---|
| 80 | uint32_t ulNPMFractBits); |
|---|
| 81 | |
|---|
| 82 | void BCSC_P_Matrix_NPM_To_RGBPrime_To_YCbCrPrime |
|---|
| 83 | ( BCSC_P_Matrix *pNPM, |
|---|
| 84 | BCSC_P_Matrix *pRetMatrix); |
|---|
| 85 | |
|---|
| 86 | void BCSC_P_Matrix_Mult |
|---|
| 87 | ( BCSC_P_Matrix *pMatrix1, |
|---|
| 88 | BCSC_P_Matrix *pMatrix2, |
|---|
| 89 | BCSC_P_Matrix *pRetMatrix); |
|---|
| 90 | |
|---|
| 91 | void BCSC_P_Matrix_MultVector |
|---|
| 92 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 93 | BCSC_P_Vector *pVector, |
|---|
| 94 | BCSC_P_Vector *pRetVector); |
|---|
| 95 | |
|---|
| 96 | void BCSC_P_Matrix_Make4x4 |
|---|
| 97 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 98 | BCSC_P_Matrix *pRetMatrix); |
|---|
| 99 | |
|---|
| 100 | void BCSC_P_Matrix_GScale |
|---|
| 101 | ( uint32_t ulN, |
|---|
| 102 | BCSC_P_Matrix *pRetMatrix, |
|---|
| 103 | uint32_t ulMatrixFractBits); |
|---|
| 104 | |
|---|
| 105 | void BCSC_P_Matrix_GScaleInverse |
|---|
| 106 | ( uint32_t ulN, |
|---|
| 107 | BCSC_P_Matrix *pRetMatrix, |
|---|
| 108 | uint32_t ulMatrixFractBits); |
|---|
| 109 | |
|---|
| 110 | void BCSC_P_Matrix_GGain |
|---|
| 111 | ( uint32_t ulN, |
|---|
| 112 | BCSC_P_Matrix *pRetMatrix, |
|---|
| 113 | uint32_t ulMatrixFractBits); |
|---|
| 114 | |
|---|
| 115 | uint32_t BCSC_P_Matrix_Cofactor |
|---|
| 116 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 117 | uint32_t ulRow, |
|---|
| 118 | uint32_t ulCol); |
|---|
| 119 | |
|---|
| 120 | uint32_t BCSC_P_Matrix_Determinant |
|---|
| 121 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 122 | BCSC_P_Matrix *pCofactors); |
|---|
| 123 | |
|---|
| 124 | void BCSC_P_Matrix_CofactorMatrix |
|---|
| 125 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 126 | BCSC_P_Matrix *pCofactors); |
|---|
| 127 | |
|---|
| 128 | void BCSC_P_Matrix_Transpose |
|---|
| 129 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 130 | BCSC_P_Matrix *pRetMatrix); |
|---|
| 131 | |
|---|
| 132 | void BCSC_P_Matrix_Inverse |
|---|
| 133 | ( BCSC_P_Matrix *pMatrix, |
|---|
| 134 | BCSC_P_Matrix *pRetMatrix); |
|---|
| 135 | |
|---|
| 136 | void BCSC_P_Matrix_Dump |
|---|
| 137 | ( BCSC_P_Matrix *pMatrix); |
|---|
| 138 | |
|---|
| 139 | /* Given source and display (xR, yR), (xG, yG), (xB, yB), (xW, yW), derive CMP matrix; |
|---|
| 140 | Output: CMP matrix in array of 12 fixed point coefficients; |
|---|
| 141 | inputs: |
|---|
| 142 | pul_SrcRGBW - Source gamut in (xR, yR), (xG, yG), (xB, yB), (xW, yW) array, 8 values; |
|---|
| 143 | pul_DispRGBW: - Display gamut in (xR, yR), (xG, yG), (xB, yB), (xW, yW) array, 8 values; |
|---|
| 144 | ulXyFractBits - Fixed-point fractional bits of input gamut values in (x, y) array; |
|---|
| 145 | ulMatrixFractBits - Fixed-point fractional bits of output matrix coefficients; */ |
|---|
| 146 | BERR_Code BCSC_RGBW2CmpMatrix |
|---|
| 147 | ( uint32_t *pul_SrcRGBW, |
|---|
| 148 | uint32_t *pul_DispRGBW, |
|---|
| 149 | uint32_t ulXyFractBits, |
|---|
| 150 | uint32_t ulMatrixFractBits, |
|---|
| 151 | uint32_t ulN, |
|---|
| 152 | int32_t *plCmpMatrix, |
|---|
| 153 | int32_t *plDvoMatrix) |
|---|
| 154 | { |
|---|
| 155 | BCSC_P_Matrix stMatrix3_SrcNPM; |
|---|
| 156 | BCSC_P_Matrix stMatrix3_Src_RGBPrime_To_YCbCrPrime; |
|---|
| 157 | BCSC_P_Matrix stMatrix3_Src_YCbCrPrime_To_RGBPrime; |
|---|
| 158 | BCSC_P_Matrix stMatrix4_Src_YCbCrPrime_To_RGBPrime; |
|---|
| 159 | BCSC_P_Matrix stMatrix3_DispNPM; |
|---|
| 160 | BCSC_P_Matrix stMatrix3_DispNPMInv; |
|---|
| 161 | BCSC_P_Matrix stMatrix3_Disp_RGBPrime_To_YCbCrPrime; |
|---|
| 162 | BCSC_P_Matrix stMatrix4_Disp_RGBPrime_To_YCbCrPrime; |
|---|
| 163 | BCSC_P_Matrix stMatrix4_Disp_YCbCrPrime_To_RGBPrime; |
|---|
| 164 | BCSC_P_Matrix stMatrix4_RGB_S_To_D; |
|---|
| 165 | BCSC_P_Matrix stMatrix4_GScale; |
|---|
| 166 | BCSC_P_Matrix stMatrix4_GScaleInv; |
|---|
| 167 | BCSC_P_Matrix stMatrix4_GGain; |
|---|
| 168 | BCSC_P_Matrix stMatrix4_CMP_CSC; |
|---|
| 169 | BCSC_P_Matrix stMatrix4_DVI_CSC; |
|---|
| 170 | BCSC_P_Matrix stMatrix3_Temp; |
|---|
| 171 | |
|---|
| 172 | uint32_t i = 0; |
|---|
| 173 | uint32_t j = 0; |
|---|
| 174 | |
|---|
| 175 | if(!pul_SrcRGBW || !pul_DispRGBW || !plCmpMatrix || !plDvoMatrix) |
|---|
| 176 | { |
|---|
| 177 | return BERR_INVALID_PARAMETER; |
|---|
| 178 | } |
|---|
| 179 | |
|---|
| 180 | stMatrix3_SrcNPM.ulSize = 3; |
|---|
| 181 | stMatrix3_Src_RGBPrime_To_YCbCrPrime.ulSize = 3; |
|---|
| 182 | stMatrix3_DispNPM.ulSize = 3; |
|---|
| 183 | stMatrix3_DispNPMInv.ulSize = 3; |
|---|
| 184 | stMatrix3_Disp_RGBPrime_To_YCbCrPrime.ulSize = 3; |
|---|
| 185 | stMatrix3_Temp.ulSize = 3; |
|---|
| 186 | |
|---|
| 187 | stMatrix4_Src_YCbCrPrime_To_RGBPrime.ulSize = 4; |
|---|
| 188 | stMatrix4_Disp_RGBPrime_To_YCbCrPrime.ulSize = 4; |
|---|
| 189 | stMatrix4_Disp_YCbCrPrime_To_RGBPrime.ulSize = 4; |
|---|
| 190 | stMatrix4_RGB_S_To_D.ulSize = 4; |
|---|
| 191 | stMatrix4_GScale.ulSize = 4; |
|---|
| 192 | stMatrix4_GScaleInv.ulSize = 4; |
|---|
| 193 | stMatrix4_GGain.ulSize = 4; |
|---|
| 194 | stMatrix4_CMP_CSC.ulSize = 4; |
|---|
| 195 | stMatrix4_DVI_CSC.ulSize = 4; |
|---|
| 196 | |
|---|
| 197 | /* calculate 3x3 Source NPM */ |
|---|
| 198 | BCSC_P_Matrix_RGBW_To_NPM(pul_SrcRGBW, ulXyFractBits, &stMatrix3_SrcNPM, ulMatrixFractBits); |
|---|
| 199 | |
|---|
| 200 | /* calculate 3x3 Source R'G'B' to Y'Cb'Cr' matrix */ |
|---|
| 201 | BCSC_P_Matrix_NPM_To_RGBPrime_To_YCbCrPrime(&stMatrix3_SrcNPM, &stMatrix3_Src_RGBPrime_To_YCbCrPrime); |
|---|
| 202 | |
|---|
| 203 | /* calculate 4x4 Source Y'Cb'Cr' to R'G'B' matrix */ |
|---|
| 204 | BCSC_P_Matrix_Inverse(&stMatrix3_Src_RGBPrime_To_YCbCrPrime, &stMatrix3_Src_YCbCrPrime_To_RGBPrime); |
|---|
| 205 | BCSC_P_Matrix_Make4x4(&stMatrix3_Src_YCbCrPrime_To_RGBPrime, &stMatrix4_Src_YCbCrPrime_To_RGBPrime); |
|---|
| 206 | |
|---|
| 207 | /* calculate 3x3 Display NPM */ |
|---|
| 208 | BCSC_P_Matrix_RGBW_To_NPM(pul_DispRGBW, ulXyFractBits, &stMatrix3_DispNPM, ulMatrixFractBits); |
|---|
| 209 | |
|---|
| 210 | /* calculate 4x4 Display R'G'B' to Y'Cb'Cr' matrix */ |
|---|
| 211 | BCSC_P_Matrix_NPM_To_RGBPrime_To_YCbCrPrime(&stMatrix3_DispNPM, &stMatrix3_Disp_RGBPrime_To_YCbCrPrime); |
|---|
| 212 | BCSC_P_Matrix_Make4x4(&stMatrix3_Disp_RGBPrime_To_YCbCrPrime, &stMatrix4_Disp_RGBPrime_To_YCbCrPrime); |
|---|
| 213 | |
|---|
| 214 | /* calculate 4x4 Display Y'Cb'Cr' to R'G'B' matrix */ |
|---|
| 215 | BCSC_P_Matrix_Inverse(&stMatrix4_Disp_RGBPrime_To_YCbCrPrime, &stMatrix4_Disp_YCbCrPrime_To_RGBPrime); |
|---|
| 216 | |
|---|
| 217 | /* calculate 4x4 RGB source to RGB display matrix */ |
|---|
| 218 | BCSC_P_Matrix_Inverse(&stMatrix3_DispNPM, &stMatrix3_DispNPMInv); |
|---|
| 219 | BCSC_P_Matrix_Mult(&stMatrix3_DispNPMInv, &stMatrix3_SrcNPM, &stMatrix3_Temp); |
|---|
| 220 | BCSC_P_Matrix_Make4x4(&stMatrix3_Temp, &stMatrix4_RGB_S_To_D); |
|---|
| 221 | |
|---|
| 222 | /* calculate 4x4 G scale and G gain matrices */ |
|---|
| 223 | BCSC_P_Matrix_GScale(ulN, &stMatrix4_GScale, ulMatrixFractBits); |
|---|
| 224 | /* BCSC_P_Matrix_Inverse(&stMatrix4_GScale, &stMatrix4_GScaleInv);*/ |
|---|
| 225 | BCSC_P_Matrix_GScaleInverse(ulN, &stMatrix4_GScaleInv, ulMatrixFractBits); |
|---|
| 226 | BCSC_P_Matrix_GGain(ulN, &stMatrix4_GGain, ulMatrixFractBits); |
|---|
| 227 | |
|---|
| 228 | /* calculate final CMP CSC matrix */ |
|---|
| 229 | BCSC_P_Matrix_Mult(&stMatrix4_Src_YCbCrPrime_To_RGBPrime, &stMatrix4_GScale, &stMatrix4_CMP_CSC); |
|---|
| 230 | BCSC_P_Matrix_Mult(&stMatrix4_RGB_S_To_D, &stMatrix4_CMP_CSC, &stMatrix4_CMP_CSC); |
|---|
| 231 | BCSC_P_Matrix_Mult(&stMatrix4_Disp_RGBPrime_To_YCbCrPrime, &stMatrix4_CMP_CSC, &stMatrix4_CMP_CSC); |
|---|
| 232 | BCSC_P_Matrix_Mult(&stMatrix4_GScaleInv, &stMatrix4_CMP_CSC, &stMatrix4_CMP_CSC); |
|---|
| 233 | |
|---|
| 234 | /* calculate final DVI CSC matrix */ |
|---|
| 235 | BCSC_P_Matrix_Mult(&stMatrix4_Disp_YCbCrPrime_To_RGBPrime, &stMatrix4_GScale, &stMatrix4_DVI_CSC); |
|---|
| 236 | BCSC_P_Matrix_Mult(&stMatrix4_GGain, &stMatrix4_DVI_CSC, &stMatrix4_DVI_CSC); |
|---|
| 237 | |
|---|
| 238 | for (i = 0; i < 4; i++) |
|---|
| 239 | { |
|---|
| 240 | for (j = 0; j < 4; j++) |
|---|
| 241 | { |
|---|
| 242 | plCmpMatrix[i*4 + j] = stMatrix4_CMP_CSC.data[i][j]; |
|---|
| 243 | plDvoMatrix[i*4 + j] = stMatrix4_DVI_CSC.data[i][j]; |
|---|
| 244 | } |
|---|
| 245 | } |
|---|
| 246 | |
|---|
| 247 | return BERR_SUCCESS; |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | /*************************************************************************** |
|---|
| 251 | * {private} |
|---|
| 252 | * |
|---|
| 253 | * Takes a RGBW array and outputs a 3x3 NPM matrix. |
|---|
| 254 | */ |
|---|
| 255 | void BCSC_P_Matrix_RGBW_To_NPM(uint32_t *pulRGBW, uint32_t ulRGBWFractBits, BCSC_P_Matrix *pNPM, uint32_t ulNPMFractBits) |
|---|
| 256 | { |
|---|
| 257 | uint32_t ulSize = 3; |
|---|
| 258 | uint32_t ulRx = BCSC_P_FIX_CONVERT(pulRGBW[0], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 259 | uint32_t ulRy = BCSC_P_FIX_CONVERT(pulRGBW[1], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 260 | uint32_t ulGx = BCSC_P_FIX_CONVERT(pulRGBW[2], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 261 | uint32_t ulGy = BCSC_P_FIX_CONVERT(pulRGBW[3], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 262 | uint32_t ulBx = BCSC_P_FIX_CONVERT(pulRGBW[4], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 263 | uint32_t ulBy = BCSC_P_FIX_CONVERT(pulRGBW[5], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 264 | uint32_t ulWx = BCSC_P_FIX_CONVERT(pulRGBW[6], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 265 | uint32_t ulWy = BCSC_P_FIX_CONVERT(pulRGBW[7], ulRGBWFractBits, ulNPMFractBits); |
|---|
| 266 | BCSC_P_Matrix stMatrixP; |
|---|
| 267 | BCSC_P_Matrix stMatrixPInv; |
|---|
| 268 | BCSC_P_Matrix stMatrixC; |
|---|
| 269 | BCSC_P_Vector stVectorW; |
|---|
| 270 | BCSC_P_Vector stVectorCRGB; |
|---|
| 271 | |
|---|
| 272 | uint32_t ulFixOne = BCSC_P_ITOFIX(1, ulNPMFractBits); |
|---|
| 273 | |
|---|
| 274 | /* Matrix P */ |
|---|
| 275 | stMatrixP.ulSize = ulSize; |
|---|
| 276 | stMatrixP.ulFractBits = ulNPMFractBits; |
|---|
| 277 | stMatrixP.data[0][0] = ulRx; |
|---|
| 278 | stMatrixP.data[0][1] = ulRy; |
|---|
| 279 | stMatrixP.data[0][2] = ulGx; |
|---|
| 280 | stMatrixP.data[1][0] = ulGy; |
|---|
| 281 | stMatrixP.data[1][1] = ulBx; |
|---|
| 282 | stMatrixP.data[1][2] = ulBy; |
|---|
| 283 | stMatrixP.data[2][0] = ulFixOne - (ulRx + ulRy); |
|---|
| 284 | stMatrixP.data[2][1] = ulFixOne - (ulGx + ulGy); |
|---|
| 285 | stMatrixP.data[2][2] = ulFixOne - (ulBx + ulBy); |
|---|
| 286 | |
|---|
| 287 | /* Vector W */ |
|---|
| 288 | stVectorW.ulSize = ulSize; |
|---|
| 289 | stVectorW.ulFractBits = ulNPMFractBits; |
|---|
| 290 | /* ulWx / ulWy */ |
|---|
| 291 | stVectorW.data[0] = BCSC_P_FIX_DIV(ulWx, ulWy, ulNPMFractBits); |
|---|
| 292 | /* 1 */ |
|---|
| 293 | stVectorW.data[1] = ulFixOne; |
|---|
| 294 | /* (1 - ulWx - ulWy) / ulWy */ |
|---|
| 295 | stVectorW.data[2] = BCSC_P_FIX_DIV((ulFixOne - ulWx - ulWy), ulWy, ulNPMFractBits); |
|---|
| 296 | |
|---|
| 297 | /* Vector C RGB */ |
|---|
| 298 | stVectorCRGB.ulSize = ulSize; |
|---|
| 299 | stVectorCRGB.ulFractBits = ulNPMFractBits; |
|---|
| 300 | BCSC_P_Matrix_Inverse(&stMatrixP, &stMatrixPInv); |
|---|
| 301 | BCSC_P_Matrix_MultVector(&stMatrixPInv, &stVectorW, &stVectorCRGB); |
|---|
| 302 | |
|---|
| 303 | /* Matrix C */ |
|---|
| 304 | stMatrixC.ulSize = ulSize; |
|---|
| 305 | stMatrixC.ulFractBits = ulNPMFractBits; |
|---|
| 306 | stMatrixC.data[0][0] = stVectorCRGB.data[0]; |
|---|
| 307 | stMatrixC.data[0][1] = 0; |
|---|
| 308 | stMatrixC.data[0][2] = 0; |
|---|
| 309 | stMatrixC.data[1][0] = 0; |
|---|
| 310 | stMatrixC.data[1][1] = stVectorCRGB.data[1]; |
|---|
| 311 | stMatrixC.data[1][2] = 0; |
|---|
| 312 | stMatrixC.data[2][0] = 0; |
|---|
| 313 | stMatrixC.data[2][1] = 0; |
|---|
| 314 | stMatrixC.data[2][2] = stVectorCRGB.data[2]; |
|---|
| 315 | |
|---|
| 316 | BCSC_P_Matrix_Mult(&stMatrixP, &stMatrixC, pNPM); |
|---|
| 317 | } |
|---|
| 318 | |
|---|
| 319 | /*************************************************************************** |
|---|
| 320 | * {private} |
|---|
| 321 | * |
|---|
| 322 | * Takes a 3x3 NPM matrix and outputs a 3x3 RGBPrime_To_YCbCrPrime matrix. |
|---|
| 323 | */ |
|---|
| 324 | void BCSC_P_Matrix_NPM_To_RGBPrime_To_YCbCrPrime(BCSC_P_Matrix *pNPM, BCSC_P_Matrix *pRetMatrix) |
|---|
| 325 | { |
|---|
| 326 | uint32_t ulFractBits = pNPM->ulFractBits; |
|---|
| 327 | uint32_t ulFixOne = BCSC_P_ITOFIX(1, ulFractBits); |
|---|
| 328 | |
|---|
| 329 | pRetMatrix->ulSize = 3; |
|---|
| 330 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 331 | pRetMatrix->data[0][0] = pNPM->data[1][0]; |
|---|
| 332 | pRetMatrix->data[0][1] = pNPM->data[1][1]; |
|---|
| 333 | pRetMatrix->data[0][2] = pNPM->data[1][2]; |
|---|
| 334 | pRetMatrix->data[1][0] = BCSC_P_FIX_DIV(-(pNPM->data[1][0]), 2*(ulFixOne - pNPM->data[1][2]), ulFractBits); |
|---|
| 335 | pRetMatrix->data[1][1] = pNPM->data[1][1]; |
|---|
| 336 | pRetMatrix->data[1][2] = ulFixOne / 2; |
|---|
| 337 | pRetMatrix->data[2][0] = ulFixOne / 2; |
|---|
| 338 | pRetMatrix->data[2][1] = BCSC_P_FIX_DIV(-(pNPM->data[1][1]), 2*(ulFixOne - pNPM->data[1][0]), ulFractBits); |
|---|
| 339 | pRetMatrix->data[2][2] = BCSC_P_FIX_DIV(-(pNPM->data[1][2]), 2*(ulFixOne - pNPM->data[1][0]), ulFractBits); |
|---|
| 340 | } |
|---|
| 341 | |
|---|
| 342 | /*************************************************************************** |
|---|
| 343 | * {private} |
|---|
| 344 | * |
|---|
| 345 | * Takes two matrices and multiplies them together. Result is a matrix |
|---|
| 346 | * with the same size and fixed point fractional bits. |
|---|
| 347 | */ |
|---|
| 348 | void BCSC_P_Matrix_Mult(BCSC_P_Matrix *pMatrix1, BCSC_P_Matrix *pMatrix2, BCSC_P_Matrix *pRetMatrix) |
|---|
| 349 | { |
|---|
| 350 | BCSC_P_Matrix stMatrixTemp; |
|---|
| 351 | uint32_t ulSize = pMatrix1->ulSize; |
|---|
| 352 | uint32_t ulFractBits = pMatrix1->ulFractBits; |
|---|
| 353 | uint32_t i = 0; |
|---|
| 354 | uint32_t j = 0; |
|---|
| 355 | uint32_t k = 0; |
|---|
| 356 | |
|---|
| 357 | BDBG_ASSERT(pMatrix1->ulSize == pMatrix2->ulSize); |
|---|
| 358 | BDBG_ASSERT(pMatrix1->ulFractBits == pMatrix2->ulFractBits); |
|---|
| 359 | |
|---|
| 360 | stMatrixTemp.ulSize = ulSize; |
|---|
| 361 | stMatrixTemp.ulFractBits = ulFractBits; |
|---|
| 362 | |
|---|
| 363 | for (i = 0; i < ulSize; i++) |
|---|
| 364 | { |
|---|
| 365 | for (j = 0; j < ulSize; j++) |
|---|
| 366 | { |
|---|
| 367 | stMatrixTemp.data[i][j] = 0; |
|---|
| 368 | for (k = 0; k < ulSize; k++) |
|---|
| 369 | { |
|---|
| 370 | stMatrixTemp.data[i][j] += (unsigned)BCSC_P_FIX_MUL((signed)pMatrix1->data[i][k], (signed)pMatrix2->data[k][j], ulFractBits); |
|---|
| 371 | } |
|---|
| 372 | } |
|---|
| 373 | } |
|---|
| 374 | |
|---|
| 375 | BKNI_Memcpy(pRetMatrix, &stMatrixTemp, sizeof(stMatrixTemp)); |
|---|
| 376 | } |
|---|
| 377 | |
|---|
| 378 | /*************************************************************************** |
|---|
| 379 | * {private} |
|---|
| 380 | * |
|---|
| 381 | * Multiplies a Matrix with a Vector. Result is a vector with the same |
|---|
| 382 | * size as the original vector and same fixed point fractional bits. |
|---|
| 383 | */ |
|---|
| 384 | void BCSC_P_Matrix_MultVector(BCSC_P_Matrix *pMatrix, BCSC_P_Vector *pVector, BCSC_P_Vector *pRetVector) |
|---|
| 385 | { |
|---|
| 386 | BCSC_P_Vector stTempVector; |
|---|
| 387 | uint32_t ulSize = pMatrix->ulSize; |
|---|
| 388 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 389 | uint32_t i = 0; |
|---|
| 390 | uint32_t k = 0; |
|---|
| 391 | |
|---|
| 392 | BDBG_ASSERT(pMatrix->ulSize == pVector->ulSize); |
|---|
| 393 | BDBG_ASSERT(pMatrix->ulFractBits == pVector->ulFractBits); |
|---|
| 394 | |
|---|
| 395 | stTempVector.ulSize = ulSize; |
|---|
| 396 | stTempVector.ulFractBits = ulFractBits; |
|---|
| 397 | |
|---|
| 398 | for (i = 0; i < ulSize; i++) |
|---|
| 399 | { |
|---|
| 400 | stTempVector.data[i] = 0; |
|---|
| 401 | for (k = 0; k < ulSize; k++) |
|---|
| 402 | { |
|---|
| 403 | stTempVector.data[i] += BCSC_P_FIX_MUL(pMatrix->data[i][k], pVector->data[k], ulFractBits); |
|---|
| 404 | } |
|---|
| 405 | } |
|---|
| 406 | |
|---|
| 407 | BKNI_Memcpy(pRetVector, &stTempVector, sizeof(stTempVector)); |
|---|
| 408 | } |
|---|
| 409 | |
|---|
| 410 | /*************************************************************************** |
|---|
| 411 | * {private} |
|---|
| 412 | * |
|---|
| 413 | * Takes a 3x3 matrix and converts it to a 4x4 matrix. |
|---|
| 414 | */ |
|---|
| 415 | void BCSC_P_Matrix_Make4x4(BCSC_P_Matrix *pMatrix, BCSC_P_Matrix *pRetMatrix) |
|---|
| 416 | { |
|---|
| 417 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 418 | uint32_t i = 0; |
|---|
| 419 | uint32_t j = 0; |
|---|
| 420 | |
|---|
| 421 | BDBG_ASSERT(pMatrix->ulSize == 3); |
|---|
| 422 | |
|---|
| 423 | BKNI_Memset(pRetMatrix, 0, sizeof(BCSC_P_Matrix)); |
|---|
| 424 | pRetMatrix->ulSize = 4; |
|---|
| 425 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 426 | pRetMatrix->data[3][3] = BCSC_P_ITOFIX(1, ulFractBits); |
|---|
| 427 | |
|---|
| 428 | for (i = 0; i < 3; i++) |
|---|
| 429 | { |
|---|
| 430 | for (j = 0; j < 3; j++) |
|---|
| 431 | { |
|---|
| 432 | pRetMatrix->data[i][j] = pMatrix->data[i][j]; |
|---|
| 433 | } |
|---|
| 434 | } |
|---|
| 435 | } |
|---|
| 436 | |
|---|
| 437 | /*************************************************************************** |
|---|
| 438 | * {private} |
|---|
| 439 | * |
|---|
| 440 | * Produces a 4x4 GScale matrix. |
|---|
| 441 | */ |
|---|
| 442 | void BCSC_P_Matrix_GScale(uint32_t ulN, BCSC_P_Matrix *pRetMatrix, uint32_t ulFractBits) |
|---|
| 443 | { |
|---|
| 444 | uint32_t ulFixOne = BCSC_P_ITOFIX(1, ulFractBits); |
|---|
| 445 | |
|---|
| 446 | BKNI_Memset(pRetMatrix, 0, sizeof(BCSC_P_Matrix)); |
|---|
| 447 | pRetMatrix->ulSize = 4; |
|---|
| 448 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 449 | pRetMatrix->data[0][0] = ulFixOne / (219 * (1 << (ulN - 8))); |
|---|
| 450 | pRetMatrix->data[1][1] = ulFixOne / (224 * (1 << (ulN - 8))); |
|---|
| 451 | pRetMatrix->data[2][2] = ulFixOne / (224 * (1 << (ulN - 8))); |
|---|
| 452 | pRetMatrix->data[0][3] = (signed) BCSC_P_ITOFIX(-16, ulFractBits) / 219; |
|---|
| 453 | pRetMatrix->data[1][3] = (signed) BCSC_P_ITOFIX(-128, ulFractBits) / 224; |
|---|
| 454 | pRetMatrix->data[2][3] = (signed) BCSC_P_ITOFIX(-128, ulFractBits) / 224; |
|---|
| 455 | pRetMatrix->data[3][3] = ulFixOne; |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | /*************************************************************************** |
|---|
| 459 | * {private} |
|---|
| 460 | * |
|---|
| 461 | * Produces a 4x4 inverted GScale matrix. We calculate the GScale |
|---|
| 462 | * inverse matrix directly because it's easy to calculate and the |
|---|
| 463 | * result is more accurate than using the inverse matrix algorithm. |
|---|
| 464 | * This also avoids the problem of the determinant being too small |
|---|
| 465 | * for the fixed-point representation. |
|---|
| 466 | */ |
|---|
| 467 | void BCSC_P_Matrix_GScaleInverse(uint32_t ulN, BCSC_P_Matrix *pRetMatrix, uint32_t ulFractBits) |
|---|
| 468 | { |
|---|
| 469 | uint32_t ulFixOne = BCSC_P_ITOFIX(1, ulFractBits); |
|---|
| 470 | |
|---|
| 471 | BKNI_Memset(pRetMatrix, 0, sizeof(BCSC_P_Matrix)); |
|---|
| 472 | pRetMatrix->ulSize = 4; |
|---|
| 473 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 474 | pRetMatrix->data[0][0] = BCSC_P_ITOFIX(219 * (1 << (ulN - 8)), ulFractBits); |
|---|
| 475 | pRetMatrix->data[1][1] = BCSC_P_ITOFIX(224 * (1 << (ulN - 8)), ulFractBits); |
|---|
| 476 | pRetMatrix->data[2][2] = BCSC_P_ITOFIX(224 * (1 << (ulN - 8)), ulFractBits); |
|---|
| 477 | pRetMatrix->data[0][3] = BCSC_P_ITOFIX((1 << (ulN - 4)), ulFractBits); |
|---|
| 478 | pRetMatrix->data[1][3] = BCSC_P_ITOFIX((1 << (ulN - 1)), ulFractBits); |
|---|
| 479 | pRetMatrix->data[2][3] = BCSC_P_ITOFIX((1 << (ulN - 1)), ulFractBits); |
|---|
| 480 | pRetMatrix->data[3][3] = ulFixOne; |
|---|
| 481 | } |
|---|
| 482 | |
|---|
| 483 | /*************************************************************************** |
|---|
| 484 | * {private} |
|---|
| 485 | * |
|---|
| 486 | * Produces a 4x4 GGain matrix. |
|---|
| 487 | */ |
|---|
| 488 | void BCSC_P_Matrix_GGain(uint32_t ulN, BCSC_P_Matrix *pRetMatrix, uint32_t ulFractBits) |
|---|
| 489 | { |
|---|
| 490 | uint32_t ulFixOne = BCSC_P_ITOFIX(1, ulFractBits); |
|---|
| 491 | |
|---|
| 492 | BKNI_Memset(pRetMatrix, 0, sizeof(BCSC_P_Matrix)); |
|---|
| 493 | pRetMatrix->ulSize = 4; |
|---|
| 494 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 495 | pRetMatrix->data[0][0] = BCSC_P_ITOFIX(1 >> ulN, ulFractBits) - ulFixOne; |
|---|
| 496 | pRetMatrix->data[1][1] = BCSC_P_ITOFIX(1 >> ulN, ulFractBits) - ulFixOne; |
|---|
| 497 | pRetMatrix->data[2][2] = BCSC_P_ITOFIX(1 >> ulN, ulFractBits) - ulFixOne; |
|---|
| 498 | pRetMatrix->data[3][3] = ulFixOne; |
|---|
| 499 | } |
|---|
| 500 | |
|---|
| 501 | /*************************************************************************** |
|---|
| 502 | * {private} |
|---|
| 503 | * |
|---|
| 504 | * Calculates the cofactor of a matrix at a specific position. |
|---|
| 505 | */ |
|---|
| 506 | uint32_t BCSC_P_Matrix_Cofactor(BCSC_P_Matrix *pMatrix, uint32_t ulRow, uint32_t ulCol) |
|---|
| 507 | { |
|---|
| 508 | uint32_t ulSignPos = (ulCol + ulRow) & 1; |
|---|
| 509 | uint32_t ulSize = pMatrix->ulSize; |
|---|
| 510 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 511 | uint32_t i = 0; |
|---|
| 512 | uint32_t j = 0; |
|---|
| 513 | uint32_t ulSrcRow = 0; |
|---|
| 514 | uint32_t ulSrcCol = 0; |
|---|
| 515 | uint32_t ulCofactor = 0; |
|---|
| 516 | |
|---|
| 517 | BCSC_P_Matrix stTempMatrix; |
|---|
| 518 | |
|---|
| 519 | stTempMatrix.ulSize = ulSize - 1; |
|---|
| 520 | stTempMatrix.ulFractBits = ulFractBits; |
|---|
| 521 | |
|---|
| 522 | /* build 3x3 matrix for calculating determinant */ |
|---|
| 523 | for (i = 0, ulSrcRow = 0; i < ulSize; i++, ulSrcRow++) |
|---|
| 524 | { |
|---|
| 525 | if (i == ulRow) |
|---|
| 526 | { |
|---|
| 527 | ulSrcRow++; |
|---|
| 528 | } |
|---|
| 529 | for (j = 0, ulSrcCol = 0; j < ulSize; j++, ulSrcCol++) |
|---|
| 530 | { |
|---|
| 531 | if (j == ulCol) |
|---|
| 532 | { |
|---|
| 533 | ulSrcCol++; |
|---|
| 534 | } |
|---|
| 535 | stTempMatrix.data[i][j] = pMatrix->data[ulSrcRow][ulSrcCol]; |
|---|
| 536 | } |
|---|
| 537 | } |
|---|
| 538 | |
|---|
| 539 | /* get determinant */ |
|---|
| 540 | ulCofactor = BCSC_P_Matrix_Determinant(&stTempMatrix, NULL); |
|---|
| 541 | |
|---|
| 542 | /* apply sign based on position */ |
|---|
| 543 | ulCofactor *= (ulSignPos) ? -1 : 1; |
|---|
| 544 | |
|---|
| 545 | return ulCofactor; |
|---|
| 546 | } |
|---|
| 547 | |
|---|
| 548 | /*************************************************************************** |
|---|
| 549 | * {private} |
|---|
| 550 | * |
|---|
| 551 | * Calculates the determinant of a matrix. If cofactor matrix is present, |
|---|
| 552 | * precaculated cofactors from the table are used. |
|---|
| 553 | */ |
|---|
| 554 | uint32_t BCSC_P_Matrix_Determinant(BCSC_P_Matrix *pMatrix, BCSC_P_Matrix *pCofactors) |
|---|
| 555 | { |
|---|
| 556 | uint32_t ulCol; |
|---|
| 557 | uint32_t ulDeterminant = 0; |
|---|
| 558 | uint32_t ulSize = pMatrix->ulSize; |
|---|
| 559 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 560 | |
|---|
| 561 | if (ulSize == 1) |
|---|
| 562 | { |
|---|
| 563 | ulDeterminant = pMatrix->data[0][0]; |
|---|
| 564 | } |
|---|
| 565 | else if (ulSize == 2) |
|---|
| 566 | { |
|---|
| 567 | ulDeterminant = BCSC_P_FIX_MUL(pMatrix->data[0][0], pMatrix->data[1][1], ulFractBits) - |
|---|
| 568 | BCSC_P_FIX_MUL(pMatrix->data[0][1], pMatrix->data[1][0], ulFractBits); |
|---|
| 569 | } |
|---|
| 570 | else |
|---|
| 571 | { |
|---|
| 572 | /* add cofactors along top row */ |
|---|
| 573 | for (ulCol = 0; ulCol < ulSize; ulCol++) |
|---|
| 574 | { |
|---|
| 575 | if (pCofactors) |
|---|
| 576 | { |
|---|
| 577 | /* use precomputed cofactors */ |
|---|
| 578 | ulDeterminant += BCSC_P_FIX_MUL(pMatrix->data[0][ulCol], pCofactors->data[0][ulCol], ulFractBits); |
|---|
| 579 | } |
|---|
| 580 | else |
|---|
| 581 | { |
|---|
| 582 | ulDeterminant += BCSC_P_FIX_MUL(pMatrix->data[0][ulCol], BCSC_P_Matrix_Cofactor(pMatrix, 0, ulCol), ulFractBits); |
|---|
| 583 | } |
|---|
| 584 | } |
|---|
| 585 | } |
|---|
| 586 | |
|---|
| 587 | return ulDeterminant; |
|---|
| 588 | } |
|---|
| 589 | |
|---|
| 590 | /*************************************************************************** |
|---|
| 591 | * {private} |
|---|
| 592 | * |
|---|
| 593 | * Creates a matrix holding all cofactors of a matrix. |
|---|
| 594 | */ |
|---|
| 595 | void BCSC_P_Matrix_CofactorMatrix(BCSC_P_Matrix *pMatrix, BCSC_P_Matrix *pCofactors) |
|---|
| 596 | { |
|---|
| 597 | uint32_t ulRow; |
|---|
| 598 | uint32_t ulCol; |
|---|
| 599 | uint32_t ulSize = pMatrix->ulSize; |
|---|
| 600 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 601 | |
|---|
| 602 | for (ulRow = 0; ulRow < ulSize; ulRow++) |
|---|
| 603 | { |
|---|
| 604 | for (ulCol = 0; ulCol < ulSize; ulCol++) |
|---|
| 605 | { |
|---|
| 606 | pCofactors->data[ulRow][ulCol] = BCSC_P_Matrix_Cofactor(pMatrix, ulRow, ulCol); |
|---|
| 607 | } |
|---|
| 608 | } |
|---|
| 609 | |
|---|
| 610 | pCofactors->ulSize = ulSize; |
|---|
| 611 | pCofactors->ulFractBits = ulFractBits; |
|---|
| 612 | } |
|---|
| 613 | |
|---|
| 614 | /*************************************************************************** |
|---|
| 615 | * {private} |
|---|
| 616 | * |
|---|
| 617 | * Transposes a matrix. |
|---|
| 618 | */ |
|---|
| 619 | void BCSC_P_Matrix_Transpose(BCSC_P_Matrix *pMatrix, BCSC_P_Matrix *pRetMatrix) |
|---|
| 620 | { |
|---|
| 621 | uint32_t ulRow; |
|---|
| 622 | uint32_t ulCol; |
|---|
| 623 | uint32_t ulSize = pMatrix->ulSize; |
|---|
| 624 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 625 | |
|---|
| 626 | for (ulRow = 0; ulRow < ulSize; ulRow++) |
|---|
| 627 | { |
|---|
| 628 | for (ulCol = 0; ulCol < ulSize; ulCol++) |
|---|
| 629 | { |
|---|
| 630 | pRetMatrix->data[ulRow][ulCol] = pMatrix->data[ulCol][ulRow]; |
|---|
| 631 | } |
|---|
| 632 | } |
|---|
| 633 | |
|---|
| 634 | pRetMatrix->ulSize = ulSize; |
|---|
| 635 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 636 | } |
|---|
| 637 | |
|---|
| 638 | /*************************************************************************** |
|---|
| 639 | * {private} |
|---|
| 640 | * |
|---|
| 641 | * Multiplies a matrix by a scalar. |
|---|
| 642 | */ |
|---|
| 643 | void BCSC_P_Matrix_MultScalar(BCSC_P_Matrix *pMatrix, uint32_t ulScalar, BCSC_P_Matrix *pRetMatrix) |
|---|
| 644 | { |
|---|
| 645 | uint32_t ulRow; |
|---|
| 646 | uint32_t ulCol; |
|---|
| 647 | uint32_t ulSize = pMatrix->ulSize; |
|---|
| 648 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 649 | |
|---|
| 650 | for (ulRow = 0; ulRow < ulSize; ulRow++) |
|---|
| 651 | { |
|---|
| 652 | for (ulCol = 0; ulCol < ulSize; ulCol++) |
|---|
| 653 | { |
|---|
| 654 | pRetMatrix->data[ulRow][ulCol] = BCSC_P_FIX_MUL(pMatrix->data[ulRow][ulCol], ulScalar, ulFractBits); |
|---|
| 655 | } |
|---|
| 656 | } |
|---|
| 657 | |
|---|
| 658 | pRetMatrix->ulSize = ulSize; |
|---|
| 659 | pRetMatrix->ulFractBits = ulFractBits; |
|---|
| 660 | } |
|---|
| 661 | |
|---|
| 662 | /*************************************************************************** |
|---|
| 663 | * {private} |
|---|
| 664 | * |
|---|
| 665 | * Calculates the inverse matrix. |
|---|
| 666 | */ |
|---|
| 667 | void BCSC_P_Matrix_Inverse(BCSC_P_Matrix *pMatrix, BCSC_P_Matrix *pRetMatrix) |
|---|
| 668 | { |
|---|
| 669 | uint32_t ulFractBits = pMatrix->ulFractBits; |
|---|
| 670 | BCSC_P_Matrix stCofactorMatrix; |
|---|
| 671 | BCSC_P_Matrix stAdjointMatrix; |
|---|
| 672 | uint32_t ulDeterminant; |
|---|
| 673 | uint32_t ulOneOverDeterminant; |
|---|
| 674 | uint32_t ulFixOne = BCSC_P_ITOFIX(1, ulFractBits); |
|---|
| 675 | |
|---|
| 676 | /* InvM = 1/det(M) * Transpose(Cofactor(M)) */ |
|---|
| 677 | |
|---|
| 678 | /* compute all cofactors */ |
|---|
| 679 | BCSC_P_Matrix_CofactorMatrix(pMatrix, &stCofactorMatrix); |
|---|
| 680 | ulDeterminant = BCSC_P_Matrix_Determinant(pMatrix, &stCofactorMatrix); |
|---|
| 681 | BDBG_ASSERT(ulDeterminant); |
|---|
| 682 | ulOneOverDeterminant = BCSC_P_FIX_DIV(ulFixOne, ulDeterminant, ulFractBits); |
|---|
| 683 | BCSC_P_Matrix_Transpose(&stCofactorMatrix, &stAdjointMatrix); |
|---|
| 684 | BCSC_P_Matrix_MultScalar(&stAdjointMatrix, ulOneOverDeterminant, pRetMatrix); |
|---|
| 685 | } |
|---|
| 686 | |
|---|
| 687 | void BCSC_P_Matrix_Dump(BCSC_P_Matrix *pMatrix) |
|---|
| 688 | { |
|---|
| 689 | uint32_t i = 0; |
|---|
| 690 | uint32_t j = 0; |
|---|
| 691 | |
|---|
| 692 | for (i = 0; i < pMatrix->ulSize; i++) |
|---|
| 693 | { |
|---|
| 694 | for (j = 0; j < pMatrix->ulSize; j++) |
|---|
| 695 | { |
|---|
| 696 | BKNI_Printf("0x%x ", pMatrix->data[i][j]); |
|---|
| 697 | } |
|---|
| 698 | BKNI_Printf("\n"); |
|---|
| 699 | } |
|---|
| 700 | BKNI_Printf("\n"); |
|---|
| 701 | } |
|---|
| 702 | |
|---|
| 703 | /* End of File */ |
|---|