/home/andreas/src/svn/mapnik/include/mapnik/graphics.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: graphics.hpp 39 2005-04-10 20:39:53Z pavlenko $
00024 
00025 #ifndef GRAPHICS_HPP
00026 #define GRAPHICS_HPP
00027 // stl
00028 #include <cmath>
00029 #include <string>
00030 #include <cassert>
00031 // mapnik
00032 #include <mapnik/color.hpp>
00033 #include <mapnik/gamma.hpp>
00034 #include <mapnik/image_data.hpp>
00035 #include <mapnik/envelope.hpp>
00036 #include <mapnik/image_view.hpp>
00037 
00038 namespace mapnik
00039 {
00040     class MAPNIK_DECL Image32
00041     {
00042     private:
00043         unsigned width_;
00044         unsigned height_;
00045         Color background_;
00046         ImageData32 data_;
00047     public:
00048         Image32(int width,int height);
00049         Image32(Image32 const& rhs);
00050         ~Image32();
00051         void setBackground(Color const& background);
00052         const Color& getBackground() const;     
00053         const ImageData32& data() const;
00054         
00055         inline ImageData32& data() 
00056         {
00057             return data_;
00058         }
00059         
00060         inline const unsigned char* raw_data() const
00061         {
00062             return data_.getBytes();
00063         }
00064         
00065         inline unsigned char* raw_data()
00066         {
00067             return data_.getBytes();
00068         }
00069         
00070         inline image_view<ImageData32> get_view(unsigned x,unsigned y, unsigned w,unsigned h)
00071         {
00072             return image_view<ImageData32>(x,y,w,h,data_);
00073         }
00074         
00075         void saveToFile(const std::string& file,const std::string& format="auto"); 
00076 
00077     private:
00078         
00079         inline bool checkBounds(unsigned x, unsigned y) const
00080         {
00081             return (x < width_ && y < height_);
00082         }
00083 
00084     public:
00085         inline void setPixel(int x,int y,unsigned int rgba)
00086         {
00087             if (checkBounds(x,y))
00088             {
00089                 data_(x,y)=rgba;
00090             }
00091         }
00092         inline void blendPixel(int x,int y,unsigned int rgba1,int t)
00093         {
00094             if (checkBounds(x,y))
00095             {
00096                 unsigned rgba0 = data_(x,y);    
00097                 unsigned a1 = t;//(rgba1 >> 24) & 0xff;
00098                 if (a1 == 0) return;
00099                 unsigned r1 = rgba1 & 0xff;
00100                 unsigned g1 = (rgba1 >> 8 ) & 0xff;
00101                 unsigned b1 = (rgba1 >> 16) & 0xff;
00102                 
00103                 unsigned a0 = (rgba0 >> 24) & 0xff;
00104                 unsigned r0 = (rgba0 & 0xff) * a0;
00105                 unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
00106                 unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
00107                 
00108                 
00109                 a0 = ((a1 + a0) << 8) - a0*a1;
00110                 
00111                 r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
00112                 g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
00113                 b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
00114                 a0 = a0 >> 8;
00115                 data_(x,y)= (a0 << 24)| (b0 << 16) |  (g0 << 8) | (r0) ;
00116             }
00117         }
00118 
00119         inline unsigned width() const
00120         {
00121             return width_;
00122         }
00123         
00124         inline unsigned height() const
00125         {
00126             return height_;
00127         }
00128 
00129         inline void set_rectangle(int x0,int y0,ImageData32 const& data)
00130         {
00131             Envelope<int> ext0(0,0,width_,height_);   
00132             Envelope<int> ext1(x0,y0,x0+data.width(),y0+data.height());
00133             
00134             if (ext0.intersects(ext1))
00135             {   
00136                 Envelope<int> box = ext0.intersect(ext1);
00137                 for (int y = box.miny(); y < box.maxy(); ++y)
00138                 {
00139                     for (int x = box.minx(); x < box.maxx(); ++x)
00140                     {
00141                         if ((data(x-x0,y-y0) & 0xff000000)) 
00142                         {
00143                             data_(x,y)=data(x-x0,y-y0);
00144                         }
00145                     }
00146                 }   
00147             }
00148         }
00149         
00150         inline void set_rectangle_alpha(int x0,int y0,const ImageData32& data)
00151         {
00152             Envelope<int> ext0(0,0,width_,height_);   
00153             Envelope<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
00154             
00155             if (ext0.intersects(ext1))
00156             {                                   
00157                 Envelope<int> box = ext0.intersect(ext1);               
00158                 for (int y = box.miny(); y < box.maxy(); ++y)
00159                 {
00160                     for (int x = box.minx(); x < box.maxx(); ++x)
00161                     {
00162                         unsigned rgba0 = data_(x,y);
00163                         unsigned rgba1 = data(x-x0,y-y0);
00164                     
00165                         unsigned a1 = (rgba1 >> 24) & 0xff;
00166                         if (a1 == 0) continue;
00167                         unsigned r1 = rgba1 & 0xff;
00168                         unsigned g1 = (rgba1 >> 8 ) & 0xff;
00169                         unsigned b1 = (rgba1 >> 16) & 0xff;
00170                     
00171                         unsigned a0 = (rgba0 >> 24) & 0xff;
00172                         unsigned r0 = (rgba0 & 0xff) * a0;
00173                         unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
00174                         unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
00175                     
00176                     
00177                         a0 = ((a1 + a0) << 8) - a0*a1;
00178                     
00179                         r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
00180                         g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
00181                         b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
00182                         a0 = a0 >> 8;
00183                         data_(x,y)= (a0 << 24)| (b0 << 16) |  (g0 << 8) | (r0) ;
00184                     }
00185                 }
00186             }
00187         }
00188     };
00189 }
00190 #endif //GRAPHICS_HPP

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