color.c (2584B)
1 /* Copyright 2017 Jason Williams 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 2 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "color.h" 18 #include "led_tables.h" 19 #include "progmem.h" 20 #include "util.h" 21 22 rgb_t hsv_to_rgb_impl(hsv_t hsv, bool use_cie) { 23 rgb_t rgb; 24 uint8_t region, remainder, p, q, t; 25 uint16_t h, s, v; 26 27 if (hsv.s == 0) { 28 #ifdef USE_CIE1931_CURVE 29 if (use_cie) { 30 rgb.r = rgb.g = rgb.b = pgm_read_byte(&CIE1931_CURVE[hsv.v]); 31 } else { 32 rgb.r = hsv.v; 33 rgb.g = hsv.v; 34 rgb.b = hsv.v; 35 } 36 #else 37 rgb.r = hsv.v; 38 rgb.g = hsv.v; 39 rgb.b = hsv.v; 40 #endif 41 return rgb; 42 } 43 44 h = hsv.h; 45 s = hsv.s; 46 #ifdef USE_CIE1931_CURVE 47 if (use_cie) { 48 v = pgm_read_byte(&CIE1931_CURVE[hsv.v]); 49 } else { 50 v = hsv.v; 51 } 52 #else 53 v = hsv.v; 54 #endif 55 56 region = h * 6 / 255; 57 remainder = (h * 2 - region * 85) * 3; 58 59 p = (v * (255 - s)) >> 8; 60 q = (v * (255 - ((s * remainder) >> 8))) >> 8; 61 t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; 62 63 switch (region) { 64 case 6: 65 case 0: 66 rgb.r = v; 67 rgb.g = t; 68 rgb.b = p; 69 break; 70 case 1: 71 rgb.r = q; 72 rgb.g = v; 73 rgb.b = p; 74 break; 75 case 2: 76 rgb.r = p; 77 rgb.g = v; 78 rgb.b = t; 79 break; 80 case 3: 81 rgb.r = p; 82 rgb.g = q; 83 rgb.b = v; 84 break; 85 case 4: 86 rgb.r = t; 87 rgb.g = p; 88 rgb.b = v; 89 break; 90 default: 91 rgb.r = v; 92 rgb.g = p; 93 rgb.b = q; 94 break; 95 } 96 97 return rgb; 98 } 99 100 rgb_t hsv_to_rgb(hsv_t hsv) { 101 #ifdef USE_CIE1931_CURVE 102 return hsv_to_rgb_impl(hsv, true); 103 #else 104 return hsv_to_rgb_impl(hsv, false); 105 #endif 106 } 107 108 rgb_t hsv_to_rgb_nocie(hsv_t hsv) { 109 return hsv_to_rgb_impl(hsv, false); 110 }