/* ============================================================ * * This file is a part of digiKam project * http://www.digikam.org * * Date : 2005-12-02 * Description : 8-16 bits color container. * * Copyright (C) 2005-2007 by Gilles Caulier * * RGB<->HLS transformation algorithms are inspired from methods * describe at this url : * http://www.paris-pc-gis.com/MI_Enviro/Colors/color_models.htm * * This program is free software; you can redistribute it * and/or modify it under the terms of the GNU General * Public License as published by the Free Software Foundation; * either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * ============================================================ */ // C++ includes. #include // Local includes. #include "ddebug.h" #include "dcolor.h" namespace Digikam { /* DColor::DColor(const DColor& color) { m_red = color.m_red; m_green = color.m_green; m_blue = color.m_blue; m_alpha = color.m_alpha; m_sixteenBit = color.m_sixteenBit; } */ DColor::DColor(const TQColor& color, bool sixteenBit) { // initialize as eight bit m_red = color.red(); m_green = color.green(); m_blue = color.blue(); m_alpha = 255; m_sixteenBit = false; // convert to sixteen bit if requested if (sixteenBit) convertToSixteenBit(); } /* DColor& DColor::operator=(const DColor& color) { m_red = color.m_red; m_green = color.m_green; m_blue = color.m_blue; m_alpha = color.m_alpha; m_sixteenBit = color.m_sixteenBit; return *this; } */ TQColor DColor::getTQColor() const { if (m_sixteenBit) { DColor eightBit(*this); eightBit.convertToEightBit(); return eightBit.getTQColor(); } return (TQColor(m_red, m_green, m_blue)); } void DColor::convertToSixteenBit() { if (m_sixteenBit) return; m_red = (m_red + 1) * 256 - 1; m_green = (m_green + 1) * 256 - 1; m_blue = (m_blue + 1) * 256 - 1; m_alpha = (m_alpha + 1) * 256 - 1; m_sixteenBit = true; } void DColor::convertToEightBit() { if (!m_sixteenBit) return; m_red = (m_red + 1) / 256 - 1; m_green = (m_green + 1) / 256 - 1; m_blue = (m_blue + 1) / 256 - 1; m_alpha = (m_alpha + 1) / 256 - 1; m_sixteenBit = false; } void DColor::getHSL(int* h, int* s, int* l) const { double min; double max; double red; double green; double blue; double delta; double sum; double hue, sat, lig; double range = m_sixteenBit ? 65535.0 : 255.0; red = m_red / range; green = m_green / range; blue = m_blue / range; if (red > green) { if (red > blue) max = red; else max = blue; if (green < blue) min = green; else min = blue; } else { if (green > blue) max = green; else max = blue; if (red < blue) min = red; else min = blue; } sum = max + min; lig = sum / 2; sat = 0; hue = 0; if (max != min) { delta = max - min; if (lig <= 0.5) sat = delta / sum; else sat = delta / (2 - sum); if (red == max) hue = (green - blue) / delta; else if (green == max) hue = 2 + (blue - red) / delta; else if (blue == max) hue = 4 + (red - green) / delta; if (hue < 0) hue += 6; if (hue > 6) hue -= 6; hue *= 60; } *h = lround(hue * range / 360.0); *s = lround(sat * range); *l = lround(lig * range); } void DColor::setRGB(int h, int s, int l, bool sixteenBit) { double hue; double lightness; double saturation; double m1, m2; double r, g, b; double range = m_sixteenBit ? 65535.0 : 255.0; if (s == 0) { m_red = l; m_green = l; m_blue = l; } else { hue = (double)(h * 360.0 / range); lightness = (double)(l / range); saturation = (double)(s / range); if (lightness <= 0.5) m2 = lightness * (1 + saturation); else m2 = lightness + saturation - lightness * saturation; m1 = 2 * lightness - m2; double mh; mh = hue + 120; while (mh > 360) mh -= 360; while (mh < 0) mh += 360; if (mh < 60) r = m1 + (m2 - m1) * mh / 60; else if (mh < 180) r = m2; else if (mh < 240) r = m1 + (m2 - m1) * (240 - mh) / 60; else r = m1; mh = hue; while (mh > 360) mh -= 360; while (mh < 0) mh += 360; if (mh < 60) g = m1 + (m2 - m1) * mh / 60; else if (mh < 180) g = m2; else if (mh < 240) g = m1 + (m2 - m1) * (240 - mh) / 60; else g = m1; mh = hue - 120; while (mh > 360) mh -= 360; while (mh < 0) mh += 360; if (mh < 60) b = m1 + (m2 - m1) * mh / 60; else if (mh < 180) b = m2; else if (mh < 240) b = m1 + (m2 - m1) * (240 - mh) / 60; else b = m1; m_red = lround(r * range); m_green = lround(g * range); m_blue = lround(b * range); } m_sixteenBit = sixteenBit; // Fully opaque color. if (m_sixteenBit) m_alpha = 65535; else m_alpha = 255; } } // NameSpace Digikam