/home/andreas/src/svn/mapnik/include/mapnik/image_util.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * 
00003  * This file is part of Mapnik (c++ mapping toolkit)
00004  *
00005  * Copyright (C) 2006 Artem Pavlenko
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  *
00021  *****************************************************************************/
00022 
00023 //$Id: image_util.hpp 39 2005-04-10 20:39:53Z pavlenko $
00024 
00025 #ifndef IMAGE_UTIL_HPP
00026 #define IMAGE_UTIL_HPP
00027 
00028 // stl
00029 #include <string>
00030 // mapnik
00031 #include <mapnik/config.hpp>
00032 #include <mapnik/graphics.hpp>
00033 
00034 namespace mapnik {
00035     
00036     template <typename T>
00037     void save_to_file(std::string const& filename,
00038                       std::string const& type,
00039                       T const& image);
00040     template <typename T>
00041     void save_as_png(std::string const& filename,
00042                      T const& image);
00043 
00044     template <typename T>
00045     void save_as_jpeg(std::string const& filename,
00046                       int quality,
00047                       T const& image);
00048 
00049     template <typename T>
00050     double distance(T x0,T y0,T x1,T y1)
00051     {
00052         double dx = x1-x0;
00053         double dy = y1-y0;
00054         return sqrt(dx * dx + dy * dy);
00055     }
00056 
00057     template <typename Image>
00058     inline void scale_down2(Image& target,const Image& source)
00059     {
00060         int source_width=source.width();
00061         int source_height=source.height();
00062 
00063         int target_width=target.width();
00064         int target_height=target.height();
00065         if (target_width<source_width/2 || target_height<source_height/2)
00066             return;
00067         int y1,x1;
00068         for (int y=0;y<target_height;++y)
00069         {
00070             y1=2*y;
00071             for(int x=0;x<target_width;++x)
00072             {
00073                 x1=2*x;
00074                 //todo calculate average???
00075                 target(x,y)=source(x1,y1);
00076             }
00077         }
00078     }
00079 
00080     template <typename Image,int scale>
00081     struct image_op
00082     {
00083         static void scale_up(Image& target,const Image& source)
00084         {
00085             if (scale<3) return;
00086             int source_width=source.width();
00087             int source_height=source.height();
00088 
00089             int target_width=target.width();
00090             int target_height=target.height();
00091             if (target_width<scale*source_width || target_height<scale*source_height)
00092                 return;
00093             for (int y=0;y<source_height;++y)
00094             {
00095                 for(int x=0;x<source_width;++x)
00096                 {
00097                     unsigned p=source(x,y);
00098                     for (int i=0;i<scale;++i)
00099                         for (int j=0;j<scale;++j)
00100                             target(scale*x+i,scale*y+j)=p;
00101                 }
00102             }
00103         }
00104     };
00105 
00106     template <typename Image>
00107     struct image_op<Image,2>
00108     {
00109         static void scale_up(Image& target,const Image& source)
00110         {
00111             int source_width=source.width();
00112             int source_height=source.height();
00113 
00114             int target_width=target.width();
00115             int target_height=target.height();
00116             if (target_width<2*source_width || target_height<2*source_height)
00117                 return;
00118             for (int y=0;y<source_height;++y)
00119             {
00120                 for(int x=0;x<source_width;++x)
00121                 {
00122                     target(2*x,2*y)=source(x,y);
00123                     target(2*x+1,2*y)=source(x,y);
00124                     target(2*x+1,2*y+1)=source(x,y);
00125                     target(2*x,2*y+1)=source(x,y);
00126                 }
00127             }
00128         }
00129     };
00130 
00131     namespace
00132     {
00133         template <typename Image>
00134         inline void scale_up(Image& target,const Image& source,unsigned scale)
00135         {
00136             int source_width=source.width();
00137             int source_height=source.height();
00138 
00139             int target_width=target.width();
00140             int target_height=target.height();
00141             if (target_width<scale*source_width || target_height<scale*source_height)
00142                 return;
00143             for (int y=0;y<source_height;++y)
00144             {
00145                 for(int x=0;x<source_width;++x)
00146                 {
00147                     unsigned p=source(x,y);
00148                     for (int i=0;i<scale;++i)
00149                         for (int j=0;j<scale;++j)
00150                             target(scale*x+i,scale*y+j)=p;
00151                 }
00152             }
00153         }
00154     }
00155     
00156     template <typename Image>
00157     void scale_image(Image& target,const Image& source,unsigned scale)
00158     {
00159         if (scale==2)
00160         {
00161             image_op<Image,2>::scale_up(target,source);
00162         }
00163         else
00164         {
00165             scale_up<Image>(target,source,scale);
00166         }
00167     }
00168 
00169     template <typename Image>
00170     inline void scale_image (Image& target,const Image& source)
00171     {
00172 
00173         int source_width=source.width();
00174         int source_height=source.height();
00175 
00176         int target_width=target.width();
00177         int target_height=target.height();
00178 
00179         if (source_width<1 || source_height<1 ||
00180             target_width<1 || target_height<1) return;
00181         int int_part_y=source_height/target_height;
00182         int fract_part_y=source_height%target_height;
00183         int err_y=0;
00184         int int_part_x=source_width/target_width;
00185         int fract_part_x=source_width%target_width;
00186         int err_x=0;
00187         int x=0,y=0,xs=0,ys=0;
00188         int prev_y=-1;
00189         for (y=0;y<target_height;++y)
00190         {
00191             if (ys==prev_y)
00192             {
00193                 target.setRow(y,target.getRow(y-1),target_width);
00194             }
00195             else
00196             {
00197                 xs=0;
00198                 for (x=0;x<target_width;++x)
00199                 {
00200                     target(x,y)=source(xs,ys);
00201                     xs+=int_part_x;
00202                     err_x+=fract_part_x;
00203                     if (err_x>=target_width)
00204                     {
00205                         err_x-=target_width;
00206                         ++xs;
00207                     }
00208                 }
00209                 prev_y=ys;
00210             }
00211             ys+=int_part_y;
00212             err_y+=fract_part_y;
00213             if (err_y>=target_height)
00214             {
00215                 err_y-=target_height;
00216                 ++ys;
00217             }
00218         }
00219     }
00220 
00221 #ifdef _MSC_VER
00222   template MAPNIK_DECL void save_to_file<ImageData32>(std::string const&,
00223                                                       std::string const& ,
00224                                                       ImageData32 const&);
00225   template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (std::string const&,
00226                                                                     std::string const& ,
00227                                                                     image_view<ImageData32> const&);
00228 #endif
00229 
00230 }
00231 
00232 #endif //IMAGE_UTIL_HPP

Generated on Thu Jul 19 17:59:26 2007 for Mapnik by  doxygen 1.4.7