OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2007 The Android Open Source Project | 2 * Copyright 2007 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 | 8 |
9 #include "SkScaledBitmapSampler.h" | 9 #include "SkScaledBitmapSampler.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
12 #include "SkDither.h" | 12 #include "SkDither.h" |
13 #include "SkTypes.h" | 13 #include "SkTypes.h" |
14 | 14 |
15 // 8888 | 15 // 8888 |
16 | 16 |
17 static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, | 17 static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, |
18 const uint8_t* SK_RESTRICT src, | 18 const uint8_t* SK_RESTRICT src, |
19 int width, int deltaSrc, int, const SkPMColor[]) { | 19 int width, int deltaSrc, int, const SkPMColor[]) { |
20 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 20 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
21 for (int x = 0; x < width; x++) { | 21 for (int x = 0; x < width; x++) { |
22 dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); | 22 dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); |
23 src += deltaSrc; | 23 src += deltaSrc; |
24 } | 24 } |
25 return false; | 25 return false; |
26 } | 26 } |
27 | 27 |
| 28 static SkScaledBitmapSampler::RowProc get_gray_to_8888_proc(const SkImageDecoder
& decoder) { |
| 29 // Dither, unpremul, and skipZeroes have no effect |
| 30 return Sample_Gray_D8888; |
| 31 } |
| 32 |
28 static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, | 33 static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, |
29 const uint8_t* SK_RESTRICT src, | 34 const uint8_t* SK_RESTRICT src, |
30 int width, int deltaSrc, int, const SkPMColor[]) { | 35 int width, int deltaSrc, int, const SkPMColor[]) { |
31 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 36 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
32 for (int x = 0; x < width; x++) { | 37 for (int x = 0; x < width; x++) { |
33 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); | 38 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); |
34 src += deltaSrc; | 39 src += deltaSrc; |
35 } | 40 } |
36 return false; | 41 return false; |
37 } | 42 } |
38 | 43 |
| 44 static SkScaledBitmapSampler::RowProc get_RGBx_to_8888_proc(const SkImageDecoder
& decoder) { |
| 45 // Dither, unpremul, and skipZeroes have no effect |
| 46 return Sample_RGBx_D8888; |
| 47 } |
| 48 |
39 static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, | 49 static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, |
40 const uint8_t* SK_RESTRICT src, | 50 const uint8_t* SK_RESTRICT src, |
41 int width, int deltaSrc, int, const SkPMColor[]) { | 51 int width, int deltaSrc, int, const SkPMColor[]) { |
42 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 52 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
43 unsigned alphaMask = 0xFF; | 53 unsigned alphaMask = 0xFF; |
44 for (int x = 0; x < width; x++) { | 54 for (int x = 0; x < width; x++) { |
45 unsigned alpha = src[3]; | 55 unsigned alpha = src[3]; |
46 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 56 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
47 src += deltaSrc; | 57 src += deltaSrc; |
48 alphaMask &= alpha; | 58 alphaMask &= alpha; |
49 } | 59 } |
50 return alphaMask != 0xFF; | 60 return alphaMask != 0xFF; |
51 } | 61 } |
52 | 62 |
| 63 static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow, |
| 64 const uint8_t* SK_RESTRICT src, |
| 65 int width, int deltaSrc, int, |
| 66 const SkPMColor[]) { |
| 67 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); |
| 68 unsigned alphaMask = 0xFF; |
| 69 for (int x = 0; x < width; x++) { |
| 70 unsigned alpha = src[3]; |
| 71 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); |
| 72 src += deltaSrc; |
| 73 alphaMask &= alpha; |
| 74 } |
| 75 return alphaMask != 0xFF; |
| 76 } |
| 77 |
| 78 static bool Sample_RGBA_D8888_SkipZ(void* SK_RESTRICT dstRow, |
| 79 const uint8_t* SK_RESTRICT src, |
| 80 int width, int deltaSrc, int, |
| 81 const SkPMColor[]) { |
| 82 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
| 83 unsigned alphaMask = 0xFF; |
| 84 for (int x = 0; x < width; x++) { |
| 85 unsigned alpha = src[3]; |
| 86 if (0 != alpha) { |
| 87 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
| 88 } |
| 89 src += deltaSrc; |
| 90 alphaMask &= alpha; |
| 91 } |
| 92 return alphaMask != 0xFF; |
| 93 } |
| 94 |
| 95 static SkScaledBitmapSampler::RowProc get_RGBA_to_8888_proc(const SkImageDecoder
& decoder) { |
| 96 // Dither has no effect. |
| 97 if (decoder.getRequireUnpremultipliedColors()) { |
| 98 // We could check each component for a zero, at the expense of extra che
cks. |
| 99 // For now, just return unpremul. |
| 100 return Sample_RGBA_D8888_Unpremul; |
| 101 } |
| 102 // Supply the versions that premultiply the colors |
| 103 if (decoder.getSkipWritingZeroes()) { |
| 104 return Sample_RGBA_D8888_SkipZ; |
| 105 } |
| 106 return Sample_RGBA_D8888; |
| 107 } |
| 108 |
53 // 565 | 109 // 565 |
54 | 110 |
55 static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, | 111 static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, |
56 const uint8_t* SK_RESTRICT src, | 112 const uint8_t* SK_RESTRICT src, |
57 int width, int deltaSrc, int, const SkPMColor[]) { | 113 int width, int deltaSrc, int, const SkPMColor[]) { |
58 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 114 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
59 for (int x = 0; x < width; x++) { | 115 for (int x = 0; x < width; x++) { |
60 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); | 116 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); |
61 src += deltaSrc; | 117 src += deltaSrc; |
62 } | 118 } |
63 return false; | 119 return false; |
64 } | 120 } |
65 | 121 |
66 static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, | 122 static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, |
67 const uint8_t* SK_RESTRICT src, | 123 const uint8_t* SK_RESTRICT src, |
68 int width, int deltaSrc, int y, const SkPMColor[]) { | 124 int width, int deltaSrc, int y, const SkPMColor[]) { |
69 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 125 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
70 DITHER_565_SCAN(y); | 126 DITHER_565_SCAN(y); |
71 for (int x = 0; x < width; x++) { | 127 for (int x = 0; x < width; x++) { |
72 dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); | 128 dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); |
73 src += deltaSrc; | 129 src += deltaSrc; |
74 } | 130 } |
75 return false; | 131 return false; |
76 } | 132 } |
77 | 133 |
| 134 static SkScaledBitmapSampler::RowProc get_gray_to_565_proc(const SkImageDecoder&
decoder) { |
| 135 // Unpremul and skip zeroes make no difference |
| 136 if (decoder.getDitherImage()) { |
| 137 return Sample_Gray_D565_D; |
| 138 } |
| 139 return Sample_Gray_D565; |
| 140 } |
| 141 |
78 static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, | 142 static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, |
79 const uint8_t* SK_RESTRICT src, | 143 const uint8_t* SK_RESTRICT src, |
80 int width, int deltaSrc, int, const SkPMColor[]) { | 144 int width, int deltaSrc, int, const SkPMColor[]) { |
81 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 145 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
82 for (int x = 0; x < width; x++) { | 146 for (int x = 0; x < width; x++) { |
83 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); | 147 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); |
84 src += deltaSrc; | 148 src += deltaSrc; |
85 } | 149 } |
86 return false; | 150 return false; |
87 } | 151 } |
88 | 152 |
| 153 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, |
| 154 const uint8_t* SK_RESTRICT src, |
| 155 int width, int deltaSrc, int y, |
| 156 const SkPMColor[]) { |
| 157 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
| 158 DITHER_565_SCAN(y); |
| 159 for (int x = 0; x < width; x++) { |
| 160 dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); |
| 161 src += deltaSrc; |
| 162 } |
| 163 return false; |
| 164 } |
| 165 |
| 166 static SkScaledBitmapSampler::RowProc get_RGBx_to_565_proc(const SkImageDecoder&
decoder) { |
| 167 // Unpremul and skip zeroes make no difference |
| 168 if (decoder.getDitherImage()) { |
| 169 return Sample_RGBx_D565_D; |
| 170 } |
| 171 return Sample_RGBx_D565; |
| 172 } |
| 173 |
| 174 |
89 static bool Sample_D565_D565(void* SK_RESTRICT dstRow, | 175 static bool Sample_D565_D565(void* SK_RESTRICT dstRow, |
90 const uint8_t* SK_RESTRICT src, | 176 const uint8_t* SK_RESTRICT src, |
91 int width, int deltaSrc, int, const SkPMColor[]) { | 177 int width, int deltaSrc, int, const SkPMColor[]) { |
92 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 178 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
93 uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src; | 179 uint16_t* SK_RESTRICT castedSrc = (uint16_t*) src; |
94 for (int x = 0; x < width; x++) { | 180 for (int x = 0; x < width; x++) { |
95 dst[x] = castedSrc[0]; | 181 dst[x] = castedSrc[0]; |
96 castedSrc += deltaSrc >> 1; | 182 castedSrc += deltaSrc >> 1; |
97 } | 183 } |
98 return false; | 184 return false; |
99 } | 185 } |
100 | 186 |
101 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, | 187 static SkScaledBitmapSampler::RowProc get_565_to_565_proc(const SkImageDecoder&
decoder) { |
102 const uint8_t* SK_RESTRICT src, | 188 // Unpremul, dither, and skip zeroes have no effect |
103 int width, int deltaSrc, int y, const SkPMColor[]) { | 189 return Sample_D565_D565; |
104 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
105 DITHER_565_SCAN(y); | |
106 for (int x = 0; x < width; x++) { | |
107 dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); | |
108 src += deltaSrc; | |
109 } | |
110 return false; | |
111 } | 190 } |
112 | 191 |
113 // 4444 | 192 // 4444 |
114 | 193 |
115 static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, | 194 static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, |
116 const uint8_t* SK_RESTRICT src, | 195 const uint8_t* SK_RESTRICT src, |
117 int width, int deltaSrc, int, const SkPMColor[]) { | 196 int width, int deltaSrc, int, const SkPMColor[]) { |
118 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 197 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
119 for (int x = 0; x < width; x++) { | 198 for (int x = 0; x < width; x++) { |
120 unsigned gray = src[0] >> 4; | 199 unsigned gray = src[0] >> 4; |
121 dst[x] = SkPackARGB4444(0xF, gray, gray, gray); | 200 dst[x] = SkPackARGB4444(0xF, gray, gray, gray); |
122 src += deltaSrc; | 201 src += deltaSrc; |
123 } | 202 } |
124 return false; | 203 return false; |
125 } | 204 } |
126 | 205 |
127 static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, | 206 static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, |
128 const uint8_t* SK_RESTRICT src, | 207 const uint8_t* SK_RESTRICT src, |
129 int width, int deltaSrc, int y, const SkPMColor[]) { | 208 int width, int deltaSrc, int y, const SkPMColor[]) { |
130 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 209 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
131 DITHER_4444_SCAN(y); | 210 DITHER_4444_SCAN(y); |
132 for (int x = 0; x < width; x++) { | 211 for (int x = 0; x < width; x++) { |
133 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], | 212 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], |
134 DITHER_VALUE(x)); | 213 DITHER_VALUE(x)); |
135 src += deltaSrc; | 214 src += deltaSrc; |
136 } | 215 } |
137 return false; | 216 return false; |
138 } | 217 } |
139 | 218 |
| 219 static SkScaledBitmapSampler::RowProc get_gray_to_4444_proc(const SkImageDecoder
& decoder) { |
| 220 // Skip zeroes and unpremul make no difference |
| 221 if (decoder.getDitherImage()) { |
| 222 return Sample_Gray_D4444_D; |
| 223 } |
| 224 return Sample_Gray_D4444; |
| 225 } |
| 226 |
140 static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, | 227 static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, |
141 const uint8_t* SK_RESTRICT src, | 228 const uint8_t* SK_RESTRICT src, |
142 int width, int deltaSrc, int, const SkPMColor[]) { | 229 int width, int deltaSrc, int, const SkPMColor[]) { |
143 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 230 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
144 for (int x = 0; x < width; x++) { | 231 for (int x = 0; x < width; x++) { |
145 dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); | 232 dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); |
146 src += deltaSrc; | 233 src += deltaSrc; |
147 } | 234 } |
148 return false; | 235 return false; |
149 } | 236 } |
150 | 237 |
151 static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, | 238 static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, |
152 const uint8_t* SK_RESTRICT src, | 239 const uint8_t* SK_RESTRICT src, |
153 int width, int deltaSrc, int y, const SkPMColor[]) { | 240 int width, int deltaSrc, int y, const SkPMColor[]) { |
154 SkPMColor16* dst = (SkPMColor16*)dstRow; | 241 SkPMColor16* dst = (SkPMColor16*)dstRow; |
155 DITHER_4444_SCAN(y); | 242 DITHER_4444_SCAN(y); |
156 | 243 |
157 for (int x = 0; x < width; x++) { | 244 for (int x = 0; x < width; x++) { |
158 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], | 245 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], |
159 DITHER_VALUE(x)); | 246 DITHER_VALUE(x)); |
160 src += deltaSrc; | 247 src += deltaSrc; |
161 } | 248 } |
162 return false; | 249 return false; |
163 } | 250 } |
164 | 251 |
| 252 static SkScaledBitmapSampler::RowProc get_RGBx_to_4444_proc(const SkImageDecoder
& decoder) { |
| 253 // Skip zeroes and unpremul make no difference |
| 254 if (decoder.getDitherImage()) { |
| 255 return Sample_RGBx_D4444_D; |
| 256 } |
| 257 return Sample_RGBx_D4444; |
| 258 } |
| 259 |
165 static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, | 260 static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, |
166 const uint8_t* SK_RESTRICT src, | 261 const uint8_t* SK_RESTRICT src, |
167 int width, int deltaSrc, int, const SkPMColor[]) { | 262 int width, int deltaSrc, int, const SkPMColor[]) { |
168 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 263 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
169 unsigned alphaMask = 0xFF; | 264 unsigned alphaMask = 0xFF; |
170 | 265 |
171 for (int x = 0; x < width; x++) { | 266 for (int x = 0; x < width; x++) { |
172 unsigned alpha = src[3]; | 267 unsigned alpha = src[3]; |
173 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 268 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
174 dst[x] = SkPixel32ToPixel4444(c); | 269 dst[x] = SkPixel32ToPixel4444(c); |
175 src += deltaSrc; | 270 src += deltaSrc; |
176 alphaMask &= alpha; | 271 alphaMask &= alpha; |
177 } | 272 } |
178 return alphaMask != 0xFF; | 273 return alphaMask != 0xFF; |
179 } | 274 } |
180 | 275 |
| 276 static bool Sample_RGBA_D4444_SkipZ(void* SK_RESTRICT dstRow, |
| 277 const uint8_t* SK_RESTRICT src, |
| 278 int width, int deltaSrc, int, |
| 279 const SkPMColor[]) { |
| 280 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
| 281 unsigned alphaMask = 0xFF; |
| 282 |
| 283 for (int x = 0; x < width; x++) { |
| 284 unsigned alpha = src[3]; |
| 285 if (alpha != 0) { |
| 286 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
| 287 dst[x] = SkPixel32ToPixel4444(c); |
| 288 } |
| 289 src += deltaSrc; |
| 290 alphaMask &= alpha; |
| 291 } |
| 292 return alphaMask != 0xFF; |
| 293 } |
| 294 |
| 295 |
181 static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, | 296 static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, |
182 const uint8_t* SK_RESTRICT src, | 297 const uint8_t* SK_RESTRICT src, |
183 int width, int deltaSrc, int y, const SkPMColor[]) { | 298 int width, int deltaSrc, int y, |
| 299 const SkPMColor[]) { |
184 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 300 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
185 unsigned alphaMask = 0xFF; | 301 unsigned alphaMask = 0xFF; |
186 DITHER_4444_SCAN(y); | 302 DITHER_4444_SCAN(y); |
187 | 303 |
188 for (int x = 0; x < width; x++) { | 304 for (int x = 0; x < width; x++) { |
189 unsigned alpha = src[3]; | 305 unsigned alpha = src[3]; |
190 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | 306 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
191 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | 307 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |
192 src += deltaSrc; | 308 src += deltaSrc; |
193 alphaMask &= alpha; | 309 alphaMask &= alpha; |
194 } | 310 } |
195 return alphaMask != 0xFF; | 311 return alphaMask != 0xFF; |
196 } | 312 } |
197 | 313 |
| 314 static bool Sample_RGBA_D4444_D_SkipZ(void* SK_RESTRICT dstRow, |
| 315 const uint8_t* SK_RESTRICT src, |
| 316 int width, int deltaSrc, int y, |
| 317 const SkPMColor[]) { |
| 318 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
| 319 unsigned alphaMask = 0xFF; |
| 320 DITHER_4444_SCAN(y); |
| 321 |
| 322 for (int x = 0; x < width; x++) { |
| 323 unsigned alpha = src[3]; |
| 324 if (alpha != 0) { |
| 325 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); |
| 326 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |
| 327 } |
| 328 src += deltaSrc; |
| 329 alphaMask &= alpha; |
| 330 } |
| 331 return alphaMask != 0xFF; |
| 332 } |
| 333 |
| 334 static SkScaledBitmapSampler::RowProc get_RGBA_to_4444_proc(const SkImageDecoder
& decoder) { |
| 335 if (decoder.getRequireUnpremultipliedColors()) { |
| 336 // Unpremultiplied is not supported for 4444 |
| 337 return NULL; |
| 338 } |
| 339 const bool dither = decoder.getDitherImage(); |
| 340 if (decoder.getSkipWritingZeroes()) { |
| 341 if (dither) { |
| 342 return Sample_RGBA_D4444_D_SkipZ; |
| 343 } |
| 344 return Sample_RGBA_D4444_SkipZ; |
| 345 } |
| 346 if (dither) { |
| 347 return Sample_RGBA_D4444_D; |
| 348 } |
| 349 return Sample_RGBA_D4444; |
| 350 } |
| 351 |
198 // Index | 352 // Index |
199 | 353 |
200 #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT) | 354 #define A32_MASK_IN_PLACE (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT) |
201 | 355 |
202 static bool Sample_Index_D8888(void* SK_RESTRICT dstRow, | 356 static bool Sample_Index_D8888(void* SK_RESTRICT dstRow, |
203 const uint8_t* SK_RESTRICT src, | 357 const uint8_t* SK_RESTRICT src, |
204 int width, int deltaSrc, int, const SkPMColor ctable[]) { | 358 int width, int deltaSrc, int, const SkPMColor ctable[]) { |
205 | 359 |
206 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | 360 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
207 SkPMColor cc = A32_MASK_IN_PLACE; | 361 SkPMColor cc = A32_MASK_IN_PLACE; |
208 for (int x = 0; x < width; x++) { | 362 for (int x = 0; x < width; x++) { |
209 SkPMColor c = ctable[*src]; | 363 SkPMColor c = ctable[*src]; |
210 cc &= c; | 364 cc &= c; |
211 dst[x] = c; | 365 dst[x] = c; |
212 src += deltaSrc; | 366 src += deltaSrc; |
213 } | 367 } |
214 return cc != A32_MASK_IN_PLACE; | 368 return cc != A32_MASK_IN_PLACE; |
215 } | 369 } |
216 | 370 |
| 371 static bool Sample_Index_D8888_SkipZ(void* SK_RESTRICT dstRow, |
| 372 const uint8_t* SK_RESTRICT src, |
| 373 int width, int deltaSrc, int, |
| 374 const SkPMColor ctable[]) { |
| 375 |
| 376 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; |
| 377 SkPMColor cc = A32_MASK_IN_PLACE; |
| 378 for (int x = 0; x < width; x++) { |
| 379 SkPMColor c = ctable[*src]; |
| 380 cc &= c; |
| 381 if (c != 0) { |
| 382 dst[x] = c; |
| 383 } |
| 384 src += deltaSrc; |
| 385 } |
| 386 return cc != A32_MASK_IN_PLACE; |
| 387 } |
| 388 |
| 389 static SkScaledBitmapSampler::RowProc get_index_to_8888_proc(const SkImageDecode
r& decoder) { |
| 390 if (decoder.getRequireUnpremultipliedColors()) { |
| 391 // Unpremultiplied is not supported for an index source. |
| 392 return NULL; |
| 393 } |
| 394 // Dither makes no difference |
| 395 if (decoder.getSkipWritingZeroes()) { |
| 396 return Sample_Index_D8888_SkipZ; |
| 397 } |
| 398 return Sample_Index_D8888; |
| 399 } |
| 400 |
217 static bool Sample_Index_D565(void* SK_RESTRICT dstRow, | 401 static bool Sample_Index_D565(void* SK_RESTRICT dstRow, |
218 const uint8_t* SK_RESTRICT src, | 402 const uint8_t* SK_RESTRICT src, |
219 int width, int deltaSrc, int, const SkPMColor ctable[]) { | 403 int width, int deltaSrc, int, const SkPMColor ctable[]) { |
220 | 404 |
221 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 405 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
222 for (int x = 0; x < width; x++) { | 406 for (int x = 0; x < width; x++) { |
223 dst[x] = SkPixel32ToPixel16(ctable[*src]); | 407 dst[x] = SkPixel32ToPixel16(ctable[*src]); |
224 src += deltaSrc; | 408 src += deltaSrc; |
225 } | 409 } |
226 return false; | 410 return false; |
227 } | 411 } |
228 | 412 |
229 static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow, | 413 static bool Sample_Index_D565_D(void* SK_RESTRICT dstRow, |
230 const uint8_t* SK_RESTRICT src, int width, | 414 const uint8_t* SK_RESTRICT src, int width, |
231 int deltaSrc, int y, const SkPMColor ctable[]) { | 415 int deltaSrc, int y, const SkPMColor ctable[]) { |
232 | 416 |
233 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | 417 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; |
234 DITHER_565_SCAN(y); | 418 DITHER_565_SCAN(y); |
235 | 419 |
236 for (int x = 0; x < width; x++) { | 420 for (int x = 0; x < width; x++) { |
237 SkPMColor c = ctable[*src]; | 421 SkPMColor c = ctable[*src]; |
238 dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c), | 422 dst[x] = SkDitherRGBTo565(SkGetPackedR32(c), SkGetPackedG32(c), |
239 SkGetPackedB32(c), DITHER_VALUE(x)); | 423 SkGetPackedB32(c), DITHER_VALUE(x)); |
240 src += deltaSrc; | 424 src += deltaSrc; |
241 } | 425 } |
242 return false; | 426 return false; |
243 } | 427 } |
244 | 428 |
| 429 static SkScaledBitmapSampler::RowProc get_index_to_565_proc(const SkImageDecoder
& decoder) { |
| 430 // Unpremultiplied and skip zeroes make no difference |
| 431 if (decoder.getDitherImage()) { |
| 432 return Sample_Index_D565_D; |
| 433 } |
| 434 return Sample_Index_D565; |
| 435 } |
| 436 |
245 static bool Sample_Index_D4444(void* SK_RESTRICT dstRow, | 437 static bool Sample_Index_D4444(void* SK_RESTRICT dstRow, |
246 const uint8_t* SK_RESTRICT src, int width, | 438 const uint8_t* SK_RESTRICT src, int width, |
247 int deltaSrc, int y, const SkPMColor ctable[]) { | 439 int deltaSrc, int y, const SkPMColor ctable[]) { |
248 | 440 |
249 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | 441 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
250 SkPMColor cc = A32_MASK_IN_PLACE; | 442 SkPMColor cc = A32_MASK_IN_PLACE; |
251 for (int x = 0; x < width; x++) { | 443 for (int x = 0; x < width; x++) { |
252 SkPMColor c = ctable[*src]; | 444 SkPMColor c = ctable[*src]; |
253 cc &= c; | 445 cc &= c; |
254 dst[x] = SkPixel32ToPixel4444(c); | 446 dst[x] = SkPixel32ToPixel4444(c); |
(...skipping 12 matching lines...) Expand all Loading... |
267 | 459 |
268 for (int x = 0; x < width; x++) { | 460 for (int x = 0; x < width; x++) { |
269 SkPMColor c = ctable[*src]; | 461 SkPMColor c = ctable[*src]; |
270 cc &= c; | 462 cc &= c; |
271 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | 463 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |
272 src += deltaSrc; | 464 src += deltaSrc; |
273 } | 465 } |
274 return cc != A32_MASK_IN_PLACE; | 466 return cc != A32_MASK_IN_PLACE; |
275 } | 467 } |
276 | 468 |
| 469 static bool Sample_Index_D4444_SkipZ(void* SK_RESTRICT dstRow, |
| 470 const uint8_t* SK_RESTRICT src, int width, |
| 471 int deltaSrc, int y, const SkPMColor ctable
[]) { |
| 472 |
| 473 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
| 474 SkPMColor cc = A32_MASK_IN_PLACE; |
| 475 for (int x = 0; x < width; x++) { |
| 476 SkPMColor c = ctable[*src]; |
| 477 cc &= c; |
| 478 if (c != 0) { |
| 479 dst[x] = SkPixel32ToPixel4444(c); |
| 480 } |
| 481 src += deltaSrc; |
| 482 } |
| 483 return cc != A32_MASK_IN_PLACE; |
| 484 } |
| 485 |
| 486 static bool Sample_Index_D4444_D_SkipZ(void* SK_RESTRICT dstRow, |
| 487 const uint8_t* SK_RESTRICT src, int width
, |
| 488 int deltaSrc, int y, const SkPMColor ctab
le[]) { |
| 489 |
| 490 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; |
| 491 SkPMColor cc = A32_MASK_IN_PLACE; |
| 492 DITHER_4444_SCAN(y); |
| 493 |
| 494 for (int x = 0; x < width; x++) { |
| 495 SkPMColor c = ctable[*src]; |
| 496 cc &= c; |
| 497 if (c != 0) { |
| 498 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); |
| 499 } |
| 500 src += deltaSrc; |
| 501 } |
| 502 return cc != A32_MASK_IN_PLACE; |
| 503 } |
| 504 |
| 505 static SkScaledBitmapSampler::RowProc get_index_to_4444_proc(const SkImageDecode
r& decoder) { |
| 506 // Unpremul not allowed |
| 507 if (decoder.getRequireUnpremultipliedColors()) { |
| 508 return NULL; |
| 509 } |
| 510 const bool dither = decoder.getDitherImage(); |
| 511 if (decoder.getSkipWritingZeroes()) { |
| 512 if (dither) { |
| 513 return Sample_Index_D4444_D_SkipZ; |
| 514 } |
| 515 return Sample_Index_D4444_SkipZ; |
| 516 } |
| 517 if (dither) { |
| 518 return Sample_Index_D4444_D; |
| 519 } |
| 520 return Sample_Index_D4444; |
| 521 } |
| 522 |
277 static bool Sample_Index_DI(void* SK_RESTRICT dstRow, | 523 static bool Sample_Index_DI(void* SK_RESTRICT dstRow, |
278 const uint8_t* SK_RESTRICT src, | 524 const uint8_t* SK_RESTRICT src, |
279 int width, int deltaSrc, int, const SkPMColor[]) { | 525 int width, int deltaSrc, int, const SkPMColor[]) { |
280 if (1 == deltaSrc) { | 526 if (1 == deltaSrc) { |
281 memcpy(dstRow, src, width); | 527 memcpy(dstRow, src, width); |
282 } else { | 528 } else { |
283 uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; | 529 uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; |
284 for (int x = 0; x < width; x++) { | 530 for (int x = 0; x < width; x++) { |
285 dst[x] = src[0]; | 531 dst[x] = src[0]; |
286 src += deltaSrc; | 532 src += deltaSrc; |
287 } | 533 } |
288 } | 534 } |
289 return false; | 535 return false; |
290 } | 536 } |
291 | 537 |
| 538 static SkScaledBitmapSampler::RowProc get_index_to_index_proc(const SkImageDecod
er& decoder) { |
| 539 // Unpremul not allowed |
| 540 if (decoder.getRequireUnpremultipliedColors()) { |
| 541 return NULL; |
| 542 } |
| 543 // Ignore dither and skip zeroes |
| 544 return Sample_Index_DI; |
| 545 } |
| 546 |
292 // A8 | 547 // A8 |
293 static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow, | 548 static bool Sample_Gray_DA8(void* SK_RESTRICT dstRow, |
294 const uint8_t* SK_RESTRICT src, | 549 const uint8_t* SK_RESTRICT src, |
295 int width, int deltaSrc, int, | 550 int width, int deltaSrc, int, |
296 const SkPMColor[]) { | 551 const SkPMColor[]) { |
297 memcpy(dstRow, src, width); | 552 memcpy(dstRow, src, width); |
298 return true; | 553 return true; |
299 } | 554 } |
300 | 555 |
301 // 8888 Unpremul | 556 static SkScaledBitmapSampler::RowProc get_gray_to_A8_proc(const SkImageDecoder&
decoder) { |
302 | 557 if (decoder.getRequireUnpremultipliedColors()) { |
303 static bool Sample_Gray_D8888_Unpremul(void* SK_RESTRICT dstRow, | 558 return NULL; |
304 const uint8_t* SK_RESTRICT src, | |
305 int width, int deltaSrc, int, | |
306 const SkPMColor[]) { | |
307 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); | |
308 for (int x = 0; x < width; x++) { | |
309 dst[x] = SkPackARGB32NoCheck(0xFF, src[0], src[0], src[0]); | |
310 src += deltaSrc; | |
311 } | 559 } |
312 return false; | 560 // Ignore skip and dither. |
| 561 return Sample_Gray_DA8; |
313 } | 562 } |
314 | 563 |
315 // Sample_RGBx_D8888_Unpremul is no different from Sample_RGBx_D8888, since alph
a | 564 typedef SkScaledBitmapSampler::RowProc (*RowProcChooser)(const SkImageDecoder& d
ecoder); |
316 // is 0xFF | |
317 | |
318 static bool Sample_RGBA_D8888_Unpremul(void* SK_RESTRICT dstRow, | |
319 const uint8_t* SK_RESTRICT src, | |
320 int width, int deltaSrc, int, | |
321 const SkPMColor[]) { | |
322 uint32_t* SK_RESTRICT dst = reinterpret_cast<uint32_t*>(dstRow); | |
323 unsigned alphaMask = 0xFF; | |
324 for (int x = 0; x < width; x++) { | |
325 unsigned alpha = src[3]; | |
326 dst[x] = SkPackARGB32NoCheck(alpha, src[0], src[1], src[2]); | |
327 src += deltaSrc; | |
328 alphaMask &= alpha; | |
329 } | |
330 return alphaMask != 0xFF; | |
331 } | |
332 | |
333 // Sample_Index_D8888_Unpremul is the same as Sample_Index_D8888, since the | |
334 // color table has its colors inserted unpremultiplied. | |
335 | |
336 /////////////////////////////////////////////////////////////////////////////// | 565 /////////////////////////////////////////////////////////////////////////////// |
337 | 566 |
338 #include "SkScaledBitmapSampler.h" | 567 #include "SkScaledBitmapSampler.h" |
339 | 568 |
340 SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, | 569 SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, |
341 int sampleSize) { | 570 int sampleSize) { |
342 fCTable = NULL; | 571 fCTable = NULL; |
343 fDstRow = NULL; | 572 fDstRow = NULL; |
344 fRowProc = NULL; | 573 fRowProc = NULL; |
345 | 574 |
(...skipping 24 matching lines...) Expand all Loading... |
370 SkASSERT(fX0 >= 0 && fX0 < width); | 599 SkASSERT(fX0 >= 0 && fX0 < width); |
371 SkASSERT(fY0 >= 0 && fY0 < height); | 600 SkASSERT(fY0 >= 0 && fY0 < height); |
372 | 601 |
373 fDX = dx; | 602 fDX = dx; |
374 fDY = dy; | 603 fDY = dy; |
375 | 604 |
376 SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); | 605 SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); |
377 SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); | 606 SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); |
378 } | 607 } |
379 | 608 |
380 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither, | 609 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, |
381 const SkPMColor ctable[], | 610 const SkImageDecoder& decoder, |
382 bool requireUnpremul) { | 611 const SkPMColor ctable[]) { |
383 static const RowProc gProcs[] = { | 612 static const RowProcChooser gProcChoosers[] = { |
384 // 8888 (no dither distinction) | 613 get_gray_to_8888_proc, |
385 Sample_Gray_D8888, Sample_Gray_D8888, | 614 get_RGBx_to_8888_proc, |
386 Sample_RGBx_D8888, Sample_RGBx_D8888, | 615 get_RGBA_to_8888_proc, |
387 Sample_RGBA_D8888, Sample_RGBA_D8888, | 616 get_index_to_8888_proc, |
388 Sample_Index_D8888, Sample_Index_D8888, | 617 NULL, // 565 to 8888 |
389 NULL, NULL, | 618 |
390 // 565 (no alpha distinction) | 619 get_gray_to_565_proc, |
391 Sample_Gray_D565, Sample_Gray_D565_D, | 620 get_RGBx_to_565_proc, |
392 Sample_RGBx_D565, Sample_RGBx_D565_D, | 621 get_RGBx_to_565_proc, // The source alpha will be ignored. |
393 Sample_RGBx_D565, Sample_RGBx_D565_D, | 622 get_index_to_565_proc, |
394 Sample_Index_D565, Sample_Index_D565_D, | 623 get_565_to_565_proc, |
395 Sample_D565_D565, Sample_D565_D565, | 624 |
396 // 4444 | 625 get_gray_to_4444_proc, |
397 Sample_Gray_D4444, Sample_Gray_D4444_D, | 626 get_RGBx_to_4444_proc, |
398 Sample_RGBx_D4444, Sample_RGBx_D4444_D, | 627 get_RGBA_to_4444_proc, |
399 Sample_RGBA_D4444, Sample_RGBA_D4444_D, | 628 get_index_to_4444_proc, |
400 Sample_Index_D4444, Sample_Index_D4444_D, | 629 NULL, // 565 to 4444 |
401 NULL, NULL, | 630 |
402 // Index8 | 631 NULL, // gray to index |
403 NULL, NULL, | 632 NULL, // rgbx to index |
404 NULL, NULL, | 633 NULL, // rgba to index |
405 NULL, NULL, | 634 get_index_to_index_proc, |
406 Sample_Index_DI, Sample_Index_DI, | 635 NULL, // 565 to index |
407 NULL, NULL, | 636 |
408 // A8 | 637 get_gray_to_A8_proc, |
409 Sample_Gray_DA8, Sample_Gray_DA8, | 638 NULL, // rgbx to a8 |
410 NULL, NULL, | 639 NULL, // rgba to a8 |
411 NULL, NULL, | 640 NULL, // index to a8 |
412 NULL, NULL, | 641 NULL, // 565 to a8 |
413 NULL, NULL, | |
414 // 8888 Unpremul (no dither distinction) | |
415 Sample_Gray_D8888_Unpremul, Sample_Gray_D8888_Unpremul, | |
416 Sample_RGBx_D8888, Sample_RGBx_D8888, | |
417 Sample_RGBA_D8888_Unpremul, Sample_RGBA_D8888_Unpremul, | |
418 Sample_Index_D8888, Sample_Index_D8888, | |
419 NULL, NULL, | |
420 }; | 642 }; |
| 643 |
421 // The jump between dst configs in the table | 644 // The jump between dst configs in the table |
422 static const int gProcDstConfigSpan = 10; | 645 static const int gProcDstConfigSpan = 5; |
423 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcs) == 6 * gProcDstConfigSpan, | 646 SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gProcChoosers) == 5 * gProcDstConfigSpan, |
424 gProcs_has_the_wrong_number_of_entries); | 647 gProcs_has_the_wrong_number_of_entries); |
425 | 648 |
426 fCTable = ctable; | 649 fCTable = ctable; |
427 | 650 |
428 int index = 0; | 651 int index = 0; |
429 if (dither) { | |
430 index += 1; | |
431 } | |
432 switch (sc) { | 652 switch (sc) { |
433 case SkScaledBitmapSampler::kGray: | 653 case SkScaledBitmapSampler::kGray: |
434 fSrcPixelSize = 1; | 654 fSrcPixelSize = 1; |
435 index += 0; | 655 index += 0; |
436 break; | 656 break; |
437 case SkScaledBitmapSampler::kRGB: | 657 case SkScaledBitmapSampler::kRGB: |
438 fSrcPixelSize = 3; | 658 fSrcPixelSize = 3; |
439 index += 2; | 659 index += 1; |
440 break; | 660 break; |
441 case SkScaledBitmapSampler::kRGBX: | 661 case SkScaledBitmapSampler::kRGBX: |
442 fSrcPixelSize = 4; | 662 fSrcPixelSize = 4; |
443 index += 2; | 663 index += 1; |
444 break; | 664 break; |
445 case SkScaledBitmapSampler::kRGBA: | 665 case SkScaledBitmapSampler::kRGBA: |
446 fSrcPixelSize = 4; | 666 fSrcPixelSize = 4; |
447 index += 4; | 667 index += 2; |
448 break; | 668 break; |
449 case SkScaledBitmapSampler::kIndex: | 669 case SkScaledBitmapSampler::kIndex: |
450 fSrcPixelSize = 1; | 670 fSrcPixelSize = 1; |
451 index += 6; | 671 index += 3; |
452 break; | 672 break; |
453 case SkScaledBitmapSampler::kRGB_565: | 673 case SkScaledBitmapSampler::kRGB_565: |
454 fSrcPixelSize = 2; | 674 fSrcPixelSize = 2; |
455 index += 8; | 675 index += 4; |
456 break; | 676 break; |
457 default: | 677 default: |
458 return false; | 678 return false; |
459 } | 679 } |
460 | 680 |
461 switch (dst->config()) { | 681 switch (dst->config()) { |
462 case SkBitmap::kARGB_8888_Config: | 682 case SkBitmap::kARGB_8888_Config: |
463 index += 0 * gProcDstConfigSpan; | 683 index += 0 * gProcDstConfigSpan; |
464 break; | 684 break; |
465 case SkBitmap::kRGB_565_Config: | 685 case SkBitmap::kRGB_565_Config: |
466 index += 1 * gProcDstConfigSpan; | 686 index += 1 * gProcDstConfigSpan; |
467 break; | 687 break; |
468 case SkBitmap::kARGB_4444_Config: | 688 case SkBitmap::kARGB_4444_Config: |
469 index += 2 * gProcDstConfigSpan; | 689 index += 2 * gProcDstConfigSpan; |
470 break; | 690 break; |
471 case SkBitmap::kIndex8_Config: | 691 case SkBitmap::kIndex8_Config: |
472 index += 3 * gProcDstConfigSpan; | 692 index += 3 * gProcDstConfigSpan; |
473 break; | 693 break; |
474 case SkBitmap::kA8_Config: | 694 case SkBitmap::kA8_Config: |
475 index += 4 * gProcDstConfigSpan; | 695 index += 4 * gProcDstConfigSpan; |
476 break; | 696 break; |
477 default: | 697 default: |
478 return false; | 698 return false; |
479 } | 699 } |
480 | 700 |
481 if (requireUnpremul) { | 701 RowProcChooser chooser = gProcChoosers[index]; |
482 if (dst->config() != SkBitmap::kARGB_8888_Config) { | 702 if (NULL == chooser) { |
483 return false; | 703 fRowProc = NULL; |
484 } | 704 } else { |
485 index += 5 * gProcDstConfigSpan; | 705 fRowProc = chooser(decoder); |
486 } | 706 } |
487 | |
488 fRowProc = gProcs[index]; | |
489 fDstRow = (char*)dst->getPixels(); | 707 fDstRow = (char*)dst->getPixels(); |
490 fDstRowBytes = dst->rowBytes(); | 708 fDstRowBytes = dst->rowBytes(); |
491 fCurrY = 0; | 709 fCurrY = 0; |
492 return fRowProc != NULL; | 710 return fRowProc != NULL; |
493 } | 711 } |
494 | 712 |
495 bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { | 713 bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { |
496 SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); | 714 SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); |
497 | 715 |
498 bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, | 716 bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, |
499 fDX * fSrcPixelSize, fCurrY, fCTable); | 717 fDX * fSrcPixelSize, fCurrY, fCTable); |
500 fDstRow += fDstRowBytes; | 718 fDstRow += fDstRowBytes; |
501 fCurrY += 1; | 719 fCurrY += 1; |
502 return hadAlpha; | 720 return hadAlpha; |
503 } | 721 } |
| 722 |
| 723 #ifdef SK_DEBUG |
| 724 // The following code is for a test to ensure that changing the method to get th
e right row proc |
| 725 // did not change the row proc unintentionally. Tested by ImageDecodingTest.cpp |
| 726 |
| 727 // friend of SkScaledBitmapSampler solely for the purpose of accessing fRowProc. |
| 728 class RowProcTester { |
| 729 public: |
| 730 static SkScaledBitmapSampler::RowProc getRowProc(const SkScaledBitmapSampler
& sampler) { |
| 731 return sampler.fRowProc; |
| 732 } |
| 733 }; |
| 734 |
| 735 |
| 736 // Table showing the expected RowProc for each combination of inputs. |
| 737 // Table formated as follows: |
| 738 // Each group of 5 consecutive rows represents sampling from a single |
| 739 // SkScaledBitmapSampler::SrcConfig. |
| 740 // Within each set, each row represents a different destination SkBitmap::Config |
| 741 // Each column represents a different combination of dither and unpremul. |
| 742 // D = dither ~D = no dither |
| 743 // U = unpremul ~U = no unpremul |
| 744 // ~D~U D~U ~DU DU |
| 745 SkScaledBitmapSampler::RowProc gTestProcs[] = { |
| 746 // Gray |
| 747 Sample_Gray_DA8, Sample_Gray_DA8, NULL, NULL
, // to A8 |
| 748 NULL, NULL, NULL, NULL
, // to Index8 |
| 749 Sample_Gray_D565, Sample_Gray_D565_D, Sample_Gray_D565, Samp
le_Gray_D565_D, // to 565 |
| 750 Sample_Gray_D4444, Sample_Gray_D4444_D, Sample_Gray_D4444, Samp
le_Gray_D4444_D, // to 4444 |
| 751 Sample_Gray_D8888, Sample_Gray_D8888, Sample_Gray_D8888, Samp
le_Gray_D8888, // to 8888 |
| 752 // Index |
| 753 NULL, NULL, NULL, NULL
, // to A8 |
| 754 Sample_Index_DI, Sample_Index_DI, NULL, NULL
, // to Index8 |
| 755 Sample_Index_D565, Sample_Index_D565_D, Sample_Index_D565, Samp
le_Index_D565_D, // to 565 |
| 756 Sample_Index_D4444, Sample_Index_D4444_D, NULL, NULL
, // to 4444 |
| 757 Sample_Index_D8888, Sample_Index_D8888, NULL, NULL
, // to 8888 |
| 758 // RGB |
| 759 NULL, NULL, NULL, NULL
, // to A8 |
| 760 NULL, NULL, NULL, NULL
, // to Index8 |
| 761 Sample_RGBx_D565, Sample_RGBx_D565_D, Sample_RGBx_D565, Samp
le_RGBx_D565_D, // to 565 |
| 762 Sample_RGBx_D4444, Sample_RGBx_D4444_D, Sample_RGBx_D4444, Samp
le_RGBx_D4444_D, // to 4444 |
| 763 Sample_RGBx_D8888, Sample_RGBx_D8888, Sample_RGBx_D8888, Samp
le_RGBx_D8888, // to 8888 |
| 764 // RGBx is the same as RGB |
| 765 NULL, NULL, NULL, NULL
, // to A8 |
| 766 NULL, NULL, NULL, NULL
, // to Index8 |
| 767 Sample_RGBx_D565, Sample_RGBx_D565_D, Sample_RGBx_D565, Samp
le_RGBx_D565_D, // to 565 |
| 768 Sample_RGBx_D4444, Sample_RGBx_D4444_D, Sample_RGBx_D4444, Samp
le_RGBx_D4444_D, // to 4444 |
| 769 Sample_RGBx_D8888, Sample_RGBx_D8888, Sample_RGBx_D8888, Samp
le_RGBx_D8888, // to 8888 |
| 770 // RGBA |
| 771 NULL, NULL, NULL, NULL
, // to A8 |
| 772 NULL, NULL, NULL, NULL
, // to Index8 |
| 773 Sample_RGBx_D565, Sample_RGBx_D565_D, Sample_RGBx_D565, Samp
le_RGBx_D565_D, // to 565 |
| 774 Sample_RGBA_D4444, Sample_RGBA_D4444_D, NULL, NULL
, // to 4444 |
| 775 Sample_RGBA_D8888, Sample_RGBA_D8888, Sample_RGBA_D8888_Unpremul, Samp
le_RGBA_D8888_Unpremul, // to 8888 |
| 776 // RGB_565 |
| 777 NULL, NULL, NULL, NULL
, // to A8 |
| 778 NULL, NULL, NULL, NULL
, // to Index8 |
| 779 Sample_D565_D565, Sample_D565_D565, Sample_D565_D565, Samp
le_D565_D565, // to 565 |
| 780 NULL, NULL, NULL, NULL
, // to 4444 |
| 781 NULL, NULL, NULL, NULL
, // to 8888 |
| 782 }; |
| 783 |
| 784 // Dummy class that allows instantiation of an ImageDecoder, so begin can query
its fields. |
| 785 class DummyDecoder : public SkImageDecoder { |
| 786 public: |
| 787 DummyDecoder() {} |
| 788 protected: |
| 789 virtual bool onDecode(SkStream*, SkBitmap*, SkImageDecoder::Mode) SK_OVERRID
E { |
| 790 return false; |
| 791 } |
| 792 }; |
| 793 |
| 794 void test_row_proc_choice() { |
| 795 SkBitmap dummyBitmap; |
| 796 DummyDecoder dummyDecoder; |
| 797 size_t procCounter = 0; |
| 798 for (int sc = SkScaledBitmapSampler::kGray; sc <= SkScaledBitmapSampler::kRG
B_565; ++sc) { |
| 799 for (int c = SkBitmap::kA8_Config; c <= SkBitmap::kARGB_8888_Config; ++c
) { |
| 800 for (int unpremul = 0; unpremul <= 1; ++unpremul) { |
| 801 for (int dither = 0; dither <= 1; ++dither) { |
| 802 // Arbitrary width/height/sampleSize to allow SkScaledBitmap
Sampler to |
| 803 // be considered valid. |
| 804 SkScaledBitmapSampler sampler(10, 10, 1); |
| 805 dummyBitmap.setConfig((SkBitmap::Config) c, 10, 10); |
| 806 dummyDecoder.setDitherImage(SkToBool(dither)); |
| 807 dummyDecoder.setRequireUnpremultipliedColors(SkToBool(unprem
ul)); |
| 808 sampler.begin(&dummyBitmap, (SkScaledBitmapSampler::SrcConfi
g) sc, |
| 809 dummyDecoder); |
| 810 SkScaledBitmapSampler::RowProc expected = gTestProcs[procCou
nter]; |
| 811 SkScaledBitmapSampler::RowProc actual = RowProcTester::getRo
wProc(sampler); |
| 812 SkASSERT(expected == actual); |
| 813 procCounter++; |
| 814 } |
| 815 } |
| 816 } |
| 817 } |
| 818 SkASSERT(SK_ARRAY_COUNT(gTestProcs) == procCounter); |
| 819 } |
| 820 #endif // SK_DEBUG |
OLD | NEW |