#include <stdio.h> #include <stdlib.h> #include <math.h> #include <time.h> #include "agg_rendering_buffer.h" #include "agg_rasterizer_scanline_aa.h" #include "agg_ellipse.h" #include "agg_trans_affine.h" #include "agg_conv_transform.h" #include "agg_scanline_u.h" #include "agg_scanline_p.h" #include "agg_renderer_scanline.h" #include "agg_pixfmt_rgba.h" #include "agg_gamma_lut.h" #include "agg_span_allocator.h" #include "agg_span_image_filter_rgba.h" #include "agg_span_interpolator_linear.h" #include "agg_image_accessors.h" #include "ctrl/agg_slider_ctrl.h" #include "ctrl/agg_rbox_ctrl.h" #include "ctrl/agg_cbox_ctrl.h" #include "platform/agg_platform_support.h" enum flip_y_e { flip_y = true }; enum { l = 255 }; static agg::int8u g_image[] = { 0,l,0,l, 0,0,l,l, l,l,l,l, l,0,0,l, l,0,0,l, 0,0,0,l, l,l,l,l, l,l,l,l, l,l,l,l, l,l,l,l, 0,0,l,l, l,0,0,l, 0,0,l,l, l,l,l,l, 0,0,0,l, 0,l,0,l }; class the_application : public agg::platform_support { typedef agg::pixfmt_bgra32 pixfmt; typedef agg::pixfmt_bgra32_pre pixfmt_pre; typedef agg::renderer_base<pixfmt> renderer_base; typedef agg::renderer_base<pixfmt_pre> renderer_base_pre; agg::slider_ctrl<agg::rgba> m_gamma; agg::slider_ctrl<agg::rgba> m_radius; agg::rbox_ctrl<agg::rgba> m_filters; agg::cbox_ctrl<agg::rgba> m_normalize; double m_cur_angle; int m_cur_filter; int m_num_steps; double m_num_pix; clock_t m_time1; clock_t m_time2; public: the_application(agg::pix_format_e format, bool flip_y) : agg::platform_support(format, flip_y), m_gamma (115, 5, 500-5, 11, !flip_y), m_radius(115, 5+15, 500-5, 11+15, !flip_y), m_filters(0.0, 0.0, 110.0, 210.0, !flip_y), m_normalize (8.0, 215.0, "Normalize Filter", !flip_y), m_cur_angle(0.0), m_cur_filter(1), m_num_steps(0), m_num_pix(0.0), m_time1(0), m_time2(0) { add_ctrl(m_gamma); add_ctrl(m_radius); add_ctrl(m_filters); add_ctrl(m_normalize); m_normalize.text_size(7.5); m_normalize.status(true); m_radius.label("Filter Radius=%.3f"); m_radius.range(2.0, 8.0); m_radius.value(4.0); m_gamma.label("Gamma=%.3f"); m_gamma.range(0.5, 3.0); m_gamma.value(1.0); m_filters.add_item("simple (NN)"); m_filters.add_item("bilinear"); m_filters.add_item("bicubic"); m_filters.add_item("spline16"); m_filters.add_item("spline36"); m_filters.add_item("hanning"); m_filters.add_item("hamming"); m_filters.add_item("hermite"); m_filters.add_item("kaiser"); m_filters.add_item("quadric"); m_filters.add_item("catrom"); m_filters.add_item("gaussian"); m_filters.add_item("bessel"); m_filters.add_item("mitchell"); m_filters.add_item("sinc"); m_filters.add_item("lanczos"); m_filters.add_item("blackman"); m_filters.cur_item(1); m_filters.border_width(0, 0); m_filters.background_color(agg::rgba(0.0, 0.0, 0.0, 0.1)); m_filters.text_size(6.0); m_filters.text_thickness(0.85); } virtual ~the_application() { } virtual void on_draw() { pixfmt pixf(rbuf_window()); renderer_base rb(pixf); rb.clear(agg::rgba(1.0, 1.0, 1.0)); rb.copy_from(rbuf_img(0), 0, 110, 35); agg::rasterizer_scanline_aa<> ras; agg::scanline_u8 sl; agg::rendering_buffer img_rbuf(g_image, 4, 4, 4*4); double para[] = { 200, 40, 200+300, 40, 200+300, 40+300, 200, 40+300 }; agg::trans_affine img_mtx(para, 0,0,4,4); typedef agg::span_interpolator_linear<> interpolator_type; interpolator_type interpolator(img_mtx); agg::span_allocator<agg::rgba8> sa; pixfmt img_pixf(img_rbuf); typedef agg::image_accessor_clone<pixfmt> img_source_type; img_source_type source(img_pixf); ras.reset(); ras.move_to_d(para[0], para[1]); ras.line_to_d(para[2], para[3]); ras.line_to_d(para[4], para[5]); ras.line_to_d(para[6], para[7]); switch(m_filters.cur_item()) { case 0: { typedef agg::span_image_filter_rgba_nn<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(source, interpolator); agg::render_scanlines_aa(ras, sl, rb, sa, sg); } break; case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: { agg::image_filter_lut filter; bool norm = m_normalize.status(); switch(m_filters.cur_item()) { case 1: filter.calculate(agg::image_filter_bilinear(), norm); break; case 2: filter.calculate(agg::image_filter_bicubic(), norm); break; case 3: filter.calculate(agg::image_filter_spline16(), norm); break; case 4: filter.calculate(agg::image_filter_spline36(), norm); break; case 5: filter.calculate(agg::image_filter_hanning(), norm); break; case 6: filter.calculate(agg::image_filter_hamming(), norm); break; case 7: filter.calculate(agg::image_filter_hermite(), norm); break; case 8: filter.calculate(agg::image_filter_kaiser(), norm); break; case 9: filter.calculate(agg::image_filter_quadric(), norm); break; case 10: filter.calculate(agg::image_filter_catrom(), norm); break; case 11: filter.calculate(agg::image_filter_gaussian(), norm); break; case 12: filter.calculate(agg::image_filter_bessel(), norm); break; case 13: filter.calculate(agg::image_filter_mitchell(), norm); break; case 14: filter.calculate(agg::image_filter_sinc(m_radius.value()), norm); break; case 15: filter.calculate(agg::image_filter_lanczos(m_radius.value()), norm); break; case 16: filter.calculate(agg::image_filter_blackman(m_radius.value()), norm); break; } typedef agg::span_image_filter_rgba<img_source_type, interpolator_type> span_gen_type; span_gen_type sg(source, interpolator, filter); agg::render_scanlines_aa(ras, sl, rb, sa, sg); agg::gamma_lut<agg::int8u, agg::int8u, 8, 8> gamma(m_gamma.value()); pixf.apply_gamma_inv(gamma); double x_start = 5.0; double x_end = 195.0; double y_start = 235.0; double y_end = initial_height() - 5.0; double x_center = (x_start + x_end) / 2; agg::path_storage p; agg::conv_stroke<agg::path_storage> stroke(p); stroke.width(0.8); unsigned i; for(i = 0; i <= 16; i++) { double x = x_start + (x_end - x_start) * i / 16.0; p.remove_all(); p.move_to(x+0.5, y_start); p.line_to(x+0.5, y_end); ras.add_path(stroke); agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba8(0, 0, 0, i == 8 ? 255 : 100)); } double ys = y_start + (y_end - y_start) / 6.0; p.remove_all(); p.move_to(x_start, ys); p.line_to(x_end, ys); ras.add_path(stroke); agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba8(0, 0, 0)); double radius = filter.radius(); unsigned n = unsigned(radius * 256 * 2); double dx = (x_end - x_start) * radius / 8.0; double dy = y_end - ys; const agg::int16* weights = filter.weight_array(); double xs = (x_end + x_start)/2.0 - (filter.diameter() * (x_end - x_start) / 32.0); unsigned nn = filter.diameter() * 256; p.remove_all(); p.move_to(xs+0.5, ys + dy * weights[0] / agg::image_filter_scale); for(i = 1; i < nn; i++) { p.line_to(xs + dx * i / n + 0.5, ys + dy * weights[i] / agg::image_filter_scale); } ras.add_path(stroke); agg::render_scanlines_aa_solid(ras, sl, rb, agg::rgba8(100, 0, 0)); } break; } agg::render_ctrl(ras, sl, rb, m_gamma); if(m_filters.cur_item() >= 14) { agg::render_ctrl(ras, sl, rb, m_radius); } agg::render_ctrl(ras, sl, rb, m_filters); agg::render_ctrl(ras, sl, rb, m_normalize); } }; int agg_main(int argc, char* argv[]) { the_application app(agg::pix_format_bgra32, flip_y); app.caption("Image transformation filters comparison"); if(app.init(500, 340, 0)) { return app.run(); } return 0; } |