| 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 |