Index: app/gfx/color_utils.cc |
=================================================================== |
--- app/gfx/color_utils.cc (revision 26699) |
+++ app/gfx/color_utils.cc (working copy) |
@@ -1,4 +1,4 @@ |
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
@@ -19,18 +19,23 @@ |
namespace color_utils { |
+// Helper functions ----------------------------------------------------------- |
+ |
+namespace { |
+ |
// These transformations are based on the equations in: |
// http://en.wikipedia.org/wiki/Lab_color |
-// http://en.wikipedia.org/wiki/SRGB_color_space#Specification_of_the_transformation |
+// http://en.wikipedia.org/wiki/SRGB_color_space# |
brettw
2009/09/22 16:40:51
I would have kept this link as-is, since now nobod
|
+// Specification_of_the_transformation |
// See also: |
// http://www.brucelindbloom.com/index.html?ColorCalculator.html |
-static const double kCIEConversionAlpha = 0.055; |
-static const double kCIEConversionGamma = 2.2; |
-static const double kE = 0.008856; |
-static const double kK = 903.3; |
+const double kCIEConversionAlpha = 0.055; |
+const double kCIEConversionGamma = 2.2; |
+const double kE = 0.008856; |
+const double kK = 903.3; |
-static double CIEConvertNonLinear(uint8 color_component) { |
+double CIEConvertNonLinear(uint8 color_component) { |
double color_component_d = static_cast<double>(color_component) / 255.0; |
if (color_component_d > 0.04045) { |
double base = (color_component_d + kCIEConversionAlpha) / |
@@ -41,46 +46,7 @@ |
} |
} |
-// Note: this works only for sRGB. |
-void SkColorToCIEXYZ(SkColor c, CIE_XYZ* xyz) { |
- uint8 r = SkColorGetR(c); |
- uint8 g = SkColorGetG(c); |
- uint8 b = SkColorGetB(c); |
- |
- xyz->X = |
- 0.4124 * CIEConvertNonLinear(r) + |
- 0.3576 * CIEConvertNonLinear(g) + |
- 0.1805 * CIEConvertNonLinear(b); |
- xyz->Y = |
- 0.2126 * CIEConvertNonLinear(r) + |
- 0.7152 * CIEConvertNonLinear(g) + |
- 0.0722 * CIEConvertNonLinear(g); |
- xyz->Z = |
- 0.0193 * CIEConvertNonLinear(r) + |
- 0.1192 * CIEConvertNonLinear(g) + |
- 0.9505 * CIEConvertNonLinear(b); |
-} |
- |
-static double LabConvertNonLinear(double value) { |
- if (value > 0.008856) { |
- double goat = pow(value, static_cast<double>(1) / 3); |
- return goat; |
- } |
- return (kK * value + 16) / 116; |
-} |
- |
-void CIEXYZToLabColor(const CIE_XYZ& xyz, LabColor* lab) { |
- CIE_XYZ white_xyz; |
- SkColorToCIEXYZ(SkColorSetRGB(255, 255, 255), &white_xyz); |
- double fx = LabConvertNonLinear(xyz.X / white_xyz.X); |
- double fy = LabConvertNonLinear(xyz.Y / white_xyz.Y); |
- double fz = LabConvertNonLinear(xyz.Z / white_xyz.Z); |
- lab->L = static_cast<int>(116 * fy) - 16; |
- lab->a = static_cast<int>(500 * (fx - fy)); |
- lab->b = static_cast<int>(200 * (fy - fz)); |
-} |
- |
-static uint8 sRGBColorComponentFromLinearComponent(double component) { |
+uint8 sRGBColorComponentFromLinearComponent(double component) { |
double result; |
if (component <= 0.0031308) { |
result = 12.92 * component; |
@@ -92,34 +58,32 @@ |
return std::min(static_cast<uint8>(255), static_cast<uint8>(result * 255)); |
} |
-SkColor CIEXYZToSkColor(SkAlpha alpha, const CIE_XYZ& xyz) { |
- double r_linear = 3.2410 * xyz.X - 1.5374 * xyz.Y - 0.4986 * xyz.Z; |
- double g_linear = -0.9692 * xyz.X + 1.8760 * xyz.Y + 0.0416 * xyz.Z; |
- double b_linear = 0.0556 * xyz.X - 0.2040 * xyz.Y + 1.0570 * xyz.Z; |
- uint8 r = sRGBColorComponentFromLinearComponent(r_linear); |
- uint8 g = sRGBColorComponentFromLinearComponent(g_linear); |
- uint8 b = sRGBColorComponentFromLinearComponent(b_linear); |
- return SkColorSetARGB(alpha, r, g, b); |
+double LabConvertNonLinear(double value) { |
+ if (value > 0.008856) { |
+ double goat = pow(value, static_cast<double>(1) / 3); |
+ return goat; |
+ } |
+ return (kK * value + 16) / 116; |
} |
-static double gen_yr(const LabColor& lab) { |
+double gen_yr(const LabColor& lab) { |
if (lab.L > (kE * kK)) |
return pow((lab.L + 16.0) / 116, 3.0); |
return static_cast<double>(lab.L) / kK; |
} |
-static double fy(const LabColor& lab) { |
+double fy(const LabColor& lab) { |
double yr = gen_yr(lab); |
if (yr > kE) |
return (lab.L + 16.0) / 116; |
return (kK * yr + 16.0) / 116; |
} |
-static double fx(const LabColor& lab) { |
+double fx(const LabColor& lab) { |
return (static_cast<double>(lab.a) / 500) + fy(lab); |
} |
-static double gen_xr(const LabColor& lab) { |
+double gen_xr(const LabColor& lab) { |
double x = fx(lab); |
double x_cubed = pow(x, 3.0); |
if (x_cubed > kE) |
@@ -127,11 +91,11 @@ |
return (116.0 * x - 16.0) / kK; |
} |
-static double fz(const LabColor& lab) { |
+double fz(const LabColor& lab) { |
return fy(lab) - (static_cast<double>(lab.b) / 200); |
} |
-static double gen_zr(const LabColor& lab) { |
+double gen_zr(const LabColor& lab) { |
double z = fz(lab); |
double z_cubed = pow(z, 3.0); |
if (z_cubed > kE) |
@@ -139,19 +103,76 @@ |
return (116.0 * z - 16.0) / kK; |
} |
-void LabColorToCIEXYZ(const LabColor& lab, CIE_XYZ* xyz) { |
- CIE_XYZ result; |
+int GetLumaForColor(SkColor* color) { |
+ int r = SkColorGetR(*color); |
+ int g = SkColorGetG(*color); |
+ int b = SkColorGetB(*color); |
- CIE_XYZ white_xyz; |
- SkColorToCIEXYZ(SkColorSetRGB(255, 255, 255), &white_xyz); |
+ int luma = static_cast<int>(0.3*r + 0.59*g + 0.11*b); |
+ if (luma < 0) |
+ luma = 0; |
+ else if (luma > 255) |
+ luma = 255; |
- result.X = gen_xr(lab) * white_xyz.X; |
- result.Y = gen_yr(lab) * white_xyz.Y; |
- result.Z = gen_zr(lab) * white_xyz.Z; |
+ return luma; |
+} |
- *xyz = result; |
+// Next three functions' formulas from: |
+// http://www.w3.org/TR/WCAG20/#relativeluminancedef |
+// http://www.w3.org/TR/WCAG20/#contrast-ratiodef |
+ |
+double ConvertSRGB(double eight_bit_component) { |
+ const double component = eight_bit_component / 255.0; |
+ return (component <= 0.03928) ? |
+ (component / 12.92) : pow((component + 0.055) / 1.055, 2.4); |
} |
+double RelativeLuminance(SkColor color) { |
+ return (0.2126 * ConvertSRGB(SkColorGetR(color))) + |
+ (0.7152 * ConvertSRGB(SkColorGetG(color))) + |
+ (0.0722 * ConvertSRGB(SkColorGetB(color))); |
+} |
+ |
+double ContrastRatio(SkColor color1, SkColor color2) { |
+ const double l1 = RelativeLuminance(color1) + 0.05; |
+ const double l2 = RelativeLuminance(color2) + 0.05; |
+ return (l1 > l2) ? (l1 / l2) : (l2 / l1); |
+} |
+ |
+} // namespace |
+ |
+// ---------------------------------------------------------------------------- |
+ |
+// Note: this works only for sRGB. |
+void SkColorToCIEXYZ(SkColor c, CIE_XYZ* xyz) { |
+ uint8 r = SkColorGetR(c); |
+ uint8 g = SkColorGetG(c); |
+ uint8 b = SkColorGetB(c); |
+ |
+ xyz->X = |
brettw
2009/09/22 16:40:51
Can you indent the wrapped lines 2 more spaces whi
|
+ 0.4124 * CIEConvertNonLinear(r) + |
+ 0.3576 * CIEConvertNonLinear(g) + |
+ 0.1805 * CIEConvertNonLinear(b); |
+ xyz->Y = |
+ 0.2126 * CIEConvertNonLinear(r) + |
+ 0.7152 * CIEConvertNonLinear(g) + |
+ 0.0722 * CIEConvertNonLinear(g); |
+ xyz->Z = |
+ 0.0193 * CIEConvertNonLinear(r) + |
+ 0.1192 * CIEConvertNonLinear(g) + |
+ 0.9505 * CIEConvertNonLinear(b); |
+} |
+ |
+SkColor CIEXYZToSkColor(SkAlpha alpha, const CIE_XYZ& xyz) { |
+ double r_linear = 3.2410 * xyz.X - 1.5374 * xyz.Y - 0.4986 * xyz.Z; |
+ double g_linear = -0.9692 * xyz.X + 1.8760 * xyz.Y + 0.0416 * xyz.Z; |
+ double b_linear = 0.0556 * xyz.X - 0.2040 * xyz.Y + 1.0570 * xyz.Z; |
+ uint8 r = sRGBColorComponentFromLinearComponent(r_linear); |
+ uint8 g = sRGBColorComponentFromLinearComponent(g_linear); |
+ uint8 b = sRGBColorComponentFromLinearComponent(b_linear); |
+ return SkColorSetARGB(alpha, r, g, b); |
+} |
+ |
void SkColorToLabColor(SkColor c, LabColor* lab) { |
CIE_XYZ xyz; |
SkColorToCIEXYZ(c, &xyz); |
@@ -164,14 +185,37 @@ |
return CIEXYZToSkColor(alpha, xyz); |
} |
-static const int kCloseToBoundary = 64; |
-static const int kAverageBoundary = 15; |
+void CIEXYZToLabColor(const CIE_XYZ& xyz, LabColor* lab) { |
+ CIE_XYZ white_xyz; |
+ SkColorToCIEXYZ(SkColorSetRGB(255, 255, 255), &white_xyz); |
+ double fx = LabConvertNonLinear(xyz.X / white_xyz.X); |
+ double fy = LabConvertNonLinear(xyz.Y / white_xyz.Y); |
+ double fz = LabConvertNonLinear(xyz.Z / white_xyz.Z); |
+ lab->L = static_cast<int>(116 * fy) - 16; |
+ lab->a = static_cast<int>(500 * (fx - fy)); |
+ lab->b = static_cast<int>(200 * (fy - fz)); |
+} |
+void LabColorToCIEXYZ(const LabColor& lab, CIE_XYZ* xyz) { |
+ CIE_XYZ result; |
+ |
+ CIE_XYZ white_xyz; |
+ SkColorToCIEXYZ(SkColorSetRGB(255, 255, 255), &white_xyz); |
+ |
+ result.X = gen_xr(lab) * white_xyz.X; |
+ result.Y = gen_yr(lab) * white_xyz.Y; |
+ result.Z = gen_zr(lab) * white_xyz.Z; |
+ |
+ *xyz = result; |
+} |
+ |
bool IsColorCloseToTransparent(SkAlpha alpha) { |
+ const int kCloseToBoundary = 64; |
return alpha < kCloseToBoundary; |
} |
bool IsColorCloseToGrey(int r, int g, int b) { |
+ const int kAverageBoundary = 15; |
int average = (r + g + b) / 3; |
return (abs(r - average) < kAverageBoundary) && |
(abs(g - average) < kAverageBoundary) && |
@@ -221,20 +265,6 @@ |
return result; |
} |
-inline int GetLumaForColor(SkColor* color) { |
- int r = SkColorGetR(*color); |
- int g = SkColorGetG(*color); |
- int b = SkColorGetB(*color); |
- |
- int luma = static_cast<int>(0.3*r + 0.59*g + 0.11*b); |
- if (luma < 0) |
- luma = 0; |
- else if (luma > 255) |
- luma = 255; |
- |
- return luma; |
-} |
- |
void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]) { |
SkAutoLockPixels bitmap_lock(*bitmap); |
// Assume ARGB_8888 format. |
@@ -265,27 +295,6 @@ |
(SkColorGetB(background) * (0xFF - alpha))) / 0xFF); |
} |
-// Next three functions' formulas from: |
-// http://www.w3.org/TR/WCAG20/#relativeluminancedef |
-// http://www.w3.org/TR/WCAG20/#contrast-ratiodef |
-static double ConvertSRGB(double eight_bit_component) { |
- const double component = eight_bit_component / 255.0; |
- return (component <= 0.03928) ? |
- (component / 12.92) : pow((component + 0.055) / 1.055, 2.4); |
-} |
- |
-static double RelativeLuminance(SkColor color) { |
- return (0.2126 * ConvertSRGB(SkColorGetR(color))) + |
- (0.7152 * ConvertSRGB(SkColorGetG(color))) + |
- (0.0722 * ConvertSRGB(SkColorGetB(color))); |
-} |
- |
-static double ContrastRatio(SkColor color1, SkColor color2) { |
- const double l1 = RelativeLuminance(color1) + 0.05; |
- const double l2 = RelativeLuminance(color2) + 0.05; |
- return (l1 > l2) ? (l1 / l2) : (l2 / l1); |
-} |
- |
SkColor PickMoreReadableColor(SkColor foreground1, |
SkColor foreground2, |
SkColor background) { |