| /* |
| * Copyright 2011 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "SkBlitRow.h" |
| #include "SkColorPriv.h" |
| #include "SkDither.h" |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| static void S32_D4444_Opaque(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, int count, |
| U8CPU alpha, int /*x*/, int /*y*/) { |
| SkASSERT(255 == alpha); |
| |
| if (count > 0) { |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| SkASSERT(SkGetPackedA32(c) == 255); |
| *dst++ = SkPixel32ToPixel4444(c); |
| } while (--count != 0); |
| } |
| } |
| |
| static void S32_D4444_Blend(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, int count, |
| U8CPU alpha, int /*x*/, int /*y*/) { |
| SkASSERT(255 > alpha); |
| |
| if (count > 0) { |
| unsigned scale16 = SkAlpha255To256(alpha) >> 4; |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| SkASSERT(SkGetPackedA32(c) == 255); |
| |
| uint32_t src_expand = SkExpand32_4444(c); |
| uint32_t dst_expand = SkExpand_4444(*dst); |
| dst_expand += (src_expand - dst_expand) * scale16 >> 4; |
| *dst++ = SkCompact_4444(dst_expand); |
| } while (--count != 0); |
| } |
| } |
| |
| static void S32A_D4444_Opaque(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, int count, |
| U8CPU alpha, int /*x*/, int /*y*/) { |
| SkASSERT(255 == alpha); |
| |
| if (count > 0) { |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| // if (__builtin_expect(c!=0, 1)) |
| if (c) |
| { |
| unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4; |
| uint32_t src_expand = SkExpand_8888(c); |
| uint32_t dst_expand = SkExpand_4444(*dst) * scale16; |
| *dst = SkCompact_4444((src_expand + dst_expand) >> 4); |
| } |
| dst += 1; |
| } while (--count != 0); |
| } |
| } |
| |
| static void S32A_D4444_Blend(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, int count, |
| U8CPU alpha, int /*x*/, int /*y*/) { |
| SkASSERT(255 > alpha); |
| |
| if (count > 0) { |
| int src_scale = SkAlpha255To256(alpha) >> 4; |
| do { |
| SkPMColor sc = *src++; |
| SkPMColorAssert(sc); |
| |
| if (sc) { |
| unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8); |
| uint32_t src_expand = SkExpand32_4444(sc) * src_scale; |
| uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale; |
| *dst = SkCompact_4444((src_expand + dst_expand) >> 4); |
| } |
| dst += 1; |
| } while (--count != 0); |
| } |
| } |
| |
| ///////////////////////////////////////////////////////////////////////////// |
| |
| static void S32_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, |
| int count, U8CPU alpha, int x, int y) { |
| SkASSERT(255 == alpha); |
| |
| if (count > 0) { |
| DITHER_4444_SCAN(y); |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| SkASSERT(SkGetPackedA32(c) == 255); |
| |
| unsigned dither = DITHER_VALUE(x); |
| *dst++ = SkDitherARGB32To4444(c, dither); |
| DITHER_INC_X(x); |
| } while (--count != 0); |
| } |
| } |
| |
| static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, |
| int count, U8CPU alpha, int x, int y) { |
| SkASSERT(255 > alpha); |
| |
| if (count > 0) { |
| int scale16 = SkAlpha255To256(alpha) >> 4; |
| DITHER_4444_SCAN(y); |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| SkASSERT(SkGetPackedA32(c) == 255); |
| |
| uint32_t src_expand = SkExpand32_4444(c) * scale16; |
| uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16); |
| |
| c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor |
| *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |
| DITHER_INC_X(x); |
| } while (--count != 0); |
| } |
| } |
| |
| static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, |
| int count, U8CPU alpha, int x, int y) { |
| SkASSERT(255 == alpha); |
| |
| if (count > 0) { |
| DITHER_4444_SCAN(y); |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| if (c) { |
| unsigned a = SkGetPackedA32(c); |
| int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); |
| |
| unsigned scale16 = SkAlpha255To256(255 - a) >> 4; |
| uint32_t src_expand = SkExpand_8888(c); |
| uint32_t dst_expand = SkExpand_4444(*dst) * scale16; |
| // convert back to SkPMColor |
| c = SkCompact_8888(src_expand + dst_expand); |
| *dst = SkDitherARGB32To4444(c, d); |
| } |
| dst += 1; |
| DITHER_INC_X(x); |
| } while (--count != 0); |
| } |
| } |
| |
| // need DitherExpand888To4444(expand, dither) |
| |
| static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst, |
| const SkPMColor* SK_RESTRICT src, |
| int count, U8CPU alpha, int x, int y) { |
| SkASSERT(255 > alpha); |
| |
| if (count > 0) { |
| int src_scale = SkAlpha255To256(alpha) >> 4; |
| DITHER_4444_SCAN(y); |
| do { |
| SkPMColor c = *src++; |
| SkPMColorAssert(c); |
| if (c) { |
| unsigned a = SkAlpha255To256(SkGetPackedA32(c)); |
| int d = SkAlphaMul(DITHER_VALUE(x), a); |
| |
| unsigned dst_scale = 16 - SkAlphaMul(src_scale, a); |
| uint32_t src_expand = SkExpand32_4444(c) * src_scale; |
| uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale; |
| // convert back to SkPMColor |
| c = SkCompact_8888(src_expand + dst_expand); |
| *dst = SkDitherARGB32To4444(c, d); |
| } |
| dst += 1; |
| DITHER_INC_X(x); |
| } while (--count != 0); |
| } |
| } |
| |
| /////////////////////////////////////////////////////////////////////////////// |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| static const SkBlitRow::Proc gProcs4444[] = { |
| // no dither |
| S32_D4444_Opaque, |
| S32_D4444_Blend, |
| |
| S32A_D4444_Opaque, |
| S32A_D4444_Blend, |
| |
| // dither |
| S32_D4444_Opaque_Dither, |
| S32_D4444_Blend_Dither, |
| |
| S32A_D4444_Opaque_Dither, |
| S32A_D4444_Blend_Dither |
| }; |
| |
| SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); |
| SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags) |
| { |
| SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444)); |
| |
| return gProcs4444[flags]; |
| } |
| |
| |