SkColorPriv.h revision 7ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577
18a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 28a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Copyright (C) 2006 The Android Open Source Project 38a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 48a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Licensed under the Apache License, Version 2.0 (the "License"); 58a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * you may not use this file except in compliance with the License. 68a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * You may obtain a copy of the License at 78a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 88a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * http://www.apache.org/licenses/LICENSE-2.0 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * Unless required by applicable law or agreed to in writing, software 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * distributed under the License is distributed on an "AS IS" BASIS, 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * See the License for the specific language governing permissions and 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com * limitations under the License. 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkColorPriv_DEFINED 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkColorPriv_DEFINED 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// turn this own for extra debug checking when blending onto 565 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define CHECK_FOR_565_OVERFLOW 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkColor.h" 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkMath.h" 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Turn 0..255 into 0..256 by adding 1 at the half-way point. Used to turn a 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com byte into a scale value, so that we can say scale * value >> 8 instead of 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com alpha * value / 255. 31e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com In debugging, asserts that alpha is 0..255 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline unsigned SkAlpha255To256(U8CPU alpha) { 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkToU8(alpha) == alpha); 369781ca586618cc8ea055f54021e706824313d4f5reed@android.com // this one assues that blending on top of an opaque dst keeps it that way 379781ca586618cc8ea055f54021e706824313d4f5reed@android.com // even though it is less accurate than a+(a>>7) for non-opaque dsts 389781ca586618cc8ea055f54021e706824313d4f5reed@android.com return alpha + 1; 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Multiplify value by 0..256, and shift the result down 8 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (i.e. return (value * alpha256) >> 8) 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com */ 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8) 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// The caller may want negative values, so keep all params signed (int) 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// so we don't accidentally slip into unsigned math and lose the sign 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// extension when we shift (in SkAlphaMul) 4934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline int SkAlphaBlend(int src, int dst, int scale256) { 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)scale256 <= 256); 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return dst + SkAlphaMul(src - dst, scale256); 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R16_BITS 5 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G16_BITS 6 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B16_BITS 5 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS) 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G16_SHIFT (SK_B16_BITS) 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B16_SHIFT 0 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R16_MASK ((1 << SK_R16_BITS) - 1) 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G16_MASK ((1 << SK_G16_BITS) - 1) 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B16_MASK ((1 << SK_B16_BITS) - 1) 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK) 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK) 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK) 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK) 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK) 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK) 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) { 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(r <= SK_R16_MASK); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(g <= SK_G16_MASK); 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= SK_B16_MASK); 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT)); 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT) 838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT) 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT) 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Expand the 16bit color into a 32bit value that can be scaled all at once 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com by a value up to 32. Used in conjunction with SkCompact_rgb_16. 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline uint32_t SkExpand_rgb_16(U16CPU c) { 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(c == (uint16_t)c); 918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Compress an expanded value (from SkExpand_rgb_16) back down to a 16bit 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com color value. The computation yields only 16bits of valid data, but we claim 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to return 32bits, so that the compiler won't generate extra instructions to 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "clean" the top 16bits. However, the top 16 can contain garbage, so it is 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com up to the caller to safely ignore them. 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline U16CPU SkCompact_rgb_16(uint32_t c) { 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Scale the 16bit color value by the 0..256 scale parameter. 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The computation yields only 16bits of valid data, but we claim 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to return 32bits, so that the compiler won't generate extra instructions to 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "clean" the top 16bits. 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) { 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5); 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// this helper explicitly returns a clean 16bit value (but slower) 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s) 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Blend src and dst 16bit colors by the 0..256 scale parameter. 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com The computation yields only 16bits of valid data, but we claim 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to return 32bits, so that the compiler won't generate extra instructions to 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com "clean" the top 16bits. 1218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) { 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)srcScale <= 256); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcScale >>= 3; 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t src32 = SkExpand_rgb_16(src); 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t dst32 = SkExpand_rgb_16(dst); 1298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); 1308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[], 1338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int srcScale, int count) { 1348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count > 0); 1358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)srcScale <= 256); 136e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 1378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com srcScale >>= 3; 1388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 1408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t src32 = SkExpand_rgb_16(*src++); 1418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t dst32 = SkExpand_rgb_16(*dst); 1428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)); 1438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count > 0); 1448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 147fc25abdabff76f913fb9d4f373418c10a1eca92breed@android.com static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) { 1488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK); 1498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK); 1508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK); 151e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 1528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a + b; 1538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 1558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkRGB16Add(a, b) ((a) + (b)) 1568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////////////// 1598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_A32_BITS 8 1618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R32_BITS 8 1628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G32_BITS 8 1638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B32_BITS 8 1648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* we check to see if the SHIFT value has already been defined (SkUserConfig.h) 1668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if not, we define it ourself to some default values. We default to OpenGL 1678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com order (in memory: r,g,b,a) 1688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 1698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SK_A32_SHIFT 1708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #ifdef SK_CPU_BENDIAN 1718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_R32_SHIFT 24 1728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_G32_SHIFT 16 1738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_B32_SHIFT 8 1748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_A32_SHIFT 0 1758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #else 1768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_R32_SHIFT 0 1778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_G32_SHIFT 8 1788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_B32_SHIFT 16 1798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SK_A32_SHIFT 24 1808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #endif 1818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 1828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_A32_MASK ((1 << SK_A32_BITS) - 1) 1848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R32_MASK ((1 << SK_R32_BITS) - 1) 1858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G32_MASK ((1 << SK_G32_BITS) - 1) 1868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B32_MASK ((1 << SK_B32_BITS) - 1) 1878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24) 1898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24) 1908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24) 1918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24) 1928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK) 1948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK) 1958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK) 1968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK) 1978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 19934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com static inline void SkPMColorAssert(SkPMColor c) { 2008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a = SkGetPackedA32(c); 2018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkGetPackedR32(c); 2028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkGetPackedG32(c); 2038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkGetPackedB32(c); 204e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 2058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkA32Assert(a); 2068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(r <= a); 2078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(g <= a); 2088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= a); 2098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 2118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkPMColorAssert(c) 2128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 214e686322eba17fee0b5671393dc842e52f77109d9reed@google.com/** 215e686322eba17fee0b5671393dc842e52f77109d9reed@google.com * Pack the components into a SkPMColor, checking (in the debug version) that 216e686322eba17fee0b5671393dc842e52f77109d9reed@google.com * the components are 0..255, and are already premultiplied (i.e. alpha >= color) 217e686322eba17fee0b5671393dc842e52f77109d9reed@google.com */ 21834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 2198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkA32Assert(a); 2208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(r <= a); 2218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(g <= a); 2228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= a); 2238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | 2258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); 2268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 228e686322eba17fee0b5671393dc842e52f77109d9reed@google.com/** 229e686322eba17fee0b5671393dc842e52f77109d9reed@google.com * Same as SkPackARGB32, but this version guarantees to not check that the 230e686322eba17fee0b5671393dc842e52f77109d9reed@google.com * values are premultiplied in the debug version. 231e686322eba17fee0b5671393dc842e52f77109d9reed@google.com */ 232e686322eba17fee0b5671393dc842e52f77109d9reed@google.comstatic inline SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b) { 233e686322eba17fee0b5671393dc842e52f77109d9reed@google.com return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) | 234e686322eba17fee0b5671393dc842e52f77109d9reed@google.com (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT); 235e686322eba17fee0b5671393dc842e52f77109d9reed@google.com} 236e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 2377ffb1b21abcc7bbed5a0fc711f6dd7b9dbb4f577ctguil@chromium.orgSK_API extern const uint32_t gMask_00FF00FF; 2388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 23934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) { 2408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t mask = gMask_00FF00FF; 2418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// uint32_t mask = 0xFF00FF; 2428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t rb = ((c & mask) * scale) >> 8; 2448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t ag = ((c >> 8) & mask) * scale; 2458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (rb & mask) | (ag & ~mask); 2468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) { 2498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src))); 2508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 25234245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) { 2538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)aa <= 255); 2548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned src_scale = SkAlpha255To256(aa); 2568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale)); 2578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale); 2598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////////// 2628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Convert a 32bit pixel to a 16bit pixel (no dither) 2638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS)) 2658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS)) 2668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS)) 2678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 26934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com static inline unsigned SkR32ToR16(unsigned r) { 2708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkR32Assert(r); 2718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkR32ToR16_MACRO(r); 2728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com static inline unsigned SkG32ToG16(unsigned g) { 2748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkG32Assert(g); 2758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkG32ToG16_MACRO(g); 2768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 27734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com static inline unsigned SkB32ToB16(unsigned b) { 2788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkB32Assert(b); 2798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkB32ToB16_MACRO(b); 2808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 2818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 2828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkR32ToR16(r) SkR32ToR16_MACRO(r) 2838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkG32ToG16(g) SkG32ToG16_MACRO(g) 2848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkB32ToB16(b) SkB32ToB16_MACRO(b) 2858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 2868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK) 2888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK) 2898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK) 2908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline U16CPU SkPixel32ToPixel16(SkPMColor c) { 2928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT; 2938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT; 2948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT; 2958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return r | g | b; 2968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 2978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 29834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { 2998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkR32ToR16(r) << SK_R16_SHIFT) | 3008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkG32ToG16(g) << SK_G16_SHIFT) | 3018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkB32ToB16(b) << SK_B16_SHIFT); 3028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src)) 3058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com///////////////////////////////////////////////////////////////////////////////////////// 3078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Fast dither from 32->16 3088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1) 3108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b) { 3128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS); 3138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS); 3148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS); 315e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 3168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(r, g, b); 3178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 31934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c) { 3208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c)); 3218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Return c in expanded_rgb_16 format, but also scaled up by 32 (5 bits) 3248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com It is now suitable for combining with a scaled expanded_rgb_16 color 3258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com as in SkSrcOver32To16(). 3268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com We must do this 565 high-bit replication, in order for the subsequent add 3278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com to saturate properly (and not overflow). If we take the 8 bits as is, it is 3288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com possible to overflow. 3298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 33034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint32_t SkPMColorToExpanded16x5(SkPMColor c) { 3318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sr = SkPacked32ToR16(c); 3328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sg = SkPacked32ToG16(c); 3338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sb = SkPacked32ToB16(c); 334e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 3358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sr = (sr << 5) | sr; 3368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sg = (sg << 5) | (sg >> 1); 3378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sb = (sb << 5) | sb; 3388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (sr << 11) | (sg << 21) | (sb << 0); 3398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* SrcOver the 32bit src color with the 16bit dst, returning a 16bit value 3428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (with dirt in the high 16bits, so caller beware). 3438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 3448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) { 3458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sr = SkGetPackedR32(src); 3468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sg = SkGetPackedG32(src); 3478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sb = SkGetPackedB32(src); 348e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 3498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dr = SkGetPackedR16(dst); 3508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dg = SkGetPackedG16(dst); 3518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned db = SkGetPackedB16(dst); 352e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 3538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned isa = 255 - SkGetPackedA32(src); 354e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 3558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS); 3568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS); 3578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS); 358e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 3598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(dr, dg, db); 3608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//////////////////////////////////////////////////////////////////////////////////////////// 3638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Convert a 16bit pixel to a 32bit pixel 3648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 36534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkR16ToR32(unsigned r) { 3668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8)); 3678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 36834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com 36934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkG16ToG32(unsigned g) { 3708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8)); 3718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 37234245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com 37334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkB16ToB32(unsigned b) { 3748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8)); 3758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c)) 3788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c)) 3798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c)) 3808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 38134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor SkPixel16ToPixel32(U16CPU src) { 3828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(src == SkToU16(src)); 3838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkPacked16ToR32(src); 3858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkPacked16ToG32(src); 3868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkPacked16ToB32(src); 3878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); 3898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); 3908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); 3918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackARGB32(0xFF, r, g, b); 3938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 3948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 395c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com// similar to SkPixel16ToPixel32, but returns SkColor instead of SkPMColor 396c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.comstatic inline SkColor SkPixel16ToColor(U16CPU src) { 397c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com SkASSERT(src == SkToU16(src)); 398e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 399c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com unsigned r = SkPacked16ToR32(src); 400c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com unsigned g = SkPacked16ToG32(src); 401c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com unsigned b = SkPacked16ToB32(src); 402e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 403c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src)); 404c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src)); 405c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src)); 406e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 407c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com return SkColorSetRGB(r, g, b); 408c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com} 409c64599649bab68aedf07959f86fa506fc46fa3c2reed@android.com 4108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/////////////////////////////////////////////////////////////////////////////// 4118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comtypedef uint16_t SkPMColor16; 4138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// Put in OpenGL order (r g b a) 4158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_A4444_SHIFT 0 4168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_R4444_SHIFT 12 4178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_G4444_SHIFT 8 4188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SK_B4444_SHIFT 4 4198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkA32To4444(a) ((unsigned)(a) >> 4) 4218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkR32To4444(r) ((unsigned)(r) >> 4) 4228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkG32To4444(g) ((unsigned)(g) >> 4) 4238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkB32To4444(b) ((unsigned)(b) >> 4) 4248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 42534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline U8CPU SkReplicateNibble(unsigned nib) { 4268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(nib <= 0xF); 4278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (nib << 4) | nib; 4288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkA4444ToA32(a) SkReplicateNibble(a) 4318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkR4444ToR32(r) SkReplicateNibble(r) 4328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkG4444ToG32(g) SkReplicateNibble(g) 4338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkB4444ToB32(b) SkReplicateNibble(b) 4348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF) 4368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF) 4378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF) 4388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF) 4398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c)) 4418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c)) 4428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c)) 4438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c)) 4448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 44634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline void SkPMColor16Assert(U16CPU c) { 4478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned a = SkGetPackedA4444(c); 4488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned r = SkGetPackedR4444(c); 4498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned g = SkGetPackedG4444(c); 4508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned b = SkGetPackedB4444(c); 451e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 4528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(a <= 0xF); 4538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(r <= a); 4548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(g <= a); 4558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= a); 4568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 4588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkPMColor16Assert(c) 4598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 4608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 46134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkAlpha15To16(unsigned a) { 4628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(a <= 0xF); 4638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return a + (a >> 3); 4648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 46734245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com static inline int SkAlphaMul4(int value, int scale) { 4688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)scale <= 0x10); 4698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return value * scale >> 4; 4708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 4718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 4728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com #define SkAlphaMul4(value, scale) ((value) * (scale) >> 4) 4738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 4748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 47534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkR4444ToR565(unsigned r) { 4768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(r <= 0xF); 4778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS)); 4788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 48034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkG4444ToG565(unsigned g) { 4818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(g <= 0xF); 4828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS)); 4838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 48534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline unsigned SkB4444ToB565(unsigned b) { 4868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= 0xF); 4878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS)); 4888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 4898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r, 49134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com unsigned g, unsigned b) { 4928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(a <= 0xF); 4938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(r <= a); 4948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(g <= a); 4958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(b <= a); 496e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 4978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) | 4988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT)); 4998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comextern const uint16_t gMask_0F0F; 5028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 50334245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale) { 5048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(scale <= 16); 5058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const unsigned mask = 0xF0F; //gMask_0F0F; 507e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 5088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 5098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned rb = ((c & mask) * scale) >> 4; 5108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned ag = ((c >> 4) & mask) * scale; 5118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (rb & mask) | (ag & ~mask); 5128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#else 5138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com c = (c & mask) | ((c & (mask << 4)) << 12); 5148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com c = c * scale >> 4; 5158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (c & mask) | ((c >> 12) & (mask << 4)); 5168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 5178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Expand the SkPMColor16 color into a 32bit value that can be scaled all at 5208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com once by a value up to 16. Used in conjunction with SkCompact_4444. 5218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 52234245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint32_t SkExpand_4444(U16CPU c) { 5238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(c == (uint16_t)c); 524e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 5258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const unsigned mask = 0xF0F; //gMask_0F0F; 5268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (c & mask) | ((c & ~mask) << 12); 5278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/** Compress an expanded value (from SkExpand_4444) back down to a SkPMColor16. 5308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com NOTE: this explicitly does not clean the top 16 bits (which may be garbage). 5318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com It does this for speed, since if it is being written directly to 16bits of 5328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memory, the top 16bits will be ignored. Casting the result to uint16_t here 5338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com would add 2 more instructions, slow us down. It is up to the caller to 5348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com perform the cast if needed. 5358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 53634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline U16CPU SkCompact_4444(uint32_t c) { 5378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const unsigned mask = 0xF0F; //gMask_0F0F; 5388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (c & mask) | ((c >> 12) & ~mask); 5398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 54134245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) { 5428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sa = SkGetPackedA4444(s); 5438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sr = SkR4444ToR565(SkGetPackedR4444(s)); 5448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sg = SkG4444ToG565(SkGetPackedG4444(s)); 5458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned sb = SkB4444ToB565(SkGetPackedB4444(s)); 5468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // To avoid overflow, we have to clear the low bit of the synthetic sg 5488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // if the src alpha is <= 7. 5498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // to see why, try blending 0x4444 on top of 565-white and watch green 5508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // overflow (sum == 64) 5518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sg &= ~(~(sa >> 3) & 1); 5528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned scale = SkAlpha15To16(15 - sa); 5548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale); 5558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale); 5568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale); 557e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 5588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#if 0 5598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (sg + dg > 63) { 5608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg); 5618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 5638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackRGB16(sr + dr, sg + dg, sb + db); 5648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16) { 5678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)scale16 <= 16); 568e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 5698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst); 5708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 57234245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16) { 5738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT((unsigned)scale16 <= 16); 574e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 5758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t src32 = SkExpand_4444(src) * scale16; 5768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // the scaled srcAlpha is the bottom byte 5778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifdef SK_DEBUG 5788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com { 5798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned srcA = SkGetPackedA4444(src) * scale16; 5808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(srcA == (src32 & 0xFF)); 5818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 5828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 5838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4; 5848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t dst32 = SkExpand_4444(dst) * dstScale; 5858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkCompact_4444((src32 + dst32) >> 4); 5868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 58834245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor SkPixel4444ToPixel32(U16CPU c) { 5898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) | 5908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkGetPackedR4444(c) << SK_R32_SHIFT) | 5918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkGetPackedG4444(c) << SK_G32_SHIFT) | 5928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (SkGetPackedB4444(c) << SK_B32_SHIFT); 5938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return d | (d << 4); 5948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 5958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 59634245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c) { 5978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) | 5988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) | 5998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) | 6008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT); 6018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// cheap 2x2 dither 6048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstatic inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, 60534245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.com U8CPU g, U8CPU b) { 606735b790150096c3d5e817854b228945a9b869e86reed@android.com // to ensure that we stay a legal premultiplied color, we take the max() 607735b790150096c3d5e817854b228945a9b869e86reed@android.com // of the truncated and dithered alpha values. If we didn't, cases like 608735b790150096c3d5e817854b228945a9b869e86reed@android.com // SkDitherARGB32To4444(0x31, 0x2E, ...) would generate SkPackARGB4444(2, 3, ...) 609735b790150096c3d5e817854b228945a9b869e86reed@android.com // which is not legal premultiplied, since a < color 610735b790150096c3d5e817854b228945a9b869e86reed@android.com unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4; 611735b790150096c3d5e817854b228945a9b869e86reed@android.com a = SkMax32(a >> 4, dithered_a); 612735b790150096c3d5e817854b228945a9b869e86reed@android.com // these we just dither in place 6138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4; 6148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4; 6158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4; 616e686322eba17fee0b5671393dc842e52f77109d9reed@google.com 6178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkPackARGB4444(a, r, g, b); 6188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c) { 6218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c), 6228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkGetPackedG32(c), SkGetPackedB32(c)); 6238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Assumes 16bit is in standard RGBA order. 6268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Transforms a normal ARGB_8888 into the same byte order as 6278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com expanded ARGB_4444, but keeps each component 8bits 6288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 62934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint32_t SkExpand_8888(SkPMColor c) { 6308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (((c >> SK_R32_SHIFT) & 0xFF) << 24) | 6318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> SK_G32_SHIFT) & 0xFF) << 8) | 6328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> SK_B32_SHIFT) & 0xFF) << 16) | 6338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> SK_A32_SHIFT) & 0xFF) << 0); 6348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Undo the operation of SkExpand_8888, turning the argument back into 6378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com a SkPMColor. 6388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 63934245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline SkPMColor SkCompact_8888(uint32_t c) { 6408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (((c >> 24) & 0xFF) << SK_R32_SHIFT) | 6418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> 8) & 0xFF) << SK_G32_SHIFT) | 6428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> 16) & 0xFF) << SK_B32_SHIFT) | 6438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> 0) & 0xFF) << SK_A32_SHIFT); 6448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* Like SkExpand_8888, this transforms a pmcolor into the expanded 4444 format, 6478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com but this routine just keeps the high 4bits of each component in the low 6488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 4bits of the result (just like a newly expanded PMColor16). 6498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 65034245c7871f6339de8cc2be8fb1090ca3cba54efreed@android.comstatic inline uint32_t SkExpand32_4444(SkPMColor c) { 6518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) | 6528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) | 6538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) | 6548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com (((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0); 6558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 6568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// takes two values and alternamtes them as part of a memset16 6588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com// used for cheap 2x2 dithering when the colors are opaque 6598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n); 6608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 6628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 663