Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <basegfx/numeric/ftools.hxx>
30 : : #include <basegfx/color/bcolor.hxx>
31 : : #include <basegfx/color/bcolortools.hxx>
32 : :
33 : : //////////////////////////////////////////////////////////////////////////////
34 : :
35 : : namespace basegfx { namespace tools
36 : : {
37 : 187 : BColor rgb2hsl(const BColor& rRGBColor)
38 : : {
39 : 187 : const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
40 [ + - ][ + - ]: 187 : const double minVal = ::std::min( ::std::min( r, g ), b );
41 [ + - ][ + - ]: 187 : const double maxVal = ::std::max( ::std::max( r, g ), b );
42 : 187 : const double d = maxVal - minVal;
43 : :
44 : 187 : double h=0, s=0, l=0;
45 : :
46 : 187 : l = (maxVal + minVal) / 2.0;
47 : :
48 [ + + ]: 187 : if( ::basegfx::fTools::equalZero(d) )
49 : : {
50 : 57 : s = h = 0; // hue undefined (achromatic case)
51 : : }
52 : : else
53 : : {
54 : : s = l > 0.5 ? d/(2.0-maxVal-minVal) :
55 [ - + ]: 130 : d/(maxVal + minVal);
56 : :
57 [ + + ]: 130 : if( r == maxVal )
58 : 50 : h = (g - b)/d;
59 [ + + ]: 80 : else if( g == maxVal )
60 : 30 : h = 2.0 + (b - r)/d;
61 : : else
62 : 50 : h = 4.0 + (r - g)/d;
63 : :
64 : 130 : h *= 60.0;
65 : :
66 [ + + ]: 130 : if( h < 0.0 )
67 : 15 : h += 360.0;
68 : : }
69 : :
70 : 187 : return BColor(h,s,l);
71 : : }
72 : :
73 : 180 : static inline double hsl2rgbHelper( double nValue1, double nValue2, double nHue )
74 : : {
75 : : // clamp hue to [0,360]
76 : 180 : nHue = fmod( nHue, 360.0 );
77 : :
78 : : // cope with wrap-arounds
79 [ + + ]: 180 : if( nHue < 0.0 )
80 : 10 : nHue += 360.0;
81 : :
82 [ + + ]: 180 : if( nHue < 60.0 )
83 : 45 : return nValue1 + (nValue2 - nValue1)*nHue/60.0;
84 [ + + ]: 135 : else if( nHue < 180.0 )
85 : 60 : return nValue2;
86 [ + + ]: 75 : else if( nHue < 240.0 )
87 : 15 : return nValue1 + (nValue2 - nValue1)*(240.0 - nHue)/60.0;
88 : : else
89 : 180 : return nValue1;
90 : : }
91 : :
92 : 97 : BColor hsl2rgb(const BColor& rHSLColor)
93 : : {
94 : 97 : const double h=rHSLColor.getRed(), s=rHSLColor.getGreen(), l=rHSLColor.getBlue();
95 : :
96 [ + + ]: 97 : if( fTools::equalZero(s) )
97 : 37 : return BColor(l, l, l ); // achromatic case
98 : :
99 [ + + ]: 60 : const double nVal1( l <= 0.5 ? l*(1.0 + s) : l + s - l*s );
100 : 60 : const double nVal2( 2.0*l - nVal1 );
101 : :
102 : : return BColor(
103 : : hsl2rgbHelper(nVal2,
104 : : nVal1,
105 : : h + 120.0),
106 : : hsl2rgbHelper(nVal2,
107 : : nVal1,
108 : : h),
109 : : hsl2rgbHelper(nVal2,
110 : : nVal1,
111 : 97 : h - 120.0) );
112 : : }
113 : :
114 : 125 : BColor rgb2hsv(const BColor& rRGBColor)
115 : : {
116 : 125 : const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
117 [ + - ][ + - ]: 125 : const double maxVal = std::max(std::max(r,g),b);
118 [ + - ][ + - ]: 125 : const double minVal = std::min(std::min(r,g),b);
119 : 125 : const double delta = maxVal-minVal;
120 : :
121 : 125 : double h=0, s=0, v=0;
122 : :
123 : 125 : v = maxVal;
124 [ + + ]: 125 : if( fTools::equalZero(v) )
125 : 10 : s = 0;
126 : : else
127 : 115 : s = delta / v;
128 : :
129 [ + + ]: 125 : if( !fTools::equalZero(s) )
130 : : {
131 [ + + ]: 95 : if( maxVal == r )
132 : : {
133 : 50 : h = (g - b) / delta;
134 : : }
135 [ + + ]: 45 : else if( maxVal == g )
136 : : {
137 : 30 : h = 2.0 + (b - r) / delta;
138 : : }
139 : : else
140 : : {
141 : 15 : h = 4.0 + (r - g) / delta;
142 : : }
143 : :
144 : 95 : h *= 60.0;
145 : :
146 [ + + ]: 95 : if( h < 0 )
147 : 15 : h += 360;
148 : : }
149 : :
150 : 125 : return BColor(h,s,v);
151 : : }
152 : :
153 : 40 : BColor hsv2rgb(const BColor& rHSVColor)
154 : : {
155 : 40 : double h=rHSVColor.getRed();
156 : 40 : const double s=rHSVColor.getGreen(), v=rHSVColor.getBlue();
157 : :
158 [ + + ]: 40 : if( fTools::equalZero(s) )
159 : : {
160 : : // achromatic case: no hue.
161 : 10 : return BColor(v,v,v);
162 : : }
163 : : else
164 : : {
165 [ - + ]: 30 : if( fTools::equal(h,360) )
166 : 0 : h = 0; // 360 degrees is equivalent to 0 degrees
167 : :
168 : 30 : h /= 60.0;
169 : 30 : const sal_Int32 intval = static_cast< sal_Int32 >( h );
170 : 30 : const double f = h - intval;
171 : 30 : const double p = v*(1.0-s);
172 : 30 : const double q = v*(1.0-(s*f));
173 : 30 : const double t = v*(1.0-(s*(1.0-f)));
174 : :
175 : : /* which hue area? */
176 [ + + + + : 30 : switch( intval )
+ + - ]
177 : : {
178 : : case 0:
179 : 5 : return BColor(v,t,p);
180 : :
181 : : case 1:
182 : 5 : return BColor(q,v,p);
183 : :
184 : : case 2:
185 : 5 : return BColor(p,v,t);
186 : :
187 : : case 3:
188 : 5 : return BColor(p,q,v);
189 : :
190 : : case 4:
191 : 5 : return BColor(t,p,v);
192 : :
193 : : case 5:
194 : 5 : return BColor(v,p,q);
195 : :
196 : : default:
197 : : // hue overflow
198 : 40 : return BColor();
199 : : }
200 : : }
201 : : }
202 : :
203 : 40 : BColor rgb2ciexyz( const BColor& rRGBColor )
204 : : {
205 : : // from Poynton color faq, and SMPTE RP 177-1993, Derivation
206 : : // of Basic Television Color Equations
207 : 40 : const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
208 : : return BColor(
209 : : 0.412453*r + 0.35758*g + 0.180423*b,
210 : : 0.212671*r + 0.71516*g + 0.072169*b,
211 : 40 : 0.019334*r + 0.119193*g + 0.950227*b);
212 : : }
213 : :
214 : : } } // end of namespace basegfx
215 : :
216 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|