| /* | |
| * Copyright 2011 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "include/effects/SkColorMatrix.h" | |
| #include "src/core/SkYUVMath.h" | |
| enum SkYUVColorSpace : int; | |
| SkColorMatrix SkColorMatrix::RGBtoYUV(SkYUVColorSpace cs) { | |
| SkColorMatrix m; | |
| SkColorMatrix_RGB2YUV(cs, m.fMat.data()); | |
| return m; | |
| } | |
| SkColorMatrix SkColorMatrix::YUVtoRGB(SkYUVColorSpace cs) { | |
| SkColorMatrix m; | |
| SkColorMatrix_YUV2RGB(cs, m.fMat.data()); | |
| return m; | |
| } | |
| enum { | |
| kR_Scale = 0, | |
| kG_Scale = 6, | |
| kB_Scale = 12, | |
| kA_Scale = 18, | |
| kR_Trans = 4, | |
| kG_Trans = 9, | |
| kB_Trans = 14, | |
| kA_Trans = 19, | |
| }; | |
| static void set_concat(float result[20], const float outer[20], const float inner[20]) { | |
| float tmp[20]; | |
| float* target; | |
| if (outer == result || inner == result) { | |
| target = tmp; // will memcpy answer when we're done into result | |
| } else { | |
| target = result; | |
| } | |
| int index = 0; | |
| for (int j = 0; j < 20; j += 5) { | |
| for (int i = 0; i < 4; i++) { | |
| target[index++] = outer[j + 0] * inner[i + 0] + | |
| outer[j + 1] * inner[i + 5] + | |
| outer[j + 2] * inner[i + 10] + | |
| outer[j + 3] * inner[i + 15]; | |
| } | |
| target[index++] = outer[j + 0] * inner[4] + | |
| outer[j + 1] * inner[9] + | |
| outer[j + 2] * inner[14] + | |
| outer[j + 3] * inner[19] + | |
| outer[j + 4]; | |
| } | |
| if (target != result) { | |
| std::copy_n(target, 20, result); | |
| } | |
| } | |
| void SkColorMatrix::setIdentity() { | |
| fMat.fill(0.0f); | |
| fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1; | |
| } | |
| void SkColorMatrix::setScale(float rScale, float gScale, float bScale, float aScale) { | |
| fMat.fill(0.0f); | |
| fMat[kR_Scale] = rScale; | |
| fMat[kG_Scale] = gScale; | |
| fMat[kB_Scale] = bScale; | |
| fMat[kA_Scale] = aScale; | |
| } | |
| void SkColorMatrix::postTranslate(float dr, float dg, float db, float da) { | |
| fMat[kR_Trans] += dr; | |
| fMat[kG_Trans] += dg; | |
| fMat[kB_Trans] += db; | |
| fMat[kA_Trans] += da; | |
| } | |
| /////////////////////////////////////////////////////////////////////////////// | |
| void SkColorMatrix::setConcat(const SkColorMatrix& matA, const SkColorMatrix& matB) { | |
| set_concat(fMat.data(), matA.fMat.data(), matB.fMat.data()); | |
| } | |
| /////////////////////////////////////////////////////////////////////////////// | |
| static void setrow(float row[], float r, float g, float b) { | |
| row[0] = r; | |
| row[1] = g; | |
| row[2] = b; | |
| } | |
| static const float kHueR = 0.213f; | |
| static const float kHueG = 0.715f; | |
| static const float kHueB = 0.072f; | |
| void SkColorMatrix::setSaturation(float sat) { | |
| fMat.fill(0.0f); | |
| const float R = kHueR * (1 - sat); | |
| const float G = kHueG * (1 - sat); | |
| const float B = kHueB * (1 - sat); | |
| setrow(fMat.data() + 0, R + sat, G, B); | |
| setrow(fMat.data() + 5, R, G + sat, B); | |
| setrow(fMat.data() + 10, R, G, B + sat); | |
| fMat[kA_Scale] = 1; | |
| } |