OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "SkConvolver.h" | 5 #include "SkConvolver.h" |
6 #include "SkMath.h" | 6 #include "SkTArray.h" |
7 #include "SkSize.h" | |
8 #include "SkTypes.h" | |
9 | 7 |
10 namespace { | 8 namespace { |
11 | 9 |
12 // Converts the argument to an 8-bit unsigned value by clamping to the range | 10 // Converts the argument to an 8-bit unsigned value by clamping to the range |
13 // 0-255. | 11 // 0-255. |
14 inline unsigned char ClampTo8(int a) { | 12 inline unsigned char ClampTo8(int a) { |
15 if (static_cast<unsigned>(a) < 256) { | 13 if (static_cast<unsigned>(a) < 256) { |
16 return a; // Avoid the extra check in the common case. | 14 return a; // Avoid the extra check in the common case. |
17 } | 15 } |
18 if (a < 0) { | 16 if (a < 0) { |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 // SkConvolutionFilter1D -------------------------------------------------------
-- | 276 // SkConvolutionFilter1D -------------------------------------------------------
-- |
279 | 277 |
280 SkConvolutionFilter1D::SkConvolutionFilter1D() | 278 SkConvolutionFilter1D::SkConvolutionFilter1D() |
281 : fMaxFilter(0) { | 279 : fMaxFilter(0) { |
282 } | 280 } |
283 | 281 |
284 SkConvolutionFilter1D::~SkConvolutionFilter1D() { | 282 SkConvolutionFilter1D::~SkConvolutionFilter1D() { |
285 } | 283 } |
286 | 284 |
287 void SkConvolutionFilter1D::AddFilter(int filterOffset, | 285 void SkConvolutionFilter1D::AddFilter(int filterOffset, |
288 const float* filterValues, | |
289 int filterLength) { | |
290 SkASSERT(filterLength > 0); | |
291 | |
292 SkTArray<ConvolutionFixed> fixedValues; | |
293 fixedValues.reset(filterLength); | |
294 | |
295 for (int i = 0; i < filterLength; ++i) { | |
296 fixedValues.push_back(FloatToFixed(filterValues[i])); | |
297 } | |
298 | |
299 AddFilter(filterOffset, &fixedValues[0], filterLength); | |
300 } | |
301 | |
302 void SkConvolutionFilter1D::AddFilter(int filterOffset, | |
303 const ConvolutionFixed* filterValues, | 286 const ConvolutionFixed* filterValues, |
304 int filterLength) { | 287 int filterLength) { |
305 // It is common for leading/trailing filter values to be zeros. In such | 288 // It is common for leading/trailing filter values to be zeros. In such |
306 // cases it is beneficial to only store the central factors. | 289 // cases it is beneficial to only store the central factors. |
307 // For a scaling to 1/4th in each dimension using a Lanczos-2 filter on | 290 // For a scaling to 1/4th in each dimension using a Lanczos-2 filter on |
308 // a 1080p image this optimization gives a ~10% speed improvement. | 291 // a 1080p image this optimization gives a ~10% speed improvement. |
309 int filterSize = filterLength; | 292 int filterSize = filterLength; |
310 int firstNonZero = 0; | 293 int firstNonZero = 0; |
311 while (firstNonZero < filterLength && filterValues[firstNonZero] == 0) { | 294 while (firstNonZero < filterLength && filterValues[firstNonZero] == 0) { |
312 firstNonZero++; | 295 firstNonZero++; |
313 } | 296 } |
314 | 297 |
315 if (firstNonZero < filterLength) { | 298 if (firstNonZero < filterLength) { |
316 // Here we have at least one non-zero factor. | 299 // Here we have at least one non-zero factor. |
317 int lastNonZero = filterLength - 1; | 300 int lastNonZero = filterLength - 1; |
318 while (lastNonZero >= 0 && filterValues[lastNonZero] == 0) { | 301 while (lastNonZero >= 0 && filterValues[lastNonZero] == 0) { |
319 lastNonZero--; | 302 lastNonZero--; |
320 } | 303 } |
321 | 304 |
322 filterOffset += firstNonZero; | 305 filterOffset += firstNonZero; |
323 filterLength = lastNonZero + 1 - firstNonZero; | 306 filterLength = lastNonZero + 1 - firstNonZero; |
324 SkASSERT(filterLength > 0); | 307 SkASSERT(filterLength > 0); |
325 | 308 |
326 for (int i = firstNonZero; i <= lastNonZero; i++) { | 309 fFilterValues.append(filterLength, &filterValues[firstNonZero]); |
327 fFilterValues.push_back(filterValues[i]); | |
328 } | |
329 } else { | 310 } else { |
330 // Here all the factors were zeroes. | 311 // Here all the factors were zeroes. |
331 filterLength = 0; | 312 filterLength = 0; |
332 } | 313 } |
333 | 314 |
334 FilterInstance instance; | 315 FilterInstance instance; |
335 | 316 |
336 // We pushed filterLength elements onto fFilterValues | 317 // We pushed filterLength elements onto fFilterValues |
337 instance.fDataLocation = (static_cast<int>(fFilterValues.count()) - | 318 instance.fDataLocation = (static_cast<int>(fFilterValues.count()) - |
338 filterLength); | 319 filterLength); |
339 instance.fOffset = filterOffset; | 320 instance.fOffset = filterOffset; |
340 instance.fTrimmedLength = filterLength; | 321 instance.fTrimmedLength = filterLength; |
341 instance.fLength = filterSize; | 322 instance.fLength = filterSize; |
342 fFilters.push_back(instance); | 323 fFilters.push(instance); |
343 | 324 |
344 fMaxFilter = SkTMax(fMaxFilter, filterLength); | 325 fMaxFilter = SkTMax(fMaxFilter, filterLength); |
345 } | 326 } |
346 | 327 |
347 const SkConvolutionFilter1D::ConvolutionFixed* SkConvolutionFilter1D::GetSingleF
ilter( | 328 const SkConvolutionFilter1D::ConvolutionFixed* SkConvolutionFilter1D::GetSingleF
ilter( |
348 int* specifiedFilterlength, | 329 int* specifiedFilterlength, |
349 int* filterOffset, | 330 int* filterOffset, |
350 int* filterLength) const { | 331 int* filterLength) const { |
351 const FilterInstance& filter = fFilters[0]; | 332 const FilterInstance& filter = fFilters[0]; |
352 *filterOffset = filter.fOffset; | 333 *filterOffset = filter.fOffset; |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 sourceHasAlpha); | 477 sourceHasAlpha); |
497 } else { | 478 } else { |
498 ConvolveVertically(filterValues, filterLength, | 479 ConvolveVertically(filterValues, filterLength, |
499 firstRowForFilter, | 480 firstRowForFilter, |
500 filterX.numValues(), curOutputRow, | 481 filterX.numValues(), curOutputRow, |
501 sourceHasAlpha); | 482 sourceHasAlpha); |
502 } | 483 } |
503 } | 484 } |
504 return true; | 485 return true; |
505 } | 486 } |
OLD | NEW |