Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

image_fltr_graph.cpp

Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <math.h>
00004 #include <time.h>
00005 #include "agg_rendering_buffer.h"
00006 #include "agg_rasterizer_scanline_aa.h"
00007 #include "agg_ellipse.h"
00008 #include "agg_trans_affine.h"
00009 #include "agg_conv_transform.h"
00010 #include "agg_conv_stroke.h"
00011 #include "agg_pixfmt_rgb.h"
00012 #include "agg_scanline_p.h"
00013 #include "agg_renderer_scanline.h"
00014 #include "agg_image_filters.h"
00015 #include "ctrl/agg_slider_ctrl.h"
00016 #include "ctrl/agg_rbox_ctrl.h"
00017 #include "ctrl/agg_cbox_ctrl.h"
00018 #include "platform/agg_platform_support.h"
00019 
00020 
00021 enum flip_y_e { flip_y = true };
00022 
00023 
00024 struct filter_base
00025 {
00026     virtual double radius() const = 0;
00027     virtual void set_radius(double r) = 0;
00028     virtual double calc_weight(double x) const = 0;
00029 };
00030 
00031 
00032 template<class Filter> struct image_filter_const_radius_adaptor : filter_base
00033 {
00034     virtual double radius() const { return m_filter.radius(); }
00035     virtual void set_radius(double r) {}
00036     virtual double calc_weight(double x) const { return m_filter.calc_weight(fabs(x)); }
00037     Filter m_filter;
00038 };
00039 
00040 
00041 template<class Filter> struct image_filter_variable_radius_adaptor : filter_base
00042 {
00043     virtual double radius() const { return m_filter.radius(); }
00044     virtual double calc_weight(double x) const { return m_filter.calc_weight(fabs(x)); }
00045     virtual void set_radius(double r) { m_filter = Filter(r); }
00046     image_filter_variable_radius_adaptor() : m_filter(2.0) {}
00047     Filter m_filter;
00048 };
00049 
00050 
00051 
00052 class the_application : public agg::platform_support
00053 {
00054     agg::slider_ctrl<agg::rgba>  m_radius;
00055     agg::cbox_ctrl<agg::rgba>  m_bilinear;
00056     agg::cbox_ctrl<agg::rgba>  m_bicubic;
00057     agg::cbox_ctrl<agg::rgba>  m_spline16;
00058     agg::cbox_ctrl<agg::rgba>  m_spline36;
00059     agg::cbox_ctrl<agg::rgba>  m_hanning;
00060     agg::cbox_ctrl<agg::rgba>  m_hamming;
00061     agg::cbox_ctrl<agg::rgba>  m_hermite;
00062     agg::cbox_ctrl<agg::rgba>  m_kaiser;
00063     agg::cbox_ctrl<agg::rgba>  m_quadric;
00064     agg::cbox_ctrl<agg::rgba>  m_catrom;
00065     agg::cbox_ctrl<agg::rgba>  m_gaussian;
00066     agg::cbox_ctrl<agg::rgba>  m_bessel;
00067     agg::cbox_ctrl<agg::rgba>  m_mitchell;
00068     agg::cbox_ctrl<agg::rgba>  m_sinc;
00069     agg::cbox_ctrl<agg::rgba>  m_lanczos;
00070     agg::cbox_ctrl<agg::rgba>  m_blackman;
00071     agg::cbox_ctrl<agg::rgba>* m_filters[32];
00072 
00073     image_filter_const_radius_adaptor<agg::image_filter_bilinear>    m_filter_bilinear;
00074     image_filter_const_radius_adaptor<agg::image_filter_bicubic>     m_filter_bicubic;
00075     image_filter_const_radius_adaptor<agg::image_filter_spline16>    m_filter_spline16;
00076     image_filter_const_radius_adaptor<agg::image_filter_spline36>    m_filter_spline36;
00077     image_filter_const_radius_adaptor<agg::image_filter_hanning>     m_filter_hanning;
00078     image_filter_const_radius_adaptor<agg::image_filter_hamming>     m_filter_hamming;
00079     image_filter_const_radius_adaptor<agg::image_filter_hermite>     m_filter_hermite;
00080     image_filter_const_radius_adaptor<agg::image_filter_kaiser>      m_filter_kaiser;
00081     image_filter_const_radius_adaptor<agg::image_filter_quadric>     m_filter_quadric;
00082     image_filter_const_radius_adaptor<agg::image_filter_catrom>      m_filter_catrom;
00083     image_filter_const_radius_adaptor<agg::image_filter_gaussian>    m_filter_gaussian;
00084     image_filter_const_radius_adaptor<agg::image_filter_bessel>      m_filter_bessel;
00085     image_filter_const_radius_adaptor<agg::image_filter_mitchell>    m_filter_mitchell;
00086     image_filter_variable_radius_adaptor<agg::image_filter_sinc>     m_filter_sinc;
00087     image_filter_variable_radius_adaptor<agg::image_filter_lanczos>  m_filter_lanczos;
00088     image_filter_variable_radius_adaptor<agg::image_filter_blackman> m_filter_blackman;
00089 
00090     filter_base* m_filter_func[32];
00091     unsigned     m_num_filters;
00092 
00093 
00094 public:
00095     the_application(agg::pix_format_e format, bool flip_y) :
00096         agg::platform_support(format, flip_y),
00097         m_radius     (5.0, 5.0, 780-5, 10.0,     !flip_y),
00098         m_bilinear (8.0, 30.0+15*0,  "bilinear", !flip_y), 
00099         m_bicubic  (8.0, 30.0+15*1,  "bicubic ", !flip_y),
00100         m_spline16 (8.0, 30.0+15*2,  "spline16", !flip_y),
00101         m_spline36 (8.0, 30.0+15*3,  "spline36", !flip_y),
00102         m_hanning  (8.0, 30.0+15*4,  "hanning ", !flip_y), 
00103         m_hamming  (8.0, 30.0+15*5,  "hamming ", !flip_y),
00104         m_hermite  (8.0, 30.0+15*6,  "hermite ", !flip_y),
00105         m_kaiser   (8.0, 30.0+15*7,  "kaiser  ", !flip_y), 
00106         m_quadric  (8.0, 30.0+15*8,  "quadric ", !flip_y), 
00107         m_catrom   (8.0, 30.0+15*9,  "catrom  ", !flip_y), 
00108         m_gaussian (8.0, 30.0+15*10, "gaussian", !flip_y), 
00109         m_bessel   (8.0, 30.0+15*11, "bessel  ", !flip_y),
00110         m_mitchell (8.0, 30.0+15*12, "mitchell", !flip_y), 
00111         m_sinc     (8.0, 30.0+15*13, "sinc    ", !flip_y),
00112         m_lanczos  (8.0, 30.0+15*14, "lanczos ", !flip_y), 
00113         m_blackman (8.0, 30.0+15*15, "blackman", !flip_y), 
00114         m_num_filters(0)
00115     {
00116         m_filters[m_num_filters++] = &m_bilinear;
00117         m_filters[m_num_filters++] = &m_bicubic;
00118         m_filters[m_num_filters++] = &m_spline16;
00119         m_filters[m_num_filters++] = &m_spline36;
00120         m_filters[m_num_filters++] = &m_hanning;
00121         m_filters[m_num_filters++] = &m_hamming;
00122         m_filters[m_num_filters++] = &m_hermite;
00123         m_filters[m_num_filters++] = &m_kaiser;
00124         m_filters[m_num_filters++] = &m_quadric;
00125         m_filters[m_num_filters++] = &m_catrom;
00126         m_filters[m_num_filters++] = &m_gaussian;
00127         m_filters[m_num_filters++] = &m_bessel;
00128         m_filters[m_num_filters++] = &m_mitchell;
00129         m_filters[m_num_filters++] = &m_sinc;
00130         m_filters[m_num_filters++] = &m_lanczos;
00131         m_filters[m_num_filters++] = &m_blackman;
00132 
00133         unsigned i = 0;
00134 
00135         m_filter_func[i++] = &m_filter_bilinear;
00136         m_filter_func[i++] = &m_filter_bicubic;
00137         m_filter_func[i++] = &m_filter_spline16;
00138         m_filter_func[i++] = &m_filter_spline36;
00139         m_filter_func[i++] = &m_filter_hanning;
00140         m_filter_func[i++] = &m_filter_hamming;
00141         m_filter_func[i++] = &m_filter_hermite;
00142         m_filter_func[i++] = &m_filter_kaiser;
00143         m_filter_func[i++] = &m_filter_quadric;
00144         m_filter_func[i++] = &m_filter_catrom;
00145         m_filter_func[i++] = &m_filter_gaussian;
00146         m_filter_func[i++] = &m_filter_bessel;
00147         m_filter_func[i++] = &m_filter_mitchell;
00148         m_filter_func[i++] = &m_filter_sinc;
00149         m_filter_func[i++] = &m_filter_lanczos;
00150         m_filter_func[i++] = &m_filter_blackman;
00151         for(i = 0; i < m_num_filters; i++)
00152         {
00153             add_ctrl(*m_filters[i]);
00154         }
00155 
00156         m_radius.range(2.0, 8.0);
00157         m_radius.value(4.0);
00158         m_radius.label("Radius=%.3f");
00159         add_ctrl(m_radius);
00160     }
00161 
00162     virtual ~the_application()
00163     {
00164     }
00165 
00166     virtual void on_draw()
00167     {
00168         typedef agg::pixfmt_bgr24 pixfmt; 
00169         typedef agg::renderer_base<pixfmt> renderer_base;
00170         typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
00171        
00172         pixfmt pixf(rbuf_window());
00173         renderer_base rb(pixf);
00174         renderer_solid rs(rb);
00175 
00176         rb.clear(agg::rgba(1.0, 1.0, 1.0));
00177         agg::rasterizer_scanline_aa<> ras;
00178         agg::scanline_p8 sl;
00179 
00180         double x_start = 125.0;
00181         double x_end   = initial_width() - 15.0;
00182         double y_start = 10.0;
00183         double y_end   = initial_height() - 10.0;
00184         double x_center = (x_start + x_end) / 2;
00185 
00186         unsigned i;
00187 
00188         agg::path_storage p;
00189         agg::conv_stroke<agg::path_storage> pl(p);
00190         agg::conv_transform<agg::conv_stroke<agg::path_storage> > tr(pl, trans_affine_resizing());
00191 
00192         for(i = 0; i <= 16; i++)
00193         {
00194             double x = x_start + (x_end - x_start) * i / 16.0;
00195             p.remove_all();
00196             p.move_to(x+0.5, y_start);
00197             p.line_to(x+0.5, y_end);
00198             ras.add_path(tr);
00199             rs.color(agg::rgba8(0, 0, 0, i == 8 ? 255 : 100));
00200             agg::render_scanlines(ras, sl, rs);
00201         }
00202 
00203         double ys = y_start + (y_end - y_start) / 6.0;
00204 
00205         p.remove_all();
00206         p.move_to(x_start, ys);
00207         p.line_to(x_end,   ys);
00208         ras.add_path(tr);
00209         rs.color(agg::rgba8(0, 0, 0));
00210         agg::render_scanlines(ras, sl, rs);
00211 
00212 
00213         pl.width(1.0);
00214         
00215         for(i = 0; i < m_num_filters; i++)
00216         {
00217             if(m_filters[i]->status())
00218             {
00219                 m_filter_func[i]->set_radius(m_radius.value());
00220                 unsigned j;
00221 
00222                 double radius = m_filter_func[i]->radius();
00223                 unsigned n = unsigned(radius * 256 * 2);
00224                 double dy = y_end - ys;
00225 
00226                 double xs = (x_end + x_start)/2.0 - (radius * (x_end - x_start) / 16.0);
00227                 double dx = (x_end - x_start) * radius / 8.0;
00228 
00229                 p.remove_all();
00230                 p.move_to(xs+0.5, ys + dy * m_filter_func[i]->calc_weight(-radius));
00231                 for(j = 1; j < n; j++)
00232                 {
00233                     p.line_to(xs + dx * j / n + 0.5,
00234                               ys + dy * m_filter_func[i]->calc_weight(j / 256.0 - radius));
00235                 }
00236                 ras.add_path(tr);
00237                 rs.color(agg::rgba8(100, 0, 0));
00238                 agg::render_scanlines(ras, sl, rs);
00239 
00240                 p.remove_all();
00241                 unsigned xint;
00242                 int ir = int(ceil(radius) + 0.1);
00243 
00244                 for(xint = 0; xint < 256; xint++)
00245                 {
00246                     int xfract;
00247                     double sum = 0;
00248                     for(xfract = -ir; xfract < ir; xfract++) 
00249                     {
00250                         double xf = xint/256.0 + xfract;
00251                         if(xf >= -radius || xf <= radius)
00252                         {
00253                             sum += m_filter_func[i]->calc_weight(xf);
00254                         }
00255                     }
00256 
00257                     double x = x_center + ((-128.0 + xint) / 128.0) * radius * (x_end - x_start) / 16.0;
00258                     double y = ys + sum * 256 - 256;
00259 
00260                     if(xint == 0) p.move_to(x, y);
00261                     else          p.line_to(x, y);
00262                 }
00263                 ras.add_path(tr);
00264                 rs.color(agg::rgba8(0, 100, 0));
00265                 agg::render_scanlines(ras, sl, rs);
00266 
00267                 agg::image_filter_lut normalized(*m_filter_func[i]);
00268                 const agg::int16* weights = normalized.weight_array();
00269 
00270                 xs = (x_end + x_start)/2.0 - (normalized.diameter() * (x_end - x_start) / 32.0);
00271                 unsigned nn = normalized.diameter() * 256;
00272                 p.remove_all();
00273                 p.move_to(xs+0.5, ys + dy * weights[0] / agg::image_filter_scale);
00274                 for(j = 1; j < nn; j++)
00275                 {
00276                     p.line_to(xs + dx * j / n + 0.5,
00277                               ys + dy * weights[j] / agg::image_filter_scale);
00278                 }
00279                 ras.add_path(tr);
00280                 rs.color(agg::rgba8(0, 0, 100, 255));
00281                 agg::render_scanlines(ras, sl, rs);
00282             }
00283         }
00284 
00285         for(i = 0; i < m_num_filters; i++)
00286         {
00287             agg::render_ctrl(ras, sl, rb, *m_filters[i]);
00288         }
00289         if(m_sinc.status() || m_lanczos.status() || m_blackman.status())
00290         {
00291             agg::render_ctrl(ras, sl, rb, m_radius);
00292         }
00293     }
00294 };
00295 
00296 
00297 
00298 
00299 
00300 
00301 
00302 int agg_main(int argc, char* argv[])
00303 {
00304     the_application app(agg::pix_format_bgr24, flip_y);
00305     app.caption("Image filters' shape comparison");
00306 
00307     if(app.init(780, 300, agg::window_resize))
00308     {
00309         return app.run();
00310     }
00311     return 0;
00312 }
00313 
00314 

© sourcejam.com 2005-2008