HSV2RGB and RGB2HSV

Dependents:   RGB_Matrix_Test

Committer:
JackB
Date:
Fri Oct 02 22:29:47 2015 +0000
Revision:
1:a06dfdf279e2
Parent:
0:e3c23a157dee
Adafruit 64x32 RGB LED Matrix - 3mm pitch Demo program for Nucleo F446RE.; Use User button to display color palette in second framebuffer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JackB 0:e3c23a157dee 1 /* mbed HSV Library
JackB 0:e3c23a157dee 2 *
JackB 0:e3c23a157dee 3 * Copyright (c) 2013-2013 JackB, cstyles
JackB 0:e3c23a157dee 4 *
JackB 0:e3c23a157dee 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
JackB 0:e3c23a157dee 6 * of this software and associated documentation files (the "Software"), to deal
JackB 0:e3c23a157dee 7 * in the Software without restriction, including without limitation the rights
JackB 0:e3c23a157dee 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
JackB 0:e3c23a157dee 9 * copies of the Software, and to permit persons to whom the Software is
JackB 0:e3c23a157dee 10 * furnished to do so, subject to the following conditions:
JackB 0:e3c23a157dee 11 *
JackB 0:e3c23a157dee 12 * The above copyright notice and this permission notice shall be included in
JackB 0:e3c23a157dee 13 * all copies or substantial portions of the Software.
JackB 0:e3c23a157dee 14 *
JackB 0:e3c23a157dee 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
JackB 0:e3c23a157dee 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
JackB 0:e3c23a157dee 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
JackB 0:e3c23a157dee 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
JackB 0:e3c23a157dee 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
JackB 0:e3c23a157dee 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
JackB 0:e3c23a157dee 21 * THE SOFTWARE.
JackB 0:e3c23a157dee 22 */
JackB 0:e3c23a157dee 23
JackB 0:e3c23a157dee 24 #include "HSV.h"
JackB 0:e3c23a157dee 25
JackB 0:e3c23a157dee 26 HSV::HSV() {
JackB 0:e3c23a157dee 27 Rgb.Out = 4095.0;
JackB 0:e3c23a157dee 28 SetRcf(1.0);
JackB 0:e3c23a157dee 29 SetGcf(1.0);
JackB 0:e3c23a157dee 30 SetBcf(1.0);
JackB 0:e3c23a157dee 31 SetWcf(1.0);
JackB 0:e3c23a157dee 32 SetH(0.0); // Hue
JackB 0:e3c23a157dee 33 SetS(1.0); // Saturation
JackB 0:e3c23a157dee 34 SetV(1.0); // Value
JackB 0:e3c23a157dee 35 SetP(1.0); // Power
JackB 0:e3c23a157dee 36 SetPower(true);
JackB 0:e3c23a157dee 37 }
JackB 0:e3c23a157dee 38
JackB 0:e3c23a157dee 39 void HSV::SetPower(bool Power)
JackB 0:e3c23a157dee 40 {
JackB 0:e3c23a157dee 41 _Power = Power;
JackB 0:e3c23a157dee 42 }
JackB 0:e3c23a157dee 43
JackB 0:e3c23a157dee 44
JackB 0:e3c23a157dee 45 int HSV::UseWeb(char* String)
JackB 0:e3c23a157dee 46 {
JackB 0:e3c23a157dee 47 // #c08040
JackB 0:e3c23a157dee 48 char Str[3];
JackB 0:e3c23a157dee 49 Str[2] = '\0';
JackB 0:e3c23a157dee 50 Str[0] = String[1];
JackB 0:e3c23a157dee 51 Str[1] = String[2];
JackB 0:e3c23a157dee 52 int R = (int)strtol(Str, NULL, 16);
JackB 0:e3c23a157dee 53 Str[0] = String[3];
JackB 0:e3c23a157dee 54 Str[1] = String[4];
JackB 0:e3c23a157dee 55 int G = (int)strtol(Str, NULL, 16);
JackB 0:e3c23a157dee 56 Str[0] = String[5];
JackB 0:e3c23a157dee 57 Str[1] = String[6];
JackB 0:e3c23a157dee 58 int B = (int)strtol(Str, NULL, 16);
JackB 0:e3c23a157dee 59 return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3));
JackB 0:e3c23a157dee 60 }
JackB 0:e3c23a157dee 61
JackB 0:e3c23a157dee 62 int HSV::UseRGB(int R, int G, int B)
JackB 0:e3c23a157dee 63 {
JackB 0:e3c23a157dee 64 return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3));
JackB 0:e3c23a157dee 65 }
JackB 0:e3c23a157dee 66
JackB 0:e3c23a157dee 67 int HSV::UseHSV(float H, float S, float V)
JackB 0:e3c23a157dee 68 {
JackB 0:e3c23a157dee 69 Hsv.H = H;
JackB 0:e3c23a157dee 70 Hsv.S = S;
JackB 0:e3c23a157dee 71 Hsv.V = V;
JackB 0:e3c23a157dee 72 HSV_to_RGB();
JackB 0:e3c23a157dee 73 int R = (int) (sqrt(Rgb.R) * (float)255.0);
JackB 0:e3c23a157dee 74 int G = (int) (sqrt(Rgb.G) * (float)255.0);
JackB 0:e3c23a157dee 75 int B = (int) (sqrt(Rgb.B) * (float)255.0);
JackB 0:e3c23a157dee 76 return (int)(((R & 0xf8) << 8) + ((G & 0xfc) << 3) + ((B & 0xf8) >> 3));
JackB 0:e3c23a157dee 77 }
JackB 0:e3c23a157dee 78
JackB 0:e3c23a157dee 79 void HSV::SetRcf(float Rcf)
JackB 0:e3c23a157dee 80 {
JackB 0:e3c23a157dee 81 Rgb.Rcf = Rcf;
JackB 0:e3c23a157dee 82 HSV_to_RGB();
JackB 0:e3c23a157dee 83 // RGB_to_HSV();
JackB 0:e3c23a157dee 84 }
JackB 0:e3c23a157dee 85
JackB 0:e3c23a157dee 86 void HSV::SetGcf(float Gcf)
JackB 0:e3c23a157dee 87 {
JackB 0:e3c23a157dee 88 Rgb.Gcf = Gcf;
JackB 0:e3c23a157dee 89 HSV_to_RGB();
JackB 0:e3c23a157dee 90 // RGB_to_HSV();
JackB 0:e3c23a157dee 91 }
JackB 0:e3c23a157dee 92
JackB 0:e3c23a157dee 93 void HSV::SetBcf(float Bcf)
JackB 0:e3c23a157dee 94 {
JackB 0:e3c23a157dee 95 Rgb.Bcf = Bcf;
JackB 0:e3c23a157dee 96 HSV_to_RGB();
JackB 0:e3c23a157dee 97 // RGB_to_HSV();
JackB 0:e3c23a157dee 98 }
JackB 0:e3c23a157dee 99
JackB 0:e3c23a157dee 100 void HSV::SetWcf(float Wcf)
JackB 0:e3c23a157dee 101 {
JackB 0:e3c23a157dee 102 Rgb.Wcf = Wcf;
JackB 0:e3c23a157dee 103 HSV_to_RGB();
JackB 0:e3c23a157dee 104 // RGB_to_HSV();
JackB 0:e3c23a157dee 105 }
JackB 0:e3c23a157dee 106
JackB 0:e3c23a157dee 107 void HSV::SetH(float Hue)
JackB 0:e3c23a157dee 108 {
JackB 0:e3c23a157dee 109 Hsv.H = Hue;
JackB 0:e3c23a157dee 110 HSV_to_RGB();
JackB 0:e3c23a157dee 111 // RGB_to_HSV();
JackB 0:e3c23a157dee 112 }
JackB 0:e3c23a157dee 113
JackB 0:e3c23a157dee 114 void HSV::SetS(float Saturation)
JackB 0:e3c23a157dee 115 {
JackB 0:e3c23a157dee 116 Hsv.S = Saturation;
JackB 0:e3c23a157dee 117 HSV_to_RGB();
JackB 0:e3c23a157dee 118 // RGB_to_HSV();
JackB 0:e3c23a157dee 119 }
JackB 0:e3c23a157dee 120
JackB 0:e3c23a157dee 121 void HSV::SetV(float Value)
JackB 0:e3c23a157dee 122 {
JackB 1:a06dfdf279e2 123 Hsv.V = Value;
JackB 1:a06dfdf279e2 124 HSV_to_RGB();
JackB 1:a06dfdf279e2 125 // RGB_to_HSV();
JackB 1:a06dfdf279e2 126 }
JackB 1:a06dfdf279e2 127
JackB 1:a06dfdf279e2 128 void HSV::SetVV(float Value)
JackB 1:a06dfdf279e2 129 {
JackB 0:e3c23a157dee 130 Hsv.V = Value * Value;
JackB 0:e3c23a157dee 131 HSV_to_RGB();
JackB 0:e3c23a157dee 132 // RGB_to_HSV();
JackB 0:e3c23a157dee 133 }
JackB 0:e3c23a157dee 134
JackB 0:e3c23a157dee 135 void HSV::SetP(float Value)
JackB 0:e3c23a157dee 136 {
JackB 0:e3c23a157dee 137 Hsv.P = Value;
JackB 0:e3c23a157dee 138 HSV_to_RGB();
JackB 0:e3c23a157dee 139 // RGB_to_HSV();
JackB 0:e3c23a157dee 140 }
JackB 0:e3c23a157dee 141
JackB 0:e3c23a157dee 142 void HSV::SetW(float White)
JackB 0:e3c23a157dee 143 {
JackB 0:e3c23a157dee 144 Rgb.W = White;
JackB 0:e3c23a157dee 145 }
JackB 0:e3c23a157dee 146
JackB 0:e3c23a157dee 147 uint16_t HSV::GetRout(void)
JackB 0:e3c23a157dee 148 {
JackB 0:e3c23a157dee 149 if (_Power)
JackB 0:e3c23a157dee 150 return (uint16_t)(Rgb.R * Rgb.Rcf * Rgb.Out);
JackB 0:e3c23a157dee 151 return 0;
JackB 0:e3c23a157dee 152 }
JackB 0:e3c23a157dee 153
JackB 0:e3c23a157dee 154 uint16_t HSV::GetGout(void)
JackB 0:e3c23a157dee 155 {
JackB 0:e3c23a157dee 156 if (_Power)
JackB 0:e3c23a157dee 157 return (uint16_t)(Rgb.G * Rgb.Gcf * Rgb.Out);
JackB 0:e3c23a157dee 158 return 0;
JackB 0:e3c23a157dee 159 }
JackB 0:e3c23a157dee 160
JackB 0:e3c23a157dee 161 uint16_t HSV::GetBout(void)
JackB 0:e3c23a157dee 162 {
JackB 0:e3c23a157dee 163 if (_Power)
JackB 0:e3c23a157dee 164 return (uint16_t)(Rgb.B * Rgb.Bcf * Rgb.Out);
JackB 0:e3c23a157dee 165 return 0;
JackB 0:e3c23a157dee 166 }
JackB 0:e3c23a157dee 167
JackB 0:e3c23a157dee 168 uint16_t HSV::GetWout(void)
JackB 0:e3c23a157dee 169 {
JackB 0:e3c23a157dee 170 if (_Power)
JackB 0:e3c23a157dee 171 return (uint16_t)(Rgb.W * Rgb.Wcf * Rgb.Out);
JackB 0:e3c23a157dee 172 return 0;
JackB 0:e3c23a157dee 173 }
JackB 0:e3c23a157dee 174
JackB 0:e3c23a157dee 175 float HSV::GetR(void)
JackB 0:e3c23a157dee 176 {
JackB 0:e3c23a157dee 177 return Rgb.R;
JackB 0:e3c23a157dee 178 }
JackB 0:e3c23a157dee 179
JackB 0:e3c23a157dee 180 float HSV::GetG(void)
JackB 0:e3c23a157dee 181 {
JackB 0:e3c23a157dee 182 return Rgb.G;
JackB 0:e3c23a157dee 183 }
JackB 0:e3c23a157dee 184
JackB 0:e3c23a157dee 185 float HSV::GetB(void)
JackB 0:e3c23a157dee 186 {
JackB 0:e3c23a157dee 187 return Rgb.B;
JackB 0:e3c23a157dee 188 }
JackB 0:e3c23a157dee 189
JackB 0:e3c23a157dee 190 float HSV::GetW(void)
JackB 0:e3c23a157dee 191 {
JackB 0:e3c23a157dee 192 return Rgb.W;
JackB 0:e3c23a157dee 193 }
JackB 0:e3c23a157dee 194
JackB 0:e3c23a157dee 195 float HSV::GetH(void)
JackB 0:e3c23a157dee 196 {
JackB 0:e3c23a157dee 197 return Hsv.H;
JackB 0:e3c23a157dee 198 }
JackB 0:e3c23a157dee 199
JackB 0:e3c23a157dee 200 float HSV::GetS(void)
JackB 0:e3c23a157dee 201 {
JackB 0:e3c23a157dee 202 return Hsv.S;
JackB 0:e3c23a157dee 203 }
JackB 0:e3c23a157dee 204
JackB 0:e3c23a157dee 205 float HSV::GetV(void)
JackB 0:e3c23a157dee 206 {
JackB 0:e3c23a157dee 207 return Hsv.V;
JackB 0:e3c23a157dee 208 }
JackB 0:e3c23a157dee 209
JackB 0:e3c23a157dee 210 float HSV::GetH2(void)
JackB 0:e3c23a157dee 211 {
JackB 0:e3c23a157dee 212 return Hsv2.H;
JackB 0:e3c23a157dee 213 }
JackB 0:e3c23a157dee 214
JackB 0:e3c23a157dee 215 float HSV::GetS2(void)
JackB 0:e3c23a157dee 216 {
JackB 0:e3c23a157dee 217 return Hsv2.S;
JackB 0:e3c23a157dee 218 }
JackB 0:e3c23a157dee 219
JackB 0:e3c23a157dee 220 float HSV::GetV2(void)
JackB 0:e3c23a157dee 221 {
JackB 0:e3c23a157dee 222 return Hsv2.V;
JackB 0:e3c23a157dee 223 }
JackB 0:e3c23a157dee 224
JackB 0:e3c23a157dee 225 void HSV::HSV_to_RGB(void)
JackB 0:e3c23a157dee 226 {
JackB 0:e3c23a157dee 227 // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1].
JackB 0:e3c23a157dee 228 // RGB are each returned on [0, 1].
JackB 0:e3c23a157dee 229 Rgb.W = ((float)1.0 - Hsv.S) * Hsv.V * Hsv.P;
JackB 0:e3c23a157dee 230 while (Hsv.H < (float)0.0)
JackB 0:e3c23a157dee 231 Hsv.H += (float)1.0;
JackB 0:e3c23a157dee 232 while (Hsv.H >= (float)1.0)
JackB 0:e3c23a157dee 233 Hsv.H -= (float)1.0;
JackB 0:e3c23a157dee 234 float h_div = (float)1.0 / (float)6.0;
JackB 0:e3c23a157dee 235 float h = Hsv.H/h_div;
JackB 0:e3c23a157dee 236 float s = Hsv.S;
JackB 0:e3c23a157dee 237 float v = Hsv.V * Hsv.P;
JackB 0:e3c23a157dee 238 float m, n, f;
JackB 0:e3c23a157dee 239 int i = floor(h);
JackB 0:e3c23a157dee 240 f = h - (float) i;
JackB 0:e3c23a157dee 241 if ( !(i&1) )
JackB 0:e3c23a157dee 242 f = 1 - f; // if i is even
JackB 0:e3c23a157dee 243 m = v * (1 - s);
JackB 0:e3c23a157dee 244 n = v * (1 - s * f);
JackB 0:e3c23a157dee 245 switch (i) {
JackB 0:e3c23a157dee 246 case 0 : Rgb.R = v; Rgb.G = n; Rgb.B = m; break;
JackB 0:e3c23a157dee 247 case 1 : Rgb.R = n; Rgb.G = v; Rgb.B = m; break;
JackB 0:e3c23a157dee 248 case 2 : Rgb.R = m; Rgb.G = v; Rgb.B = n; break;
JackB 0:e3c23a157dee 249 case 3 : Rgb.R = m; Rgb.G = n; Rgb.B = v; break;
JackB 0:e3c23a157dee 250 case 4 : Rgb.R = n; Rgb.G = m; Rgb.B = v; break;
JackB 0:e3c23a157dee 251 case 5 : Rgb.R = v; Rgb.G = m; Rgb.B = n; break;
JackB 0:e3c23a157dee 252 default : Rgb.R = v; Rgb.G = n; Rgb.B = m; break;
JackB 0:e3c23a157dee 253 }
JackB 0:e3c23a157dee 254 }
JackB 0:e3c23a157dee 255
JackB 0:e3c23a157dee 256 void HSV::RGB_to_HSV(void)
JackB 0:e3c23a157dee 257 {
JackB 0:e3c23a157dee 258 float rgbMin, rgbMax;
JackB 0:e3c23a157dee 259
JackB 0:e3c23a157dee 260 rgbMin = Rgb.R < Rgb.G ? (Rgb.R < Rgb.B ? Rgb.R : Rgb.B) : (Rgb.G < Rgb.B ? Rgb.G : Rgb.B);
JackB 0:e3c23a157dee 261 rgbMax = Rgb.R > Rgb.G ? (Rgb.R > Rgb.B ? Rgb.R : Rgb.B) : (Rgb.G > Rgb.B ? Rgb.G : Rgb.B);
JackB 0:e3c23a157dee 262
JackB 0:e3c23a157dee 263 Hsv2.V = rgbMax;
JackB 0:e3c23a157dee 264 if (Hsv2.V == 0.0)
JackB 0:e3c23a157dee 265 {
JackB 0:e3c23a157dee 266 Hsv2.H = 0.0;
JackB 0:e3c23a157dee 267 Hsv2.S = 0.0;
JackB 0:e3c23a157dee 268 return;
JackB 0:e3c23a157dee 269 }
JackB 0:e3c23a157dee 270
JackB 0:e3c23a157dee 271 Hsv2.S = (rgbMax - rgbMin) / Hsv2.V;
JackB 0:e3c23a157dee 272 if (Hsv2.S == 0.0)
JackB 0:e3c23a157dee 273 {
JackB 0:e3c23a157dee 274 Hsv2.H = 0.0;
JackB 0:e3c23a157dee 275 return;
JackB 0:e3c23a157dee 276 }
JackB 0:e3c23a157dee 277
JackB 0:e3c23a157dee 278 if (rgbMax == Rgb.R)
JackB 0:e3c23a157dee 279 Hsv2.H = 1.0/6.0 * (Rgb.G - Rgb.B) / (rgbMax - rgbMin);
JackB 0:e3c23a157dee 280 else if (rgbMax == Rgb.G)
JackB 0:e3c23a157dee 281 Hsv2.H = 1.0/3.0 + 1.0/6.0 * (Rgb.B - Rgb.R) / (rgbMax - rgbMin);
JackB 0:e3c23a157dee 282 else
JackB 0:e3c23a157dee 283 Hsv2.H = 2.0/3.0 + 1.0/6.0 * (Rgb.R - Rgb.G) / (rgbMax - rgbMin);
JackB 0:e3c23a157dee 284 }
JackB 0:e3c23a157dee 285