Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: skia/effects/SkBlurMask.cpp

Issue 113827: Remove the remainder of the skia source code from the Chromium repo.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « skia/effects/SkBlurMask.h ('k') | skia/effects/SkBlurMaskFilter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /* libs/graphics/effects/SkBlurMask.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "SkBlurMask.h"
19 #include "SkTemplates.h"
20
21 static void build_sum_buffer(uint32_t dst[], int w, int h, const uint8_t src[], int srcRB)
22 {
23 SkASSERT(srcRB >= w);
24 // mod srcRB so we can apply it after each row
25 srcRB -= w;
26
27 int x, y;
28
29 // special case first row
30 uint32_t X = 0;
31 for (x = w - 1; x >= 0; --x)
32 {
33 X = *src++ + X;
34 *dst++ = X;
35 }
36 src += srcRB;
37
38 // now do the rest of the rows
39 for (y = h - 1; y > 0; --y)
40 {
41 uint32_t L = 0;
42 uint32_t C = 0;
43 for (x = w - 1; x >= 0; --x)
44 {
45 uint32_t T = dst[-w];
46 X = *src++ + L + T - C;
47 *dst++ = X;
48 L = X;
49 C = T;
50 }
51 src += srcRB;
52 }
53 }
54
55 static void apply_kernel(uint8_t dst[], int rx, int ry, const uint32_t src[], in t sw, int sh)
56 {
57 uint32_t scale = (1 << 24) / ((2*rx + 1)*(2*ry + 1));
58
59 int rowBytes = sw;
60
61 int dw = sw + 2*rx;
62 int dh = sh + 2*ry;
63
64 sw -= 1; // now it is max_x
65 sh -= 1; // now it is max_y
66
67 int prev_y = -ry - 1 -ry;
68 int next_y = ry -ry;
69
70 for (int y = 0; y < dh; y++)
71 {
72 int py = SkClampPos(prev_y) * rowBytes;
73 int ny = SkFastMin32(next_y, sh) * rowBytes;
74
75 int prev_x = -rx - 1 -rx;
76 int next_x = rx -rx;
77
78 for (int x = 0; x < dw; x++)
79 {
80 int px = SkClampPos(prev_x);
81 int nx = SkFastMin32(next_x, sw);
82
83 uint32_t sum = src[px+py] + src[nx+ny] - src[nx+py] - src[px+ny];
84 *dst++ = SkToU8(sum * scale >> 24);
85
86 prev_x += 1;
87 next_x += 1;
88 }
89 prev_y += 1;
90 next_y += 1;
91 }
92 }
93
94 static void apply_kernel_interp(uint8_t dst[], int rx, int ry, const uint32_t sr c[], int sw, int sh, U8CPU outer_weight)
95 {
96 SkASSERT(rx > 0 && ry > 0);
97 SkASSERT(outer_weight <= 255);
98
99 int inner_weight = 255 - outer_weight;
100
101 // round these guys up if they're bigger than 127
102 outer_weight += outer_weight >> 7;
103 inner_weight += inner_weight >> 7;
104
105 uint32_t outer_scale = (outer_weight << 16) / ((2*rx + 1)*(2*ry + 1));
106 uint32_t inner_scale = (inner_weight << 16) / ((2*rx - 1)*(2*ry - 1));
107
108 int rowBytes = sw;
109
110 int dw = sw + 2*rx;
111 int dh = sh + 2*ry;
112
113 sw -= 1; // now it is max_x
114 sh -= 1; // now it is max_y
115
116 int prev_y = -ry - 1 -ry;
117 int next_y = ry -ry;
118
119 for (int y = 0; y < dh; y++)
120 {
121 int py = SkClampPos(prev_y) * rowBytes;
122 int ny = SkFastMin32(next_y, sh) * rowBytes;
123
124 int ipy = SkClampPos(prev_y + 1) * rowBytes;
125 int iny = SkClampMax(next_y - 1, sh) * rowBytes;
126
127 int prev_x = -rx - 1 -rx;
128 int next_x = rx -rx;
129
130 for (int x = 0; x < dw; x++)
131 {
132 int px = SkClampPos(prev_x);
133 int nx = SkFastMin32(next_x, sw);
134
135 int ipx = SkClampPos(prev_x + 1);
136 int inx = SkClampMax(next_x - 1, sw);
137
138 uint32_t outer_sum = src[px+py] + src[nx+ny] - src[nx+py] - src[px+n y];
139 uint32_t inner_sum = src[ipx+ipy] + src[inx+iny] - src[inx+ipy] - sr c[ipx+iny];
140 *dst++ = SkToU8((outer_sum * outer_scale + inner_sum * inner_scale) >> 24);
141
142 prev_x += 1;
143 next_x += 1;
144 }
145 prev_y += 1;
146 next_y += 1;
147 }
148 }
149
150 #include "SkColorPriv.h"
151
152 static void merge_src_with_blur(uint8_t dst[],
153 const uint8_t src[], int sw, int sh,
154 const uint8_t blur[], int blurRowBytes)
155 {
156 while (--sh >= 0)
157 {
158 for (int x = sw - 1; x >= 0; --x)
159 {
160 *dst = SkToU8(SkAlphaMul(*blur, SkAlpha255To256(*src)));
161 dst += 1;
162 src += 1;
163 blur += 1;
164 }
165 blur += blurRowBytes - sw;
166 }
167 }
168
169 static void clamp_with_orig(uint8_t dst[], int dstRowBytes,
170 const uint8_t src[], int sw, int sh,
171 SkBlurMask::Style style)
172 {
173 int x;
174 while (--sh >= 0)
175 {
176 switch (style) {
177 case SkBlurMask::kSolid_Style:
178 for (x = sw - 1; x >= 0; --x)
179 {
180 *dst = SkToU8(*src + SkAlphaMul(*dst, SkAlpha255To256(255 - *src )));
181 dst += 1;
182 src += 1;
183 }
184 break;
185 case SkBlurMask::kOuter_Style:
186 for (x = sw - 1; x >= 0; --x)
187 {
188 if (*src)
189 *dst = SkToU8(SkAlphaMul(*dst, SkAlpha255To256(255 - *src))) ;
190 dst += 1;
191 src += 1;
192 }
193 break;
194 default:
195 SkASSERT(!"Unexpected blur style here");
196 break;
197 }
198 dst += dstRowBytes - sw;
199 }
200 }
201
202 ////////////////////////////////////////////////////////////////////////
203
204 // we use a local funciton to wrap the class static method to work around
205 // a bug in gcc98
206 void SkMask_FreeImage(uint8_t* image);
207 void SkMask_FreeImage(uint8_t* image)
208 {
209 SkMask::FreeImage(image);
210 }
211
212 bool SkBlurMask::Blur(SkMask* dst, const SkMask& src,
213 SkScalar radius, Style style)
214 {
215 if (src.fFormat != SkMask::kA8_Format)
216 return false;
217
218 int rx = SkScalarCeil(radius);
219 int outer_weight = 255 - SkScalarRound((SkIntToScalar(rx) - radius) * 255);
220
221 SkASSERT(rx >= 0);
222 SkASSERT((unsigned)outer_weight <= 255);
223
224 if (rx == 0)
225 return false;
226
227 int ry = rx; // only do square blur for now
228
229 dst->fBounds.set(src.fBounds.fLeft - rx, src.fBounds.fTop - ry,
230 src.fBounds.fRight + rx, src.fBounds.fBottom + ry);
231 dst->fRowBytes = SkToU16(dst->fBounds.width());
232 dst->fFormat = SkMask::kA8_Format;
233 dst->fImage = NULL;
234
235 if (src.fImage)
236 {
237 size_t dstSize = dst->computeImageSize();
238 if (0 == dstSize) {
239 return false; // too big to allocate, abort
240 }
241
242 int sw = src.fBounds.width();
243 int sh = src.fBounds.height();
244 const uint8_t* sp = src.fImage;
245 uint8_t* dp = SkMask::AllocImage(dstSize);
246
247 SkAutoTCallVProc<uint8_t, SkMask_FreeImage> autoCall(dp);
248
249 // build the blurry destination
250 {
251 SkAutoTMalloc<uint32_t> storage(sw * sh);
252 uint32_t* sumBuffer = storage.get();
253
254 build_sum_buffer(sumBuffer, sw, sh, sp, src.fRowBytes);
255 if (outer_weight == 255)
256 apply_kernel(dp, rx, ry, sumBuffer, sw, sh);
257 else
258 apply_kernel_interp(dp, rx, ry, sumBuffer, sw, sh, outer_weight) ;
259 }
260
261 dst->fImage = dp;
262 // if need be, alloc the "real" dst (same size as src) and copy/merge
263 // the blur into it (applying the src)
264 if (style == kInner_Style)
265 {
266 size_t srcSize = src.computeImageSize();
267 if (0 == srcSize) {
268 return false; // too big to allocate, abort
269 }
270 dst->fImage = SkMask::AllocImage(srcSize);
271 merge_src_with_blur(dst->fImage, sp, sw, sh,
272 dp + rx + ry*dst->fBounds.width(),
273 dst->fBounds.width());
274 SkMask::FreeImage(dp);
275 }
276 else if (style != kNormal_Style)
277 {
278 clamp_with_orig(dp + rx + ry*dst->fBounds.width(),
279 dst->fBounds.width(),
280 sp, sw, sh,
281 style);
282 }
283 (void)autoCall.detach();
284 }
285
286 if (style == kInner_Style)
287 {
288 dst->fBounds = src.fBounds; // restore trimmed bounds
289 dst->fRowBytes = SkToU16(dst->fBounds.width());
290 }
291
292 #if 0
293 if (gamma && dst->fImage)
294 {
295 uint8_t* image = dst->fImage;
296 uint8_t* stop = image + dst->computeImageSize();
297
298 for (; image < stop; image += 1)
299 *image = gamma[*image];
300 }
301 #endif
302 return true;
303 }
304
305 #if 0
306 void SkBlurMask::BuildSqrtGamma(uint8_t gamma[256], SkScalar percent)
307 {
308 SkASSERT(gamma);
309 SkASSERT(percent >= 0 && percent <= SK_Scalar1);
310
311 int scale = SkScalarRound(percent * 256);
312
313 for (int i = 0; i < 256; i++)
314 {
315 SkFixed n = i * 257;
316 n += n >> 15;
317 SkASSERT(n >= 0 && n <= SK_Fixed1);
318 n = SkFixedSqrt(n);
319 n = n * 255 >> 16;
320 n = SkAlphaBlend(n, i, scale);
321 gamma[i] = SkToU8(n);
322 }
323 }
324
325 void SkBlurMask::BuildSqrGamma(uint8_t gamma[256], SkScalar percent)
326 {
327 SkASSERT(gamma);
328 SkASSERT(percent >= 0 && percent <= SK_Scalar1);
329
330 int scale = SkScalarRound(percent * 256);
331 SkFixed div255 = SK_Fixed1 / 255;
332
333 for (int i = 0; i < 256; i++)
334 {
335 int square = i * i;
336 int linear = i * 255;
337 int n = SkAlphaBlend(square, linear, scale);
338 gamma[i] = SkToU8(n * div255 >> 16);
339 }
340 }
341 #endif
OLDNEW
« no previous file with comments | « skia/effects/SkBlurMask.h ('k') | skia/effects/SkBlurMaskFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698