1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/include/core/SkDither.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,198 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2008 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#ifndef SkDither_DEFINED 1.14 +#define SkDither_DEFINED 1.15 + 1.16 +#include "SkColorPriv.h" 1.17 + 1.18 +#define SK_DitherValueMax4444 15 1.19 +#define SK_DitherValueMax565 7 1.20 + 1.21 +/* need to use macros for bit-counts for each component, and then 1.22 + move these into SkColorPriv.h 1.23 +*/ 1.24 + 1.25 +#define SkDITHER_R32_FOR_565_MACRO(r, d) (r + d - (r >> 5)) 1.26 +#define SkDITHER_G32_FOR_565_MACRO(g, d) (g + (d >> 1) - (g >> 6)) 1.27 +#define SkDITHER_B32_FOR_565_MACRO(b, d) (b + d - (b >> 5)) 1.28 + 1.29 +#define SkDITHER_A32_FOR_4444_MACRO(a, d) (a + 15 - (a >> 4)) 1.30 +#define SkDITHER_R32_FOR_4444_MACRO(r, d) (r + d - (r >> 4)) 1.31 +#define SkDITHER_G32_FOR_4444_MACRO(g, d) (g + d - (g >> 4)) 1.32 +#define SkDITHER_B32_FOR_4444_MACRO(b, d) (b + d - (b >> 4)) 1.33 + 1.34 +#ifdef SK_DEBUG 1.35 + inline unsigned SkDITHER_R32_FOR_565(unsigned r, unsigned d) 1.36 + { 1.37 + SkASSERT(d <= SK_DitherValueMax565); 1.38 + SkA32Assert(r); 1.39 + r = SkDITHER_R32_FOR_565_MACRO(r, d); 1.40 + SkA32Assert(r); 1.41 + return r; 1.42 + } 1.43 + inline unsigned SkDITHER_G32_FOR_565(unsigned g, unsigned d) 1.44 + { 1.45 + SkASSERT(d <= SK_DitherValueMax565); 1.46 + SkG32Assert(g); 1.47 + g = SkDITHER_G32_FOR_565_MACRO(g, d); 1.48 + SkG32Assert(g); 1.49 + return g; 1.50 + } 1.51 + inline unsigned SkDITHER_B32_FOR_565(unsigned b, unsigned d) 1.52 + { 1.53 + SkASSERT(d <= SK_DitherValueMax565); 1.54 + SkB32Assert(b); 1.55 + b = SkDITHER_B32_FOR_565_MACRO(b, d); 1.56 + SkB32Assert(b); 1.57 + return b; 1.58 + } 1.59 +#else 1.60 + #define SkDITHER_R32_FOR_565(r, d) SkDITHER_R32_FOR_565_MACRO(r, d) 1.61 + #define SkDITHER_G32_FOR_565(g, d) SkDITHER_G32_FOR_565_MACRO(g, d) 1.62 + #define SkDITHER_B32_FOR_565(b, d) SkDITHER_B32_FOR_565_MACRO(b, d) 1.63 +#endif 1.64 + 1.65 +#define SkDITHER_R32To565(r, d) SkR32ToR16(SkDITHER_R32_FOR_565(r, d)) 1.66 +#define SkDITHER_G32To565(g, d) SkG32ToG16(SkDITHER_G32_FOR_565(g, d)) 1.67 +#define SkDITHER_B32To565(b, d) SkB32ToB16(SkDITHER_B32_FOR_565(b, d)) 1.68 + 1.69 +#define SkDITHER_A32To4444(a, d) SkA32To4444(SkDITHER_A32_FOR_4444_MACRO(a, d)) 1.70 +#define SkDITHER_R32To4444(r, d) SkR32To4444(SkDITHER_R32_FOR_4444_MACRO(r, d)) 1.71 +#define SkDITHER_G32To4444(g, d) SkG32To4444(SkDITHER_G32_FOR_4444_MACRO(g, d)) 1.72 +#define SkDITHER_B32To4444(b, d) SkB32To4444(SkDITHER_B32_FOR_4444_MACRO(b, d)) 1.73 + 1.74 +static inline SkPMColor SkDitherARGB32For565(SkPMColor c, unsigned dither) 1.75 +{ 1.76 + SkASSERT(dither <= SK_DitherValueMax565); 1.77 + 1.78 + unsigned sa = SkGetPackedA32(c); 1.79 + dither = SkAlphaMul(dither, SkAlpha255To256(sa)); 1.80 + 1.81 + unsigned sr = SkGetPackedR32(c); 1.82 + unsigned sg = SkGetPackedG32(c); 1.83 + unsigned sb = SkGetPackedB32(c); 1.84 + sr = SkDITHER_R32_FOR_565(sr, dither); 1.85 + sg = SkDITHER_G32_FOR_565(sg, dither); 1.86 + sb = SkDITHER_B32_FOR_565(sb, dither); 1.87 + 1.88 + return SkPackARGB32(sa, sr, sg, sb); 1.89 +} 1.90 + 1.91 +static inline SkPMColor SkDitherRGB32For565(SkPMColor c, unsigned dither) 1.92 +{ 1.93 + SkASSERT(dither <= SK_DitherValueMax565); 1.94 + 1.95 + unsigned sr = SkGetPackedR32(c); 1.96 + unsigned sg = SkGetPackedG32(c); 1.97 + unsigned sb = SkGetPackedB32(c); 1.98 + sr = SkDITHER_R32_FOR_565(sr, dither); 1.99 + sg = SkDITHER_G32_FOR_565(sg, dither); 1.100 + sb = SkDITHER_B32_FOR_565(sb, dither); 1.101 + 1.102 + return SkPackARGB32(0xFF, sr, sg, sb); 1.103 +} 1.104 + 1.105 +static inline uint16_t SkDitherRGBTo565(U8CPU r, U8CPU g, U8CPU b, 1.106 + unsigned dither) 1.107 +{ 1.108 + SkASSERT(dither <= SK_DitherValueMax565); 1.109 + r = SkDITHER_R32To565(r, dither); 1.110 + g = SkDITHER_G32To565(g, dither); 1.111 + b = SkDITHER_B32To565(b, dither); 1.112 + return SkPackRGB16(r, g, b); 1.113 +} 1.114 + 1.115 +static inline uint16_t SkDitherRGB32To565(SkPMColor c, unsigned dither) 1.116 +{ 1.117 + SkASSERT(dither <= SK_DitherValueMax565); 1.118 + 1.119 + unsigned sr = SkGetPackedR32(c); 1.120 + unsigned sg = SkGetPackedG32(c); 1.121 + unsigned sb = SkGetPackedB32(c); 1.122 + sr = SkDITHER_R32To565(sr, dither); 1.123 + sg = SkDITHER_G32To565(sg, dither); 1.124 + sb = SkDITHER_B32To565(sb, dither); 1.125 + 1.126 + return SkPackRGB16(sr, sg, sb); 1.127 +} 1.128 + 1.129 +static inline uint16_t SkDitherARGB32To565(U8CPU sa, SkPMColor c, unsigned dither) 1.130 +{ 1.131 + SkASSERT(dither <= SK_DitherValueMax565); 1.132 + dither = SkAlphaMul(dither, SkAlpha255To256(sa)); 1.133 + 1.134 + unsigned sr = SkGetPackedR32(c); 1.135 + unsigned sg = SkGetPackedG32(c); 1.136 + unsigned sb = SkGetPackedB32(c); 1.137 + sr = SkDITHER_R32To565(sr, dither); 1.138 + sg = SkDITHER_G32To565(sg, dither); 1.139 + sb = SkDITHER_B32To565(sb, dither); 1.140 + 1.141 + return SkPackRGB16(sr, sg, sb); 1.142 +} 1.143 + 1.144 +///////////////////////// 4444 1.145 + 1.146 +static inline SkPMColor16 SkDitherARGB32To4444(U8CPU a, U8CPU r, U8CPU g, 1.147 + U8CPU b, unsigned dither) 1.148 +{ 1.149 + dither = SkAlphaMul(dither, SkAlpha255To256(a)); 1.150 + 1.151 + a = SkDITHER_A32To4444(a, dither); 1.152 + r = SkDITHER_R32To4444(r, dither); 1.153 + g = SkDITHER_G32To4444(g, dither); 1.154 + b = SkDITHER_B32To4444(b, dither); 1.155 + 1.156 + return SkPackARGB4444(a, r, g, b); 1.157 +} 1.158 + 1.159 +static inline SkPMColor16 SkDitherARGB32To4444(SkPMColor c, unsigned dither) 1.160 +{ 1.161 + unsigned a = SkGetPackedA32(c); 1.162 + unsigned r = SkGetPackedR32(c); 1.163 + unsigned g = SkGetPackedG32(c); 1.164 + unsigned b = SkGetPackedB32(c); 1.165 + 1.166 + dither = SkAlphaMul(dither, SkAlpha255To256(a)); 1.167 + 1.168 + a = SkDITHER_A32To4444(a, dither); 1.169 + r = SkDITHER_R32To4444(r, dither); 1.170 + g = SkDITHER_G32To4444(g, dither); 1.171 + b = SkDITHER_B32To4444(b, dither); 1.172 + 1.173 + return SkPackARGB4444(a, r, g, b); 1.174 +} 1.175 + 1.176 +// TODO: need dither routines for 565 -> 4444 1.177 + 1.178 +// this toggles between a 4x4 and a 1x4 array 1.179 +//#define ENABLE_DITHER_MATRIX_4X4 1.180 + 1.181 +#ifdef ENABLE_DITHER_MATRIX_4X4 1.182 + extern const uint8_t gDitherMatrix_4Bit_4X4[4][4]; 1.183 + extern const uint8_t gDitherMatrix_3Bit_4X4[4][4]; 1.184 + 1.185 + #define DITHER_4444_SCAN(y) const uint8_t* dither_scan = gDitherMatrix_4Bit_4X4[(y) & 3] 1.186 + #define DITHER_565_SCAN(y) const uint8_t* dither_scan = gDitherMatrix_3Bit_4X4[(y) & 3] 1.187 + 1.188 + #define DITHER_VALUE(x) dither_scan[(x) & 3] 1.189 +#else 1.190 + extern const uint16_t gDitherMatrix_4Bit_16[4]; 1.191 + extern const uint16_t gDitherMatrix_3Bit_16[4]; 1.192 + 1.193 + #define DITHER_4444_SCAN(y) const uint16_t dither_scan = gDitherMatrix_4Bit_16[(y) & 3] 1.194 + #define DITHER_565_SCAN(y) const uint16_t dither_scan = gDitherMatrix_3Bit_16[(y) & 3] 1.195 + 1.196 + #define DITHER_VALUE(x) ((dither_scan >> (((x) & 3) << 2)) & 0xF) 1.197 +#endif 1.198 + 1.199 +#define DITHER_INC_X(x) ++(x) 1.200 + 1.201 +#endif