inline Color convertToRGB(const Color& color) const { const float hue6 = fmod(color_r(color), 1.0f) * 6.0f; float hue2 = hue6; if (hue6 > 4.0f) hue2 -= 4.0f; else if (hue6 > 2.0f) hue2 -= 2.0f; const float sat = std::max(std::min(color_g(color), 1.0f), 0.0f); const float chroma = (1.0f - fabsf(2.0f * color_b(color) - 1.0f)) * sat; const float component = chroma * (1.0f - fabsf(hue2 - 1.0f)); Color rgb = make_color(0.0f, 0.0f, 0.0f); if (hue6 < 1) rgb = make_color(chroma, component, 0.0f); else if (hue6 < 2) rgb = make_color(component, chroma, 0.0f); else if (hue6 < 3) rgb = make_color(0.0f, chroma, component); else if (hue6 < 4) rgb = make_color(0.0f, component, chroma); else if (hue6 < 5) rgb = make_color(component, 0.0f, chroma); else rgb = make_color(chroma, 0.0f, component); const float ca = color_b(color) - chroma * 0.5f; rgb += make_color(ca, ca, ca); return rgb; }
// don't worry, we are modifying the color, so copying is appropriate inline Color apply_rgb_controls(Color color) const { if (m_gamma != 1.0f) { color_r(color) = powf(color_r(color), 1.0f / m_gamma); color_g(color) = powf(color_g(color), 1.0f / m_gamma); color_b(color) = powf(color_b(color), 1.0f / m_gamma); } if (m_hue_shift != 0.0f || m_saturation != 1.0f) { color = convertFromRGB(color); color_r(color) += m_hue_shift; color_r(color) = color_r(color) - floorf(color_r(color)); // keep hue in [0, 1] color_g(color) *= m_saturation; color = convertToRGB(color); } if (m_contrast != 1.0f) color = (color - make_color(m_contrast_pivot, m_contrast_pivot, m_contrast_pivot)) * m_contrast + make_color(m_contrast_pivot, m_contrast_pivot, m_contrast_pivot); if (m_exposure > 0.0001f) color *= powf(2.0f, m_exposure); if (m_multiply != 1.0f) color *= m_multiply; if (m_add != 0.0f) color = make_color(m_add, m_add, m_add); return color; }
inline Color evaluate(const Color& v) const { if (m_channel_mode == CHANNEL_MODE_RAW) return v; else if (m_channel_mode == CHANNEL_MODE_FLOAT) return make_color(1.0f, 1.0f, 1.0f) * apply_float_controls(apply_float_range((color_r(v) + color_g(v) + color_b(v)) / 3.0f)); else if (m_channel_mode == CHANNEL_MODE_RGB) return apply_rgb_controls(v); else if (m_channel_mode == CHANNEL_MODE_FLOAT_RAMP) return make_color(1.0f, 1.0f, 1.0f) * apply_float_controls(apply_float_gradient((color_r(v) + color_g(v) + color_b(v)) / 3.0f)); else return apply_rgb_controls(apply_rgb_gradient((color_r(v) + color_g(v) + color_b(v)) / 3.0f)); }
inline Color convertFromRGB(const Color& color) const { const float cmax = color_max(color); const float cmin = color_min(color); const float chroma = cmax - cmin; float hue = 0.0f; if (chroma == 0.0f) hue = 0.0f; else if (cmax == color_r(color)) hue = (color_g(color) - color_b(color)) / chroma; else if (cmax == color_g(color)) hue = (color_b(color) - color_r(color)) / chroma + 2.0f; else hue = (color_r(color) - color_g(color)) / chroma + 4.0f; hue *= 1.0f / 6.0f; if (hue < 0.0f) hue += 1.0f; const float lightness = (cmax + cmin) * 0.5f; const float saturation = chroma == 0.0f ? 0.0f : chroma / (1.0f - fabsf(2.0f * lightness - 1.0f)); return make_color(hue, saturation, lightness); }
unsigned int gencol(int t) { return (color_r(t) << 24) | (color_g(t) << 16) | (color_b(t) << 8); }
inline float color_min(const Color& color) const { return std::min(color_r(color), std::min(color_g(color), color_b(color))); }