Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
ColorLib.cpp
00001 /* ColorLib.cpp 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2016 muetch, t.kuroki, MIT License 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00006 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00007 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00008 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in all copies or 00012 * substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00015 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00016 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00017 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00018 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00019 */ 00020 00021 #include <stdlib.h> 00022 #include "ColorLib.h" 00023 00024 //---------------------------------------------------------------------------- 00025 /* 00026 #define RGB_MAX_VAL 255 00027 #define HSV_MAX_HUE 3600 00028 #define HSV_MAX_SAT 255 00029 #define HSV_MAX_VAL 255 00030 */ 00031 00032 #define MAX_COLOR(r, g, b) (((r) > (g)) ? (((r) > (b)) ? (r) : (b)) : (((g) > (b)) ? (g) : (b))) 00033 #define MIN_COLOR(r, g, b) (((r) < (g)) ? (((r) < (b)) ? (r) : (b)) : (((g) < (b)) ? (g) : (b))) 00034 00035 inline __attribute__((always_inline)) 00036 static int MulDiv(int nNumber, int nNumerator, int nDenominator) 00037 { 00038 return (nNumber * nNumerator) / nDenominator; 00039 } 00040 00041 //#define constrain(amt, low, high) ((amt) < (low) ? (low) : ((amt) > (high) ? (high) : (amt))) 00042 template<class T> 00043 __attribute__((always_inline)) 00044 inline const T& constrain(const T& x, const T& a, const T& b) 00045 { 00046 return (x < a) ? a : ((b < x) ? b : x); 00047 } 00048 00049 //---------------------------------------------------------------------------- 00050 // Integer version 00051 00052 void rgb2hsv(RGBColor const& rgb, HSVColor& hsv) 00053 { 00054 int r, g, b; // rgb : 0 - 255 00055 int h, s, v; // h: 0 - 3600, sv: 0 - 255 00056 int min, max, delta; 00057 00058 r = rgb.r; 00059 g = rgb.g; 00060 b = rgb.b; 00061 00062 max = MAX_COLOR(r, g, b); 00063 min = MIN_COLOR(r, g, b); 00064 delta = max - min; 00065 00066 v = MulDiv(max, HSV_MAX_VAL, RGB_MAX_VAL); 00067 s = (max == 0) ? 0 : MulDiv(delta, HSV_MAX_SAT, max); 00068 00069 if (s == 0) 00070 h = 0; 00071 else 00072 { 00073 #define MAXHUE_DIV_6 (int)(HSV_MAX_HUE/6.00f+0.5f) 00074 #define MAXHUE_1of3 (int)(HSV_MAX_HUE/3.00f+0.5f) 00075 #define MAXHUE_2of3 (int)(2.0f*HSV_MAX_HUE/3.00f+0.5f) 00076 if (r >= max) // > is bogus, just keeps compilor happy 00077 h = MulDiv(g - b, MAXHUE_DIV_6, delta); // between yellow & magenta 00078 else if (g >= max) 00079 h = MAXHUE_1of3 + MulDiv(b - r, MAXHUE_DIV_6, delta); // between cyan & yellow 00080 else 00081 h = MAXHUE_2of3 + MulDiv(r - g, MAXHUE_DIV_6, delta); // between magenta & cyan 00082 00083 if (h < 0) 00084 h += HSV_MAX_HUE; 00085 } 00086 hsv.h = h; 00087 hsv.s = s; 00088 hsv.v = v; 00089 } 00090 00091 void hsv2rgb(HSVColor const& hsv, RGBColor& rgb) 00092 { 00093 const int DIVISOR = 255 * (HSV_MAX_HUE/6); 00094 int h, s, v; 00095 int p, q, t; 00096 00097 h = hsv.h; 00098 s = hsv.s; 00099 v = hsv.v; 00100 00101 // H = 0 to 3600 (corresponding to 0..3600 degrees around hexcone) 00102 // 0 (undefined) for S = 0 00103 // S = 0 (shade of gray) to 255 (pure color) 00104 // V = 0 (black) to 255 (white) 00105 00106 if (s <= 0 || v <= 0) // < is bogus, just shuts up warnings 00107 { 00108 if (v < 0) 00109 v = 0; 00110 rgb.r = rgb.g = rgb.b = v; 00111 return; 00112 } 00113 00114 if (h < 0) 00115 h = HSV_MAX_HUE - (-h % HSV_MAX_HUE); 00116 h %= HSV_MAX_HUE; 00117 00118 div_t hh = div(h, (HSV_MAX_HUE/6)); // quot:0..6, rem:0..599 00119 int vs = v * s; 00120 p = v - vs / 255; // p = v * (1 - s) 00121 q = v - MulDiv(vs, hh.rem, DIVISOR); // q = v * (1 - s*f) 00122 t = v - MulDiv(vs, (HSV_MAX_HUE/6) - hh.rem, DIVISOR); // t = v * (1 - s * (1 - f)) 00123 00124 switch (hh.quot) 00125 { 00126 case 0: rgb.r = v; rgb.g = t; rgb.b = p; break; 00127 case 1: rgb.r = q; rgb.g = v; rgb.b = p; break; 00128 case 2: rgb.r = p; rgb.g = v; rgb.b = t; break; 00129 case 3: rgb.r = p; rgb.g = q; rgb.b = v; break; 00130 case 4: rgb.r = t; rgb.g = p; rgb.b = v; break; 00131 default: rgb.r = v; rgb.g = p; rgb.b = q; break; 00132 } 00133 } 00134 00135 //---------------------------------------------------------------------------- 00136 //---------------------------------------------------------------------------- 00137 // Gamma 2.0 00138 const uint8_t gamma20_table[256] = 00139 { 00140 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 00141 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 00142 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 00143 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 00144 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 00145 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 34, 34, 35, 36, 00146 37, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 00147 50, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 00148 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 00149 82, 83, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 96, 97, 98, 99, 00150 101, 102, 103, 104, 106, 107, 108, 109,111, 112, 113, 115, 116, 117, 119, 120, 00151 122, 123, 124, 126, 127, 129, 130, 131,133, 134, 136, 137, 139, 140, 142, 143, 00152 145, 146, 148, 149, 151, 152, 154, 155,157, 158, 160, 162, 163, 165, 166, 168, 00153 170, 171, 173, 175, 176, 178, 180, 181,183, 185, 186, 188, 190, 192, 193, 195, 00154 197, 199, 200, 202, 204, 206, 207, 209,211, 213, 215, 217, 218, 220, 222, 224, 00155 226, 228, 230, 232, 233, 235, 237, 239,241, 243, 245, 247, 249, 251, 253, 255 00156 }; 00157 00158 //---------------------------------------------------------------------------- 00159 #define GAMMA(c) gamma20_table[c] 00160 //#define GAMMA(c) ((((c)+1)*((c)+1)-1)>>8) 00161 00162 RGBColor GammaColor(RGBColor color) 00163 { 00164 RGBColor ret; 00165 00166 ret.red = GAMMA(color.red); 00167 ret.green = GAMMA(color.green); 00168 ret.blue = GAMMA(color.blue); 00169 return ret; 00170 } 00171 00172 RGBColor GammaColor(RGBColor color, int brightness) 00173 { 00174 HSVColor hsv(color); 00175 hsv.val = (brightness < 0) ? 0 : (brightness > 255) ? 255 : brightness; 00176 return GammaColor(hsv); 00177 } 00178 00179 RGBColor* GammaCorrection(RGBColor *color, int size) 00180 { 00181 if (color && size > 0) 00182 { 00183 RGBColor *p = color; 00184 for (int i = 0; i < size; ++i) 00185 { 00186 p->red = GAMMA(p->red); 00187 p->green = GAMMA(p->green); 00188 p->blue = GAMMA(p->blue); 00189 ++p; 00190 } 00191 } 00192 return color; 00193 } 00194 00195 HSVColor* GammaCorrection(HSVColor *color, int size) 00196 { 00197 if (color && size > 0) 00198 { 00199 HSVColor *p = color; 00200 for (int i = 0; i < size; ++i) 00201 { 00202 p->val = GAMMA(p->val); 00203 ++p; 00204 } 00205 } 00206 return color; 00207 } 00208 00209 //----------------------------------------------------------------------------
Generated on Thu Jul 14 2022 04:31:44 by
