OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2007, The Android Open Source Project | |
3 * | |
4 * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 * you may not use this file except in compliance with the License. | |
6 * You may obtain a copy of the License at | |
7 * | |
8 * http://www.apache.org/licenses/LICENSE-2.0 | |
9 * | |
10 * Unless required by applicable law or agreed to in writing, software | |
11 * distributed under the License is distributed on an "AS IS" BASIS, | |
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 * See the License for the specific language governing permissions and | |
14 * limitations under the License. | |
15 */ | |
16 | |
17 #include "SkScaledBitmapSampler.h" | |
18 #include "SkBitmap.h" | |
19 #include "SkColorPriv.h" | |
20 #include "SkDither.h" | |
21 | |
22 // 8888 | |
23 | |
24 static bool Sample_Gray_D8888(void* SK_RESTRICT dstRow, | |
25 const uint8_t* SK_RESTRICT src, | |
26 int width, int deltaSrc, int) { | |
27 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
28 for (int x = 0; x < width; x++) { | |
29 dst[x] = SkPackARGB32(0xFF, src[0], src[0], src[0]); | |
30 src += deltaSrc; | |
31 } | |
32 return false; | |
33 } | |
34 | |
35 static bool Sample_RGBx_D8888(void* SK_RESTRICT dstRow, | |
36 const uint8_t* SK_RESTRICT src, | |
37 int width, int deltaSrc, int) { | |
38 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
39 for (int x = 0; x < width; x++) { | |
40 dst[x] = SkPackARGB32(0xFF, src[0], src[1], src[2]); | |
41 src += deltaSrc; | |
42 } | |
43 return false; | |
44 } | |
45 | |
46 static bool Sample_RGBA_D8888(void* SK_RESTRICT dstRow, | |
47 const uint8_t* SK_RESTRICT src, | |
48 int width, int deltaSrc, int) { | |
49 SkPMColor* SK_RESTRICT dst = (SkPMColor*)dstRow; | |
50 unsigned alphaMask = 0xFF; | |
51 for (int x = 0; x < width; x++) { | |
52 unsigned alpha = src[3]; | |
53 dst[x] = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
54 src += deltaSrc; | |
55 alphaMask &= alpha; | |
56 } | |
57 return alphaMask != 0xFF; | |
58 } | |
59 | |
60 // 565 | |
61 | |
62 static bool Sample_Gray_D565(void* SK_RESTRICT dstRow, | |
63 const uint8_t* SK_RESTRICT src, | |
64 int width, int deltaSrc, int) { | |
65 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
66 for (int x = 0; x < width; x++) { | |
67 dst[x] = SkPack888ToRGB16(src[0], src[0], src[0]); | |
68 src += deltaSrc; | |
69 } | |
70 return false; | |
71 } | |
72 | |
73 static bool Sample_Gray_D565_D(void* SK_RESTRICT dstRow, | |
74 const uint8_t* SK_RESTRICT src, | |
75 int width, int deltaSrc, int y) { | |
76 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
77 DITHER_565_SCAN(y); | |
78 for (int x = 0; x < width; x++) { | |
79 dst[x] = SkDitherRGBTo565(src[0], src[0], src[0], DITHER_VALUE(x)); | |
80 src += deltaSrc; | |
81 } | |
82 return false; | |
83 } | |
84 | |
85 static bool Sample_RGBx_D565(void* SK_RESTRICT dstRow, | |
86 const uint8_t* SK_RESTRICT src, | |
87 int width, int deltaSrc, int) { | |
88 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
89 for (int x = 0; x < width; x++) { | |
90 dst[x] = SkPack888ToRGB16(src[0], src[1], src[2]); | |
91 src += deltaSrc; | |
92 } | |
93 return false; | |
94 } | |
95 | |
96 static bool Sample_RGBx_D565_D(void* SK_RESTRICT dstRow, | |
97 const uint8_t* SK_RESTRICT src, | |
98 int width, int deltaSrc, int y) { | |
99 uint16_t* SK_RESTRICT dst = (uint16_t*)dstRow; | |
100 DITHER_565_SCAN(y); | |
101 for (int x = 0; x < width; x++) { | |
102 dst[x] = SkDitherRGBTo565(src[0], src[1], src[2], DITHER_VALUE(x)); | |
103 src += deltaSrc; | |
104 } | |
105 return false; | |
106 } | |
107 | |
108 // 4444 | |
109 | |
110 static bool Sample_Gray_D4444(void* SK_RESTRICT dstRow, | |
111 const uint8_t* SK_RESTRICT src, | |
112 int width, int deltaSrc, int) { | |
113 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
114 for (int x = 0; x < width; x++) { | |
115 unsigned gray = src[0] >> 4; | |
116 dst[x] = SkPackARGB4444(0xF, gray, gray, gray); | |
117 src += deltaSrc; | |
118 } | |
119 return false; | |
120 } | |
121 | |
122 static bool Sample_Gray_D4444_D(void* SK_RESTRICT dstRow, | |
123 const uint8_t* SK_RESTRICT src, | |
124 int width, int deltaSrc, int y) { | |
125 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
126 DITHER_4444_SCAN(y); | |
127 for (int x = 0; x < width; x++) { | |
128 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[0], src[0], | |
129 DITHER_VALUE(x)); | |
130 src += deltaSrc; | |
131 } | |
132 return false; | |
133 } | |
134 | |
135 static bool Sample_RGBx_D4444(void* SK_RESTRICT dstRow, | |
136 const uint8_t* SK_RESTRICT src, | |
137 int width, int deltaSrc, int) { | |
138 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
139 for (int x = 0; x < width; x++) { | |
140 dst[x] = SkPackARGB4444(0xF, src[0] >> 4, src[1] >> 4, src[2] >> 4); | |
141 src += deltaSrc; | |
142 } | |
143 return false; | |
144 } | |
145 | |
146 static bool Sample_RGBx_D4444_D(void* SK_RESTRICT dstRow, | |
147 const uint8_t* SK_RESTRICT src, | |
148 int width, int deltaSrc, int y) { | |
149 SkPMColor16* dst = (SkPMColor16*)dstRow; | |
150 DITHER_4444_SCAN(y); | |
151 | |
152 for (int x = 0; x < width; x++) { | |
153 dst[x] = SkDitherARGB32To4444(0xFF, src[0], src[1], src[2], | |
154 DITHER_VALUE(x)); | |
155 src += deltaSrc; | |
156 } | |
157 return false; | |
158 } | |
159 | |
160 static bool Sample_RGBA_D4444(void* SK_RESTRICT dstRow, | |
161 const uint8_t* SK_RESTRICT src, | |
162 int width, int deltaSrc, int) { | |
163 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
164 unsigned alphaMask = 0xFF; | |
165 | |
166 for (int x = 0; x < width; x++) { | |
167 unsigned alpha = src[3]; | |
168 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
169 dst[x] = SkPixel32ToPixel4444(c); | |
170 src += deltaSrc; | |
171 alphaMask &= alpha; | |
172 } | |
173 return alphaMask != 0xFF; | |
174 } | |
175 | |
176 static bool Sample_RGBA_D4444_D(void* SK_RESTRICT dstRow, | |
177 const uint8_t* SK_RESTRICT src, | |
178 int width, int deltaSrc, int y) { | |
179 SkPMColor16* SK_RESTRICT dst = (SkPMColor16*)dstRow; | |
180 unsigned alphaMask = 0xFF; | |
181 DITHER_4444_SCAN(y); | |
182 | |
183 for (int x = 0; x < width; x++) { | |
184 unsigned alpha = src[3]; | |
185 SkPMColor c = SkPreMultiplyARGB(alpha, src[0], src[1], src[2]); | |
186 dst[x] = SkDitherARGB32To4444(c, DITHER_VALUE(x)); | |
187 src += deltaSrc; | |
188 alphaMask &= alpha; | |
189 } | |
190 return alphaMask != 0xFF; | |
191 } | |
192 | |
193 // Index | |
194 | |
195 static bool Sample_Index_DI(void* SK_RESTRICT dstRow, | |
196 const uint8_t* SK_RESTRICT src, | |
197 int width, int deltaSrc, int) { | |
198 if (1 == deltaSrc) { | |
199 memcpy(dstRow, src, width); | |
200 } else { | |
201 uint8_t* SK_RESTRICT dst = (uint8_t*)dstRow; | |
202 for (int x = 0; x < width; x++) { | |
203 dst[x] = src[0]; | |
204 src += deltaSrc; | |
205 } | |
206 } | |
207 return false; | |
208 } | |
209 | |
210 /////////////////////////////////////////////////////////////////////////////// | |
211 | |
212 #include "SkScaledBitmapSampler.h" | |
213 | |
214 SkScaledBitmapSampler::SkScaledBitmapSampler(int width, int height, | |
215 int sampleSize) { | |
216 if (width <= 0 || height <= 0) { | |
217 sk_throw(); | |
218 } | |
219 | |
220 if (sampleSize <= 1) { | |
221 fScaledWidth = width; | |
222 fScaledHeight = height; | |
223 fX0 = fY0 = 0; | |
224 fDX = fDY = 1; | |
225 return; | |
226 } | |
227 | |
228 int dx = SkMin32(sampleSize, width); | |
229 int dy = SkMin32(sampleSize, height); | |
230 | |
231 fScaledWidth = width / dx; | |
232 fScaledHeight = height / dy; | |
233 | |
234 SkASSERT(fScaledWidth > 0); | |
235 SkASSERT(fScaledHeight > 0); | |
236 | |
237 fX0 = dx >> 1; | |
238 fY0 = dy >> 1; | |
239 | |
240 SkASSERT(fX0 >= 0 && fX0 < width); | |
241 SkASSERT(fY0 >= 0 && fY0 < height); | |
242 | |
243 fDX = dx; | |
244 fDY = dy; | |
245 | |
246 SkASSERT(fDX > 0 && (fX0 + fDX * (fScaledWidth - 1)) < width); | |
247 SkASSERT(fDY > 0 && (fY0 + fDY * (fScaledHeight - 1)) < height); | |
248 | |
249 fRowProc = NULL; | |
250 } | |
251 | |
252 bool SkScaledBitmapSampler::begin(SkBitmap* dst, SrcConfig sc, bool dither) { | |
253 static const RowProc gProcs[] = { | |
254 // 8888 (no dither distinction) | |
255 Sample_Gray_D8888, Sample_Gray_D8888, | |
256 Sample_RGBx_D8888, Sample_RGBx_D8888, | |
257 Sample_RGBA_D8888, Sample_RGBA_D8888, | |
258 NULL, NULL, | |
259 // 565 (no alpha distinction) | |
260 Sample_Gray_D565, Sample_Gray_D565_D, | |
261 Sample_RGBx_D565, Sample_RGBx_D565_D, | |
262 Sample_RGBx_D565, Sample_RGBx_D565_D, | |
263 NULL, NULL, | |
264 // 4444 | |
265 Sample_Gray_D4444, Sample_Gray_D4444_D, | |
266 Sample_RGBx_D4444, Sample_RGBx_D4444_D, | |
267 Sample_RGBA_D4444, Sample_RGBA_D4444_D, | |
268 NULL, NULL, | |
269 // Index8 | |
270 NULL, NULL, | |
271 NULL, NULL, | |
272 NULL, NULL, | |
273 Sample_Index_DI, Sample_Index_DI, | |
274 }; | |
275 | |
276 | |
277 int index = 0; | |
278 if (dither) { | |
279 index += 1; | |
280 } | |
281 switch (sc) { | |
282 case SkScaledBitmapSampler::kGray: | |
283 fSrcPixelSize = 1; | |
284 index += 0; | |
285 break; | |
286 case SkScaledBitmapSampler::kRGB: | |
287 fSrcPixelSize = 3; | |
288 index += 2; | |
289 break; | |
290 case SkScaledBitmapSampler::kRGBX: | |
291 fSrcPixelSize = 4; | |
292 index += 2; | |
293 break; | |
294 case SkScaledBitmapSampler::kRGBA: | |
295 fSrcPixelSize = 4; | |
296 index += 4; | |
297 break; | |
298 case SkScaledBitmapSampler::kIndex: | |
299 fSrcPixelSize = 1; | |
300 index += 6; | |
301 break; | |
302 default: | |
303 return false; | |
304 } | |
305 | |
306 switch (dst->config()) { | |
307 case SkBitmap::kARGB_8888_Config: | |
308 index += 0; | |
309 break; | |
310 case SkBitmap::kRGB_565_Config: | |
311 index += 8; | |
312 break; | |
313 case SkBitmap::kARGB_4444_Config: | |
314 index += 16; | |
315 break; | |
316 case SkBitmap::kIndex8_Config: | |
317 index += 24; | |
318 break; | |
319 default: | |
320 return false; | |
321 } | |
322 | |
323 fRowProc = gProcs[index]; | |
324 fDstRow = (char*)dst->getPixels(); | |
325 fDstRowBytes = dst->rowBytes(); | |
326 fCurrY = 0; | |
327 return fRowProc != NULL; | |
328 } | |
329 | |
330 bool SkScaledBitmapSampler::next(const uint8_t* SK_RESTRICT src) { | |
331 SkASSERT((unsigned)fCurrY < (unsigned)fScaledHeight); | |
332 | |
333 bool hadAlpha = fRowProc(fDstRow, src + fX0 * fSrcPixelSize, fScaledWidth, | |
334 fDX * fSrcPixelSize, fCurrY); | |
335 fDstRow += fDstRowBytes; | |
336 fCurrY += 1; | |
337 return hadAlpha; | |
338 } | |
OLD | NEW |