Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d9d7d15

Browse files
committed
Fix the handling of image resampling beyond the image bounds
For nearest-neighbor interpolation, the code no longer applies any antialiasing of edges under an affine transform for more accurate edges and no longer shows data beyond the image bounds under a non-affine transform.
1 parent 0ecf660 commit d9d7d15

1 file changed

Lines changed: 13 additions & 11 deletions

File tree

src/_image_resample.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,8 @@ void resample(
708708
using scanline_t = agg::scanline32_u8;
709709

710710
using reflect_t = agg::wrap_mode_reflect;
711-
using image_accessor_t = agg::image_accessor_wrap<input_pixfmt_t, reflect_t, reflect_t>;
711+
using image_accessor_wrap_t = agg::image_accessor_wrap<input_pixfmt_t, reflect_t, reflect_t>;
712+
using image_accessor_clip_t = agg::image_accessor_clip<input_pixfmt_t>;
712713

713714
using span_alloc_t = agg::span_allocator<color_type>;
714715
using span_conv_alpha_t = span_conv_alpha<color_type>;
@@ -742,7 +743,8 @@ void resample(
742743
input_buffer.attach(
743744
(unsigned char *)input, in_width, in_height, in_width * itemsize);
744745
input_pixfmt_t input_pixfmt(input_buffer);
745-
image_accessor_t input_accessor(input_pixfmt);
746+
image_accessor_wrap_t input_accessor_wrap(input_pixfmt);
747+
image_accessor_clip_t input_accessor_clip(input_pixfmt, color_type::no_color());
746748

747749
agg::rendering_buffer output_buffer;
748750
output_buffer.attach(
@@ -756,7 +758,7 @@ void resample(
756758
rasterizer.clip_box(0, 0, out_width, out_height);
757759

758760
agg::path_storage path;
759-
if (params.is_affine) {
761+
if (params.is_affine && params.interpolation != NEAREST) {
760762
path.move_to(0, 0);
761763
path.line_to(in_width, 0);
762764
path.line_to(in_width, in_height);
@@ -775,22 +777,22 @@ void resample(
775777

776778
if (params.interpolation == NEAREST) {
777779
if (params.is_affine) {
778-
using span_gen_t = typename type_mapping_t::template span_gen_nn_type<image_accessor_t, nn_affine_interpolator_t>;
780+
using span_gen_t = typename type_mapping_t::template span_gen_nn_type<image_accessor_clip_t, nn_affine_interpolator_t>;
779781
using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
780782
using nn_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
781783
nn_affine_interpolator_t interpolator(inverted);
782-
span_gen_t span_gen(input_accessor, interpolator);
784+
span_gen_t span_gen(input_accessor_clip, interpolator);
783785
span_conv_t span_conv(span_gen, conv_alpha);
784786
nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
785787
agg::render_scanlines(rasterizer, scanline, nn_renderer);
786788
} else {
787-
using span_gen_t = typename type_mapping_t::template span_gen_nn_type<image_accessor_t, arbitrary_interpolator_t>;
789+
using span_gen_t = typename type_mapping_t::template span_gen_nn_type<image_accessor_clip_t, arbitrary_interpolator_t>;
788790
using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
789791
using nn_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
790792
lookup_distortion dist(
791793
params.transform_mesh, in_width, in_height, out_width, out_height, true);
792794
arbitrary_interpolator_t interpolator(inverted, dist);
793-
span_gen_t span_gen(input_accessor, interpolator);
795+
span_gen_t span_gen(input_accessor_clip, interpolator);
794796
span_conv_t span_conv(span_gen, conv_alpha);
795797
nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
796798
agg::render_scanlines(rasterizer, scanline, nn_renderer);
@@ -800,22 +802,22 @@ void resample(
800802
get_filter(params, filter);
801803

802804
if (params.is_affine && params.resample) {
803-
using span_gen_t = typename type_mapping_t::template span_gen_affine_type<image_accessor_t>;
805+
using span_gen_t = typename type_mapping_t::template span_gen_affine_type<image_accessor_wrap_t>;
804806
using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
805807
using int_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
806808
affine_interpolator_t interpolator(inverted);
807-
span_gen_t span_gen(input_accessor, interpolator, filter);
809+
span_gen_t span_gen(input_accessor_wrap, interpolator, filter);
808810
span_conv_t span_conv(span_gen, conv_alpha);
809811
int_renderer_t int_renderer(renderer, span_alloc, span_conv);
810812
agg::render_scanlines(rasterizer, scanline, int_renderer);
811813
} else {
812-
using span_gen_t = typename type_mapping_t::template span_gen_filter_type<image_accessor_t, arbitrary_interpolator_t>;
814+
using span_gen_t = typename type_mapping_t::template span_gen_filter_type<image_accessor_wrap_t, arbitrary_interpolator_t>;
813815
using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
814816
using int_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
815817
lookup_distortion dist(
816818
params.transform_mesh, in_width, in_height, out_width, out_height, false);
817819
arbitrary_interpolator_t interpolator(inverted, dist);
818-
span_gen_t span_gen(input_accessor, interpolator, filter);
820+
span_gen_t span_gen(input_accessor_wrap, interpolator, filter);
819821
span_conv_t span_conv(span_gen, conv_alpha);
820822
int_renderer_t int_renderer(renderer, span_alloc, span_conv);
821823
agg::render_scanlines(rasterizer, scanline, int_renderer);

0 commit comments

Comments
 (0)