18ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com/*
28ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * Copyright 2012 Google Inc.
38ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *
48ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * Use of this source code is governed by a BSD-style license that can be
58ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * found in the LICENSE file.
68ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com */
78ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
88ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#ifndef SkMaskGamma_DEFINED
98ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#define SkMaskGamma_DEFINED
108ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
118ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#include "SkTypes.h"
128ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#include "SkColor.h"
138ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#include "SkColorPriv.h"
148ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#include "SkRefCnt.h"
158ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
168ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com/**
178ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * SkColorSpaceLuminance is used to convert luminances to and from linear and
188ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * perceptual color spaces.
198ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *
208ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * Luma is used to specify a linear luminance value [0.0, 1.0].
218ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * Luminance is used to specify a luminance value in an arbitrary color space [0.0, 1.0].
228ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com */
238ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comclass SkColorSpaceLuminance : SkNoncopyable {
248ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.compublic:
2589299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    virtual ~SkColorSpaceLuminance() { }
26b2d1d1cbf9c06614991367c529dde1ca9a92e8e5robertphillips@google.com
278ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /** Converts a color component luminance in the color space to a linear luma. */
2889299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    virtual SkScalar toLuma(SkScalar gamma, SkScalar luminance) const = 0;
298ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /** Converts a linear luma to a color component luminance in the color space. */
3089299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    virtual SkScalar fromLuma(SkScalar gamma, SkScalar luma) const = 0;
318ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
328ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /** Converts a color to a luminance value. */
3389299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    static U8CPU computeLuminance(SkScalar gamma, SkColor c) {
3489299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        const SkColorSpaceLuminance& luminance = Fetch(gamma);
3589299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        SkScalar r = luminance.toLuma(gamma, SkIntToScalar(SkColorGetR(c)) / 255);
3689299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        SkScalar g = luminance.toLuma(gamma, SkIntToScalar(SkColorGetG(c)) / 255);
3789299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        SkScalar b = luminance.toLuma(gamma, SkIntToScalar(SkColorGetB(c)) / 255);
38dfc928cc9afc242d1125e8d5ae48e8bca66c4834commit-bot@chromium.org        SkScalar luma = r * SK_LUM_COEFF_R +
39dfc928cc9afc242d1125e8d5ae48e8bca66c4834commit-bot@chromium.org                        g * SK_LUM_COEFF_G +
40dfc928cc9afc242d1125e8d5ae48e8bca66c4834commit-bot@chromium.org                        b * SK_LUM_COEFF_B;
418ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com        SkASSERT(luma <= SK_Scalar1);
4289299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        return SkScalarRoundToInt(luminance.fromLuma(gamma, luma) * 255);
438ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    }
448ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
4589299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    /** Retrieves the SkColorSpaceLuminance for the given gamma. */
4689299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    static const SkColorSpaceLuminance& Fetch(SkScalar gamma);
47a3fabefbaabda8ec54ab2358321dee46b8ed57a6bungeman@google.com};
48a3fabefbaabda8ec54ab2358321dee46b8ed57a6bungeman@google.com
498ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com///@{
508ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com/**
518ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * Scales base <= 2^N-1 to 2^8-1
528ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * @param N [1, 8] the number of bits used by base.
538ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * @param base the number to be scaled to [0, 255].
548ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com */
558ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<U8CPU N> static inline U8CPU sk_t_scale255(U8CPU base) {
568ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    base <<= (8 - N);
578ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    U8CPU lum = base;
588ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    for (unsigned int i = N; i < 8; i += N) {
598ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com        lum |= base >> i;
608ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    }
618ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return lum;
628ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
638ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<> /*static*/ inline U8CPU sk_t_scale255<1>(U8CPU base) {
648ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return base * 0xFF;
658ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
668ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<> /*static*/ inline U8CPU sk_t_scale255<2>(U8CPU base) {
678ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return base * 0x55;
688ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
698ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<> /*static*/ inline U8CPU sk_t_scale255<4>(U8CPU base) {
708ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return base * 0x11;
718ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
728ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<> /*static*/ inline U8CPU sk_t_scale255<8>(U8CPU base) {
738ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return base;
748ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
758ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com///@}
768ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
778ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskPreBlend;
788ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
798ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comvoid SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar contrast,
8089299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com                                       const SkColorSpaceLuminance& srcConvert, SkScalar srcGamma,
8189299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com                                       const SkColorSpaceLuminance& dstConvert, SkScalar dstGamma);
828ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
838ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com/**
848ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * A regular mask contains linear alpha values. A gamma correcting mask
858ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * contains non-linear alpha values in an attempt to create gamma correct blits
868ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * in the presence of a gamma incorrect (linear) blend in the blitter.
878ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *
888ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * SkMaskGamma creates and maintains tables which convert linear alpha values
898ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * to gamma correcting alpha values.
908ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * @param R The number of luminance bits to use [1, 8] from the red channel.
918ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * @param G The number of luminance bits to use [1, 8] from the green channel.
928ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * @param B The number of luminance bits to use [1, 8] from the blue channel.
938ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com */
948ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskGamma : public SkRefCnt {
953fc092543559b6819a64c8f66c5bf6e23e2d4069commit-bot@chromium.org    SK_DECLARE_INST_COUNT(SkTMaskGamma)
968ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.compublic:
9718723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
98ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    /** Creates a linear SkTMaskGamma. */
99ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    SkTMaskGamma() : fIsLinear(true) { }
100a3fabefbaabda8ec54ab2358321dee46b8ed57a6bungeman@google.com
1018ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /**
1028ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * Creates tables to convert linear alpha values to gamma correcting alpha
1038ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * values.
1048ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     *
1058ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * @param contrast A value in the range [0.0, 1.0] which indicates the
1068ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     *                 amount of artificial contrast to add.
1078ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * @param paint The color space in which the paint color was chosen.
1088ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * @param device The color space of the target device.
1098ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     */
11089299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com    SkTMaskGamma(SkScalar contrast, SkScalar paintGamma, SkScalar deviceGamma) : fIsLinear(false) {
11189299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        const SkColorSpaceLuminance& paintConvert = SkColorSpaceLuminance::Fetch(paintGamma);
11289299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com        const SkColorSpaceLuminance& deviceConvert = SkColorSpaceLuminance::Fetch(deviceGamma);
113ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com        for (U8CPU i = 0; i < (1 << MAX_LUM_BITS); ++i) {
114ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com            U8CPU lum = sk_t_scale255<MAX_LUM_BITS>(i);
11589299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com            SkTMaskGamma_build_correcting_lut(fGammaTables[i], lum, contrast,
11689299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com                                              paintConvert, paintGamma,
11789299d71f05400f5218d9d75cdcb27b27523ba46bungeman@google.com                                              deviceConvert, deviceGamma);
1188ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com        }
1198ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    }
1208ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
1212e19ac8c586450ca8f8102fa326b9ff01152c756reed@google.com    /** Given a color, returns the closest canonical color. */
1222e19ac8c586450ca8f8102fa326b9ff01152c756reed@google.com    static SkColor CanonicalColor(SkColor color) {
1238ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com        return SkColorSetRGB(
124ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                   sk_t_scale255<R_LUM_BITS>(SkColorGetR(color) >> (8 - R_LUM_BITS)),
125ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                   sk_t_scale255<G_LUM_BITS>(SkColorGetG(color) >> (8 - G_LUM_BITS)),
126ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                   sk_t_scale255<B_LUM_BITS>(SkColorGetB(color) >> (8 - B_LUM_BITS)));
1278ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    }
1288ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
1298ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /** The type of the mask pre-blend which will be returned from preBlend(SkColor). */
1308ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    typedef SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> PreBlend;
1318ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
1328ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /**
1338ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * Provides access to the tables appropriate for converting linear alpha
1348ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * values into gamma correcting alpha values when drawing the given color
1358ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * through the mask. The destination color will be approximated.
1368ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     */
137ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    PreBlend preBlend(SkColor color) const;
1388ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
1398ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comprivate:
140ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    static const int MAX_LUM_BITS =
141ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com          B_LUM_BITS > (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS)
142ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com        ? B_LUM_BITS : (R_LUM_BITS > G_LUM_BITS ? R_LUM_BITS : G_LUM_BITS);
143ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    uint8_t fGammaTables[1 << MAX_LUM_BITS][256];
144a3fabefbaabda8ec54ab2358321dee46b8ed57a6bungeman@google.com    bool fIsLinear;
14518723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com
14618723ff03ab6a08cd02c5ae008ae6775d13b3281robertphillips@google.com    typedef SkRefCnt INHERITED;
1478ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com};
1488ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
14949d83c6f5dfc0d5ea7c65c379b49149e46554a4crobertphillips@google.com
1508ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com/**
1518ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * SkTMaskPreBlend is a tear-off of SkTMaskGamma. It provides the tables to
1528ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * convert a linear alpha value for a given channel to a gamma correcting alpha
1538ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com * value for that channel. This class is immutable.
154961a69dffc5bc09a632257942c12d89160fb3947skia.committer@gmail.com *
155a3fabefbaabda8ec54ab2358321dee46b8ed57a6bungeman@google.com * If fR, fG, or fB is NULL, all of them will be. This indicates that no mask
156ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com * pre blend should be applied. SkTMaskPreBlend::isApplicable() is provided as
157ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com * a convenience function to test for the absence of this case.
1588ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com */
1598ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS> class SkTMaskPreBlend {
1608ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comprivate:
161ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    SkTMaskPreBlend(const SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>* parent,
162ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                    const uint8_t* r, const uint8_t* g, const uint8_t* b)
163ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    : fParent(SkSafeRef(parent)), fR(r), fG(g), fB(b) { }
164ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com
165ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    SkAutoTUnref<const SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS> > fParent;
1668ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    friend class SkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>;
1678ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.compublic:
168ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    /** Creates a non applicable SkTMaskPreBlend. */
169ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    SkTMaskPreBlend() : fParent(), fR(NULL), fG(NULL), fB(NULL) { }
170ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com
1718ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    /**
1728ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * This copy contructor exists for correctness, but should never be called
1738ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     * when return value optimization is enabled.
1748ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com     */
1758ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    SkTMaskPreBlend(const SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>& that)
176ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    : fParent(SkSafeRef(that.fParent.get())), fR(that.fR), fG(that.fG), fB(that.fB) { }
177ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com
1788ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    ~SkTMaskPreBlend() { }
179ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com
180ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    /** True if this PreBlend should be applied. When false, fR, fG, and fB are NULL. */
181ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    bool isApplicable() const {
182ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com        return NULL != this->fG;
183ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    }
184ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com
1858ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    const uint8_t* fR;
1868ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    const uint8_t* fG;
1878ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    const uint8_t* fB;
1888ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com};
1898ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
1908ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate <int R_LUM_BITS, int G_LUM_BITS, int B_LUM_BITS>
1918ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comSkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>
192ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.comSkTMaskGamma<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>::preBlend(SkColor color) const {
193ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com    return fIsLinear ? SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>()
194ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                     : SkTMaskPreBlend<R_LUM_BITS, G_LUM_BITS, B_LUM_BITS>(this,
195ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                         fGammaTables[SkColorGetR(color) >> (8 - MAX_LUM_BITS)],
196ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                         fGammaTables[SkColorGetG(color) >> (8 - MAX_LUM_BITS)],
197ec0f292459a7b5fb0300c83e456714033ab802fbbungeman@google.com                         fGammaTables[SkColorGetB(color) >> (8 - MAX_LUM_BITS)]);
1988ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
1998ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
2008ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com///@{
2018ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com/**
2028ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *  If APPLY_LUT is false, returns component unchanged.
2038ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *  If APPLY_LUT is true, returns lut[component].
2048ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *  @param APPLY_LUT whether or not the look-up table should be applied to component.
2058ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *  @component the initial component.
2068ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com *  @lut a look-up table which transforms the component.
2078ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com */
2088ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<bool APPLY_LUT> static inline U8CPU sk_apply_lut_if(U8CPU component, const uint8_t*) {
2098ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return component;
2108ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
2118ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.comtemplate<> /*static*/ inline U8CPU sk_apply_lut_if<true>(U8CPU component, const uint8_t* lut) {
2128ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com    return lut[component];
2138ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com}
2148ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com///@}
2158ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com
2168ebb786eca7079fed1c2d9521e2bf9604bb5825dbungeman@google.com#endif
217