Parent directory

color.c

2584 bytes
  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
 22rgb_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
100rgb_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
108rgb_t hsv_to_rgb_nocie(hsv_t hsv) {
109    return hsv_to_rgb_impl(hsv, false);
110}