00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SkColorPriv_DEFINED
00018 #define SkColorPriv_DEFINED
00019
00020
00021 #ifdef SK_DEBUG
00022 #define CHECK_FOR_565_OVERFLOW
00023 #endif
00024
00025 #include "SkColor.h"
00026 #include "SkMath.h"
00027
00034 static inline unsigned SkAlpha255To256(U8CPU alpha) {
00035 SkASSERT(SkToU8(alpha) == alpha);
00036 #ifndef SK_USE_OLD_255_TO_256
00037
00038
00039 return alpha + 1;
00040 #else
00041 return alpha + (alpha >> 7);
00042 #endif
00043 }
00044
00048 #define SkAlphaMul(value, alpha256) (SkMulS16(value, alpha256) >> 8)
00049
00050
00051
00052
00053 inline int SkAlphaBlend(int src, int dst, int scale256) {
00054 SkASSERT((unsigned)scale256 <= 256);
00055 return dst + SkAlphaMul(src - dst, scale256);
00056 }
00057
00058 #define SK_R16_BITS 5
00059 #define SK_G16_BITS 6
00060 #define SK_B16_BITS 5
00061
00062 #define SK_R16_SHIFT (SK_B16_BITS + SK_G16_BITS)
00063 #define SK_G16_SHIFT (SK_B16_BITS)
00064 #define SK_B16_SHIFT 0
00065
00066 #define SK_R16_MASK ((1 << SK_R16_BITS) - 1)
00067 #define SK_G16_MASK ((1 << SK_G16_BITS) - 1)
00068 #define SK_B16_MASK ((1 << SK_B16_BITS) - 1)
00069
00070 #define SkGetPackedR16(color) (((unsigned)(color) >> SK_R16_SHIFT) & SK_R16_MASK)
00071 #define SkGetPackedG16(color) (((unsigned)(color) >> SK_G16_SHIFT) & SK_G16_MASK)
00072 #define SkGetPackedB16(color) (((unsigned)(color) >> SK_B16_SHIFT) & SK_B16_MASK)
00073
00074 #define SkR16Assert(r) SkASSERT((unsigned)(r) <= SK_R16_MASK)
00075 #define SkG16Assert(g) SkASSERT((unsigned)(g) <= SK_G16_MASK)
00076 #define SkB16Assert(b) SkASSERT((unsigned)(b) <= SK_B16_MASK)
00077
00078 static inline uint16_t SkPackRGB16(unsigned r, unsigned g, unsigned b) {
00079 SkASSERT(r <= SK_R16_MASK);
00080 SkASSERT(g <= SK_G16_MASK);
00081 SkASSERT(b <= SK_B16_MASK);
00082
00083 return SkToU16((r << SK_R16_SHIFT) | (g << SK_G16_SHIFT) | (b << SK_B16_SHIFT));
00084 }
00085
00086 #define SK_R16_MASK_IN_PLACE (SK_R16_MASK << SK_R16_SHIFT)
00087 #define SK_G16_MASK_IN_PLACE (SK_G16_MASK << SK_G16_SHIFT)
00088 #define SK_B16_MASK_IN_PLACE (SK_B16_MASK << SK_B16_SHIFT)
00089
00093 static inline uint32_t SkExpand_rgb_16(U16CPU c) {
00094 SkASSERT(c == (uint16_t)c);
00095
00096 return ((c & SK_G16_MASK_IN_PLACE) << 16) | (c & ~SK_G16_MASK_IN_PLACE);
00097 }
00098
00105 static inline U16CPU SkCompact_rgb_16(uint32_t c) {
00106 return ((c >> 16) & SK_G16_MASK_IN_PLACE) | (c & ~SK_G16_MASK_IN_PLACE);
00107 }
00108
00114 static inline U16CPU SkAlphaMulRGB16(U16CPU c, unsigned scale) {
00115 return SkCompact_rgb_16(SkExpand_rgb_16(c) * (scale >> 3) >> 5);
00116 }
00117
00118
00119 #define SkAlphaMulRGB16_ToU16(c, s) (uint16_t)SkAlphaMulRGB16(c, s)
00120
00126 static inline U16CPU SkBlendRGB16(U16CPU src, U16CPU dst, int srcScale) {
00127 SkASSERT((unsigned)srcScale <= 256);
00128
00129 srcScale >>= 3;
00130
00131 uint32_t src32 = SkExpand_rgb_16(src);
00132 uint32_t dst32 = SkExpand_rgb_16(dst);
00133 return SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
00134 }
00135
00136 static inline void SkBlendRGB16(const uint16_t src[], uint16_t dst[],
00137 int srcScale, int count) {
00138 SkASSERT(count > 0);
00139 SkASSERT((unsigned)srcScale <= 256);
00140
00141 srcScale >>= 3;
00142
00143 do {
00144 uint32_t src32 = SkExpand_rgb_16(*src++);
00145 uint32_t dst32 = SkExpand_rgb_16(*dst);
00146 *dst++ = SkCompact_rgb_16(dst32 + ((src32 - dst32) * srcScale >> 5));
00147 } while (--count > 0);
00148 }
00149
00150 #ifdef SK_DEBUG
00151 static inline U16CPU SkRGB16Add(U16CPU a, U16CPU b) {
00152 SkASSERT(SkGetPackedR16(a) + SkGetPackedR16(b) <= SK_R16_MASK);
00153 SkASSERT(SkGetPackedG16(a) + SkGetPackedG16(b) <= SK_G16_MASK);
00154 SkASSERT(SkGetPackedB16(a) + SkGetPackedB16(b) <= SK_B16_MASK);
00155
00156 return a + b;
00157 }
00158 #else
00159 #define SkRGB16Add(a, b) ((a) + (b))
00160 #endif
00161
00163
00164 #define SK_A32_BITS 8
00165 #define SK_R32_BITS 8
00166 #define SK_G32_BITS 8
00167 #define SK_B32_BITS 8
00168
00169
00170
00171
00172
00173 #ifndef SK_A32_SHIFT
00174 #ifdef SK_CPU_BENDIAN
00175 #define SK_R32_SHIFT 24
00176 #define SK_G32_SHIFT 16
00177 #define SK_B32_SHIFT 8
00178 #define SK_A32_SHIFT 0
00179 #else
00180 #define SK_R32_SHIFT 0
00181 #define SK_G32_SHIFT 8
00182 #define SK_B32_SHIFT 16
00183 #define SK_A32_SHIFT 24
00184 #endif
00185 #endif
00186
00187 #define SK_A32_MASK ((1 << SK_A32_BITS) - 1)
00188 #define SK_R32_MASK ((1 << SK_R32_BITS) - 1)
00189 #define SK_G32_MASK ((1 << SK_G32_BITS) - 1)
00190 #define SK_B32_MASK ((1 << SK_B32_BITS) - 1)
00191
00192 #define SkGetPackedA32(packed) ((uint32_t)((packed) << (24 - SK_A32_SHIFT)) >> 24)
00193 #define SkGetPackedR32(packed) ((uint32_t)((packed) << (24 - SK_R32_SHIFT)) >> 24)
00194 #define SkGetPackedG32(packed) ((uint32_t)((packed) << (24 - SK_G32_SHIFT)) >> 24)
00195 #define SkGetPackedB32(packed) ((uint32_t)((packed) << (24 - SK_B32_SHIFT)) >> 24)
00196
00197 #define SkA32Assert(a) SkASSERT((unsigned)(a) <= SK_A32_MASK)
00198 #define SkR32Assert(r) SkASSERT((unsigned)(r) <= SK_R32_MASK)
00199 #define SkG32Assert(g) SkASSERT((unsigned)(g) <= SK_G32_MASK)
00200 #define SkB32Assert(b) SkASSERT((unsigned)(b) <= SK_B32_MASK)
00201
00202 #ifdef SK_DEBUG
00203 inline void SkPMColorAssert(SkPMColor c) {
00204 unsigned a = SkGetPackedA32(c);
00205 unsigned r = SkGetPackedR32(c);
00206 unsigned g = SkGetPackedG32(c);
00207 unsigned b = SkGetPackedB32(c);
00208
00209 SkA32Assert(a);
00210 SkASSERT(r <= a);
00211 SkASSERT(g <= a);
00212 SkASSERT(b <= a);
00213 }
00214 #else
00215 #define SkPMColorAssert(c)
00216 #endif
00217
00218 inline SkPMColor SkPackARGB32(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
00219 SkA32Assert(a);
00220 SkASSERT(r <= a);
00221 SkASSERT(g <= a);
00222 SkASSERT(b <= a);
00223
00224 return (a << SK_A32_SHIFT) | (r << SK_R32_SHIFT) |
00225 (g << SK_G32_SHIFT) | (b << SK_B32_SHIFT);
00226 }
00227
00228 extern const uint32_t gMask_00FF00FF;
00229
00230 inline uint32_t SkAlphaMulQ(uint32_t c, unsigned scale) {
00231 uint32_t mask = gMask_00FF00FF;
00232
00233
00234 uint32_t rb = ((c & mask) * scale) >> 8;
00235 uint32_t ag = ((c >> 8) & mask) * scale;
00236 return (rb & mask) | (ag & ~mask);
00237 }
00238
00239 inline SkPMColor SkPMSrcOver(SkPMColor src, SkPMColor dst) {
00240 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
00241 }
00242
00243 inline SkPMColor SkBlendARGB32(SkPMColor src, SkPMColor dst, U8CPU aa) {
00244 SkASSERT((unsigned)aa <= 255);
00245
00246 unsigned src_scale = SkAlpha255To256(aa);
00247 unsigned dst_scale = SkAlpha255To256(255 - SkAlphaMul(SkGetPackedA32(src), src_scale));
00248
00249 return SkAlphaMulQ(src, src_scale) + SkAlphaMulQ(dst, dst_scale);
00250 }
00251
00253
00254
00255 #define SkR32ToR16_MACRO(r) ((unsigned)(r) >> (SK_R32_BITS - SK_R16_BITS))
00256 #define SkG32ToG16_MACRO(g) ((unsigned)(g) >> (SK_G32_BITS - SK_G16_BITS))
00257 #define SkB32ToB16_MACRO(b) ((unsigned)(b) >> (SK_B32_BITS - SK_B16_BITS))
00258
00259 #ifdef SK_DEBUG
00260 inline unsigned SkR32ToR16(unsigned r)
00261 {
00262 SkR32Assert(r);
00263 return SkR32ToR16_MACRO(r);
00264 }
00265 inline unsigned SkG32ToG16(unsigned g)
00266 {
00267 SkG32Assert(g);
00268 return SkG32ToG16_MACRO(g);
00269 }
00270 inline unsigned SkB32ToB16(unsigned b)
00271 {
00272 SkB32Assert(b);
00273 return SkB32ToB16_MACRO(b);
00274 }
00275 #else
00276 #define SkR32ToR16(r) SkR32ToR16_MACRO(r)
00277 #define SkG32ToG16(g) SkG32ToG16_MACRO(g)
00278 #define SkB32ToB16(b) SkB32ToB16_MACRO(b)
00279 #endif
00280
00281 #define SkPacked32ToR16(c) (((unsigned)(c) >> (SK_R32_SHIFT + SK_R32_BITS - SK_R16_BITS)) & SK_R16_MASK)
00282 #define SkPacked32ToG16(c) (((unsigned)(c) >> (SK_G32_SHIFT + SK_G32_BITS - SK_G16_BITS)) & SK_G16_MASK)
00283 #define SkPacked32ToB16(c) (((unsigned)(c) >> (SK_B32_SHIFT + SK_B32_BITS - SK_B16_BITS)) & SK_B16_MASK)
00284
00285 inline U16CPU SkPixel32ToPixel16(SkPMColor c)
00286 {
00287 unsigned r = ((c >> (SK_R32_SHIFT + (8 - SK_R16_BITS))) & SK_R16_MASK) << SK_R16_SHIFT;
00288 unsigned g = ((c >> (SK_G32_SHIFT + (8 - SK_G16_BITS))) & SK_G16_MASK) << SK_G16_SHIFT;
00289 unsigned b = ((c >> (SK_B32_SHIFT + (8 - SK_B16_BITS))) & SK_B16_MASK) << SK_B16_SHIFT;
00290 return r | g | b;
00291 }
00292
00293 inline U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
00294 {
00295 return (SkR32ToR16(r) << SK_R16_SHIFT) |
00296 (SkG32ToG16(g) << SK_G16_SHIFT) |
00297 (SkB32ToB16(b) << SK_B16_SHIFT);
00298 }
00299
00300 #define SkPixel32ToPixel16_ToU16(src) SkToU16(SkPixel32ToPixel16(src))
00301
00303
00304
00305 #define SkShouldDitherXY(x, y) (((x) ^ (y)) & 1)
00306
00307 inline uint16_t SkDitherPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
00308 {
00309 r = ((r << 1) - ((r >> (8 - SK_R16_BITS) << (8 - SK_R16_BITS)) | (r >> SK_R16_BITS))) >> (8 - SK_R16_BITS);
00310 g = ((g << 1) - ((g >> (8 - SK_G16_BITS) << (8 - SK_G16_BITS)) | (g >> SK_G16_BITS))) >> (8 - SK_G16_BITS);
00311 b = ((b << 1) - ((b >> (8 - SK_B16_BITS) << (8 - SK_B16_BITS)) | (b >> SK_B16_BITS))) >> (8 - SK_B16_BITS);
00312
00313 return SkPackRGB16(r, g, b);
00314 }
00315
00316 inline uint16_t SkDitherPixel32ToPixel16(SkPMColor c)
00317 {
00318 return SkDitherPack888ToRGB16(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c));
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 static inline uint32_t SkPMColorToExpanded16x5(SkPMColor c)
00329 {
00330 unsigned sr = SkPacked32ToR16(c);
00331 unsigned sg = SkPacked32ToG16(c);
00332 unsigned sb = SkPacked32ToB16(c);
00333
00334 sr = (sr << 5) | sr;
00335 sg = (sg << 5) | (sg >> 1);
00336 sb = (sb << 5) | sb;
00337 return (sr << 11) | (sg << 21) | (sb << 0);
00338 }
00339
00340
00341
00342
00343 static inline U16CPU SkSrcOver32To16(SkPMColor src, uint16_t dst) {
00344 unsigned sr = SkGetPackedR32(src);
00345 unsigned sg = SkGetPackedG32(src);
00346 unsigned sb = SkGetPackedB32(src);
00347
00348 unsigned dr = SkGetPackedR16(dst);
00349 unsigned dg = SkGetPackedG16(dst);
00350 unsigned db = SkGetPackedB16(dst);
00351
00352 unsigned isa = 255 - SkGetPackedA32(src);
00353
00354 dr = (sr + SkMul16ShiftRound(dr, isa, SK_R16_BITS)) >> (8 - SK_R16_BITS);
00355 dg = (sg + SkMul16ShiftRound(dg, isa, SK_G16_BITS)) >> (8 - SK_G16_BITS);
00356 db = (sb + SkMul16ShiftRound(db, isa, SK_B16_BITS)) >> (8 - SK_B16_BITS);
00357
00358 return SkPackRGB16(dr, dg, db);
00359 }
00360
00362
00363
00364 inline unsigned SkR16ToR32(unsigned r)
00365 {
00366 return (r << (8 - SK_R16_BITS)) | (r >> (2 * SK_R16_BITS - 8));
00367 }
00368 inline unsigned SkG16ToG32(unsigned g)
00369 {
00370 return (g << (8 - SK_G16_BITS)) | (g >> (2 * SK_G16_BITS - 8));
00371 }
00372 inline unsigned SkB16ToB32(unsigned b)
00373 {
00374 return (b << (8 - SK_B16_BITS)) | (b >> (2 * SK_B16_BITS - 8));
00375 }
00376
00377 #define SkPacked16ToR32(c) SkR16ToR32(SkGetPackedR16(c))
00378 #define SkPacked16ToG32(c) SkG16ToG32(SkGetPackedG16(c))
00379 #define SkPacked16ToB32(c) SkB16ToB32(SkGetPackedB16(c))
00380
00381 inline SkPMColor SkPixel16ToPixel32(U16CPU src)
00382 {
00383 SkASSERT(src == SkToU16(src));
00384
00385 unsigned r = SkPacked16ToR32(src);
00386 unsigned g = SkPacked16ToG32(src);
00387 unsigned b = SkPacked16ToB32(src);
00388
00389 SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
00390 SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
00391 SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
00392
00393 return SkPackARGB32(0xFF, r, g, b);
00394 }
00395
00396
00397 static inline SkColor SkPixel16ToColor(U16CPU src) {
00398 SkASSERT(src == SkToU16(src));
00399
00400 unsigned r = SkPacked16ToR32(src);
00401 unsigned g = SkPacked16ToG32(src);
00402 unsigned b = SkPacked16ToB32(src);
00403
00404 SkASSERT((r >> (8 - SK_R16_BITS)) == SkGetPackedR16(src));
00405 SkASSERT((g >> (8 - SK_G16_BITS)) == SkGetPackedG16(src));
00406 SkASSERT((b >> (8 - SK_B16_BITS)) == SkGetPackedB16(src));
00407
00408 return SkColorSetRGB(r, g, b);
00409 }
00410
00412
00413 typedef uint16_t SkPMColor16;
00414
00415
00416 #define SK_A4444_SHIFT 0
00417 #define SK_R4444_SHIFT 12
00418 #define SK_G4444_SHIFT 8
00419 #define SK_B4444_SHIFT 4
00420
00421 #define SkA32To4444(a) ((unsigned)(a) >> 4)
00422 #define SkR32To4444(r) ((unsigned)(r) >> 4)
00423 #define SkG32To4444(g) ((unsigned)(g) >> 4)
00424 #define SkB32To4444(b) ((unsigned)(b) >> 4)
00425
00426 static inline U8CPU SkReplicateNibble(unsigned nib)
00427 {
00428 SkASSERT(nib <= 0xF);
00429 return (nib << 4) | nib;
00430 }
00431
00432 #define SkA4444ToA32(a) SkReplicateNibble(a)
00433 #define SkR4444ToR32(r) SkReplicateNibble(r)
00434 #define SkG4444ToG32(g) SkReplicateNibble(g)
00435 #define SkB4444ToB32(b) SkReplicateNibble(b)
00436
00437 #define SkGetPackedA4444(c) (((unsigned)(c) >> SK_A4444_SHIFT) & 0xF)
00438 #define SkGetPackedR4444(c) (((unsigned)(c) >> SK_R4444_SHIFT) & 0xF)
00439 #define SkGetPackedG4444(c) (((unsigned)(c) >> SK_G4444_SHIFT) & 0xF)
00440 #define SkGetPackedB4444(c) (((unsigned)(c) >> SK_B4444_SHIFT) & 0xF)
00441
00442 #define SkPacked4444ToA32(c) SkReplicateNibble(SkGetPackedA4444(c))
00443 #define SkPacked4444ToR32(c) SkReplicateNibble(SkGetPackedR4444(c))
00444 #define SkPacked4444ToG32(c) SkReplicateNibble(SkGetPackedG4444(c))
00445 #define SkPacked4444ToB32(c) SkReplicateNibble(SkGetPackedB4444(c))
00446
00447 #ifdef SK_DEBUG
00448 static inline void SkPMColor16Assert(U16CPU c)
00449 {
00450 unsigned a = SkGetPackedA4444(c);
00451 unsigned r = SkGetPackedR4444(c);
00452 unsigned g = SkGetPackedG4444(c);
00453 unsigned b = SkGetPackedB4444(c);
00454
00455 SkASSERT(a <= 0xF);
00456 SkASSERT(r <= a);
00457 SkASSERT(g <= a);
00458 SkASSERT(b <= a);
00459 }
00460 #else
00461 #define SkPMColor16Assert(c)
00462 #endif
00463
00464 static inline unsigned SkAlpha15To16(unsigned a)
00465 {
00466 SkASSERT(a <= 0xF);
00467 return a + (a >> 3);
00468 }
00469
00470 #ifdef SK_DEBUG
00471 static inline int SkAlphaMul4(int value, int scale)
00472 {
00473 SkASSERT((unsigned)scale <= 0x10);
00474 return value * scale >> 4;
00475 }
00476 #else
00477 #define SkAlphaMul4(value, scale) ((value) * (scale) >> 4)
00478 #endif
00479
00480 static inline unsigned SkR4444ToR565(unsigned r)
00481 {
00482 SkASSERT(r <= 0xF);
00483 return (r << (SK_R16_BITS - 4)) | (r >> (8 - SK_R16_BITS));
00484 }
00485
00486 static inline unsigned SkG4444ToG565(unsigned g)
00487 {
00488 SkASSERT(g <= 0xF);
00489 return (g << (SK_G16_BITS - 4)) | (g >> (8 - SK_G16_BITS));
00490 }
00491
00492 static inline unsigned SkB4444ToB565(unsigned b)
00493 {
00494 SkASSERT(b <= 0xF);
00495 return (b << (SK_B16_BITS - 4)) | (b >> (8 - SK_B16_BITS));
00496 }
00497
00498 static inline SkPMColor16 SkPackARGB4444(unsigned a, unsigned r,
00499 unsigned g, unsigned b)
00500 {
00501 SkASSERT(a <= 0xF);
00502 SkASSERT(r <= a);
00503 SkASSERT(g <= a);
00504 SkASSERT(b <= a);
00505
00506 return (SkPMColor16)((a << SK_A4444_SHIFT) | (r << SK_R4444_SHIFT) |
00507 (g << SK_G4444_SHIFT) | (b << SK_B4444_SHIFT));
00508 }
00509
00510 extern const uint16_t gMask_0F0F;
00511
00512 inline U16CPU SkAlphaMulQ4(U16CPU c, unsigned scale)
00513 {
00514 SkASSERT(scale <= 16);
00515
00516 const unsigned mask = 0xF0F;
00517
00518 #if 0
00519 unsigned rb = ((c & mask) * scale) >> 4;
00520 unsigned ag = ((c >> 4) & mask) * scale;
00521 return (rb & mask) | (ag & ~mask);
00522 #else
00523 c = (c & mask) | ((c & (mask << 4)) << 12);
00524 c = c * scale >> 4;
00525 return (c & mask) | ((c >> 12) & (mask << 4));
00526 #endif
00527 }
00528
00532 inline uint32_t SkExpand_4444(U16CPU c)
00533 {
00534 SkASSERT(c == (uint16_t)c);
00535
00536 const unsigned mask = 0xF0F;
00537 return (c & mask) | ((c & ~mask) << 12);
00538 }
00539
00547 static inline U16CPU SkCompact_4444(uint32_t c)
00548 {
00549 const unsigned mask = 0xF0F;
00550 return (c & mask) | ((c >> 12) & ~mask);
00551 }
00552
00553 static inline uint16_t SkSrcOver4444To16(SkPMColor16 s, uint16_t d)
00554 {
00555 unsigned sa = SkGetPackedA4444(s);
00556 unsigned sr = SkR4444ToR565(SkGetPackedR4444(s));
00557 unsigned sg = SkG4444ToG565(SkGetPackedG4444(s));
00558 unsigned sb = SkB4444ToB565(SkGetPackedB4444(s));
00559
00560
00561
00562
00563
00564 sg &= ~(~(sa >> 3) & 1);
00565
00566 unsigned scale = SkAlpha15To16(15 - sa);
00567 unsigned dr = SkAlphaMul4(SkGetPackedR16(d), scale);
00568 unsigned dg = SkAlphaMul4(SkGetPackedG16(d), scale);
00569 unsigned db = SkAlphaMul4(SkGetPackedB16(d), scale);
00570
00571 #if 0
00572 if (sg + dg > 63) {
00573 SkDebugf("---- SkSrcOver4444To16 src=%x dst=%x scale=%d, sg=%d dg=%d\n", s, d, scale, sg, dg);
00574 }
00575 #endif
00576 return SkPackRGB16(sr + dr, sg + dg, sb + db);
00577 }
00578
00579 static inline uint16_t SkBlend4444To16(SkPMColor16 src, uint16_t dst, int scale16)
00580 {
00581 SkASSERT((unsigned)scale16 <= 16);
00582
00583 return SkSrcOver4444To16(SkAlphaMulQ4(src, scale16), dst);
00584 }
00585
00586 static inline uint16_t SkBlend4444(SkPMColor16 src, SkPMColor16 dst, int scale16)
00587 {
00588 SkASSERT((unsigned)scale16 <= 16);
00589
00590 uint32_t src32 = SkExpand_4444(src) * scale16;
00591
00592 #ifdef SK_DEBUG
00593 {
00594 unsigned srcA = SkGetPackedA4444(src) * scale16;
00595 SkASSERT(srcA == (src32 & 0xFF));
00596 }
00597 #endif
00598 unsigned dstScale = SkAlpha255To256(255 - (src32 & 0xFF)) >> 4;
00599 uint32_t dst32 = SkExpand_4444(dst) * dstScale;
00600 return SkCompact_4444((src32 + dst32) >> 4);
00601 }
00602
00603 static inline SkPMColor SkPixel4444ToPixel32(U16CPU c)
00604 {
00605 uint32_t d = (SkGetPackedA4444(c) << SK_A32_SHIFT) |
00606 (SkGetPackedR4444(c) << SK_R32_SHIFT) |
00607 (SkGetPackedG4444(c) << SK_G32_SHIFT) |
00608 (SkGetPackedB4444(c) << SK_B32_SHIFT);
00609 return d | (d << 4);
00610 }
00611
00612 static inline SkPMColor16 SkPixel32ToPixel4444(SkPMColor c)
00613 {
00614 return (((c >> (SK_A32_SHIFT + 4)) & 0xF) << SK_A4444_SHIFT) |
00615 (((c >> (SK_R32_SHIFT + 4)) & 0xF) << SK_R4444_SHIFT) |
00616 (((c >> (SK_G32_SHIFT + 4)) & 0xF) << SK_G4444_SHIFT) |
00617 (((c >> (SK_B32_SHIFT + 4)) & 0xF) << SK_B4444_SHIFT);
00618 }
00619
00620
00621 static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r,
00622 U8CPU g, U8CPU b)
00623 {
00624 a = ((a << 1) - ((a >> 4 << 4) | (a >> 4))) >> 4;
00625 r = ((r << 1) - ((r >> 4 << 4) | (r >> 4))) >> 4;
00626 g = ((g << 1) - ((g >> 4 << 4) | (g >> 4))) >> 4;
00627 b = ((b << 1) - ((b >> 4 << 4) | (b >> 4))) >> 4;
00628
00629 return SkPackARGB4444(a, r, g, b);
00630 }
00631
00632 static inline SkPMColor16 SkDitherPixel32To4444(SkPMColor c)
00633 {
00634 return SkDitherARGB32To4444(SkGetPackedA32(c), SkGetPackedR32(c),
00635 SkGetPackedG32(c), SkGetPackedB32(c));
00636 }
00637
00638
00639
00640
00641
00642 static inline uint32_t SkExpand_8888(SkPMColor c)
00643 {
00644 return (((c >> SK_R32_SHIFT) & 0xFF) << 24) |
00645 (((c >> SK_G32_SHIFT) & 0xFF) << 8) |
00646 (((c >> SK_B32_SHIFT) & 0xFF) << 16) |
00647 (((c >> SK_A32_SHIFT) & 0xFF) << 0);
00648 }
00649
00650
00651
00652
00653 static inline SkPMColor SkCompact_8888(uint32_t c)
00654 {
00655 return (((c >> 24) & 0xFF) << SK_R32_SHIFT) |
00656 (((c >> 8) & 0xFF) << SK_G32_SHIFT) |
00657 (((c >> 16) & 0xFF) << SK_B32_SHIFT) |
00658 (((c >> 0) & 0xFF) << SK_A32_SHIFT);
00659 }
00660
00661
00662
00663
00664
00665 static inline uint32_t SkExpand32_4444(SkPMColor c)
00666 {
00667 return (((c >> (SK_R32_SHIFT + 4)) & 0xF) << 24) |
00668 (((c >> (SK_G32_SHIFT + 4)) & 0xF) << 8) |
00669 (((c >> (SK_B32_SHIFT + 4)) & 0xF) << 16) |
00670 (((c >> (SK_A32_SHIFT + 4)) & 0xF) << 0);
00671 }
00672
00673
00674
00675 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other, int n);
00676
00677 #endif
00678