1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bcolor.cxx,v $
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
;
52 l
= (maxVal
+ minVal
) / 2.0;
54 if( ::basegfx::fTools::equalZero(d
) )
56 s
= h
= 0; // hue undefined (achromatic case)
60 s
= l
> 0.5 ? d
/(2.0-maxVal
-minVal
) :
65 else if( g
== maxVal
)
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
89 return nValue1
+ (nValue2
- nValue1
)*nHue
/60.0;
90 else if( nHue
< 180.0 )
92 else if( nHue
< 240.0 )
93 return nValue1
+ (nValue2
- nValue1
)*(240.0 - nHue
)/60.0;
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
);
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;
130 if( fTools::equalZero(v
) )
135 if( !fTools::equalZero(s
) )
141 else if( maxVal
== g
)
143 h
= 2.0 + (b
- r
) / delta
;
147 h
= 4.0 + (r
- g
) / delta
;
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
);
171 if( fTools::equal(h
,360) )
172 h
= 0; // 360 degrees is equivalent to 0 degrees
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? */
185 return BColor(v
,t
,p
);
188 return BColor(q
,v
,p
);
191 return BColor(p
,v
,t
);
194 return BColor(p
,q
,v
);
197 return BColor(t
,p
,v
);
200 return BColor(v
,p
,q
);
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();
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();
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();
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();
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();
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();
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 //////////////////////////////////////////////////////////////////////////////