Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef SkColorPriv_DEFINED
     18 #define SkColorPriv_DEFINED
     19 
     20 // turn this own for extra debug checking when blending onto 565
     21 #ifdef SK_DEBUG
     22     #define CHECK_FOR_565_OVERFLOW
     23 #endif
     24 
     25 #include "SkColor.h"
     26 #include "SkMath.h"
     27 
     28 /** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a
     29     byte into a scale value, so that we can say scale * value >> 8 instead of
     30     alpha * value / 255.
     31 
     32     In debugging, asserts that alpha is 0..255
     33 */
     34 static inline unsigned SkAlpha255To256(U8CPU alpha) {
     35     SkASSERT(SkToU8(alpha) == alpha);
     36     // this one assues that blending on top of an opaque dst keeps it that way
     37     // even though it is less accurate than a+(a>>7) for non-opaque dsts
     38     return alpha + 1;
     39 }
     40 
     41 /** Multiplify value by 0..256, and shift the result down 8
     42     (i.e. return (value * alpha256) >> 8)
     43  */
     44 #define SkAlphaMul(value, alpha256)     (SkMulS16(value, alpha256) >> 8)
     45 
     46 //  The caller may want negative values, so keep all params signed (int)
     47 //  so we don't accidentally slip into unsigned math and lose the sign
     48 //  extension when we shift (in SkAlphaMul)
     49 static inline int SkAlphaBlend(int src, int dst, int scale256) {
     50     SkASSERT((unsigned)scale256 <= 256);
     51     return dst + SkAlphaMul(src - dst, scale256);
     52 }
     53 
     54 #define SK_R16_BITS     5
     55 #define SK_G16_BITS     6
     56 #define SK_B16_BITS     5
     57 
     58 #define SK_R16_SHIFT    (SK_B16_BITS + SK_G16_BITS)
     59 #define SK_G16_SHIFT    (SK_B16_BITS)
     60 #define SK_B16_SHIFT    0
     61 
     62 #define SK_R16_MASK     ((1 << SK_R16_BITS) - 1)
     63 #define SK_G16_MASK     ((1 << SK_G16_BITS) - 1)
     64 #define SK_B16_MASK     ((1 << SK_B16_BITS) - 1)
     65 
     66 #define SkGetPackedR16(color)   (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
     67 #define SkGetPackedG16(color)   (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
     68 #define SkGetPackedB16(color)   (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
     69 
     70 #define SkR16Assert(r)  SkASSERT((unsigned)(r) <= SK_R16_MASK)
     71 #define SkG16Assert(g)  SkASSERT((unsigned)(g) <= SK_G16_MASK)
     72 #define SkB16Assert(b)  SkASSERT((unsigned)(b) <= SK_B16_MASK)
     73 
     74 static inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) {
     75     SkASSERT(r <= SK_R16_MASK);
     76     SkASSERT(g <= SK_G16_MASK);
     77     SkASSERT(b <= SK_B16_MASK);
     78 
     79     return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
     80 }
     81 
     82 #define SK_R16_MASK_IN_PLACE        (SK_R16_MASK << SK_R16_SHIFT)
     83 #define SK_G16_MASK_IN_PLACE        (SK_G16_MASK << SK_G16_SHIFT)
     84 #define SK_B16_MASK_IN_PLACE        (SK_B16_MASK << SK_B16_SHIFT)
     85 
     86 /** Expand the 16bit color into a 32bit value that can be scaled all at once
     87     by a value up to 32. Used in conjunction with SkCompact_rgb_16.
     88 */
     89 static inline uint32_t SkExpand_rgb_16(U16CPU c) {
     90     SkASSERT(c == (uint16_t)c);
     91 
     92     return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
     93 }
     94 
     95 /** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit
     96     color value. The computation yields only 16bits of valid data, but we claim
     97     to return 32bits, so that the compiler won't generate extra instructions to
     98     "clean" the top 16bits. However, the top 16 can contain garbage, so it is
     99     up to the caller to safely ignore them.
    100 */
    101 static inline U16CPU SkCompact_rgb_16(uint32_t c) {
    102     return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
    103 }
    104 
    105 /** Scale the 16bit color value by the 0..256 scale parameter.
    106     The computation yields only 16bits of valid data, but we claim
    107     to return 32bits, so that the compiler won't generate extra instructions to
    108     "clean" the top 16bits.
    109 */
    110 static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) {
    111     return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5);
    112 }
    113 
    114 // this helper explicitly returns a clean 16bit value (but slower)
    115 #define SkAlphaMulRGB16_ToU16(c, s)  (uint16_t)SkAlphaMulRGB16(c, s)
    116 
    117 /** Blend src and dst 16bit colors by the 0..256 scale parameter.
    118     The computation yields only 16bits of valid data, but we claim
    119     to return 32bits, so that the compiler won't generate extra instructions to
    120     "clean" the top 16bits.
    121 */
    122 static inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) {
    123     SkASSERT((unsigned)srcScale <= 256);
    124 
    125     srcScale >>= 3;
    126 
    127     uint32_t src32 = SkExpand_rgb_16(src);
    128     uint32_t dst32 = SkExpand_rgb_16(dst);
    129     return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
    130 }
    131 
    132 static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
    133                                 int srcScale, int count) {
    134     SkASSERT(count > 0);
    135     SkASSERT((unsigned)srcScale <= 256);
    136 
    137     srcScale >>= 3;
    138 
    139     do {
    140         uint32_t src32 = SkExpand_rgb_16(*src++);
    141         uint32_t dst32 = SkExpand_rgb_16(*dst);
    142         *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
    143     } while (--count > 0);
    144 }
    145 
    146 #ifdef SK_DEBUG
    147     static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) {
    148         SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK);
    149         SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK);
    150         SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK);
    151 
    152         return a + b;
    153     }
    154 #else
    155     #define SkRGB16Add(a, b)  ((a) + (b))
    156 #endif
    157 
    158 /////////////////////////////////////////////////////////////////////////////////////////////
    159 
    160 #define SK_A32_BITS     8
    161 #define SK_R32_BITS     8
    162 #define SK_G32_BITS     8
    163 #define SK_B32_BITS     8
    164 
    165 /* we check to see if the SHIFT value has already been defined (SkUserConfig.h)
    166     if not, we define it ourself to some default values. We default to OpenGL
    167     order (in memory: r,g,b,a)
    168 */
    169 #ifndef SK_A32_SHIFT
    170     #ifdef SK_CPU_BENDIAN
    171         #define SK_R32_SHIFT    24
    172         #define SK_G32_SHIFT    16
    173         #define SK_B32_SHIFT    8
    174         #define SK_A32_SHIFT    0
    175     #else
    176         #define SK_R32_SHIFT    0
    177         #define SK_G32_SHIFT    8
    178         #define SK_B32_SHIFT    16
    179         #define SK_A32_SHIFT    24
    180     #endif
    181 #endif
    182 
    183 #define SK_A32_MASK     ((1 << SK_A32_BITS) - 1)
    184 #define SK_R32_MASK     ((1 << SK_R32_BITS) - 1)
    185 #define SK_G32_MASK     ((1 << SK_G32_BITS) - 1)
    186 #define SK_B32_MASK     ((1 << SK_B32_BITS) - 1)
    187 
    188 #define SkGetPackedA32(packed)      ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
    189 #define SkGetPackedR32(packed)      ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
    190 #define SkGetPackedG32(packed)      ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
    191 #define SkGetPackedB32(packed)      ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
    192 
    193 #define SkA32Assert(a)  SkASSERT((unsigned)(a) <= SK_A32_MASK)
    194 #define SkR32Assert(r)  SkASSERT((unsigned)(r) <= SK_R32_MASK)
    195 #define SkG32Assert(g)  SkASSERT((unsigned)(g) <= SK_G32_MASK)
    196 #define SkB32Assert(b)  SkASSERT((unsigned)(b) <= SK_B32_MASK)
    197 
    198 #ifdef SK_DEBUG
    199     static inline void SkPMColorAssert(SkPMColor c) {
    200         unsigned a = SkGetPackedA32(c);
    201         unsigned r = SkGetPackedR32(c);
    202         unsigned g = SkGetPackedG32(c);
    203         unsigned b = SkGetPackedB32(c);
    204 
    205         SkA32Assert(a);
    206         SkASSERT(r <= a);
    207         SkASSERT(g <= a);
    208         SkASSERT(b <= a);
    209     }
    210 #else
    211     #define SkPMColorAssert(c)
    212 #endif
    213 
    214 static inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
    215     SkA32Assert(a);
    216     SkASSERT(r <= a);
    217     SkASSERT(g <= a);
    218     SkASSERT(b <= a);
    219 
    220     return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
    221            (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
    222 }
    223 
    224 extern const uint32_t gMask_00FF00FF;
    225 
    226 static inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
    227     uint32_t mask = gMask_00FF00FF;
    228 //    uint32_t mask = 0xFF00FF;
    229 
    230     uint32_t rb = ((c & mask) * scale) >> 8;
    231     uint32_t ag = ((c >> 8) & mask) * scale;
    232     return (rb & mask) | (ag & ~mask);
    233 }
    234 
    235 static inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
    236     return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
    237 }
    238 
    239 static inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
    240     SkASSERT((unsigned)aa <= 255);
    241 
    242     unsigned src_scale = SkAlpha255To256(aa);
    243     unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
    244 
    245     return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
    246 }
    247 
    248 ////////////////////////////////////////////////////////////////////////////////////////////
    249 // Convert a 32bit pixel to a 16bit pixel (no dither)
    250 
    251 #define SkR32ToR16_MACRO(r)   ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
    252 #define SkG32ToG16_MACRO(g)   ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
    253 #define SkB32ToB16_MACRO(b)   ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
    254 
    255 #ifdef SK_DEBUG
    256     static inline unsigned SkR32ToR16(unsigned r) {
    257         SkR32Assert(r);
    258         return SkR32ToR16_MACRO(r);
    259     }
    260     static inline unsigned SkG32ToG16(unsigned g) {
    261         SkG32Assert(g);
    262         return SkG32ToG16_MACRO(g);
    263     }
    264     static inline unsigned SkB32ToB16(unsigned b) {
    265         SkB32Assert(b);
    266         return SkB32ToB16_MACRO(b);
    267     }
    268 #else
    269     #define SkR32ToR16(r)   SkR32ToR16_MACRO(r)
    270     #define SkG32ToG16(g)   SkG32ToG16_MACRO(g)
    271     #define SkB32ToB16(b)   SkB32ToB16_MACRO(b)
    272 #endif
    273 
    274 #define SkPacked32ToR16(c)  (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
    275 #define SkPacked32ToG16(c)  (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
    276 #define SkPacked32ToB16(c)  (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
    277 
    278 static inline U16CPU SkPixel32ToPixel16(SkPMColor c) {
    279     unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT;
    280     unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT;
    281     unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT;
    282     return r | g | b;
    283 }
    284 
    285 static inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) {
    286     return  (SkR32ToR16(r) << SK_R16_SHIFT) |
    287             (SkG32ToG16(g) << SK_G16_SHIFT) |
    288             (SkB32ToB16(b) << SK_B16_SHIFT);
    289 }
    290 
    291 #define SkPixel32ToPixel16_ToU16(src)   SkToU16(SkPixel32ToPixel16(src))
    292 
    293 /////////////////////////////////////////////////////////////////////////////////////////
    294 // Fast dither from 32->16
    295 
    296 #define SkShouldDitherXY(x, y)  (((x) ^ (y)) & 1)
    297 
    298 static inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) {
    299     r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS);
    300     g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS);
    301     b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS);
    302 
    303     return SkPackRGB16(r, g, b);
    304 }
    305 
    306 static inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c) {
    307     return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c));
    308 }
    309 
    310 /*  Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits)
    311     It is now suitable for combining with a scaled expanded_rgb_16 color
    312     as in SkSrcOver32To16().
    313     We must do this 565 high-bit replication, in order for the subsequent add
    314     to saturate properly (and not overflow). If we take the 8 bits as is, it is
    315     possible to overflow.
    316 */
    317 static inline uint32_t SkPMColorToExpanded16x5(SkPMColor c) {
    318     unsigned sr = SkPacked32ToR16(c);
    319     unsigned sg = SkPacked32ToG16(c);
    320     unsigned sb = SkPacked32ToB16(c);
    321 
    322     sr = (sr << 5) | sr;
    323     sg = (sg << 5) | (sg >> 1);
    324     sb = (sb << 5) | sb;
    325     return (sr << 11) | (sg << 21) | (sb << 0);
    326 }
    327 
    328 /*  SrcOver the 32bit src color with the 16bit dst, returning a 16bit value
    329     (with dirt in the high 16bits, so caller beware).
    330 */
    331 static inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) {
    332     unsigned sr = SkGetPackedR32(src);
    333     unsigned sg = SkGetPackedG32(src);
    334     unsigned sb = SkGetPackedB32(src);
    335 
    336     unsigned dr = SkGetPackedR16(dst);
    337     unsigned dg = SkGetPackedG16(dst);
    338     unsigned db = SkGetPackedB16(dst);
    339 
    340     unsigned isa = 255 - SkGetPackedA32(src);
    341 
    342     dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS);
    343     dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS);
    344     db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS);
    345 
    346     return SkPackRGB16(dr, dg, db);
    347 }
    348 
    349 ////////////////////////////////////////////////////////////////////////////////////////////
    350 // Convert a 16bit pixel to a 32bit pixel
    351 
    352 static inline unsigned SkR16ToR32(unsigned r) {
    353     return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
    354 }
    355 
    356 static inline unsigned SkG16ToG32(unsigned g) {
    357     return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
    358 }
    359 
    360 static inline unsigned SkB16ToB32(unsigned b) {
    361     return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
    362 }
    363 
    364 #define SkPacked16ToR32(c)      SkR16ToR32(SkGetPackedR16(c))
    365 #define SkPacked16ToG32(c)      SkG16ToG32(SkGetPackedG16(c))
    366 #define SkPacked16ToB32(c)      SkB16ToB32(SkGetPackedB16(c))
    367 
    368 static inline SkPMColor SkPixel16ToPixel32(U16CPU src) {
    369     SkASSERT(src == SkToU16(src));
    370 
    371     unsigned    r = SkPacked16ToR32(src);
    372     unsigned    g = SkPacked16ToG32(src);
    373     unsigned    b = SkPacked16ToB32(src);
    374 
    375     SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
    376     SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
    377     SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
    378 
    379     return SkPackARGB32(0xFF, r, g, b);
    380 }
    381 
    382 // similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor
    383 static inline SkColor SkPixel16ToColor(U16CPU src) {
    384     SkASSERT(src == SkToU16(src));
    385 
    386     unsigned    r = SkPacked16ToR32(src);
    387     unsigned    g = SkPacked16ToG32(src);
    388     unsigned    b = SkPacked16ToB32(src);
    389 
    390     SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
    391     SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
    392     SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
    393 
    394     return SkColorSetRGB(r, g, b);
    395 }
    396 
    397 ///////////////////////////////////////////////////////////////////////////////
    398 
    399 typedef uint16_t SkPMColor16;
    400 
    401 // Put in OpenGL order (r g b a)
    402 #define SK_A4444_SHIFT    0
    403 #define SK_R4444_SHIFT    12
    404 #define SK_G4444_SHIFT    8
    405 #define SK_B4444_SHIFT    4
    406 
    407 #define SkA32To4444(a)  ((unsigned)(a) >> 4)
    408 #define SkR32To4444(r)  ((unsigned)(r) >> 4)
    409 #define SkG32To4444(g)  ((unsigned)(g) >> 4)
    410 #define SkB32To4444(b)  ((unsigned)(b) >> 4)
    411 
    412 static inline U8CPU SkReplicateNibble(unsigned nib) {
    413     SkASSERT(nib <= 0xF);
    414     return (nib << 4) | nib;
    415 }
    416 
    417 #define SkA4444ToA32(a)     SkReplicateNibble(a)
    418 #define SkR4444ToR32(r)     SkReplicateNibble(r)
    419 #define SkG4444ToG32(g)     SkReplicateNibble(g)
    420 #define SkB4444ToB32(b)     SkReplicateNibble(b)
    421 
    422 #define SkGetPackedA4444(c)     (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF)
    423 #define SkGetPackedR4444(c)     (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF)
    424 #define SkGetPackedG4444(c)     (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF)
    425 #define SkGetPackedB4444(c)     (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF)
    426 
    427 #define SkPacked4444ToA32(c)    SkReplicateNibble(SkGetPackedA4444(c))
    428 #define SkPacked4444ToR32(c)    SkReplicateNibble(SkGetPackedR4444(c))
    429 #define SkPacked4444ToG32(c)    SkReplicateNibble(SkGetPackedG4444(c))
    430 #define SkPacked4444ToB32(c)    SkReplicateNibble(SkGetPackedB4444(c))
    431 
    432 #ifdef SK_DEBUG
    433 static inline void SkPMColor16Assert(U16CPU c) {
    434     unsigned a = SkGetPackedA4444(c);
    435     unsigned r = SkGetPackedR4444(c);
    436     unsigned g = SkGetPackedG4444(c);
    437     unsigned b = SkGetPackedB4444(c);
    438 
    439     SkASSERT(a <= 0xF);
    440     SkASSERT(r <= a);
    441     SkASSERT(g <= a);
    442     SkASSERT(b <= a);
    443 }
    444 #else
    445 #define SkPMColor16Assert(c)
    446 #endif
    447 
    448 static inline unsigned SkAlpha15To16(unsigned a) {
    449     SkASSERT(a <= 0xF);
    450     return a + (a >> 3);
    451 }
    452 
    453 #ifdef SK_DEBUG
    454     static inline int SkAlphaMul4(int value, int scale) {
    455         SkASSERT((unsigned)scale <= 0x10);
    456         return value * scale >> 4;
    457     }
    458 #else
    459     #define SkAlphaMul4(value, scale)   ((value) * (scale) >> 4)
    460 #endif
    461 
    462 static inline unsigned SkR4444ToR565(unsigned r) {
    463     SkASSERT(r <= 0xF);
    464     return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS));
    465 }
    466 
    467 static inline unsigned SkG4444ToG565(unsigned g) {
    468     SkASSERT(g <= 0xF);
    469     return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS));
    470 }
    471 
    472 static inline unsigned SkB4444ToB565(unsigned b) {
    473     SkASSERT(b <= 0xF);
    474     return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS));
    475 }
    476 
    477 static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
    478                                          unsigned g, unsigned b) {
    479     SkASSERT(a <= 0xF);
    480     SkASSERT(r <= a);
    481     SkASSERT(g <= a);
    482     SkASSERT(b <= a);
    483 
    484     return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) |
    485                          (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
    486 }
    487 
    488 extern const uint16_t gMask_0F0F;
    489 
    490 static inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) {
    491     SkASSERT(scale <= 16);
    492 
    493     const unsigned mask = 0xF0F;    //gMask_0F0F;
    494 
    495 #if 0
    496     unsigned rb = ((c & mask) * scale) >> 4;
    497     unsigned ag = ((c >> 4) & mask) * scale;
    498     return (rb & mask) | (ag & ~mask);
    499 #else
    500     c = (c & mask) | ((c & (mask << 4)) << 12);
    501     c = c * scale >> 4;
    502     return (c & mask) | ((c >> 12) & (mask << 4));
    503 #endif
    504 }
    505 
    506 /** Expand the SkPMColor16 color into a 32bit value that can be scaled all at
    507     once by a value up to 16. Used in conjunction with SkCompact_4444.
    508 */
    509 static inline uint32_t SkExpand_4444(U16CPU c) {
    510     SkASSERT(c == (uint16_t)c);
    511 
    512     const unsigned mask = 0xF0F;    //gMask_0F0F;
    513     return (c & mask) | ((c & ~mask) << 12);
    514 }
    515 
    516 /** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16.
    517     NOTE: this explicitly does not clean the top 16 bits (which may be garbage).
    518     It does this for speed, since if it is being written directly to 16bits of
    519     memory, the top 16bits will be ignored. Casting the result to uint16_t here
    520     would add 2 more instructions, slow us down. It is up to the caller to
    521     perform the cast if needed.
    522 */
    523 static inline U16CPU SkCompact_4444(uint32_t c) {
    524     const unsigned mask = 0xF0F;    //gMask_0F0F;
    525     return (c & mask) | ((c >> 12) & ~mask);
    526 }
    527 
    528 static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) {
    529     unsigned sa = SkGetPackedA4444(s);
    530     unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
    531     unsigned sg = SkG4444ToG565(SkGetPackedG4444(s));
    532     unsigned sb = SkB4444ToB565(SkGetPackedB4444(s));
    533 
    534     // To avoid overflow, we have to clear the low bit of the synthetic sg
    535     // if the src alpha is <= 7.
    536     // to see why, try blending 0x4444 on top of 565-white and watch green
    537     // overflow (sum == 64)
    538     sg &= ~(~(sa >> 3) & 1);
    539 
    540     unsigned scale = SkAlpha15To16(15 - sa);
    541     unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale);
    542     unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale);
    543     unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale);
    544 
    545 #if 0
    546     if (sg + dg > 63) {
    547         SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg);
    548     }
    549 #endif
    550     return SkPackRGB16(sr + dr, sg + dg, sb + db);
    551 }
    552 
    553 static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) {
    554     SkASSERT((unsigned)scale16 <= 16);
    555 
    556     return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
    557 }
    558 
    559 static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) {
    560     SkASSERT((unsigned)scale16 <= 16);
    561 
    562     uint32_t src32 = SkExpand_4444(src) * scale16;
    563     // the scaled srcAlpha is the bottom byte
    564 #ifdef SK_DEBUG
    565     {
    566         unsigned srcA = SkGetPackedA4444(src) * scale16;
    567         SkASSERT(srcA == (src32 & 0xFF));
    568     }
    569 #endif
    570     unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
    571     uint32_t dst32 = SkExpand_4444(dst) * dstScale;
    572     return SkCompact_4444((src32 + dst32) >> 4);
    573 }
    574 
    575 static inline SkPMColor SkPixel4444ToPixel32(U16CPU c) {
    576     uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
    577                  (SkGetPackedR4444(c) << SK_R32_SHIFT) |
    578                  (SkGetPackedG4444(c) << SK_G32_SHIFT) |
    579                  (SkGetPackedB4444(c) << SK_B32_SHIFT);
    580     return d | (d << 4);
    581 }
    582 
    583 static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) {
    584     return  (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) |
    585     (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) |
    586     (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) |
    587     (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT);
    588 }
    589 
    590 // cheap 2x2 dither
    591 static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r,
    592                                                U8CPU g, U8CPU b) {
    593     // to ensure that we stay a legal premultiplied color, we take the max()
    594     // of the truncated and dithered alpha values. If we didn't, cases like
    595     // SkDitherARGB32To4444(0x31, 0x2E, ...) would generate SkPackARGB4444(2, 3, ...)
    596     // which is not legal premultiplied, since a < color
    597     unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
    598     a = SkMax32(a >> 4, dithered_a);
    599     // these we just dither in place
    600     r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4;
    601     g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4;
    602     b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4;
    603 
    604     return SkPackARGB4444(a, r, g, b);
    605 }
    606 
    607 static inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c) {
    608     return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c),
    609                                 SkGetPackedG32(c), SkGetPackedB32(c));
    610 }
    611 
    612 /*  Assumes 16bit is in standard RGBA order.
    613     Transforms a normal ARGB_8888 into the same byte order as
    614     expanded ARGB_4444, but keeps each component 8bits
    615 */
    616 static inline uint32_t SkExpand_8888(SkPMColor c) {
    617     return  (((c >> SK_R32_SHIFT) & 0xFF) << 24) |
    618             (((c >> SK_G32_SHIFT) & 0xFF) <<  8) |
    619             (((c >> SK_B32_SHIFT) & 0xFF) << 16) |
    620             (((c >> SK_A32_SHIFT) & 0xFF) <<  0);
    621 }
    622 
    623 /*  Undo the operation of SkExpand_8888, turning the argument back into
    624     a SkPMColor.
    625 */
    626 static inline SkPMColor SkCompact_8888(uint32_t c) {
    627     return  (((c >> 24) & 0xFF) << SK_R32_SHIFT) |
    628             (((c >>  8) & 0xFF) << SK_G32_SHIFT) |
    629             (((c >> 16) & 0xFF) << SK_B32_SHIFT) |
    630             (((c >>  0) & 0xFF) << SK_A32_SHIFT);
    631 }
    632 
    633 /*  Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format,
    634     but this routine just keeps the high 4bits of each component in the low
    635     4bits of the result (just like a newly expanded PMColor16).
    636 */
    637 static inline uint32_t SkExpand32_4444(SkPMColor c) {
    638     return  (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) |
    639             (((c >> (SK_G32_SHIFT + 4)) & 0xF) <<  8) |
    640             (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
    641             (((c >> (SK_A32_SHIFT + 4)) & 0xF) <<  0);
    642 }
    643 
    644 // takes two values and alternamtes them as part of a memset16
    645 // used for cheap 2x2 dithering when the colors are opaque
    646 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
    647 
    648 #endif
    649 
    650