1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "include/effects/SkColorMatrix.h"
9
10enum {
11 kR_Scale = 0,
12 kG_Scale = 6,
13 kB_Scale = 12,
14 kA_Scale = 18,
15
16 kR_Trans = 4,
17 kG_Trans = 9,
18 kB_Trans = 14,
19 kA_Trans = 19,
20};
21
22static void set_concat(float result[20], const float outer[20], const float inner[20]) {
23 float tmp[20];
24 float* target;
25
26 if (outer == result || inner == result) {
27 target = tmp; // will memcpy answer when we're done into result
28 } else {
29 target = result;
30 }
31
32 int index = 0;
33 for (int j = 0; j < 20; j += 5) {
34 for (int i = 0; i < 4; i++) {
35 target[index++] = outer[j + 0] * inner[i + 0] +
36 outer[j + 1] * inner[i + 5] +
37 outer[j + 2] * inner[i + 10] +
38 outer[j + 3] * inner[i + 15];
39 }
40 target[index++] = outer[j + 0] * inner[4] +
41 outer[j + 1] * inner[9] +
42 outer[j + 2] * inner[14] +
43 outer[j + 3] * inner[19] +
44 outer[j + 4];
45 }
46
47 if (target != result) {
48 std::copy_n(target, 20, result);
49 }
50}
51
52void SkColorMatrix::setIdentity() {
53 fMat.fill(0.0f);
54 fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1;
55}
56
57void SkColorMatrix::setScale(float rScale, float gScale, float bScale, float aScale) {
58 fMat.fill(0.0f);
59 fMat[kR_Scale] = rScale;
60 fMat[kG_Scale] = gScale;
61 fMat[kB_Scale] = bScale;
62 fMat[kA_Scale] = aScale;
63}
64
65void SkColorMatrix::postTranslate(float dr, float dg, float db, float da) {
66 fMat[kR_Trans] += dr;
67 fMat[kG_Trans] += dg;
68 fMat[kB_Trans] += db;
69 fMat[kA_Trans] += da;
70}
71
72///////////////////////////////////////////////////////////////////////////////
73
74void SkColorMatrix::setConcat(const SkColorMatrix& matA, const SkColorMatrix& matB) {
75 set_concat(fMat.data(), matA.fMat.data(), matB.fMat.data());
76}
77
78///////////////////////////////////////////////////////////////////////////////
79
80static void setrow(float row[], float r, float g, float b) {
81 row[0] = r;
82 row[1] = g;
83 row[2] = b;
84}
85
86static const float kHueR = 0.213f;
87static const float kHueG = 0.715f;
88static const float kHueB = 0.072f;
89
90void SkColorMatrix::setSaturation(float sat) {
91 fMat.fill(0.0f);
92
93 const float R = kHueR * (1 - sat);
94 const float G = kHueG * (1 - sat);
95 const float B = kHueB * (1 - sat);
96
97 setrow(fMat.data() + 0, R + sat, G, B);
98 setrow(fMat.data() + 5, R, G + sat, B);
99 setrow(fMat.data() + 10, R, G, B + sat);
100 fMat[kA_Scale] = 1;
101}
102