1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkBlitRow.h" 9#include "SkColorPriv.h" 10#include "SkDither.h" 11 12/////////////////////////////////////////////////////////////////////////////// 13 14static void S32_D4444_Opaque(uint16_t* SK_RESTRICT dst, 15 const SkPMColor* SK_RESTRICT src, int count, 16 U8CPU alpha, int /*x*/, int /*y*/) { 17 SkASSERT(255 == alpha); 18 19 if (count > 0) { 20 do { 21 SkPMColor c = *src++; 22 SkPMColorAssert(c); 23 SkASSERT(SkGetPackedA32(c) == 255); 24 *dst++ = SkPixel32ToPixel4444(c); 25 } while (--count != 0); 26 } 27} 28 29static void S32_D4444_Blend(uint16_t* SK_RESTRICT dst, 30 const SkPMColor* SK_RESTRICT src, int count, 31 U8CPU alpha, int /*x*/, int /*y*/) { 32 SkASSERT(255 > alpha); 33 34 if (count > 0) { 35 unsigned scale16 = SkAlpha255To256(alpha) >> 4; 36 do { 37 SkPMColor c = *src++; 38 SkPMColorAssert(c); 39 SkASSERT(SkGetPackedA32(c) == 255); 40 41 uint32_t src_expand = SkExpand32_4444(c); 42 uint32_t dst_expand = SkExpand_4444(*dst); 43 dst_expand += (src_expand - dst_expand) * scale16 >> 4; 44 *dst++ = SkCompact_4444(dst_expand); 45 } while (--count != 0); 46 } 47} 48 49static void S32A_D4444_Opaque(uint16_t* SK_RESTRICT dst, 50 const SkPMColor* SK_RESTRICT src, int count, 51 U8CPU alpha, int /*x*/, int /*y*/) { 52 SkASSERT(255 == alpha); 53 54 if (count > 0) { 55 do { 56 SkPMColor c = *src++; 57 SkPMColorAssert(c); 58// if (__builtin_expect(c!=0, 1)) 59 if (c) 60 { 61 unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4; 62 uint32_t src_expand = SkExpand_8888(c); 63 uint32_t dst_expand = SkExpand_4444(*dst) * scale16; 64 *dst = SkCompact_4444((src_expand + dst_expand) >> 4); 65 } 66 dst += 1; 67 } while (--count != 0); 68 } 69} 70 71static void S32A_D4444_Blend(uint16_t* SK_RESTRICT dst, 72 const SkPMColor* SK_RESTRICT src, int count, 73 U8CPU alpha, int /*x*/, int /*y*/) { 74 SkASSERT(255 > alpha); 75 76 if (count > 0) { 77 int src_scale = SkAlpha255To256(alpha) >> 4; 78 do { 79 SkPMColor sc = *src++; 80 SkPMColorAssert(sc); 81 82 if (sc) { 83 unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8); 84 uint32_t src_expand = SkExpand32_4444(sc) * src_scale; 85 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale; 86 *dst = SkCompact_4444((src_expand + dst_expand) >> 4); 87 } 88 dst += 1; 89 } while (--count != 0); 90 } 91} 92 93///////////////////////////////////////////////////////////////////////////// 94 95static void S32_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst, 96 const SkPMColor* SK_RESTRICT src, 97 int count, U8CPU alpha, int x, int y) { 98 SkASSERT(255 == alpha); 99 100 if (count > 0) { 101 DITHER_4444_SCAN(y); 102 do { 103 SkPMColor c = *src++; 104 SkPMColorAssert(c); 105 SkASSERT(SkGetPackedA32(c) == 255); 106 107 unsigned dither = DITHER_VALUE(x); 108 *dst++ = SkDitherARGB32To4444(c, dither); 109 DITHER_INC_X(x); 110 } while (--count != 0); 111 } 112} 113 114static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst, 115 const SkPMColor* SK_RESTRICT src, 116 int count, U8CPU alpha, int x, int y) { 117 SkASSERT(255 > alpha); 118 119 if (count > 0) { 120 int scale16 = SkAlpha255To256(alpha) >> 4; 121 DITHER_4444_SCAN(y); 122 do { 123 SkPMColor c = *src++; 124 SkPMColorAssert(c); 125 SkASSERT(SkGetPackedA32(c) == 255); 126 127 uint32_t src_expand = SkExpand32_4444(c) * scale16; 128 uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16); 129 130 c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor 131 *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x)); 132 DITHER_INC_X(x); 133 } while (--count != 0); 134 } 135} 136 137static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst, 138 const SkPMColor* SK_RESTRICT src, 139 int count, U8CPU alpha, int x, int y) { 140 SkASSERT(255 == alpha); 141 142 if (count > 0) { 143 DITHER_4444_SCAN(y); 144 do { 145 SkPMColor c = *src++; 146 SkPMColorAssert(c); 147 if (c) { 148 unsigned a = SkGetPackedA32(c); 149 int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a)); 150 151 unsigned scale16 = SkAlpha255To256(255 - a) >> 4; 152 uint32_t src_expand = SkExpand_8888(c); 153 uint32_t dst_expand = SkExpand_4444(*dst) * scale16; 154 // convert back to SkPMColor 155 c = SkCompact_8888(src_expand + dst_expand); 156 *dst = SkDitherARGB32To4444(c, d); 157 } 158 dst += 1; 159 DITHER_INC_X(x); 160 } while (--count != 0); 161 } 162} 163 164// need DitherExpand888To4444(expand, dither) 165 166static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst, 167 const SkPMColor* SK_RESTRICT src, 168 int count, U8CPU alpha, int x, int y) { 169 SkASSERT(255 > alpha); 170 171 if (count > 0) { 172 int src_scale = SkAlpha255To256(alpha) >> 4; 173 DITHER_4444_SCAN(y); 174 do { 175 SkPMColor c = *src++; 176 SkPMColorAssert(c); 177 if (c) { 178 unsigned a = SkAlpha255To256(SkGetPackedA32(c)); 179 int d = SkAlphaMul(DITHER_VALUE(x), a); 180 181 unsigned dst_scale = 16 - SkAlphaMul(src_scale, a); 182 uint32_t src_expand = SkExpand32_4444(c) * src_scale; 183 uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale; 184 // convert back to SkPMColor 185 c = SkCompact_8888(src_expand + dst_expand); 186 *dst = SkDitherARGB32To4444(c, d); 187 } 188 dst += 1; 189 DITHER_INC_X(x); 190 } while (--count != 0); 191 } 192} 193 194/////////////////////////////////////////////////////////////////////////////// 195/////////////////////////////////////////////////////////////////////////////// 196 197static const SkBlitRow::Proc gProcs4444[] = { 198 // no dither 199 S32_D4444_Opaque, 200 S32_D4444_Blend, 201 202 S32A_D4444_Opaque, 203 S32A_D4444_Blend, 204 205 // dither 206 S32_D4444_Opaque_Dither, 207 S32_D4444_Blend_Dither, 208 209 S32A_D4444_Opaque_Dither, 210 S32A_D4444_Blend_Dither 211}; 212 213SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags); 214SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags) 215{ 216 SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444)); 217 218 return gProcs4444[flags]; 219} 220 221 222