diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-17 11:04:04 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-17 11:04:04 +0000 |
commit | 5fec04903efc218ec3f13f3e0f7d6d3196893061 (patch) | |
tree | d5792c6548d2a094e2ab0a3142f7199f4db42de0 /skia/ext/convolver.cc | |
parent | f70c93f02347ae1a0864d6a854329a815ec30dcf (diff) | |
download | chromium_src-5fec04903efc218ec3f13f3e0f7d6d3196893061.zip chromium_src-5fec04903efc218ec3f13f3e0f7d6d3196893061.tar.gz chromium_src-5fec04903efc218ec3f13f3e0f7d6d3196893061.tar.bz2 |
Revert 194565 "Complete (but inefficient) implementation of the ..."
> Complete (but inefficient) implementation of the image retargetting method.
>
> This CL contains:
> 1. Convolution of arbitrary channel with arbitrary kernel (convolver*).
> 2. Gaussian gradient magnitude implementation.
> 3. Image profile (X and Y projections) computations.
> 4. Otsu-like thresholding of profiles.
> 5. Image decimation.
> 6. The main routine which binds it all together.
>
> Note: 1 and 2 do work, but remain main sources of suckiness due to performance
> problems. I actively work on this. Still, I'd love to get the current state in
> to establish a baseline and for viewing pleasure of those who are interested.
>
> BUG=155269
>
> Review URL: https://codereview.chromium.org/13947013
TBR=motek@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194567 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia/ext/convolver.cc')
-rw-r--r-- | skia/ext/convolver.cc | 196 |
1 files changed, 1 insertions, 195 deletions
diff --git a/skia/ext/convolver.cc b/skia/ext/convolver.cc index 2057b22..cbfa931 100644 --- a/skia/ext/convolver.cc +++ b/skia/ext/convolver.cc @@ -4,10 +4,8 @@ #include <algorithm> -#include "base/logging.h" #include "skia/ext/convolver.h" #include "skia/ext/convolver_SSE2.h" -#include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkTypes.h" namespace skia { @@ -24,17 +22,6 @@ inline unsigned char ClampTo8(int a) { return 255; } -// Takes the value produced by accumulating element-wise product of image with -// a kernel and brings it back into range. -// All of the filter scaling factors are in fixed point with kShiftBits bits of -// fractional part. -inline unsigned char BringBackTo8(int a, bool take_absolute) { - a >>= ConvolutionFilter1D::kShiftBits; - if (take_absolute) - a = std::abs(a); - return ClampTo8(a); -} - // Stores a list of rows in a circular buffer. The usage is you write into it // by calling AdvanceRow. It will keep track of which row in the buffer it // should use next, and the total number of rows added. @@ -284,7 +271,6 @@ void ConvolutionFilter1D::AddFilter(int filter_offset, // cases it is beneficial to only store the central factors. // For a scaling to 1/4th in each dimension using a Lanczos-2 filter on // a 1080p image this optimization gives a ~10% speed improvement. - int filter_size = filter_length; int first_non_zero = 0; while (first_non_zero < filter_length && filter_values[first_non_zero] == 0) first_non_zero++; @@ -312,27 +298,12 @@ void ConvolutionFilter1D::AddFilter(int filter_offset, instance.data_location = (static_cast<int>(filter_values_.size()) - filter_length); instance.offset = filter_offset; - instance.trimmed_length = filter_length; - instance.length = filter_size; + instance.length = filter_length; filters_.push_back(instance); max_filter_ = std::max(max_filter_, filter_length); } -const ConvolutionFilter1D::Fixed* ConvolutionFilter1D::GetSingleFilter( - int* specified_filter_length, - int* filter_offset, - int* filter_length) const { - const FilterInstance& filter = filters_[0]; - *filter_offset = filter.offset; - *filter_length = filter.trimmed_length; - *specified_filter_length = filter.length; - if (filter.trimmed_length == 0) - return NULL; - - return &filter_values_[filter.data_location]; -} - typedef void (*ConvolveVertically_pointer)( const ConvolutionFilter1D::Fixed* filter_values, int filter_length, @@ -507,169 +478,4 @@ void BGRAConvolve2D(const unsigned char* source_data, } } -void SingleChannelConvolveX1D(const unsigned char* source_data, - int source_byte_row_stride, - int input_channel_index, - int input_channel_count, - const ConvolutionFilter1D& filter, - const SkISize& image_size, - unsigned char* output, - int output_byte_row_stride, - int output_channel_index, - int output_channel_count, - bool absolute_values) { - int filter_offset, filter_length, filter_size; - // Very much unlike BGRAConvolve2D, here we expect to have the same filter - // for all pixels. - const ConvolutionFilter1D::Fixed* filter_values = - filter.GetSingleFilter(&filter_size, &filter_offset, &filter_length); - - if (filter_values == NULL || image_size.width() < filter_size) { - NOTREACHED(); - return; - } - - int centrepoint = filter_length / 2; - if (filter_size - filter_offset != 2 * filter_offset) { - // This means the original filter was not symmetrical AND - // got clipped from one side more than from the other. - centrepoint = filter_size / 2 - filter_offset; - } - - const unsigned char* source_data_row = source_data; - unsigned char* output_row = output; - - for (int r = 0; r < image_size.height(); ++r) { - unsigned char* target_byte = output_row + output_channel_index; - // Process the lead part, padding image to the left with the first pixel. - int c = 0; - for (; c < centrepoint; ++c, target_byte += output_channel_count) { - int accval = 0; - int i = 0; - int pixel_byte_index = input_channel_index; - for (; i < centrepoint - c; ++i) // Padding part. - accval += filter_values[i] * source_data_row[pixel_byte_index]; - - for (; i < filter_length; ++i, pixel_byte_index += input_channel_count) - accval += filter_values[i] * source_data_row[pixel_byte_index]; - - *target_byte = BringBackTo8(accval, absolute_values); - } - - // Now for the main event. - for (; c < image_size.width() - centrepoint; - ++c, target_byte += output_channel_count) { - int accval = 0; - int pixel_byte_index = (c - centrepoint) * input_channel_count + - input_channel_index; - - for (int i = 0; i < filter_length; - ++i, pixel_byte_index += input_channel_count) { - accval += filter_values[i] * source_data_row[pixel_byte_index]; - } - - *target_byte = BringBackTo8(accval, absolute_values); - } - - for (; c < image_size.width(); ++c, target_byte += output_channel_count) { - int accval = 0; - int overlap_taps = image_size.width() - c + centrepoint; - int pixel_byte_index = (c - centrepoint) * input_channel_count + - input_channel_index; - int i = 0; - for (; i < overlap_taps - 1; ++i, pixel_byte_index += input_channel_count) - accval += filter_values[i] * source_data_row[pixel_byte_index]; - - for (; i < filter_length; ++i) - accval += filter_values[i] * source_data_row[pixel_byte_index]; - - *target_byte = BringBackTo8(accval, absolute_values); - } - - source_data_row += source_byte_row_stride; - output_row += output_byte_row_stride; - } -} - -void SingleChannelConvolveY1D(const unsigned char* source_data, - int source_byte_row_stride, - int input_channel_index, - int input_channel_count, - const ConvolutionFilter1D& filter, - const SkISize& image_size, - unsigned char* output, - int output_byte_row_stride, - int output_channel_index, - int output_channel_count, - bool absolute_values) { - int filter_offset, filter_length, filter_size; - // Very much unlike BGRAConvolve2D, here we expect to have the same filter - // for all pixels. - const ConvolutionFilter1D::Fixed* filter_values = - filter.GetSingleFilter(&filter_size, &filter_offset, &filter_length); - - if (filter_values == NULL || image_size.height() < filter_size) { - NOTREACHED(); - return; - } - - int centrepoint = filter_length / 2; - if (filter_size - filter_offset != 2 * filter_offset) { - // This means the original filter was not symmetrical AND - // got clipped from one side more than from the other. - centrepoint = filter_size / 2 - filter_offset; - } - - for (int c = 0; c < image_size.width(); ++c) { - unsigned char* target_byte = output + c * output_channel_count + - output_channel_index; - int r = 0; - - for (; r < centrepoint; ++r, target_byte += output_byte_row_stride) { - int accval = 0; - int i = 0; - int pixel_byte_index = c * input_channel_count + input_channel_index; - - for (; i < centrepoint - r; ++i) // Padding part. - accval += filter_values[i] * source_data[pixel_byte_index]; - - for (; i < filter_length; ++i, pixel_byte_index += source_byte_row_stride) - accval += filter_values[i] * source_data[pixel_byte_index]; - - *target_byte = BringBackTo8(accval, absolute_values); - } - - for (; r < image_size.height() - centrepoint; - ++r, target_byte += output_byte_row_stride) { - int accval = 0; - int pixel_byte_index = (r - centrepoint) * source_byte_row_stride + - c * input_channel_count + input_channel_index; - for (int i = 0; i < filter_length; - ++i, pixel_byte_index += source_byte_row_stride) { - accval += filter_values[i] * source_data[pixel_byte_index]; - } - - *target_byte = BringBackTo8(accval, absolute_values); - } - - for (; r < image_size.height(); - ++r, target_byte += output_byte_row_stride) { - int accval = 0; - int overlap_taps = image_size.height() - r + centrepoint; - int pixel_byte_index = (r - centrepoint) * source_byte_row_stride + - c * input_channel_count + input_channel_index; - int i = 0; - for (; i < overlap_taps - 1; - ++i, pixel_byte_index += source_byte_row_stride) { - accval += filter_values[i] * source_data[pixel_byte_index]; - } - - for (; i < filter_length; ++i) - accval += filter_values[i] * source_data[pixel_byte_index]; - - *target_byte = BringBackTo8(accval, absolute_values); - } - } -} - } // namespace skia |