00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef GRAPHICS_HPP
00026 #define GRAPHICS_HPP
00027
00028 #include <cmath>
00029 #include <string>
00030 #include <cassert>
00031
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;
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