Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright 2012 Google Inc. |
michael@0 | 3 | * |
michael@0 | 4 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 5 | * found in the LICENSE file. |
michael@0 | 6 | */ |
michael@0 | 7 | |
michael@0 | 8 | #ifndef SkMaskGamma_DEFINED |
michael@0 | 9 | #define SkMaskGamma_DEFINED |
michael@0 | 10 | |
michael@0 | 11 | #include "SkTypes.h" |
michael@0 | 12 | #include "SkColor.h" |
michael@0 | 13 | #include "SkColorPriv.h" |
michael@0 | 14 | #include "SkRefCnt.h" |
michael@0 | 15 | |
michael@0 | 16 | /** |
michael@0 | 17 | * SkColorSpaceLuminance is used to convert luminances to and from linear and |
michael@0 | 18 | * perceptual color spaces. |
michael@0 | 19 | * |
michael@0 | 20 | * Luma is used to specify a linear luminance value [0.0, 1.0]. |
michael@0 | 21 | * Luminance is used to specify a luminance value in an arbitrary color space [0.0, 1.0]. |
michael@0 | 22 | */ |
michael@0 | 23 | class SkColorSpaceLuminance : SkNoncopyable { |
michael@0 | 24 | public: |
michael@0 | 25 | virtual ~SkColorSpaceLuminance() { } |
michael@0 | 26 | |
michael@0 | 27 | /** Converts a color component luminance in the color space to a linear luma. */ |
michael@0 | 28 | virtual SkScalar toLuma(SkScalar gamma, SkScalar luminance) const = 0; |
michael@0 | 29 | /** Converts a linear luma to a color component luminance in the color space. */ |
michael@0 | 30 | virtual SkScalar fromLuma(SkScalar gamma, SkScalar luma) const = 0; |
michael@0 | 31 | |
michael@0 | 32 | /** Converts a color to a luminance value. */ |
michael@0 | 33 | static U8CPU computeLuminance(SkScalar gamma, SkColor c) { |
michael@0 | 34 | const SkColorSpaceLuminance& luminance = Fetch(gamma); |
michael@0 | 35 | SkScalar r = luminance.toLuma(gamma, SkIntToScalar(SkColorGetR(c)) / 255); |
michael@0 | 36 | SkScalar g = luminance.toLuma(gamma, SkIntToScalar(SkColorGetG(c)) / 255); |
michael@0 | 37 | SkScalar b = luminance.toLuma(gamma, SkIntToScalar(SkColorGetB(c)) / 255); |
michael@0 | 38 | SkScalar luma = r * SK_LUM_COEFF_R + |
michael@0 | 39 | g * SK_LUM_COEFF_G + |
michael@0 | 40 | b * SK_LUM_COEFF_B; |
michael@0 | 41 | SkASSERT(luma <= SK_Scalar1); |
michael@0 | 42 | return SkScalarRoundToInt(luminance.fromLuma(gamma, luma) * 255); |
michael@0 | 43 | } |
michael@0 | 44 | |
michael@0 | 45 | /** Retrieves the SkColorSpaceLuminance for the given gamma. */ |
michael@0 | 46 | static const SkColorSpaceLuminance& Fetch(SkScalar gamma); |
michael@0 | 47 | }; |
michael@0 | 48 | |
michael@0 | 49 | ///@{ |
michael@0 | 50 | /** |
michael@0 | 51 | * Scales base <= 2^N-1 to 2^8-1 |
michael@0 | 52 | * @param N [1, 8] the number of bits used by base. |
michael@0 | 53 | * @param base the number to be scaled to [0, 255]. |
michael@0 | 54 | */ |
michael@0 | 55 | template<U8CPU N> static inline U8CPU sk_t_scale255(U8CPU base) { |
michael@0 | 56 | base <<= (8 - N); |
michael@0 | 57 | U8CPU lum = base; |
michael@0 | 58 | for (unsigned int i = N; i < 8; i += N) { |
michael@0 | 59 | lum |= base >> i; |
michael@0 | 60 | } |
michael@0 | 61 | return lum; |
michael@0 | 62 | } |
michael@0 | 63 | template<> /*static*/ inline U8CPU sk_t_scale255<1>(U8CPU base) { |
michael@0 | 64 | return base * 0xFF; |
michael@0 | 65 | } |
michael@0 | 66 | template<> /*static*/ inline U8CPU sk_t_scale255<2>(U8CPU base) { |
michael@0 | 67 | return base * 0x55; |
michael@0 | 68 | } |
michael@0 | 69 | template<> /*static*/ inline U8CPU sk_t_scale255<4>(U8CPU base) { |
michael@0 | 70 | return base * 0x11; |
michael@0 | 71 | } |
michael@0 | 72 | template<> /*static*/ inline U8CPU sk_t_scale255<8>(U8CPU base) { |
michael@0 | 73 | return base; |
michael@0 | 74 | } |
michael@0 | 75 | ///@} |
michael@0 | 76 | |
michael@0 | 77 | template <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskPreBlend; |
michael@0 | 78 | |
michael@0 | 79 | void SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar contrast, |
michael@0 | 80 | const SkColorSpaceLuminance& srcConvert, SkScalar srcGamma, |
michael@0 | 81 | const SkColorSpaceLuminance& dstConvert, SkScalar dstGamma); |
michael@0 | 82 | |
michael@0 | 83 | /** |
michael@0 | 84 | * A regular mask contains linear alpha values. A gamma correcting mask |
michael@0 | 85 | * contains non-linear alpha values in an attempt to create gamma correct blits |
michael@0 | 86 | * in the presence of a gamma incorrect (linear) blend in the blitter. |
michael@0 | 87 | * |
michael@0 | 88 | * SkMaskGamma creates and maintains tables which convert linear alpha values |
michael@0 | 89 | * to gamma correcting alpha values. |
michael@0 | 90 | * @param R The number of luminance bits to use [1, 8] from the red channel. |
michael@0 | 91 | * @param G The number of luminance bits to use [1, 8] from the green channel. |
michael@0 | 92 | * @param B The number of luminance bits to use [1, 8] from the blue channel. |
michael@0 | 93 | */ |
michael@0 | 94 | template <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskGamma : public SkRefCnt { |
michael@0 | 95 | SK_DECLARE_INST_COUNT(SkTMaskGamma) |
michael@0 | 96 | public: |
michael@0 | 97 | |
michael@0 | 98 | /** Creates a linear SkTMaskGamma. */ |
michael@0 | 99 | SkTMaskGamma() : fIsLinear(true) { } |
michael@0 | 100 | |
michael@0 | 101 | /** |
michael@0 | 102 | * Creates tables to convert linear alpha values to gamma correcting alpha |
michael@0 | 103 | * values. |
michael@0 | 104 | * |
michael@0 | 105 | * @param contrast A value in the range [0.0, 1.0] which indicates the |
michael@0 | 106 | * amount of artificial contrast to add. |
michael@0 | 107 | * @param paint The color space in which the paint color was chosen. |
michael@0 | 108 | * @param device The color space of the target device. |
michael@0 | 109 | */ |
michael@0 | 110 | SkTMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) : fIsLinear(false) { |
michael@0 | 111 | const SkColorSpaceLuminance& paintConvert = SkColorSpaceLuminance::Fetch(paintGamma); |
michael@0 | 112 | const SkColorSpaceLuminance& deviceConvert = SkColorSpaceLuminance::Fetch(deviceGamma); |
michael@0 | 113 | for (U8CPU i = 0; i < (1 << MAX_LUM_BITS); ++i) { |
michael@0 | 114 | U8CPU lum = sk_t_scale255<MAX_LUM_BITS>(i); |
michael@0 | 115 | SkTMaskGamma_build_correcting_lut(fGammaTables[i], lum, contrast, |
michael@0 | 116 | paintConvert, paintGamma, |
michael@0 | 117 | deviceConvert, deviceGamma); |
michael@0 | 118 | } |
michael@0 | 119 | } |
michael@0 | 120 | |
michael@0 | 121 | /** Given a color, returns the closest canonical color. */ |
michael@0 | 122 | static SkColor CanonicalColor(SkColor color) { |
michael@0 | 123 | return SkColorSetRGB( |
michael@0 | 124 | sk_t_scale255<R_LUM_BITS>(SkColorGetR(color) >> (8 - R_LUM_BITS)), |
michael@0 | 125 | sk_t_scale255<G_LUM_BITS>(SkColorGetG(color) >> (8 - G_LUM_BITS)), |
michael@0 | 126 | sk_t_scale255<B_LUM_BITS>(SkColorGetB(color) >> (8 - B_LUM_BITS))); |
michael@0 | 127 | } |
michael@0 | 128 | |
michael@0 | 129 | /** The type of the mask pre-blend which will be returned from preBlend(SkColor). */ |
michael@0 | 130 | typedef SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> PreBlend; |
michael@0 | 131 | |
michael@0 | 132 | /** |
michael@0 | 133 | * Provides access to the tables appropriate for converting linear alpha |
michael@0 | 134 | * values into gamma correcting alpha values when drawing the given color |
michael@0 | 135 | * through the mask. The destination color will be approximated. |
michael@0 | 136 | */ |
michael@0 | 137 | PreBlend preBlend(SkColor color) const; |
michael@0 | 138 | |
michael@0 | 139 | private: |
michael@0 | 140 | static const int MAX_LUM_BITS = |
michael@0 | 141 | B_LUM_BITS > (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS) |
michael@0 | 142 | ? B_LUM_BITS : (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS); |
michael@0 | 143 | uint8_t fGammaTables[1 << MAX_LUM_BITS][256]; |
michael@0 | 144 | bool fIsLinear; |
michael@0 | 145 | |
michael@0 | 146 | typedef SkRefCnt INHERITED; |
michael@0 | 147 | }; |
michael@0 | 148 | |
michael@0 | 149 | |
michael@0 | 150 | /** |
michael@0 | 151 | * SkTMaskPreBlend is a tear-off of SkTMaskGamma. It provides the tables to |
michael@0 | 152 | * convert a linear alpha value for a given channel to a gamma correcting alpha |
michael@0 | 153 | * value for that channel. This class is immutable. |
michael@0 | 154 | * |
michael@0 | 155 | * If fR, fG, or fB is NULL, all of them will be. This indicates that no mask |
michael@0 | 156 | * pre blend should be applied. SkTMaskPreBlend::isApplicable() is provided as |
michael@0 | 157 | * a convenience function to test for the absence of this case. |
michael@0 | 158 | */ |
michael@0 | 159 | template <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskPreBlend { |
michael@0 | 160 | private: |
michael@0 | 161 | SkTMaskPreBlend(const SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>* parent, |
michael@0 | 162 | const uint8_t* r, const uint8_t* g, const uint8_t* b) |
michael@0 | 163 | : fParent(SkSafeRef(parent)), fR(r), fG(g), fB(b) { } |
michael@0 | 164 | |
michael@0 | 165 | SkAutoTUnref<const SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> > fParent; |
michael@0 | 166 | friend class SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>; |
michael@0 | 167 | public: |
michael@0 | 168 | /** Creates a non applicable SkTMaskPreBlend. */ |
michael@0 | 169 | SkTMaskPreBlend() : fParent(), fR(NULL), fG(NULL), fB(NULL) { } |
michael@0 | 170 | |
michael@0 | 171 | /** |
michael@0 | 172 | * This copy contructor exists for correctness, but should never be called |
michael@0 | 173 | * when return value optimization is enabled. |
michael@0 | 174 | */ |
michael@0 | 175 | SkTMaskPreBlend(const SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>& that) |
michael@0 | 176 | : fParent(SkSafeRef(that.fParent.get())), fR(that.fR), fG(that.fG), fB(that.fB) { } |
michael@0 | 177 | |
michael@0 | 178 | ~SkTMaskPreBlend() { } |
michael@0 | 179 | |
michael@0 | 180 | /** True if this PreBlend should be applied. When false, fR, fG, and fB are NULL. */ |
michael@0 | 181 | bool isApplicable() const { |
michael@0 | 182 | return NULL != this->fG; |
michael@0 | 183 | } |
michael@0 | 184 | |
michael@0 | 185 | const uint8_t* fR; |
michael@0 | 186 | const uint8_t* fG; |
michael@0 | 187 | const uint8_t* fB; |
michael@0 | 188 | }; |
michael@0 | 189 | |
michael@0 | 190 | template <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> |
michael@0 | 191 | SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> |
michael@0 | 192 | SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>::preBlend(SkColor color) const { |
michael@0 | 193 | return fIsLinear ? SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>() |
michael@0 | 194 | : SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>(this, |
michael@0 | 195 | fGammaTables[SkColorGetR(color) >> (8 - MAX_LUM_BITS)], |
michael@0 | 196 | fGammaTables[SkColorGetG(color) >> (8 - MAX_LUM_BITS)], |
michael@0 | 197 | fGammaTables[SkColorGetB(color) >> (8 - MAX_LUM_BITS)]); |
michael@0 | 198 | } |
michael@0 | 199 | |
michael@0 | 200 | ///@{ |
michael@0 | 201 | /** |
michael@0 | 202 | * If APPLY_LUT is false, returns component unchanged. |
michael@0 | 203 | * If APPLY_LUT is true, returns lut[component]. |
michael@0 | 204 | * @param APPLY_LUT whether or not the look-up table should be applied to component. |
michael@0 | 205 | * @component the initial component. |
michael@0 | 206 | * @lut a look-up table which transforms the component. |
michael@0 | 207 | */ |
michael@0 | 208 | template<bool APPLY_LUT> static inline U8CPU sk_apply_lut_if(U8CPU component, const uint8_t*) { |
michael@0 | 209 | return component; |
michael@0 | 210 | } |
michael@0 | 211 | template<> /*static*/ inline U8CPU sk_apply_lut_if<true>(U8CPU component, const uint8_t* lut) { |
michael@0 | 212 | return lut[component]; |
michael@0 | 213 | } |
michael@0 | 214 | ///@} |
michael@0 | 215 | |
michael@0 | 216 | #endif |