summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authormotek@chromium.org <motek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-15 19:29:20 +0000
committermotek@chromium.org <motek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-15 19:29:20 +0000
commit87f30f7653781cbc99237d051da0d29398bd1e1a (patch)
tree4c4a1aef236209d17bb654edf02a296fcff92b91 /skia
parent89ec81f42def3e4288ca896fa7d43c7cbf3157cc (diff)
downloadchromium_src-87f30f7653781cbc99237d051da0d29398bd1e1a.zip
chromium_src-87f30f7653781cbc99237d051da0d29398bd1e1a.tar.gz
chromium_src-87f30f7653781cbc99237d051da0d29398bd1e1a.tar.bz2
As in the title. I stumbled upon that problem while integrating the code. The fix is a one-liner, the rest is unittest-cladding.
BUG=155269 Review URL: https://chromiumcodereview.appspot.com/14969034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200334 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r--skia/ext/recursive_gaussian_convolution.cc5
-rw-r--r--skia/ext/recursive_gaussian_convolution_unittest.cc73
2 files changed, 65 insertions, 13 deletions
diff --git a/skia/ext/recursive_gaussian_convolution.cc b/skia/ext/recursive_gaussian_convolution.cc
index 32802b1..195fca8 100644
--- a/skia/ext/recursive_gaussian_convolution.cc
+++ b/skia/ext/recursive_gaussian_convolution.cc
@@ -90,7 +90,10 @@ unsigned char SingleChannelRecursiveFilter(
++r, in += source_row_stride, out += output_row_stride) {
// Compute forward filter.
// First initialize start of the w (temporary) vector.
- w[0] = w[1] = w[2] = in[0];
+ if (order == RecursiveFilter::FUNCTION)
+ w[0] = w[1] = w[2] = in[0];
+ else
+ w[0] = w[1] = w[2] = 0.0f;
// Note that special-casing of w[3] is needed because of derivatives.
w[3] = ForwardFilter<order>(
in[0], in[0], in[source_pixel_stride], w, 3, b);
diff --git a/skia/ext/recursive_gaussian_convolution_unittest.cc b/skia/ext/recursive_gaussian_convolution_unittest.cc
index e51bb60..ac3f78c 100644
--- a/skia/ext/recursive_gaussian_convolution_unittest.cc
+++ b/skia/ext/recursive_gaussian_convolution_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <functional>
#include <numeric>
#include <vector>
@@ -206,6 +207,31 @@ TEST(RecursiveGaussian, SmoothingImpulse) {
// Symmetricity along X/Y (not really assured, but should be close).
EXPECT_NEAR(value_x, value_y, 1);
}
+
+ // Smooth the inverse now.
+ std::vector<unsigned char> output2(dest_byte_count);
+ std::transform(input.begin(), input.end(), input.begin(),
+ std::bind1st(std::minus<unsigned char>(), 255U));
+ SingleChannelRecursiveGaussianY(&input[0], src_row_stride,
+ kChannelIndex, kChannelCount,
+ recursive_filter, image_size,
+ &intermediate[0], dest_row_stride,
+ 0, 1, false);
+ SingleChannelRecursiveGaussianX(&intermediate[0], dest_row_stride, 0, 1,
+ recursive_filter, image_size,
+ &output2[0], dest_row_stride, 0, 1, false);
+ // The image should be the reverse of output, but permitting for rounding
+ // we will only claim that wherever output is 0, output2 should be 255.
+ // There still can be differences at the edges of the object.
+ std::vector<unsigned char>::const_iterator i1, i2;
+ int difference_count = 0;
+ for (i1 = output.begin(), i2 = output2.begin();
+ i1 != output.end(); ++i1, ++i2) {
+ // The line below checks (*i1 == 0 <==> *i2 == 255).
+ if ((*i1 != 0 && *i2 == 255) && ! (*i1 == 0 && *i2 != 255))
+ ++difference_count;
+ }
+ EXPECT_LE(difference_count, 8);
}
TEST(RecursiveGaussian, FirstDerivative) {
@@ -255,21 +281,44 @@ TEST(RecursiveGaussian, FirstDerivative) {
*target = *ix + *iy;
}
+ SkIRect inflated_rect(box);
+ inflated_rect.outset(spread, spread);
+ SkIRect deflated_rect(box);
+ deflated_rect.inset(spread, spread);
+
int image_total = ComputeBoxSum(output,
SkIRect::MakeWH(kImgWidth, kImgHeight),
kImgWidth);
- int box_inflated = ComputeBoxSum(output,
- SkIRect::MakeLTRB(box.left() - spread,
- box.top() - spread,
- box.right() + spread,
- box.bottom() + spread),
- kImgWidth);
- int box_deflated = ComputeBoxSum(output,
- SkIRect::MakeLTRB(box.left() + spread,
- box.top() + spread,
- box.right() - spread,
- box.bottom() - spread),
- kImgWidth);
+ int box_inflated = ComputeBoxSum(output, inflated_rect, kImgWidth);
+ int box_deflated = ComputeBoxSum(output, deflated_rect, kImgWidth);
+ EXPECT_EQ(box_deflated, 0);
+ EXPECT_EQ(image_total, box_inflated);
+
+ // Try inverted image. Behaviour should be very similar (modulo rounding).
+ std::transform(input.begin(), input.end(), input.begin(),
+ std::bind1st(std::minus<unsigned char>(), 255U));
+ SingleChannelRecursiveGaussianX(&input[0], src_row_stride,
+ kChannelIndex, kChannelCount,
+ recursive_filter, image_size,
+ &output_x[0], dest_row_stride,
+ 0, 1, true);
+ SingleChannelRecursiveGaussianY(&input[0], src_row_stride,
+ kChannelIndex, kChannelCount,
+ recursive_filter, image_size,
+ &output_y[0], dest_row_stride,
+ 0, 1, true);
+
+ for (target = output.begin(), ix = output_x.begin(), iy = output_y.begin();
+ target < output.end(); ++target, ++ix, ++iy) {
+ *target = *ix + *iy;
+ }
+
+ image_total = ComputeBoxSum(output,
+ SkIRect::MakeWH(kImgWidth, kImgHeight),
+ kImgWidth);
+ box_inflated = ComputeBoxSum(output, inflated_rect, kImgWidth);
+ box_deflated = ComputeBoxSum(output, deflated_rect, kImgWidth);
+
EXPECT_EQ(box_deflated, 0);
EXPECT_EQ(image_total, box_inflated);
}