180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/* 280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc. 380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be 580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file. 680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkMaskGamma_DEFINED 980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkMaskGamma_DEFINED 1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkTypes.h" 1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColor.h" 1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColorPriv.h" 1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRefCnt.h" 1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkColorSpaceLuminance is used to convert luminances to and from linear and 1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * perceptual color spaces. 1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Luma is used to specify a linear luminance value [0.0, 1.0]. 2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Luminance is used to specify a luminance value in an arbitrary color space [0.0, 1.0]. 2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass SkColorSpaceLuminance : SkNoncopyable { 2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual ~SkColorSpaceLuminance() { } 2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Converts a color component luminance in the color space to a linear luma. */ 2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkScalar toLuma(SkScalar gamma, SkScalar luminance) const = 0; 2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Converts a linear luma to a color component luminance in the color space. */ 3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru virtual SkScalar fromLuma(SkScalar gamma, SkScalar luma) const = 0; 3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Converts a color to a luminance value. */ 3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static U8CPU computeLuminance(SkScalar gamma, SkColor c) { 3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColorSpaceLuminance& luminance = Fetch(gamma); 3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar r = luminance.toLuma(gamma, SkIntToScalar(SkColorGetR(c)) / 255); 3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar g = luminance.toLuma(gamma, SkIntToScalar(SkColorGetG(c)) / 255); 3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkScalar b = luminance.toLuma(gamma, SkIntToScalar(SkColorGetB(c)) / 255); 38910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger SkScalar luma = r * SK_LUM_COEFF_R + 39910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger g * SK_LUM_COEFF_G + 40910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger b * SK_LUM_COEFF_B; 4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkASSERT(luma <= SK_Scalar1); 4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkScalarRoundToInt(luminance.fromLuma(gamma, luma) * 255); 4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** Retrieves the SkColorSpaceLuminance for the given gamma. */ 4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru static const SkColorSpaceLuminance& Fetch(SkScalar gamma); 4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@{ 5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Scales base <= 2^N-1 to 2^8-1 5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param N [1, 8] the number of bits used by base. 5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param base the number to be scaled to [0, 255]. 5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<U8CPU N> static inline U8CPU sk_t_scale255(U8CPU base) { 5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru base <<= (8 - N); 5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru U8CPU lum = base; 5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru for (unsigned int i = N; i < 8; i += N) { 5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru lum |= base >> i; 6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return lum; 6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<> /*static*/ inline U8CPU sk_t_scale255<1>(U8CPU base) { 6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return base * 0xFF; 6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<> /*static*/ inline U8CPU sk_t_scale255<2>(U8CPU base) { 6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return base * 0x55; 6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<> /*static*/ inline U8CPU sk_t_scale255<4>(U8CPU base) { 7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return base * 0x11; 7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<> /*static*/ inline U8CPU sk_t_scale255<8>(U8CPU base) { 7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return base; 7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@} 7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskPreBlend; 7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar contrast, 8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColorSpaceLuminance& srcConvert, SkScalar srcGamma, 8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColorSpaceLuminance& dstConvert, SkScalar dstGamma); 8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * A regular mask contains linear alpha values. A gamma correcting mask 8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * contains non-linear alpha values in an attempt to create gamma correct blits 8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * in the presence of a gamma incorrect (linear) blend in the blitter. 8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkMaskGamma creates and maintains tables which convert linear alpha values 8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * to gamma correcting alpha values. 9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param R The number of luminance bits to use [1, 8] from the red channel. 9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param G The number of luminance bits to use [1, 8] from the green channel. 9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param B The number of luminance bits to use [1, 8] from the blue channel. 9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskGamma : public SkRefCnt { 95910f694aefb0b671dd8522a9afe9b6be645701c1Derek Sollenberger SK_DECLARE_INST_COUNT(SkTMaskGamma) 9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 98363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Creates a linear SkTMaskGamma. */ 99363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTMaskGamma() : fIsLinear(true) { } 10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Creates tables to convert linear alpha values to gamma correcting alpha 10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * values. 10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param contrast A value in the range [0.0, 1.0] which indicates the 10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * amount of artificial contrast to add. 10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param paint The color space in which the paint color was chosen. 10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param device The color space of the target device. 10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) : fIsLinear(false) { 11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColorSpaceLuminance& paintConvert = SkColorSpaceLuminance::Fetch(paintGamma); 11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const SkColorSpaceLuminance& deviceConvert = SkColorSpaceLuminance::Fetch(deviceGamma); 113363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger for (U8CPU i = 0; i < (1 << MAX_LUM_BITS); ++i) { 114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger U8CPU lum = sk_t_scale255<MAX_LUM_BITS>(i); 11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTMaskGamma_build_correcting_lut(fGammaTables[i], lum, contrast, 11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru paintConvert, paintGamma, 11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru deviceConvert, deviceGamma); 11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 121d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger /** Given a color, returns the closest canonical color. */ 122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger static SkColor CanonicalColor(SkColor color) { 12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return SkColorSetRGB( 124363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sk_t_scale255<R_LUM_BITS>(SkColorGetR(color) >> (8 - R_LUM_BITS)), 125363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sk_t_scale255<G_LUM_BITS>(SkColorGetG(color) >> (8 - G_LUM_BITS)), 126363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger sk_t_scale255<B_LUM_BITS>(SkColorGetB(color) >> (8 - B_LUM_BITS))); 12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru } 12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** The type of the mask pre-blend which will be returned from preBlend(SkColor). */ 13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> PreBlend; 13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Provides access to the tables appropriate for converting linear alpha 13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * values into gamma correcting alpha values when drawing the given color 13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * through the mask. The destination color will be approximated. 13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 137363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger PreBlend preBlend(SkColor color) const; 13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger static const int MAX_LUM_BITS = 141363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger B_LUM_BITS > (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS) 142363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger ? B_LUM_BITS : (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS); 143363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger uint8_t fGammaTables[1 << MAX_LUM_BITS][256]; 14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru bool fIsLinear; 14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru typedef SkRefCnt INHERITED; 14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkTMaskPreBlend is a tear-off of SkTMaskGamma. It provides the tables to 15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * convert a linear alpha value for a given channel to a gamma correcting alpha 15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * value for that channel. This class is immutable. 15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If fR, fG, or fB is NULL, all of them will be. This indicates that no mask 156363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * pre blend should be applied. SkTMaskPreBlend::isApplicable() is provided as 157363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * a convenience function to test for the absence of this case. 15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskPreBlend { 16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate: 161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTMaskPreBlend(const SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>* parent, 162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger const uint8_t* r, const uint8_t* g, const uint8_t* b) 163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : fParent(SkSafeRef(parent)), fR(r), fG(g), fB(b) { } 164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkAutoTUnref<const SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> > fParent; 16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru friend class SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>; 16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic: 168363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** Creates a non applicable SkTMaskPreBlend. */ 169363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger SkTMaskPreBlend() : fParent(), fR(NULL), fG(NULL), fB(NULL) { } 170363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru /** 17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * This copy contructor exists for correctness, but should never be called 17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * when return value optimization is enabled. 17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru SkTMaskPreBlend(const SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>& that) 176363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : fParent(SkSafeRef(that.fParent.get())), fR(that.fR), fG(that.fG), fB(that.fB) { } 177363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru ~SkTMaskPreBlend() { } 179363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 180363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger /** True if this PreBlend should be applied. When false, fR, fG, and fB are NULL. */ 181363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger bool isApplicable() const { 182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return NULL != this->fG; 183363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger } 184363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger 18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* fR; 18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* fG; 18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru const uint8_t* fB; 18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}; 18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> 19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> 192363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek SollenbergerSkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>::preBlend(SkColor color) const { 193363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger return fIsLinear ? SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>() 194363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger : SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>(this, 195363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGammaTables[SkColorGetR(color) >> (8 - MAX_LUM_BITS)], 196363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGammaTables[SkColorGetG(color) >> (8 - MAX_LUM_BITS)], 197363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger fGammaTables[SkColorGetB(color) >> (8 - MAX_LUM_BITS)]); 19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@{ 20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** 20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If APPLY_LUT is false, returns component unchanged. 20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * If APPLY_LUT is true, returns lut[component]. 20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @param APPLY_LUT whether or not the look-up table should be applied to component. 20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @component the initial component. 20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * @lut a look-up table which transforms the component. 20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */ 20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<bool APPLY_LUT> static inline U8CPU sk_apply_lut_if(U8CPU component, const uint8_t*) { 20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return component; 21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutemplate<> /*static*/ inline U8CPU sk_apply_lut_if<true>(U8CPU component, const uint8_t* lut) { 21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru return lut[component]; 21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru} 21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@} 21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru 21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif 217