update dev300-m58
[ooovba.git] / basegfx / source / color / bcolortools.cxx
blob5e55e55aeb7392be207333582cd30ff7d5eaf3ba
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bcolor.cxx,v $
11 * $Revision: 1.2 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_basegfx.hxx"
35 #include <basegfx/numeric/ftools.hxx>
36 #include <basegfx/color/bcolor.hxx>
37 #include <basegfx/color/bcolortools.hxx>
39 //////////////////////////////////////////////////////////////////////////////
41 namespace basegfx { namespace tools
43 BColor rgb2hsl(const BColor& rRGBColor)
45 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
46 const double minVal = ::std::min( ::std::min( r, g ), b );
47 const double maxVal = ::std::max( ::std::max( r, g ), b );
48 const double d = maxVal - minVal;
50 double h=0, s=0, l=0;
52 l = (maxVal + minVal) / 2.0;
54 if( ::basegfx::fTools::equalZero(d) )
56 s = h = 0; // hue undefined (achromatic case)
58 else
60 s = l > 0.5 ? d/(2.0-maxVal-minVal) :
61 d/(maxVal + minVal);
63 if( r == maxVal )
64 h = (g - b)/d;
65 else if( g == maxVal )
66 h = 2.0 + (b - r)/d;
67 else
68 h = 4.0 + (r - h)/d;
70 h *= 60.0;
72 if( h < 0.0 )
73 h += 360.0;
76 return BColor(h,s,l);
79 static inline double hsl2rgbHelper( double nValue1, double nValue2, double nHue )
81 // clamp hue to [0,360]
82 nHue = fmod( nHue, 360.0 );
84 // cope with wrap-arounds
85 if( nHue < 0.0 )
86 nHue += 360.0;
88 if( nHue < 60.0 )
89 return nValue1 + (nValue2 - nValue1)*nHue/60.0;
90 else if( nHue < 180.0 )
91 return nValue2;
92 else if( nHue < 240.0 )
93 return nValue1 + (nValue2 - nValue1)*(240.0 - nHue)/60.0;
94 else
95 return nValue1;
98 BColor hsl2rgb(const BColor& rHSLColor)
100 const double h=rHSLColor.getRed(), s=rHSLColor.getGreen(), l=rHSLColor.getBlue();
102 if( fTools::equalZero(s) )
103 return BColor(l, l, l ); // achromatic case
105 const double nVal1( l <= 0.5 ? l*(1.0 + s) : l + s - l*s );
106 const double nVal2( 2.0*l - nVal1 );
108 return BColor(
109 hsl2rgbHelper(nVal2,
110 nVal1,
111 h + 120.0),
112 hsl2rgbHelper(nVal2,
113 nVal1,
115 hsl2rgbHelper(nVal2,
116 nVal1,
117 h - 120.0) );
120 BColor rgb2hsv(const BColor& rRGBColor)
122 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
123 const double maxVal = std::max(std::max(r,g),b);
124 const double minVal = std::min(std::min(r,g),b);
125 const double delta = maxVal-minVal;
127 double h=0, s=0, v=0;
129 v = maxVal;
130 if( fTools::equalZero(v) )
131 s = 0;
132 else
133 s = delta / v;
135 if( !fTools::equalZero(s) )
137 if( maxVal == r )
139 h = (g - b) / delta;
141 else if( maxVal == g )
143 h = 2.0 + (b - r) / delta;
145 else
147 h = 4.0 + (r - g) / delta;
150 h *= 60.0;
152 if( h < 0 )
153 h += 360;
156 return BColor(h,s,v);
159 BColor hsv2rgb(const BColor& rHSVColor)
161 double h=rHSVColor.getRed();
162 const double s=rHSVColor.getGreen(), v=rHSVColor.getBlue();
164 if( fTools::equalZero(s) )
166 // achromatic case: no hue.
167 return BColor(v,v,v);
169 else
171 if( fTools::equal(h,360) )
172 h = 0; // 360 degrees is equivalent to 0 degrees
174 h /= 60.0;
175 const sal_Int32 intval = static_cast< sal_Int32 >( h );
176 const double f = h - intval;
177 const double p = v*(1.0-s);
178 const double q = v*(1.0-(s*f));
179 const double t = v*(1.0-(s*(1.0-f)));
181 /* which hue area? */
182 switch( intval )
184 case 0:
185 return BColor(v,t,p);
187 case 1:
188 return BColor(q,v,p);
190 case 2:
191 return BColor(p,v,t);
193 case 3:
194 return BColor(p,q,v);
196 case 4:
197 return BColor(t,p,v);
199 case 5:
200 return BColor(v,p,q);
202 default:
203 // hue overflow
204 return BColor();
209 BColor rgb2yiq(const BColor& rRGBColor)
211 // from Foley, van Dam, Computer Graphics
212 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
213 return BColor(
214 0.299*r + 0.587*g + 0.114*b,
215 0.596*r - 0.274*g - 0.322*b,
216 0.211*r - 0.522*g + 0.311*b);
219 BColor yiq2rgb(const BColor& rYIQColor)
221 // from Foley, van Dam, Computer Graphics
222 const double y=rYIQColor.getRed(), i=rYIQColor.getGreen(), q=rYIQColor.getBlue();
223 return BColor(
224 y + 0.956*i + 0.623*q,
225 y - 0.272*i - 0.648*q,
226 y - 1.105*i + 1.705*q );
229 BColor ciexyz2rgb( const BColor& rXYZColor )
231 // from Poynton color faq, and SMPTE RP 177-1993, Derivation
232 // of Basic Television Color Equations
233 const double x=rXYZColor.getRed(), y=rXYZColor.getGreen(), z=rXYZColor.getBlue();
234 return BColor(
235 3.240479*x - 1.53715*y - 0.498535*z,
236 -0.969256*x + 1.875991*y + 0.041556*z,
237 0.055648*x - 0.204043*y + 1.057311*z );
240 BColor rgb2ciexyz( const BColor& rRGBColor )
242 // from Poynton color faq, and SMPTE RP 177-1993, Derivation
243 // of Basic Television Color Equations
244 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
245 return BColor(
246 0.412453*r + 0.35758*g + 0.180423*b,
247 0.212671*r + 0.71516*g + 0.072169*b,
248 0.019334*r + 0.119193*g + 0.950227*b);
251 BColor rgb2ypbpr(const BColor& rRGBColor)
253 const double r=rRGBColor.getRed(), g=rRGBColor.getGreen(), b=rRGBColor.getBlue();
254 return BColor(
255 0.299*r + 0.587*g + 0.114*b,
256 -0.168736*r - 0.331264*g + 0.5*b,
257 0.5*r - 0.418688*g - 0.081312*b);
260 BColor ypbpr2rgb(const BColor& rYPbPrColor)
262 const double y=rYPbPrColor.getRed(), pb=rYPbPrColor.getGreen(), pr=rYPbPrColor.getBlue();
263 return BColor(
264 1.*y + 0.*pb + 1.402*pr,
265 1.*y - 0.344136*pb - 0.714136*pr,
266 1.*y + 1.772*pb + 0.*pr);
269 } } // end of namespace basegfx
271 //////////////////////////////////////////////////////////////////////////////
272 // eof