SkColorPriv.h revision 7839ce1af63bf12fe7b3caa866970bbbb3afb13d
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef SkColorPriv_DEFINED
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkColorPriv_DEFINED
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// turn this own for extra debug checking when blending onto 565
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define CHECK_FOR_565_OVERFLOW
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkColor.h"
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMath.h"
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@{
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** See ITU-R Recommendation BT.709 at http://www.itu.int/rec/R-REC-BT.709/ .*/
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_ITU_BT709_LUM_COEFF_R (0.2126f)
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_ITU_BT709_LUM_COEFF_G (0.7152f)
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_ITU_BT709_LUM_COEFF_B (0.0722f)
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@}
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@{
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** A float value which specifies this channel's contribution to luminance. */
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///@}
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Computes the luminance from the given r, g, and b in accordance with
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_LUM_COEFF_X. For correct results, r, g, and b should be in linear space.
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b) {
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //The following is
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //r * SK_LUM_COEFF_R + g * SK_LUM_COEFF_G + b * SK_LUM_COEFF_B
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    //with SK_LUM_COEFF_X in 1.8 fixed point (rounding adjusted to sum to 256).
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (r * 54 + g * 183 + b * 19) >> 8;
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    byte into a scale value, so that we can say scale * value >> 8 instead of
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    alpha * value / 255.
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    In debugging, asserts that alpha is 0..255
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkAlpha255To256(U8CPU alpha) {
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(SkToU8(alpha) == alpha);
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // this one assues that blending on top of an opaque dst keeps it that way
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // even though it is less accurate than a+(a>>7) for non-opaque dsts
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return alpha + 1;
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Multiplify value by 0..256, and shift the result down 8
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (i.e. return (value * alpha256) >> 8)
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkAlphaMul(value, alpha256)     (SkMulS16(value, alpha256) >> 8)
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  The caller may want negative values, so keep all params signed (int)
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  so we don't accidentally slip into unsigned math and lose the sign
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//  extension when we shift (in SkAlphaMul)
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int SkAlphaBlend(int src, int dst, int scale256) {
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)scale256 <= 256);
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + SkAlphaMul(src - dst, scale256);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Returns (src * alpha + dst * (255 - alpha)) / 255
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  This is more accurate than SkAlphaBlend, but slightly slower
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int SkAlphaBlend255(S16CPU src, S16CPU dst, U8CPU alpha) {
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((int16_t)src == src);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((int16_t)dst == dst);
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((uint8_t)alpha == alpha);
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int prod = SkMulS16(src - dst, alpha) + 128;
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    prod = (prod + (prod >> 8)) >> 8;
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + prod;
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R16_BITS     5
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G16_BITS     6
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B16_BITS     5
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R16_SHIFT    (SK_B16_BITS + SK_G16_BITS)
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G16_SHIFT    (SK_B16_BITS)
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B16_SHIFT    0
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R16_MASK     ((1 << SK_R16_BITS) - 1)
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G16_MASK     ((1 << SK_G16_BITS) - 1)
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B16_MASK     ((1 << SK_B16_BITS) - 1)
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedR16(color)   (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedG16(color)   (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedB16(color)   (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkR16Assert(r)  SkASSERT((unsigned)(r) <= SK_R16_MASK)
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkG16Assert(g)  SkASSERT((unsigned)(g) <= SK_G16_MASK)
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkB16Assert(b)  SkASSERT((unsigned)(b) <= SK_B16_MASK)
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) {
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(r <= SK_R16_MASK);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(g <= SK_G16_MASK);
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(b <= SK_B16_MASK);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R16_MASK_IN_PLACE        (SK_R16_MASK << SK_R16_SHIFT)
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G16_MASK_IN_PLACE        (SK_G16_MASK << SK_G16_SHIFT)
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B16_MASK_IN_PLACE        (SK_B16_MASK << SK_B16_SHIFT)
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Expand the 16bit color into a 32bit value that can be scaled all at once
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    by a value up to 32. Used in conjunction with SkCompact_rgb_16.
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint32_t SkExpand_rgb_16(U16CPU c) {
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(c == (uint16_t)c);
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    color value. The computation yields only 16bits of valid data, but we claim
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    to return 32bits, so that the compiler won't generate extra instructions to
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    "clean" the top 16bits. However, the top 16 can contain garbage, so it is
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    up to the caller to safely ignore them.
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkCompact_rgb_16(uint32_t c) {
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Scale the 16bit color value by the 0..256 scale parameter.
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    The computation yields only 16bits of valid data, but we claim
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    to return 32bits, so that the compiler won't generate extra instructions to
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    "clean" the top 16bits.
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) {
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5);
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// this helper explicitly returns a clean 16bit value (but slower)
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkAlphaMulRGB16_ToU16(c, s)  (uint16_t)SkAlphaMulRGB16(c, s)
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Blend src and dst 16bit colors by the 0..256 scale parameter.
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    The computation yields only 16bits of valid data, but we claim
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    to return 32bits, so that the compiler won't generate extra instructions to
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    "clean" the top 16bits.
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) {
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)srcScale <= 256);
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    srcScale >>= 3;
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t src32 = SkExpand_rgb_16(src);
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t dst32 = SkExpand_rgb_16(dst);
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                int srcScale, int count) {
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(count > 0);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)srcScale <= 256);
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    srcScale >>= 3;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    do {
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t src32 = SkExpand_rgb_16(*src++);
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        uint32_t dst32 = SkExpand_rgb_16(*dst);
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } while (--count > 0);
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) {
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK);
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK);
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK);
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return a + b;
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkRGB16Add(a, b)  ((a) + (b))
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_A32_BITS     8
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R32_BITS     8
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G32_BITS     8
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B32_BITS     8
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_A32_MASK     ((1 << SK_A32_BITS) - 1)
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R32_MASK     ((1 << SK_R32_BITS) - 1)
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G32_MASK     ((1 << SK_G32_BITS) - 1)
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B32_MASK     ((1 << SK_B32_BITS) - 1)
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedA32(packed)      ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedR32(packed)      ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedG32(packed)      ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedB32(packed)      ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkA32Assert(a)  SkASSERT((unsigned)(a) <= SK_A32_MASK)
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkR32Assert(r)  SkASSERT((unsigned)(r) <= SK_R32_MASK)
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkG32Assert(g)  SkASSERT((unsigned)(g) <= SK_G32_MASK)
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkB32Assert(b)  SkASSERT((unsigned)(b) <= SK_B32_MASK)
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static inline void SkPMColorAssert(SkPMColor c) {
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unsigned a = SkGetPackedA32(c);
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unsigned r = SkGetPackedR32(c);
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unsigned g = SkGetPackedG32(c);
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unsigned b = SkGetPackedB32(c);
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkA32Assert(a);
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(r <= a);
22180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(g <= a);
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(b <= a);
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkPMColorAssert(c)
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Pack the components into a SkPMColor, checking (in the debug version) that
23080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  the components are 0..255, and are already premultiplied (i.e. alpha >= color)
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkA32Assert(a);
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(r <= a);
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(g <= a);
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(b <= a);
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru           (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
24080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
24280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Abstract 4-byte interpolation, implemented on top of SkPMColor
24480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * utility functions. Third parameter controls blending of the first two:
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *   (src, dst, 0) returns dst
24680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *   (src, dst, 0xFF) returns src
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *   srcWeight is [0..256], unlike SkFourByteInterp which takes [0..255]
24880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
24980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkFourByteInterp256(SkPMColor src, SkPMColor dst,
25080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         unsigned scale) {
25180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
25280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
25380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
25480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
25580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackARGB32(a, r, g, b);
25780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
25880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
25980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
26080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Abstract 4-byte interpolation, implemented on top of SkPMColor
26180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * utility functions. Third parameter controls blending of the first two:
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *   (src, dst, 0) returns dst
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *   (src, dst, 0xFF) returns src
26480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
26580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst,
26680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         U8CPU srcWeight) {
26780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned scale = SkAlpha255To256(srcWeight);
26880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkFourByteInterp256(src, dst, scale);
26980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
27080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
27180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
27280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * 32b optimized version; currently appears to be 10% faster even on 64b
27380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * architectures than an equivalent 64b version and 30% faster than
27480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * SkFourByteInterp(). Third parameter controls blending of the first two:
27580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *   (src, dst, 0) returns dst
2767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger *   (src, dst, 256) returns src
2777839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger * ** Does not match the results of SkFourByteInterp256() because we use
27880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * a more accurate scale computation!
27980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * TODO: migrate Skia function to using an accurate 255->266 alpha
28080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * conversion.
28180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
2827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic inline SkPMColor SkFastFourByteInterp256(SkPMColor src,
2837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                SkPMColor dst,
2847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                                unsigned scale) {
2857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(scale <= 256);
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Reorders ARGB to AG-RB in order to reduce the number of operations.
28880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const uint32_t mask = 0xFF00FF;
28980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t src_rb = src & mask;
29080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t src_ag = (src >> 8) & mask;
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t dst_rb = dst & mask;
29280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t dst_ag = (dst >> 8) & mask;
29380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
29580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
29680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
29780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (ret_ag & ~mask) | ((ret_rb & ~mask) >> 8);
29880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
29980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3007839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerstatic inline SkPMColor SkFastFourByteInterp(SkPMColor src,
3017839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             SkPMColor dst,
3027839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                                             U8CPU srcWeight) {
3037839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkASSERT(srcWeight <= 255);
3047839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // scale = srcWeight + (srcWeight >> 7) is more accurate than
3057839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // scale = srcWeight + 1, but 7% slower
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7));
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
30980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
31080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  Same as SkPackARGB32, but this version guarantees to not check that the
31180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *  values are premultiplied in the debug version.
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
31480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru           (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
31680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
31780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
31880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline
31980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPMColor SkPremultiplyARGBInline(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
32080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkA32Assert(a);
32180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkA32Assert(r);
32280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkA32Assert(g);
32380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkA32Assert(b);
32480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
32580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (a != 255) {
32680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        r = SkMulDiv255Round(r, a);
32780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        g = SkMulDiv255Round(g, a);
32880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        b = SkMulDiv255Round(b, a);
32980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
33080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackARGB32(a, r, g, b);
33180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
33280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSK_API extern const uint32_t gMask_00FF00FF;
33480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
33680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t mask = gMask_00FF00FF;
33780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru//    uint32_t mask = 0xFF00FF;
33880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
33980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t rb = ((c & mask) * scale) >> 8;
34080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t ag = ((c >> 8) & mask) * scale;
34180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (rb & mask) | (ag & ~mask);
34280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
34580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
34680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
34780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
34880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
34980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)aa <= 255);
35080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned src_scale = SkAlpha255To256(aa);
35280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
35380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
35580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
35680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
35780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////////////////
35880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Convert a 32bit pixel to a 16bit pixel (no dither)
35980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkR32ToR16_MACRO(r)   ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
36180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkG32ToG16_MACRO(g)   ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
36280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkB32ToB16_MACRO(b)   ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
36380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
36480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
36580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static inline unsigned SkR32ToR16(unsigned r) {
36680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkR32Assert(r);
36780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkR32ToR16_MACRO(r);
36880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
36980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static inline unsigned SkG32ToG16(unsigned g) {
37080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkG32Assert(g);
37180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkG32ToG16_MACRO(g);
37280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
37380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static inline unsigned SkB32ToB16(unsigned b) {
37480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkB32Assert(b);
37580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkB32ToB16_MACRO(b);
37680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
37780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
37880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkR32ToR16(r)   SkR32ToR16_MACRO(r)
37980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkG32ToG16(g)   SkG32ToG16_MACRO(g)
38080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkB32ToB16(b)   SkB32ToB16_MACRO(b)
38180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
38280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked32ToR16(c)  (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
38480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked32ToG16(c)  (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
38580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked32ToB16(c)  (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
38680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
38780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkPixel32ToPixel16(SkPMColor c) {
38880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT;
38980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT;
39080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT;
39180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return r | g | b;
39280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
39480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) {
39580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return  (SkR32ToR16(r) << SK_R16_SHIFT) |
39680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (SkG32ToG16(g) << SK_G16_SHIFT) |
39780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (SkB32ToB16(b) << SK_B16_SHIFT);
39880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
39980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPixel32ToPixel16_ToU16(src)   SkToU16(SkPixel32ToPixel16(src))
40180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////////////////
40380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Fast dither from 32->16
40480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkShouldDitherXY(x, y)  (((x) ^ (y)) & 1)
40680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
40780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) {
40880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS);
40980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS);
41080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS);
41180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackRGB16(r, g, b);
41380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
41480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c) {
41680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c));
41780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
41880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
41980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits)
42080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    It is now suitable for combining with a scaled expanded_rgb_16 color
42180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    as in SkSrcOver32To16().
42280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    We must do this 565 high-bit replication, in order for the subsequent add
42380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    to saturate properly (and not overflow). If we take the 8 bits as is, it is
42480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    possible to overflow.
42580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
42680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint32_t SkPMColorToExpanded16x5(SkPMColor c) {
42780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sr = SkPacked32ToR16(c);
42880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sg = SkPacked32ToG16(c);
42980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sb = SkPacked32ToB16(c);
43080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
43180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sr = (sr << 5) | sr;
43280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sg = (sg << 5) | (sg >> 1);
43380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sb = (sb << 5) | sb;
43480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (sr << 11) | (sg << 21) | (sb << 0);
43580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
43680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
43780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  SrcOver the 32bit src color with the 16bit dst, returning a 16bit value
43880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (with dirt in the high 16bits, so caller beware).
43980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
44080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) {
44180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sr = SkGetPackedR32(src);
44280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sg = SkGetPackedG32(src);
44380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sb = SkGetPackedB32(src);
44480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
44580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dr = SkGetPackedR16(dst);
44680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dg = SkGetPackedG16(dst);
44780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned db = SkGetPackedB16(dst);
44880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
44980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned isa = 255 - SkGetPackedA32(src);
45080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS);
45280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS);
45380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS);
45480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackRGB16(dr, dg, db);
45680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
45780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
45880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////////////////
45980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Convert a 16bit pixel to a 32bit pixel
46080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkR16ToR32(unsigned r) {
46280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
46380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
46480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkG16ToG32(unsigned g) {
46680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
46780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
46880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
46980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkB16ToB32(unsigned b) {
47080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
47180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
47280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked16ToR32(c)      SkR16ToR32(SkGetPackedR16(c))
47480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked16ToG32(c)      SkG16ToG32(SkGetPackedG16(c))
47580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked16ToB32(c)      SkB16ToB32(SkGetPackedB16(c))
47680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
47780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkPixel16ToPixel32(U16CPU src) {
47880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(src == SkToU16(src));
47980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned    r = SkPacked16ToR32(src);
48180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned    g = SkPacked16ToG32(src);
48280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned    b = SkPacked16ToB32(src);
48380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
48580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
48680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
48780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackARGB32(0xFF, r, g, b);
48980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
49080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
49180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor
49280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkColor SkPixel16ToColor(U16CPU src) {
49380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(src == SkToU16(src));
49480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
49580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned    r = SkPacked16ToR32(src);
49680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned    g = SkPacked16ToG32(src);
49780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned    b = SkPacked16ToB32(src);
49880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
49980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
50080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
50180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
50280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkColorSetRGB(r, g, b);
50480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
50580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
50780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
50880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef uint16_t SkPMColor16;
50980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
51080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// Put in OpenGL order (r g b a)
51180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_A4444_SHIFT    0
51280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_R4444_SHIFT    12
51380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_G4444_SHIFT    8
51480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SK_B4444_SHIFT    4
51580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
51680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkA32To4444(a)  ((unsigned)(a) >> 4)
51780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkR32To4444(r)  ((unsigned)(r) >> 4)
51880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkG32To4444(g)  ((unsigned)(g) >> 4)
51980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkB32To4444(b)  ((unsigned)(b) >> 4)
52080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
52180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U8CPU SkReplicateNibble(unsigned nib) {
52280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(nib <= 0xF);
52380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (nib << 4) | nib;
52480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
52580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
52680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkA4444ToA32(a)     SkReplicateNibble(a)
52780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkR4444ToR32(r)     SkReplicateNibble(r)
52880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkG4444ToG32(g)     SkReplicateNibble(g)
52980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkB4444ToB32(b)     SkReplicateNibble(b)
53080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
53180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedA4444(c)     (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF)
53280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedR4444(c)     (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF)
53380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedG4444(c)     (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF)
53480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkGetPackedB4444(c)     (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF)
53580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
53680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked4444ToA32(c)    SkReplicateNibble(SkGetPackedA4444(c))
53780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked4444ToR32(c)    SkReplicateNibble(SkGetPackedR4444(c))
53880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked4444ToG32(c)    SkReplicateNibble(SkGetPackedG4444(c))
53980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPacked4444ToB32(c)    SkReplicateNibble(SkGetPackedB4444(c))
54080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
54180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
54280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void SkPMColor16Assert(U16CPU c) {
54380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned a = SkGetPackedA4444(c);
54480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned r = SkGetPackedR4444(c);
54580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned g = SkGetPackedG4444(c);
54680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned b = SkGetPackedB4444(c);
54780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
54880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(a <= 0xF);
54980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(r <= a);
55080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(g <= a);
55180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(b <= a);
55280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
55380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
55480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SkPMColor16Assert(c)
55580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
55680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
55780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkAlpha15To16(unsigned a) {
55880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(a <= 0xF);
55980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return a + (a >> 3);
56080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
56180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
56280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
56380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    static inline int SkAlphaMul4(int value, int scale) {
56480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT((unsigned)scale <= 0x10);
56580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return value * scale >> 4;
56680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
56780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
56880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    #define SkAlphaMul4(value, scale)   ((value) * (scale) >> 4)
56980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
57080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
57180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkR4444ToR565(unsigned r) {
57280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(r <= 0xF);
57380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS));
57480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
57580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
57680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkG4444ToG565(unsigned g) {
57780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(g <= 0xF);
57880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS));
57980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
58080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
58180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline unsigned SkB4444ToB565(unsigned b) {
58280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(b <= 0xF);
58380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS));
58480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
58580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
58680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
58780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                         unsigned g, unsigned b) {
58880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(a <= 0xF);
58980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(r <= a);
59080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(g <= a);
59180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(b <= a);
59280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
59380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) |
59480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                         (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
59580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
59680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
59780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruextern const uint16_t gMask_0F0F;
59880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
59980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) {
60080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(scale <= 16);
60180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
60280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const unsigned mask = 0xF0F;    //gMask_0F0F;
60380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
60480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
60580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned rb = ((c & mask) * scale) >> 4;
60680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned ag = ((c >> 4) & mask) * scale;
60780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (rb & mask) | (ag & ~mask);
60880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
60980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    c = (c & mask) | ((c & (mask << 4)) << 12);
61080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    c = c * scale >> 4;
61180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (c & mask) | ((c >> 12) & (mask << 4));
61280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
61380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
61480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
61580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at
61680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    once by a value up to 16. Used in conjunction with SkCompact_4444.
61780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
61880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint32_t SkExpand_4444(U16CPU c) {
61980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(c == (uint16_t)c);
62080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
62180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const unsigned mask = 0xF0F;    //gMask_0F0F;
62280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (c & mask) | ((c & ~mask) << 12);
62380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
62480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
62580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16.
62680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    NOTE: this explicitly does not clean the top 16 bits (which may be garbage).
62780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    It does this for speed, since if it is being written directly to 16bits of
62880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    memory, the top 16bits will be ignored. Casting the result to uint16_t here
62980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    would add 2 more instructions, slow us down. It is up to the caller to
63080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    perform the cast if needed.
63180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
63280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline U16CPU SkCompact_4444(uint32_t c) {
63380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const unsigned mask = 0xF0F;    //gMask_0F0F;
63480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return (c & mask) | ((c >> 12) & ~mask);
63580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
63680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
63780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) {
63880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sa = SkGetPackedA4444(s);
63980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
64080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sg = SkG4444ToG565(SkGetPackedG4444(s));
64180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned sb = SkB4444ToB565(SkGetPackedB4444(s));
64280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // To avoid overflow, we have to clear the low bit of the synthetic sg
64480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // if the src alpha is <= 7.
64580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // to see why, try blending 0x4444 on top of 565-white and watch green
64680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // overflow (sum == 64)
64780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    sg &= ~(~(sa >> 3) & 1);
64880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned scale = SkAlpha15To16(15 - sa);
65080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale);
65180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale);
65280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale);
65380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
65480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
65580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (sg + dg > 63) {
65680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg);
65780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
65880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
65980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackRGB16(sr + dr, sg + dg, sb + db);
66080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
66180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
66280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) {
66380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)scale16 <= 16);
66480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
66580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
66680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
66780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
66880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) {
66980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)scale16 <= 16);
67080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
67180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t src32 = SkExpand_4444(src) * scale16;
67280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // the scaled srcAlpha is the bottom byte
67380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifdef SK_DEBUG
67480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    {
67580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        unsigned srcA = SkGetPackedA4444(src) * scale16;
67680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkASSERT(srcA == (src32 & 0xFF));
67780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
67880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
67980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
68080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t dst32 = SkExpand_4444(dst) * dstScale;
68180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkCompact_4444((src32 + dst32) >> 4);
68280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
68380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
68480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkPixel4444ToPixel32(U16CPU c) {
68580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
68680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                 (SkGetPackedR4444(c) << SK_R32_SHIFT) |
68780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                 (SkGetPackedG4444(c) << SK_G32_SHIFT) |
68880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                 (SkGetPackedB4444(c) << SK_B32_SHIFT);
68980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return d | (d << 4);
69080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
69180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
69280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) {
69380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return  (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) |
69480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) |
69580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) |
69680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT);
69780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
69880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
69980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// cheap 2x2 dither
70080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r,
70180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                               U8CPU g, U8CPU b) {
70280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // to ensure that we stay a legal premultiplied color, we take the max()
70380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // of the truncated and dithered alpha values. If we didn't, cases like
70480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // SkDitherARGB32To4444(0x31, 0x2E, ...) would generate SkPackARGB4444(2, 3, ...)
70580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // which is not legal premultiplied, since a < color
70680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
70780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    a = SkMax32(a >> 4, dithered_a);
70880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // these we just dither in place
70980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4;
71080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4;
71180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4;
71280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
71380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackARGB4444(a, r, g, b);
71480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
71580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
71680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c) {
71780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c),
71880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                SkGetPackedG32(c), SkGetPackedB32(c));
71980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
72080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
72180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  Assumes 16bit is in standard RGBA order.
72280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Transforms a normal ARGB_8888 into the same byte order as
72380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    expanded ARGB_4444, but keeps each component 8bits
72480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
72580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint32_t SkExpand_8888(SkPMColor c) {
72680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return  (((c >> SK_R32_SHIFT) & 0xFF) << 24) |
72780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> SK_G32_SHIFT) & 0xFF) <<  8) |
72880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> SK_B32_SHIFT) & 0xFF) << 16) |
72980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> SK_A32_SHIFT) & 0xFF) <<  0);
73080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
73180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
73280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  Undo the operation of SkExpand_8888, turning the argument back into
73380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    a SkPMColor.
73480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
73580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkCompact_8888(uint32_t c) {
73680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return  (((c >> 24) & 0xFF) << SK_R32_SHIFT) |
73780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >>  8) & 0xFF) << SK_G32_SHIFT) |
73880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> 16) & 0xFF) << SK_B32_SHIFT) |
73980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >>  0) & 0xFF) << SK_A32_SHIFT);
74080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
74180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
74280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*  Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format,
74380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    but this routine just keeps the high 4bits of each component in the low
74480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    4bits of the result (just like a newly expanded PMColor16).
74580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru*/
74680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline uint32_t SkExpand32_4444(SkPMColor c) {
74780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return  (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) |
74880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> (SK_G32_SHIFT + 4)) & 0xF) <<  8) |
74980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
75080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            (((c >> (SK_A32_SHIFT + 4)) & 0xF) <<  0);
75180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
75280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
75380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// takes two values and alternamtes them as part of a memset16
75480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru// used for cheap 2x2 dithering when the colors are opaque
75580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
75680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
75780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
75880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
75980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int SkUpscale31To32(int value) {
76080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)value <= 31);
76180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return value + (value >> 4);
76280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
76380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
76480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline int SkBlend32(int src, int dst, int scale) {
76580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)src <= 0xFF);
76680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)dst <= 0xFF);
76780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT((unsigned)scale <= 32);
76880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return dst + ((src - dst) * scale >> 5);
76980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
77080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
77180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkBlendLCD16(int srcA, int srcR, int srcG, int srcB,
77280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                     SkPMColor dst, uint16_t mask) {
77380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mask == 0) {
77480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return dst;
77580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
77680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
77780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /*  We want all of these in 5bits, hence the shifts in case one of them
77880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  (green) is 6bits.
77980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
78080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
78180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
78280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
78380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
78480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Now upscale them to 0..32, so we can use blend32
78580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskR = SkUpscale31To32(maskR);
78680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskG = SkUpscale31To32(maskG);
78780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskB = SkUpscale31To32(maskB);
78880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
78980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // srcA has been upscaled to 256 before passed into this function
79080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskR = maskR * srcA >> 8;
79180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskG = maskG * srcA >> 8;
79280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskB = maskB * srcA >> 8;
79380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
79480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int dstR = SkGetPackedR32(dst);
79580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int dstG = SkGetPackedG32(dst);
79680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int dstB = SkGetPackedB32(dst);
79780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
79880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // LCD blitting is only supported if the dst is known/required
79980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // to be opaque
80080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackARGB32(0xFF,
80180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkBlend32(srcR, dstR, maskR),
80280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkBlend32(srcG, dstG, maskG),
80380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkBlend32(srcB, dstB, maskB));
80480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
80580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
80680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline SkPMColor SkBlendLCD16Opaque(int srcR, int srcG, int srcB,
80780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                           SkPMColor dst, uint16_t mask,
80880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                           SkPMColor opaqueDst) {
80980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (mask == 0) {
81080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return dst;
81180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
81280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
81380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (0xFFFF == mask) {
81480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return opaqueDst;
81580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
81680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
81780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /*  We want all of these in 5bits, hence the shifts in case one of them
81880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *  (green) is 6bits.
81980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
82080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
82180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
82280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
82380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
82480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // Now upscale them to 0..32, so we can use blend32
82580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskR = SkUpscale31To32(maskR);
82680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskG = SkUpscale31To32(maskG);
82780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    maskB = SkUpscale31To32(maskB);
82880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
82980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int dstR = SkGetPackedR32(dst);
83080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int dstG = SkGetPackedG32(dst);
83180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int dstB = SkGetPackedB32(dst);
83280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
83380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // LCD blitting is only supported if the dst is known/required
83480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // to be opaque
83580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkPackARGB32(0xFF,
83680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkBlend32(srcR, dstR, maskR),
83780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkBlend32(srcG, dstG, maskG),
83880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                        SkBlend32(srcB, dstB, maskB));
83980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
84080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
84180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void SkBlitLCD16Row(SkPMColor dst[], const uint16_t src[],
84280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                  SkColor color, int width, SkPMColor) {
84380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcA = SkColorGetA(color);
84480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcR = SkColorGetR(color);
84580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcG = SkColorGetG(color);
84680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcB = SkColorGetB(color);
84780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
84880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    srcA = SkAlpha255To256(srcA);
84980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
85080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < width; i++) {
85180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], src[i]);
85280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
85380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
85480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
85580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic inline void SkBlitLCD16OpaqueRow(SkPMColor dst[], const uint16_t src[],
85680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        SkColor color, int width,
85780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                        SkPMColor opaqueDst) {
85880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcR = SkColorGetR(color);
85980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcG = SkColorGetG(color);
86080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int srcB = SkColorGetB(color);
86180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
86280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < width; i++) {
86380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], src[i],
86480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                                    opaqueDst);
86580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
86680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
86780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
86880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
869