From 564ba361b30ba95793ef505f8895d48b0df3ee2f Mon Sep 17 00:00:00 2001 From: "pkasting@chromium.org" Date: Tue, 22 Sep 2009 20:51:09 +0000 Subject: Eliminate a bunch of color conversions. I was going to try and clean up the code for these but discovered to my surprise that no one actually uses them. Also clean up a few other things, like my AlphaBlend() function using hex alpha values where everyone else uses decimal, or unnecessary global qualifiers, or needlessly long code. I avoided changing postincrement to preincrement :D BUG=none TEST=none Review URL: http://codereview.chromium.org/214054 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26856 0039d316-1c4b-4281-b951-d872f2087c98 --- app/gfx/color_utils.cc | 184 ++++--------------------------------------------- app/gfx/color_utils.h | 26 ------- 2 files changed, 13 insertions(+), 197 deletions(-) (limited to 'app') diff --git a/app/gfx/color_utils.cc b/app/gfx/color_utils.cc index 586a5e6..48a13ca 100644 --- a/app/gfx/color_utils.cc +++ b/app/gfx/color_utils.cc @@ -23,97 +23,11 @@ namespace color_utils { 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 -// See also: -// http://www.brucelindbloom.com/index.html?ColorCalculator.html - -const double kCIEConversionAlpha = 0.055; -const double kCIEConversionGamma = 2.2; -const double kE = 0.008856; -const double kK = 903.3; - -double CIEConvertNonLinear(uint8 color_component) { - double color_component_d = static_cast(color_component) / 255.0; - if (color_component_d > 0.04045) { - double base = (color_component_d + kCIEConversionAlpha) / - (1 + kCIEConversionAlpha); - return pow(base, kCIEConversionGamma); - } else { - return color_component_d / 12.92; - } -} - -uint8 sRGBColorComponentFromLinearComponent(double component) { - double result; - if (component <= 0.0031308) { - result = 12.92 * component; - } else { - result = (1 + kCIEConversionAlpha) * - pow(component, (static_cast(1) / 2.4)) - - kCIEConversionAlpha; - } - return std::min(static_cast(255), static_cast(result * 255)); -} - -double LabConvertNonLinear(double value) { - if (value > 0.008856) { - double goat = pow(value, static_cast(1) / 3); - return goat; - } - return (kK * value + 16) / 116; -} - -double gen_yr(const LabColor& lab) { - if (lab.L > (kE * kK)) - return pow((lab.L + 16.0) / 116, 3.0); - return static_cast(lab.L) / kK; -} - -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; -} - -double fx(const LabColor& lab) { - return (static_cast(lab.a) / 500) + fy(lab); -} - -double gen_xr(const LabColor& lab) { - double x = fx(lab); - double x_cubed = pow(x, 3.0); - if (x_cubed > kE) - return x_cubed; - return (116.0 * x - 16.0) / kK; -} - -double fz(const LabColor& lab) { - return fy(lab) - (static_cast(lab.b) / 200); -} - -double gen_zr(const LabColor& lab) { - double z = fz(lab); - double z_cubed = pow(z, 3.0); - if (z_cubed > kE) - return z_cubed; - return (116.0 * z - 16.0) / kK; -} - int GetLumaForColor(SkColor* color) { - int r = SkColorGetR(*color); - int g = SkColorGetG(*color); - int b = SkColorGetB(*color); - - int luma = static_cast(0.3*r + 0.59*g + 0.11*b); - if (luma < 0) - luma = 0; - else if (luma > 255) - luma = 255; - - return luma; + int luma = static_cast((0.3 * SkColorGetR(*color)) + + (0.59 * SkColorGetG(*color)) + + (0.11 * SkColorGetB(*color))); + return std::max(std::min(luma, 255), 0); } // Next three functions' formulas from: @@ -142,69 +56,6 @@ double ContrastRatio(SkColor color1, SkColor color2) { // ---------------------------------------------------------------------------- -// 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); -} - -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); - CIEXYZToLabColor(xyz, lab); -} - -SkColor LabColorToSkColor(const LabColor& lab, SkAlpha alpha) { - CIE_XYZ xyz; - LabColorToCIEXYZ(lab, &xyz); - return CIEXYZToSkColor(alpha, xyz); -} - -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(116 * fy) - 16; - lab->a = static_cast(500 * (fx - fy)); - lab->b = static_cast(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; @@ -249,16 +100,9 @@ SkColor GetAverageColorOfFavicon(SkBitmap* favicon, SkAlpha alpha) { ++color_count; } - SkColor result; - if (color_count > 0) { - result = SkColorSetARGB(alpha, - r / color_count, - g / color_count, - b / color_count); - } else { - result = SkColorSetARGB(alpha, 0, 0, 0); - } - return result; + return color_count ? + SkColorSetARGB(alpha, r / color_count, g / color_count, b / color_count) : + SkColorSetARGB(alpha, 0, 0, 0); } void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]) { @@ -270,25 +114,23 @@ void BuildLumaHistogram(SkBitmap* bitmap, int histogram[256]) { int pixel_height = bitmap->height(); for (int y = 0; y < pixel_height; ++y) { SkColor* current_color = static_cast(bitmap->getAddr32(0, y)); - for (int x = 0; x < pixel_width; ++x, ++current_color) { + for (int x = 0; x < pixel_width; ++x, ++current_color) histogram[GetLumaForColor(current_color)]++; - } } } SkColor AlphaBlend(SkColor foreground, SkColor background, SkAlpha alpha) { if (alpha == 0) return background; - else if (alpha == 0xFF) + if (alpha == 255) return foreground; - return SkColorSetRGB( ((SkColorGetR(foreground) * alpha) + - (SkColorGetR(background) * (0xFF - alpha))) / 0xFF, + (SkColorGetR(background) * (255 - alpha))) / 255, ((SkColorGetG(foreground) * alpha) + - (SkColorGetG(background) * (0xFF - alpha))) / 0xFF, + (SkColorGetG(background) * (255 - alpha))) / 255, ((SkColorGetB(foreground) * alpha) + - (SkColorGetB(background) * (0xFF - alpha))) / 0xFF); + (SkColorGetB(background) * (255 - alpha))) / 255); } SkColor PickMoreReadableColor(SkColor foreground1, @@ -300,7 +142,7 @@ SkColor PickMoreReadableColor(SkColor foreground1, SkColor GetSysSkColor(int which) { #if defined(OS_WIN) - return skia::COLORREFToSkColor(::GetSysColor(which)); + return skia::COLORREFToSkColor(GetSysColor(which)); #else NOTIMPLEMENTED(); return SK_ColorLTGRAY; diff --git a/app/gfx/color_utils.h b/app/gfx/color_utils.h index 6b4077f..30e9e52 100644 --- a/app/gfx/color_utils.h +++ b/app/gfx/color_utils.h @@ -11,32 +11,6 @@ class SkBitmap; namespace color_utils { -// Represents set of CIE XYZ tristimulus values. -struct CIE_XYZ { - double X; - double Y; // luminance - double Z; -}; - -// Represents a L*a*b* color value -struct LabColor { - int L; - int a; - int b; -}; - -// Note: these transformations assume sRGB as the source color space - -// Convert between different color spaces -void SkColorToCIEXYZ(SkColor c, CIE_XYZ* xyz); -SkColor CIEXYZToSkColor(SkAlpha alpha, const CIE_XYZ& xyz); - -void SkColorToLabColor(SkColor c, LabColor* lab); -SkColor LabColorToSkColor(const LabColor& lab, SkAlpha alpha); - -void CIEXYZToLabColor(const CIE_XYZ& xyz, LabColor* lab); -void LabColorToCIEXYZ(const LabColor& lab, CIE_XYZ* xyz); - // Determine if a given alpha value is nearly completely transparent. bool IsColorCloseToTransparent(SkAlpha alpha); -- cgit v1.1