/* * Copyright 2018 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "../skcms.h" #include "../skcms_internal.h" #include bool skcms_Matrix3x3_invert(const skcms_Matrix3x3* src, skcms_Matrix3x3* dst) { double a00 = src->vals[0][0], a01 = src->vals[1][0], a02 = src->vals[2][0], a10 = src->vals[0][1], a11 = src->vals[1][1], a12 = src->vals[2][1], a20 = src->vals[0][2], a21 = src->vals[1][2], a22 = src->vals[2][2]; double b0 = a00*a11 - a01*a10, b1 = a00*a12 - a02*a10, b2 = a01*a12 - a02*a11, b3 = a20, b4 = a21, b5 = a22; double determinant = b0*b5 - b1*b4 + b2*b3; if (determinant == 0) { return false; } double invdet = 1.0 / determinant; if (invdet > +FLT_MAX || invdet < -FLT_MAX || !isfinitef_((float)invdet)) { return false; } b0 *= invdet; b1 *= invdet; b2 *= invdet; b3 *= invdet; b4 *= invdet; b5 *= invdet; dst->vals[0][0] = (float)( a11*b5 - a12*b4 ); dst->vals[1][0] = (float)( a02*b4 - a01*b5 ); dst->vals[2][0] = (float)( + b2 ); dst->vals[0][1] = (float)( a12*b3 - a10*b5 ); dst->vals[1][1] = (float)( a00*b5 - a02*b3 ); dst->vals[2][1] = (float)( - b1 ); dst->vals[0][2] = (float)( a10*b4 - a11*b3 ); dst->vals[1][2] = (float)( a01*b3 - a00*b4 ); dst->vals[2][2] = (float)( + b0 ); for (int r = 0; r < 3; ++r) for (int c = 0; c < 3; ++c) { if (!isfinitef_(dst->vals[r][c])) { return false; } } return true; } skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3* A, const skcms_Matrix3x3* B) { skcms_Matrix3x3 m = { { { 0,0,0 },{ 0,0,0 },{ 0,0,0 } } }; for (int r = 0; r < 3; r++) for (int c = 0; c < 3; c++) { m.vals[r][c] = A->vals[r][0] * B->vals[0][c] + A->vals[r][1] * B->vals[1][c] + A->vals[r][2] * B->vals[2][c]; } return m; } skcms_Vector3 skcms_MV_mul(const skcms_Matrix3x3* m, const skcms_Vector3* v) { skcms_Vector3 dst = {{0,0,0}}; for (int row = 0; row < 3; ++row) { dst.vals[row] = m->vals[row][0] * v->vals[0] + m->vals[row][1] * v->vals[1] + m->vals[row][2] * v->vals[2]; } return dst; }