1/*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_SURFACEREPLAYER_COLOR_H
18#define ANDROID_SURFACEREPLAYER_COLOR_H
19
20#include <cmath>
21#include <cstdlib>
22
23namespace android {
24
25constexpr double modulateFactor = .0001;
26constexpr double modulateLimit = .80;
27
28struct RGB {
29    RGB(uint8_t rIn, uint8_t gIn, uint8_t bIn) : r(rIn), g(gIn), b(bIn) {}
30
31    uint8_t r = 0;
32    uint8_t g = 0;
33    uint8_t b = 0;
34};
35
36struct HSV {
37    HSV() = default;
38    HSV(double hIn, double sIn, double vIn) : h(hIn), s(sIn), v(vIn) {}
39
40    double h = 0;
41    double s = 0;
42    double v = 0;
43
44    RGB getRGB() const;
45
46    bool modulateUp = false;
47
48    void modulate();
49};
50
51void inline HSV::modulate() {
52    if(modulateUp) {
53        v += modulateFactor;
54    } else {
55        v -= modulateFactor;
56    }
57
58    if(v <= modulateLimit || v >= 1) {
59        modulateUp = !modulateUp;
60    }
61}
62
63inline RGB HSV::getRGB() const {
64    using namespace std;
65    double r = 0, g = 0, b = 0;
66
67    if (s == 0) {
68        r = v;
69        g = v;
70        b = v;
71    } else {
72        auto tempHue = static_cast<int>(h) % 360;
73        tempHue = tempHue / 60;
74
75        int i = static_cast<int>(trunc(tempHue));
76        double f = h - i;
77
78        double x = v * (1.0 - s);
79        double y = v * (1.0 - (s * f));
80        double z = v * (1.0 - (s * (1.0 - f)));
81
82        switch (i) {
83            case 0:
84                r = v;
85                g = z;
86                b = x;
87                break;
88
89            case 1:
90                r = y;
91                g = v;
92                b = x;
93                break;
94
95            case 2:
96                r = x;
97                g = v;
98                b = z;
99                break;
100
101            case 3:
102                r = x;
103                g = y;
104                b = v;
105                break;
106
107            case 4:
108                r = z;
109                g = x;
110                b = v;
111                break;
112
113            default:
114                r = v;
115                g = x;
116                b = y;
117                break;
118        }
119    }
120
121    return RGB(round(r * 255), round(g * 255), round(b * 255));
122}
123}
124#endif
125