+ handle boundary cases in 3x3 convolution
This commit is contained in:
parent
557f69314f
commit
fb34c7ef5a
1 changed files with 204 additions and 87 deletions
|
@ -196,7 +196,11 @@ void process_channel (Src const& src, Dst & dst, mapnik::filter::sobel)
|
|||
template <typename Src, typename Dst, typename FilterTag>
|
||||
void apply_convolution_3x3(Src const& src_view, Dst & dst_view, FilterTag filter_tag)
|
||||
{
|
||||
typename Src::xy_locator src_loc = src_view.xy_at(1,1);
|
||||
// p0 p1 p2
|
||||
// p3 p4 p5
|
||||
// p6 p7 p8
|
||||
|
||||
typename Src::xy_locator src_loc = src_view.xy_at(0,0);
|
||||
typename Src::xy_locator::cached_location_t loc00 = src_loc.cache_location(-1,-1);
|
||||
typename Src::xy_locator::cached_location_t loc10 = src_loc.cache_location( 0,-1);
|
||||
typename Src::xy_locator::cached_location_t loc20 = src_loc.cache_location( 1,-1);
|
||||
|
@ -207,34 +211,147 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, FilterTag filter
|
|||
typename Src::xy_locator::cached_location_t loc12 = src_loc.cache_location( 0, 1);
|
||||
typename Src::xy_locator::cached_location_t loc22 = src_loc.cache_location( 1, 1);
|
||||
|
||||
for (int y = 1; y<src_view.height()-1; ++y)
|
||||
{
|
||||
typename Src::x_iterator dst_it = dst_view.row_begin(y);
|
||||
typename Src::x_iterator dst_it = dst_view.row_begin(0);
|
||||
|
||||
// top row
|
||||
for (int x = 0 ; x < src_view.width(); ++x)
|
||||
{
|
||||
*dst_it = src_loc[loc11];
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
bits32f p[9];
|
||||
p[0] = src_loc[loc00][i];
|
||||
p[1] = src_loc[loc10][i];
|
||||
p[2] = src_loc[loc20][i];
|
||||
p[3] = src_loc[loc01][i];
|
||||
|
||||
p[4] = src_loc[loc11][i];
|
||||
p[5] = src_loc[loc21][i];
|
||||
p[6] = src_loc[loc02][i];
|
||||
p[7] = src_loc[loc12][i];
|
||||
p[8] = src_loc[loc22][i];
|
||||
process_channel(p, (*dst_it)[i], filter_tag);
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
p[3] = p[4];
|
||||
p[6] = p[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
p[3] = src_loc[loc01][i];
|
||||
p[6] = src_loc[loc02][i];
|
||||
}
|
||||
|
||||
if ( x == src_view.width()-1)
|
||||
{
|
||||
p[5] = p[4];
|
||||
p[8] = p[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
p[5] = src_loc[loc21][i];
|
||||
p[8] = src_loc[loc22][i];
|
||||
}
|
||||
|
||||
|
||||
p[0] = p[6];
|
||||
p[1] = p[7];
|
||||
p[2] = p[8];
|
||||
|
||||
process_channel(p, (*dst_it)[i], filter_tag);
|
||||
}
|
||||
++src_loc.x();
|
||||
++dst_it;
|
||||
}
|
||||
// carrige-return
|
||||
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
|
||||
|
||||
// 1... height-1 rows
|
||||
for (int y = 1; y<src_view.height()-1; ++y)
|
||||
{
|
||||
for (int x = 0; x < src_view.width(); ++x)
|
||||
{
|
||||
*dst_it = src_loc[loc11];
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
bits32f p[9];
|
||||
|
||||
p[1] = src_loc[loc10][i];
|
||||
p[4] = src_loc[loc11][i];
|
||||
p[7] = src_loc[loc12][i];
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
p[0] = p[1];
|
||||
p[3] = p[4];
|
||||
p[6] = p[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = src_loc[loc00][i];
|
||||
p[3] = src_loc[loc01][i];
|
||||
p[6] = src_loc[loc02][i];
|
||||
}
|
||||
|
||||
if ( x == src_view.width() - 1)
|
||||
{
|
||||
p[2] = p[1];
|
||||
p[5] = p[4];
|
||||
p[8] = p[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
p[2] = src_loc[loc20][i];
|
||||
p[5] = src_loc[loc21][i];
|
||||
p[8] = src_loc[loc22][i];
|
||||
}
|
||||
process_channel(p, (*dst_it)[i], filter_tag);
|
||||
}
|
||||
++dst_it;
|
||||
++src_loc.x();
|
||||
}
|
||||
// carrige-return
|
||||
src_loc += point2<std::ptrdiff_t>(-src_view.width(),1);
|
||||
}
|
||||
|
||||
// bottom row
|
||||
//src_loc = src_view.xy_at(0,src_view.height()-1);
|
||||
for (int x = 0 ; x < src_view.width(); ++x)
|
||||
{
|
||||
*dst_it = src_loc[loc11];
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
bits32f p[9];
|
||||
|
||||
p[1] = src_loc[loc10][i];
|
||||
p[4] = src_loc[loc11][i];
|
||||
|
||||
if (x == 0)
|
||||
{
|
||||
p[0] = p[1];
|
||||
p[3] = p[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
p[0] = src_loc[loc00][i];
|
||||
p[3] = src_loc[loc01][i];
|
||||
}
|
||||
|
||||
if ( x == src_view.width()-1)
|
||||
{
|
||||
p[2] = p[1];
|
||||
p[5] = p[4];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
p[2] = src_loc[loc20][i];
|
||||
p[5] = src_loc[loc21][i];
|
||||
}
|
||||
|
||||
p[6] = p[0];
|
||||
p[7] = p[1];
|
||||
p[8] = p[2];
|
||||
|
||||
process_channel(p, (*dst_it)[i], filter_tag);
|
||||
}
|
||||
++src_loc.x();
|
||||
++dst_it;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Src, typename Dst,typename FilterTag>
|
||||
void apply_filter(Src const& src, Dst & dst, FilterTag filter_tag)
|
||||
|
|
Loading…
Reference in a new issue