8 #ifndef SkColorPriv_DEFINED
9 #define SkColorPriv_DEFINED
13 #define CHECK_FOR_565_OVERFLOW
21 #define SkASSERT_IS_BYTE(x) SkASSERT(0 == ((x) & ~0xFF))
36 #define SK_RGBA_R32_SHIFT 24
37 #define SK_RGBA_G32_SHIFT 16
38 #define SK_RGBA_B32_SHIFT 8
39 #define SK_RGBA_A32_SHIFT 0
41 #define SK_BGRA_B32_SHIFT 24
42 #define SK_BGRA_G32_SHIFT 16
43 #define SK_BGRA_R32_SHIFT 8
44 #define SK_BGRA_A32_SHIFT 0
46 #define SK_RGBA_R32_SHIFT 0
47 #define SK_RGBA_G32_SHIFT 8
48 #define SK_RGBA_B32_SHIFT 16
49 #define SK_RGBA_A32_SHIFT 24
51 #define SK_BGRA_B32_SHIFT 0
52 #define SK_BGRA_G32_SHIFT 8
53 #define SK_BGRA_R32_SHIFT 16
54 #define SK_BGRA_A32_SHIFT 24
57 #if defined(SK_PMCOLOR_IS_RGBA) && defined(SK_PMCOLOR_IS_BGRA)
58 #error "can't define PMCOLOR to be RGBA and BGRA"
61 #define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA \
62 (SK_A32_SHIFT == SK_RGBA_A32_SHIFT && \
63 SK_R32_SHIFT == SK_RGBA_R32_SHIFT && \
64 SK_G32_SHIFT == SK_RGBA_G32_SHIFT && \
65 SK_B32_SHIFT == SK_RGBA_B32_SHIFT)
67 #define LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA \
68 (SK_A32_SHIFT == SK_BGRA_A32_SHIFT && \
69 SK_R32_SHIFT == SK_BGRA_R32_SHIFT && \
70 SK_G32_SHIFT == SK_BGRA_G32_SHIFT && \
71 SK_B32_SHIFT == SK_BGRA_B32_SHIFT)
74 #define SK_A_INDEX (SK_A32_SHIFT/8)
75 #define SK_R_INDEX (SK_R32_SHIFT/8)
76 #define SK_G_INDEX (SK_G32_SHIFT/8)
77 #define SK_B_INDEX (SK_B32_SHIFT/8)
79 #if defined(SK_PMCOLOR_IS_RGBA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
80 #error "SK_PMCOLOR_IS_RGBA does not match SK_*32_SHIFT values"
83 #if defined(SK_PMCOLOR_IS_BGRA) && !LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
84 #error "SK_PMCOLOR_IS_BGRA does not match SK_*32_SHIFT values"
87 #if !defined(SK_PMCOLOR_IS_RGBA) && !defined(SK_PMCOLOR_IS_BGRA)
90 #if LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
91 #define SK_PMCOLOR_IS_RGBA
92 #elif LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
93 #define SK_PMCOLOR_IS_BGRA
95 #error "need 32bit packing to be either RGBA or BGRA"
100 #undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_RGBA
101 #undef LOCAL_PMCOLOR_SHIFTS_EQUIVALENT_TO_BGRA
108 static inline uint32_t SkSwizzle_RB(uint32_t c) {
109 static const uint32_t kRBMask = (0xFF << SK_R32_SHIFT) | (0xFF << SK_B32_SHIFT);
111 unsigned c0 = (c >> SK_R32_SHIFT) & 0xFF;
112 unsigned c1 = (c >> SK_B32_SHIFT) & 0xFF;
113 return (c & ~kRBMask) | (c0 << SK_B32_SHIFT) | (c1 << SK_R32_SHIFT);
121 return (a << SK_RGBA_A32_SHIFT) | (r << SK_RGBA_R32_SHIFT) |
122 (g << SK_RGBA_G32_SHIFT) | (b << SK_RGBA_B32_SHIFT);
130 return (a << SK_BGRA_A32_SHIFT) | (r << SK_BGRA_R32_SHIFT) |
131 (g << SK_BGRA_G32_SHIFT) | (b << SK_BGRA_B32_SHIFT);
134 static inline SkPMColor SkSwizzle_RGBA_to_PMColor(uint32_t c) {
135 #ifdef SK_PMCOLOR_IS_RGBA
138 return SkSwizzle_RB(c);
142 static inline SkPMColor SkSwizzle_BGRA_to_PMColor(uint32_t c) {
143 #ifdef SK_PMCOLOR_IS_BGRA
146 return SkSwizzle_RB(c);
154 #define SK_ITU_BT709_LUM_COEFF_R (0.2126f)
155 #define SK_ITU_BT709_LUM_COEFF_G (0.7152f)
156 #define SK_ITU_BT709_LUM_COEFF_B (0.0722f)
161 #define SK_LUM_COEFF_R SK_ITU_BT709_LUM_COEFF_R
162 #define SK_LUM_COEFF_G SK_ITU_BT709_LUM_COEFF_G
163 #define SK_LUM_COEFF_B SK_ITU_BT709_LUM_COEFF_B
173 return (r * 54 + g * 183 + b * 19) >> 8;
182 static inline unsigned SkAlpha255To256(
U8CPU alpha) {
183 SkASSERT(SkToU8(alpha) == alpha);
193 static inline unsigned Sk255To256(
U8CPU value) {
194 SkASSERT(SkToU8(value) == value);
195 return value + (value >> 7);
201 #define SkAlphaMul(value, alpha256) (((value) * (alpha256)) >> 8)
207 unsigned prod = 0xFFFF - value * alpha256;
208 return (prod + (prod >> 8)) >> 8;
214 static inline int SkAlphaBlend(
int src,
int dst,
int scale256) {
215 SkASSERT((
unsigned)scale256 <= 256);
216 return dst + SkAlphaMul(src - dst, scale256);
225 SkASSERT((int16_t)src == src);
226 SkASSERT((int16_t)dst == dst);
227 SkASSERT((uint8_t)alpha == alpha);
229 int prod = (src - dst) * alpha + 128;
230 prod = (prod + (prod >> 8)) >> 8;
234 static inline U8CPU SkUnitScalarClampToByte(SkScalar x) {
235 return static_cast<U8CPU>(SkScalarPin(x, 0, 1) * 255 + 0.5);
238 #define SK_R16_BITS 5
239 #define SK_G16_BITS 6
240 #define SK_B16_BITS 5
242 #define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
243 #define SK_G16_SHIFT (SK_B16_BITS)
244 #define SK_B16_SHIFT 0
246 #define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
247 #define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
248 #define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
250 #define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
251 #define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
252 #define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
254 #define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK)
255 #define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK)
256 #define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK)
258 static inline uint16_t SkPackRGB16(
unsigned r,
unsigned g,
unsigned b) {
259 SkASSERT(r <= SK_R16_MASK);
260 SkASSERT(g <= SK_G16_MASK);
261 SkASSERT(b <= SK_B16_MASK);
263 return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
266 #define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT)
267 #define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT)
268 #define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT)
273 static inline uint32_t SkExpand_rgb_16(
U16CPU c) {
274 SkASSERT(c == (uint16_t)c);
276 return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
285 static inline U16CPU SkCompact_rgb_16(uint32_t c) {
286 return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
294 static inline U16CPU SkAlphaMulRGB16(
U16CPU c,
unsigned scale) {
295 return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5);
299 #define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s)
306 static inline U16CPU SkBlend32_RGB16(uint32_t src_expand, uint16_t dst,
unsigned scale) {
307 uint32_t dst_expand = SkExpand_rgb_16(dst) * scale;
308 return SkCompact_rgb_16((src_expand + dst_expand) >> 5);
317 SkASSERT((
unsigned)srcScale <= 256);
321 uint32_t src32 = SkExpand_rgb_16(src);
322 uint32_t dst32 = SkExpand_rgb_16(dst);
323 return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
326 static inline void SkBlendRGB16(
const uint16_t src[], uint16_t dst[],
327 int srcScale,
int count) {
329 SkASSERT((
unsigned)srcScale <= 256);
334 uint32_t src32 = SkExpand_rgb_16(*src++);
335 uint32_t dst32 = SkExpand_rgb_16(*dst);
336 *dst++ =
static_cast<uint16_t
>(
337 SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5)));
338 }
while (--count > 0);
343 SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK);
344 SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK);
345 SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK);
350 #define SkRGB16Add(a, b) ((a) + (b))
355 #define SK_A32_BITS 8
356 #define SK_R32_BITS 8
357 #define SK_G32_BITS 8
358 #define SK_B32_BITS 8
360 #define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
361 #define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
362 #define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
363 #define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
365 #define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
366 #define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
367 #define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
368 #define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
370 #define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK)
371 #define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK)
372 #define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK)
373 #define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
376 #define SkPMColorAssert(color_value) \
378 SkPMColor pm_color_value = (color_value); \
379 uint32_t alpha_color_value = SkGetPackedA32(pm_color_value); \
380 SkA32Assert(alpha_color_value); \
381 SkASSERT(SkGetPackedR32(pm_color_value) <= alpha_color_value); \
382 SkASSERT(SkGetPackedG32(pm_color_value) <= alpha_color_value); \
383 SkASSERT(SkGetPackedB32(pm_color_value) <= alpha_color_value); \
386 #define SkPMColorAssert(c)
389 static inline bool SkPMColorValid(
SkPMColor c) {
390 auto a = SkGetPackedA32(c);
391 bool valid = a <= SK_A32_MASK
392 && SkGetPackedR32(c) <= a
393 && SkGetPackedG32(c) <= a
394 && SkGetPackedB32(c) <= a;
411 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
412 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
415 static inline uint32_t SkPackPMColor_as_RGBA(
SkPMColor c) {
416 return SkPackARGB_as_RGBA(SkGetPackedA32(c), SkGetPackedR32(c),
417 SkGetPackedG32(c), SkGetPackedB32(c));
420 static inline uint32_t SkPackPMColor_as_BGRA(
SkPMColor c) {
421 return SkPackARGB_as_BGRA(SkGetPackedA32(c), SkGetPackedR32(c),
422 SkGetPackedG32(c), SkGetPackedB32(c));
434 unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
435 unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
436 unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
437 unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
439 return SkPackARGB32(a, r, g, b);
450 unsigned scale = SkAlpha255To256(srcWeight);
451 return SkFourByteInterp256(src, dst, scale);
457 static inline void SkSplay(uint32_t color, uint32_t* ag, uint32_t* rb) {
458 const uint32_t mask = 0x00FF00FF;
459 *ag = (color >> 8) & mask;
467 static inline uint64_t SkSplay(uint32_t color) {
468 const uint32_t mask = 0x00FF00FF;
469 uint64_t agrb = (color >> 8) & mask;
471 agrb |= color & mask;
478 static inline uint32_t SkUnsplay(uint32_t ag, uint32_t rb) {
479 const uint32_t mask = 0xFF00FF00;
480 return (ag & mask) | ((rb & mask) >> 8);
487 static inline uint32_t SkUnsplay(uint64_t agrb) {
488 const uint32_t mask = 0xFF00FF00;
490 ((agrb & mask) >> 8) |
491 ((agrb >> 32) & mask));
495 SkASSERT(scale <= 256);
498 uint32_t src_ag, src_rb, dst_ag, dst_rb;
499 SkSplay(src, &src_ag, &src_rb);
500 SkSplay(dst, &dst_ag, &dst_rb);
502 const uint32_t ret_ag = src_ag * scale + (256 - scale) * dst_ag;
503 const uint32_t ret_rb = src_rb * scale + (256 - scale) * dst_rb;
505 return SkUnsplay(ret_ag, ret_rb);
509 SkASSERT(scale <= 256);
511 return SkUnsplay(SkSplay(src) * scale + (256-scale) * SkSplay(dst));
521 if (
sizeof(
void*) == 4) {
522 return SkFastFourByteInterp256_32(src, dst, scale);
524 return SkFastFourByteInterp256_64(src, dst, scale);
535 SkASSERT(srcWeight <= 255);
538 return SkFastFourByteInterp256(src, dst, srcWeight + (srcWeight >> 7));
546 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
547 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
558 r = SkMulDiv255Round(r, a);
559 g = SkMulDiv255Round(g, a);
560 b = SkMulDiv255Round(b, a);
562 return SkPackARGB32(a, r, g, b);
567 static SK_ALWAYS_INLINE uint32_t SkAlphaMulQ(uint32_t c,
unsigned scale) {
568 uint32_t mask = 0xFF00FF;
570 uint32_t rb = ((c & mask) * scale) >> 8;
571 uint32_t ag = ((c >> 8) & mask) * scale;
572 return (rb & mask) | (ag & ~mask);
576 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
583 return SkFastFourByteInterp256(src, dst, scale);
587 SkASSERT((
unsigned)aa <= 255);
589 unsigned src_scale = SkAlpha255To256(aa);
590 unsigned dst_scale = SkAlphaMulInv256(SkGetPackedA32(src), src_scale);
592 const uint32_t mask = 0xFF00FF;
594 uint32_t src_rb = (src & mask) * src_scale;
595 uint32_t src_ag = ((src >> 8) & mask) * src_scale;
597 uint32_t dst_rb = (dst & mask) * dst_scale;
598 uint32_t dst_ag = ((dst >> 8) & mask) * dst_scale;
600 return (((src_rb + dst_rb) >> 8) & mask) | ((src_ag + dst_ag) & ~mask);
606 #define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
607 #define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
608 #define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
611 static inline unsigned SkR32ToR16(
unsigned r) {
613 return SkR32ToR16_MACRO(r);
615 static inline unsigned SkG32ToG16(
unsigned g) {
617 return SkG32ToG16_MACRO(g);
619 static inline unsigned SkB32ToB16(
unsigned b) {
621 return SkB32ToB16_MACRO(b);
624 #define SkR32ToR16(r) SkR32ToR16_MACRO(r)
625 #define SkG32ToG16(g) SkG32ToG16_MACRO(g)
626 #define SkB32ToB16(b) SkB32ToB16_MACRO(b)
629 #define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
630 #define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
631 #define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
634 unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT;
635 unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT;
636 unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT;
641 return (SkR32ToR16(r) << SK_R16_SHIFT) |
642 (SkG32ToG16(g) << SK_G16_SHIFT) |
643 (SkB32ToB16(b) << SK_B16_SHIFT);
646 #define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src))
651 #define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1)
653 static inline uint16_t SkDitherPack888ToRGB16(
U8CPU r,
U8CPU g,
U8CPU b) {
654 r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS);
655 g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS);
656 b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS);
658 return SkPackRGB16(r, g, b);
661 static inline uint16_t SkDitherPixel32ToPixel16(
SkPMColor c) {
662 return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c));
672 static inline uint32_t SkPMColorToExpanded16x5(
SkPMColor c) {
673 unsigned sr = SkPacked32ToR16(c);
674 unsigned sg = SkPacked32ToG16(c);
675 unsigned sb = SkPacked32ToB16(c);
678 sg = (sg << 5) | (sg >> 1);
680 return (sr << 11) | (sg << 21) | (sb << 0);
687 unsigned sr = SkGetPackedR32(src);
688 unsigned sg = SkGetPackedG32(src);
689 unsigned sb = SkGetPackedB32(src);
691 unsigned dr = SkGetPackedR16(dst);
692 unsigned dg = SkGetPackedG16(dst);
693 unsigned db = SkGetPackedB16(dst);
695 unsigned isa = 255 - SkGetPackedA32(src);
697 dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS);
698 dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS);
699 db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS);
701 return SkPackRGB16(dr, dg, db);
707 static inline unsigned SkR16ToR32(
unsigned r) {
708 return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
711 static inline unsigned SkG16ToG32(
unsigned g) {
712 return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
715 static inline unsigned SkB16ToB32(
unsigned b) {
716 return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
719 #define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
720 #define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
721 #define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
724 SkASSERT(src == SkToU16(src));
726 unsigned r = SkPacked16ToR32(src);
727 unsigned g = SkPacked16ToG32(src);
728 unsigned b = SkPacked16ToB32(src);
730 SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
731 SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
732 SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
734 return SkPackARGB32(0xFF, r, g, b);
739 SkASSERT(src == SkToU16(src));
741 unsigned r = SkPacked16ToR32(src);
742 unsigned g = SkPacked16ToG32(src);
743 unsigned b = SkPacked16ToB32(src);
745 SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
746 SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
747 SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
754 typedef uint16_t SkPMColor16;
757 #define SK_A4444_SHIFT 0
758 #define SK_R4444_SHIFT 12
759 #define SK_G4444_SHIFT 8
760 #define SK_B4444_SHIFT 4
762 #define SkA32To4444(a) ((unsigned)(a) >> 4)
763 #define SkR32To4444(r) ((unsigned)(r) >> 4)
764 #define SkG32To4444(g) ((unsigned)(g) >> 4)
765 #define SkB32To4444(b) ((unsigned)(b) >> 4)
767 static inline U8CPU SkReplicateNibble(
unsigned nib) {
768 SkASSERT(nib <= 0xF);
769 return (nib << 4) | nib;
772 #define SkA4444ToA32(a) SkReplicateNibble(a)
773 #define SkR4444ToR32(r) SkReplicateNibble(r)
774 #define SkG4444ToG32(g) SkReplicateNibble(g)
775 #define SkB4444ToB32(b) SkReplicateNibble(b)
777 #define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF)
778 #define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF)
779 #define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF)
780 #define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF)
782 #define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c))
783 #define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c))
784 #define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c))
785 #define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c))
788 static inline void SkPMColor16Assert(
U16CPU c) {
789 unsigned a = SkGetPackedA4444(c);
790 unsigned r = SkGetPackedR4444(c);
791 unsigned g = SkGetPackedG4444(c);
792 unsigned b = SkGetPackedB4444(c);
800 #define SkPMColor16Assert(c)
803 static inline unsigned SkAlpha15To16(
unsigned a) {
809 static inline int SkAlphaMul4(
int value,
int scale) {
810 SkASSERT((
unsigned)scale <= 0x10);
811 return value * scale >> 4;
814 #define SkAlphaMul4(value, scale) ((value) * (scale) >> 4)
817 static inline unsigned SkR4444ToR565(
unsigned r) {
819 return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS));
822 static inline unsigned SkG4444ToG565(
unsigned g) {
824 return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS));
827 static inline unsigned SkB4444ToB565(
unsigned b) {
829 return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS));
832 static inline SkPMColor16 SkPackARGB4444(
unsigned a,
unsigned r,
833 unsigned g,
unsigned b) {
839 return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) |
840 (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
843 static inline SkPMColor16 SkAlphaMulQ4(SkPMColor16 c,
int scale) {
844 SkASSERT(scale <= 16);
846 const unsigned mask = 0xF0F;
849 unsigned rb = ((c & mask) * scale) >> 4;
850 unsigned ag = ((c >> 4) & mask) * scale;
851 return (rb & mask) | (ag & ~mask);
853 unsigned expanded_c = (c & mask) | ((c & (mask << 4)) << 12);
854 unsigned scaled_c = (expanded_c * scale) >> 4;
855 return (scaled_c & mask) | ((scaled_c >> 12) & (mask << 4));
862 static inline uint32_t SkExpand_4444(
U16CPU c) {
863 SkASSERT(c == (uint16_t)c);
865 const unsigned mask = 0xF0F;
866 return (c & mask) | ((c & ~mask) << 12);
869 static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d) {
870 unsigned sa = SkGetPackedA4444(s);
871 unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
872 unsigned sg = SkG4444ToG565(SkGetPackedG4444(s));
873 unsigned sb = SkB4444ToB565(SkGetPackedB4444(s));
879 sg &= ~(~(sa >> 3) & 1);
881 unsigned scale = SkAlpha15To16(15 - sa);
882 unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale);
883 unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale);
884 unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale);
888 SkDebugf(
"---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg);
891 return SkPackRGB16(sr + dr, sg + dg, sb + db);
894 static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst,
int scale16) {
895 SkASSERT((
unsigned)scale16 <= 16);
897 return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
901 uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
902 (SkGetPackedR4444(c) << SK_R32_SHIFT) |
903 (SkGetPackedG4444(c) << SK_G32_SHIFT) |
904 (SkGetPackedB4444(c) << SK_B32_SHIFT);
908 static inline SkPMColor16 SkPixel32ToPixel4444(
SkPMColor c) {
909 return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) |
910 (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) |
911 (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) |
912 (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT);
916 static inline SkPMColor16 SkDitherARGB32To4444(
U8CPU a,
U8CPU r,
922 unsigned dithered_a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
923 a = SkMax32(a >> 4, dithered_a);
925 r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4;
926 g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4;
927 b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4;
929 return SkPackARGB4444(a, r, g, b);
932 static inline SkPMColor16 SkDitherPixel32To4444(
SkPMColor c) {
933 return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c),
934 SkGetPackedG32(c), SkGetPackedB32(c));
941 static inline uint32_t SkExpand_8888(
SkPMColor c) {
942 return (((c >> SK_R32_SHIFT) & 0xFF) << 24) |
943 (((c >> SK_G32_SHIFT) & 0xFF) << 8) |
944 (((c >> SK_B32_SHIFT) & 0xFF) << 16) |
945 (((c >> SK_A32_SHIFT) & 0xFF) << 0);
951 static inline SkPMColor SkCompact_8888(uint32_t c) {
952 return (((c >> 24) & 0xFF) << SK_R32_SHIFT) |
953 (((c >> 8) & 0xFF) << SK_G32_SHIFT) |
954 (((c >> 16) & 0xFF) << SK_B32_SHIFT) |
955 (((c >> 0) & 0xFF) << SK_A32_SHIFT);
962 static inline uint32_t SkExpand32_4444(
SkPMColor c) {
963 return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) |
964 (((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) |
965 (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
966 (((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0);
971 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
int n);
975 static inline int SkUpscale31To32(
int value) {
976 SkASSERT((
unsigned)value <= 31);
977 return value + (value >> 4);
980 static inline int SkBlend32(
int src,
int dst,
int scale) {
981 SkASSERT((
unsigned)src <= 0xFF);
982 SkASSERT((
unsigned)dst <= 0xFF);
983 SkASSERT((
unsigned)scale <= 32);
984 return dst + ((src - dst) * scale >> 5);
987 static inline SkPMColor SkBlendLCD16(
int srcA,
int srcR,
int srcG,
int srcB,
996 int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
997 int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
998 int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
1001 maskR = SkUpscale31To32(maskR);
1002 maskG = SkUpscale31To32(maskG);
1003 maskB = SkUpscale31To32(maskB);
1006 maskR = maskR * srcA >> 8;
1007 maskG = maskG * srcA >> 8;
1008 maskB = maskB * srcA >> 8;
1010 int dstR = SkGetPackedR32(dst);
1011 int dstG = SkGetPackedG32(dst);
1012 int dstB = SkGetPackedB32(dst);
1016 return SkPackARGB32(0xFF,
1017 SkBlend32(srcR, dstR, maskR),
1018 SkBlend32(srcG, dstG, maskG),
1019 SkBlend32(srcB, dstB, maskB));
1022 static inline SkPMColor SkBlendLCD16Opaque(
int srcR,
int srcG,
int srcB,
1029 if (0xFFFF == mask) {
1036 int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
1037 int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
1038 int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
1041 maskR = SkUpscale31To32(maskR);
1042 maskG = SkUpscale31To32(maskG);
1043 maskB = SkUpscale31To32(maskB);
1045 int dstR = SkGetPackedR32(dst);
1046 int dstG = SkGetPackedG32(dst);
1047 int dstB = SkGetPackedB32(dst);
1051 return SkPackARGB32(0xFF,
1052 SkBlend32(srcR, dstR, maskR),
1053 SkBlend32(srcG, dstG, maskG),
1054 SkBlend32(srcB, dstB, maskB));
1057 static inline void SkBlitLCD16Row(
SkPMColor dst[],
const uint16_t mask[],
1064 srcA = SkAlpha255To256(srcA);
1066 for (
int i = 0; i < width; i++) {
1067 dst[i] = SkBlendLCD16(srcA, srcR, srcG, srcB, dst[i], mask[i]);
1071 static inline void SkBlitLCD16OpaqueRow(
SkPMColor dst[],
const uint16_t mask[],
1078 for (
int i = 0; i < width; i++) {
1079 dst[i] = SkBlendLCD16Opaque(srcR, srcG, srcB, dst[i], mask[i],
unsigned U16CPU
Fast type for unsigned 16 bits.
Definition: SkTypes.h:203
#define SkColorGetG(color)
return the green byte from a SkColor value
Definition: SkColor.h:66
uint32_t SkPMColor
32 bit ARGB color value, premultiplied.
Definition: SkColor.h:161
uint32_t SkColor
32 bit ARGB color value, not premultiplied.
Definition: SkColor.h:28
#define SkColorGetB(color)
return the blue byte from a SkColor value
Definition: SkColor.h:68
#define SkColorGetR(color)
return the red byte from a SkColor value
Definition: SkColor.h:64
#define SkColorSetRGB(r, g, b)
Return a SkColor value from 8 bit component values, with an implied value of 0xFF for alpha (fully op...
Definition: SkColor.h:59
#define SkColorGetA(color)
return the alpha byte from a SkColor value
Definition: SkColor.h:62
unsigned U8CPU
Fast type for unsigned 8 bits.
Definition: SkTypes.h:191
Types and macros for colors.
int S16CPU
Fast type for signed 16 bits.
Definition: SkTypes.h:197