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

image_resample.cpp

Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <ctype.h>
00003 #include <stdio.h>
00004 #include "agg_rendering_buffer.h"
00005 #include "agg_rasterizer_scanline_aa.h"
00006 #include "agg_scanline_u.h"
00007 #include "agg_renderer_scanline.h"
00008 #include "agg_path_storage.h"
00009 #include "agg_conv_transform.h"
00010 #include "agg_trans_affine.h"
00011 #include "agg_span_allocator.h"
00012 #include "agg_span_interpolator_linear.h"
00013 #include "agg_span_interpolator_trans.h"
00014 #include "agg_span_interpolator_persp.h"
00015 #include "agg_span_subdiv_adaptor.h"
00016 #include "agg_image_accessors.h"
00017 #include "agg_gamma_lut.h"
00018 #include "ctrl/agg_rbox_ctrl.h"
00019 #include "ctrl/agg_slider_ctrl.h"
00020 #include "platform/agg_platform_support.h"
00021 #include "interactive_polygon.h"
00022 
00023 
00024 int global_offset = 0;
00025 
00026 
00027 enum flip_y_e { flip_y = true };
00028 
00029 agg::rasterizer_scanline_aa<> g_rasterizer;
00030 agg::scanline_u8  g_scanline;
00031 double            g_x1 = 0;
00032 double            g_y1 = 0;
00033 double            g_x2 = 0;
00034 double            g_y2 = 0;
00035 
00036 #include "agg_pixfmt_rgb.h"
00037 #include "agg_span_image_filter_rgb.h"
00038 #define pix_format agg::pix_format_bgr24
00039 typedef agg::pixfmt_bgr24     pixfmt;
00040 typedef agg::pixfmt_bgr24_pre pixfmt_pre;
00041 #define image_filter_2x2_type      agg::span_image_filter_rgb_2x2
00042 #define image_resample_affine_type agg::span_image_resample_rgb_affine
00043 #define image_resample_type        agg::span_image_resample_rgb
00044 
00045 typedef pixfmt::color_type                             color_type;
00046 typedef color_type::value_type                         value_type;
00047 typedef agg::renderer_base<pixfmt>                     renderer_base;
00048 typedef agg::renderer_base<pixfmt_pre>                 renderer_base_pre;
00049 typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
00050 enum base_scale_e { base_shift = color_type::base_shift };
00051 
00052 class the_application : public agg::platform_support
00053 {
00054 public:
00055     agg::gamma_lut<value_type, value_type, base_shift, base_shift> m_gamma_lut;
00056     agg::interactive_polygon     m_quad;
00057     agg::rbox_ctrl<agg::rgba>    m_trans_type;
00058     agg::slider_ctrl<agg::rgba>  m_gamma;
00059     agg::slider_ctrl<agg::rgba>  m_blur;
00060     double m_old_gamma;
00061 
00062     the_application(agg::pix_format_e format, bool flip_y) :
00063         agg::platform_support(format, flip_y),
00064         m_gamma_lut(2.0),
00065         m_quad(4, 5.0),
00066         m_trans_type(400, 5.0, 430+170.0, 100.0, !flip_y),
00067         m_gamma(5.0, 5.0+15*0, 400-5, 10.0+15*0, !flip_y),
00068         m_blur (5.0, 5.0+15*1, 400-5, 10.0+15*1, !flip_y),
00069         m_old_gamma(2.0)
00070     {
00071         m_trans_type.text_size(7);
00072         m_trans_type.add_item("Affine No Resample");
00073         m_trans_type.add_item("Affine Resample");
00074         m_trans_type.add_item("Perspective No Resample LERP");
00075         m_trans_type.add_item("Perspective No Resample Exact");
00076         m_trans_type.add_item("Perspective Resample LERP");
00077         m_trans_type.add_item("Perspective Resample Exact");
00078         m_trans_type.cur_item(4);
00079         add_ctrl(m_trans_type);
00080 
00081         m_gamma.range(0.5, 3.0);
00082         m_gamma.value(2.0);
00083         m_gamma.label("Gamma=%.3f");
00084         add_ctrl(m_gamma);
00085 
00086         m_blur.range(0.5, 2.0);
00087         m_blur.value(1.0);
00088         m_blur.label("Blur=%.3f");
00089         add_ctrl(m_blur);
00090     }
00091 
00092 
00093     virtual void on_init()
00094     {
00095         g_x1 = 0.0;
00096         g_y1 = 0.0;
00097         g_x2 = rbuf_img(0).width();
00098         g_y2 = rbuf_img(0).height();
00099 
00100         double x1 = g_x1;// * 100.0;
00101         double y1 = g_y1;// * 100.0;
00102         double x2 = g_x2;// * 100.0;
00103         double y2 = g_y2;// * 100.0;
00104 
00105         double dx = width()  / 2.0 - (x2 - x1) / 2.0;
00106         double dy = height() / 2.0 - (y2 - y1) / 2.0;
00107         m_quad.xn(0) = floor(x1 + dx);
00108         m_quad.yn(0) = floor(y1 + dy);// - 150;
00109         m_quad.xn(1) = floor(x2 + dx);
00110         m_quad.yn(1) = floor(y1 + dy);// - 110;
00111         m_quad.xn(2) = floor(x2 + dx);
00112         m_quad.yn(2) = floor(y2 + dy);// - 300;
00113         m_quad.xn(3) = floor(x1 + dx);
00114         m_quad.yn(3) = floor(y2 + dy);// - 200;
00115 
00116         pixfmt pixf(rbuf_img(0));
00117         pixf.apply_gamma_dir(m_gamma_lut);
00118     }
00119 
00120     virtual void on_draw()
00121     {
00122         if(m_gamma.value() != m_old_gamma)
00123         {
00124             m_gamma_lut.gamma(m_gamma.value());
00125             load_img(0, "spheres");
00126             pixfmt pixf(rbuf_img(0));
00127             pixf.apply_gamma_dir(m_gamma_lut);
00128             m_old_gamma = m_gamma.value();
00129         }
00130 
00131         pixfmt            pixf(rbuf_window());
00132         pixfmt_pre        pixf_pre(rbuf_window());
00133         renderer_base     rb(pixf);
00134         renderer_base_pre rb_pre(pixf_pre);
00135 
00136         renderer_solid r(rb);
00137 
00138         rb.clear(agg::rgba(1, 1, 1));
00139 
00140         if(m_trans_type.cur_item() < 2)
00141         {
00142             // For the affine parallelogram transformations we
00143             // calculate the 4-th (implicit) point of the parallelogram
00144             m_quad.xn(3) = m_quad.xn(0) + (m_quad.xn(2) - m_quad.xn(1));
00145             m_quad.yn(3) = m_quad.yn(0) + (m_quad.yn(2) - m_quad.yn(1));
00146         }
00147 
00148         //--------------------------
00149         // Render the "quad" tool and controls
00150         g_rasterizer.add_path(m_quad);
00151         r.color(agg::rgba(0, 0.3, 0.5, 0.1));
00152         agg::render_scanlines(g_rasterizer, g_scanline, r);
00153 
00154         // Prepare the polygon to rasterize. Here we need to fill
00155         // the destination (transformed) polygon.
00156         g_rasterizer.clip_box(0, 0, width(), height());
00157         g_rasterizer.reset();
00158         int b = 0;
00159         g_rasterizer.move_to_d(m_quad.xn(0)-b, m_quad.yn(0)-b);
00160         g_rasterizer.line_to_d(m_quad.xn(1)+b, m_quad.yn(1)-b);
00161         g_rasterizer.line_to_d(m_quad.xn(2)+b, m_quad.yn(2)+b);
00162         g_rasterizer.line_to_d(m_quad.xn(3)-b, m_quad.yn(3)+b);
00163 
00164         typedef agg::span_allocator<color_type> span_alloc_type;
00165         span_alloc_type sa;
00166         agg::image_filter_bilinear filter_kernel;
00167         agg::image_filter_lut filter(filter_kernel, true);
00168 
00169         pixfmt pixf_img(rbuf_img(0));
00170         typedef agg::image_accessor_clone<pixfmt> source_type;
00171         source_type source(pixf_img);
00172 
00173         start_timer();
00174         switch(m_trans_type.cur_item())
00175         {
00176             case 0:
00177             {
00178                 agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00179 
00180                 typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
00181                 interpolator_type interpolator(tr);
00182 
00183                 typedef image_filter_2x2_type<source_type, 
00184                                               interpolator_type> span_gen_type;
00185                 span_gen_type sg(source, interpolator, filter);
00186                 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00187                 break;
00188             }
00189 
00190             case 1:
00191             {
00192                 agg::trans_affine tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00193 
00194                 typedef agg::span_interpolator_linear<agg::trans_affine> interpolator_type;
00195                 typedef image_resample_affine_type<source_type> span_gen_type;
00196 
00197                 interpolator_type interpolator(tr);
00198                 span_gen_type sg(source, interpolator, filter);
00199                 sg.blur(m_blur.value());
00200                 agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00201                 break;
00202             }
00203 
00204             case 2:
00205             {
00206                 agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00207                 if(tr.is_valid())
00208                 {
00209                     typedef agg::span_interpolator_linear_subdiv<agg::trans_perspective> interpolator_type;
00210                     interpolator_type interpolator(tr);
00211 
00212                     typedef image_filter_2x2_type<source_type,
00213                                                   interpolator_type> span_gen_type;
00214                     span_gen_type sg(source, interpolator, filter);
00215                     agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00216                 }
00217                 break;
00218             }
00219 
00220             case 3:
00221             {
00222                 agg::trans_perspective tr(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00223                 if(tr.is_valid())
00224                 {
00225                     typedef agg::span_interpolator_trans<agg::trans_perspective> interpolator_type;
00226                     interpolator_type interpolator(tr);
00227 
00228                     typedef image_filter_2x2_type<source_type, 
00229                                                   interpolator_type> span_gen_type;
00230                     span_gen_type sg(source, interpolator, filter);
00231                     agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00232                 }
00233                 break;
00234             }
00235 
00236             case 4:
00237             {
00238                 typedef agg::span_interpolator_persp_lerp<> interpolator_type;
00239                 typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
00240 
00241                 interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00242                 subdiv_adaptor_type subdiv_adaptor(interpolator);
00243 
00244                 if(interpolator.is_valid())
00245                 {
00246                     typedef image_resample_type<source_type, 
00247                                                 subdiv_adaptor_type> span_gen_type;
00248                     span_gen_type sg(source, subdiv_adaptor, filter);
00249                     sg.blur(m_blur.value());
00250                     agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00251                 }
00252                 break;
00253             }
00254 
00255             case 5:
00256             {
00257                 typedef agg::span_interpolator_persp_exact<> interpolator_type;
00258                 typedef agg::span_subdiv_adaptor<interpolator_type> subdiv_adaptor_type;
00259 
00260                 interpolator_type interpolator(m_quad.polygon(), g_x1, g_y1, g_x2, g_y2);
00261                 subdiv_adaptor_type subdiv_adaptor(interpolator);
00262 
00263                 if(interpolator.is_valid())
00264                 {
00265                     typedef image_resample_type<source_type, 
00266                                                 subdiv_adaptor_type> span_gen_type;
00267                     span_gen_type sg(source, subdiv_adaptor, filter);
00268                     sg.blur(m_blur.value());
00269                     agg::render_scanlines_aa(g_rasterizer, g_scanline, rb_pre, sa, sg);
00270                 }
00271                 break;
00272             }
00273         }
00274         double tm = elapsed_time();
00275         pixf.apply_gamma_inv(m_gamma_lut);
00276 
00277         char buf[64]; 
00278         agg::gsv_text t;
00279         t.size(10.0);
00280 
00281         agg::conv_stroke<agg::gsv_text> pt(t);
00282         pt.width(1.5);
00283 
00284         sprintf(buf, "%3.2f ms", tm);
00285         t.start_point(10.0, 70.0);
00286         t.text(buf);
00287 
00288         g_rasterizer.add_path(pt);
00289         r.color(agg::rgba(0,0,0));
00290         agg::render_scanlines(g_rasterizer, g_scanline, r);
00291 
00292         //--------------------------
00293         agg::render_ctrl(g_rasterizer, g_scanline, rb, m_trans_type);
00294         agg::render_ctrl(g_rasterizer, g_scanline, rb, m_gamma);
00295         agg::render_ctrl(g_rasterizer, g_scanline, rb, m_blur);
00296     }
00297 
00298 
00299 
00300     virtual void on_mouse_button_down(int x, int y, unsigned flags)
00301     {
00302         if(flags & agg::mouse_left)
00303         {
00304             if(m_quad.on_mouse_button_down(x, y))
00305             {
00306                 force_redraw();
00307             }
00308         }
00309     }
00310 
00311 
00312     virtual void on_mouse_move(int x, int y, unsigned flags)
00313     {
00314         if(flags & agg::mouse_left)
00315         {
00316             if(m_quad.on_mouse_move(x, y))
00317             {
00318                 force_redraw();
00319             }
00320         }
00321         if((flags & agg::mouse_left) == 0)
00322         {
00323             on_mouse_button_up(x, y, flags);
00324         }
00325     }
00326 
00327 
00328     virtual void on_mouse_button_up(int x, int y, unsigned flags)
00329     {
00330         if(m_quad.on_mouse_button_up(x, y))
00331         {
00332             force_redraw();
00333         }
00334     }
00335 
00336     virtual void on_key(int x, int y, unsigned key, unsigned flags) 
00337     {
00338         if(key == ' ')
00339         {
00340             double cx = (m_quad.xn(0) + m_quad.xn(1) + m_quad.xn(2) + m_quad.xn(3)) / 4;
00341             double cy = (m_quad.yn(0) + m_quad.yn(1) + m_quad.yn(2) + m_quad.yn(3)) / 4;
00342             agg::trans_affine tr = agg::trans_affine_translation(-cx, -cy);
00343             tr *= agg::trans_affine_rotation(agg::pi / 2.0);
00344             tr *= agg::trans_affine_translation(cx, cy);
00345             tr.transform(&m_quad.xn(0), &m_quad.yn(0));
00346             tr.transform(&m_quad.xn(1), &m_quad.yn(1));
00347             tr.transform(&m_quad.xn(2), &m_quad.yn(2));
00348             tr.transform(&m_quad.xn(3), &m_quad.yn(3));
00349             force_redraw();
00350         }
00351     }
00352 
00353 };
00354 
00355 
00356 
00357 
00358 
00359 
00360 int agg_main(int argc, char* argv[])
00361 {
00362     the_application app(pix_format, flip_y);
00363     app.caption("AGG Example. Image Transformations with Resampling");
00364 
00365     const char* img_name = "spheres";
00366     if(argc >= 2) img_name = argv[1];
00367     if(!app.load_img(0, img_name)) 
00368     {
00369         char buf[256];
00370         if(strcmp(img_name, "spheres") == 0)
00371         {
00372             sprintf(buf, "File not found: %s%s. Download http://www.antigrain.com/%s%s\n"
00373                          "or copy it from another directory if available.",
00374                     img_name, app.img_ext(), img_name, app.img_ext());
00375         }
00376         else
00377         {
00378             sprintf(buf, "File not found: %s%s", img_name, app.img_ext());
00379         }
00380         app.message(buf);
00381         return 1;
00382     }
00383     
00384 
00385     if(app.init(600, 600, agg::window_resize))
00386     {
00387         return app.run();
00388     }
00389     return 1;
00390 }
00391 
00392 
00393 
00394 
00395 
00396 

© sourcejam.com 2005-2008