00001 #ifndef BLUR_CPP
00002 #define BLUR_CPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cmath>
00023
00024
00025
00026 template<int aprec, int zprec>
00027 static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha);
00028
00029 template<int aprec,int zprec>
00030 static inline void blurrow( QImage & im, int line, int alpha);
00031
00032 template<int aprec, int zprec>
00033 static inline void blurcol( QImage & im, int col, int alpha);
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template<int aprec,int zprec>
00051 void expblur( QImage &img, int radius )
00052 {
00053 if(radius<1)
00054 return;
00055
00056
00057
00058
00059
00060 int alpha = (int)((1<<aprec)*(1.0f-std::exp(-2.3f/(radius+1.f))));
00061
00062 for(int row=0;row<img.height();row++)
00063 {
00064 blurrow<aprec,zprec>(img,row,alpha);
00065 }
00066
00067 for(int col=0;col<img.width();col++)
00068 {
00069 blurcol<aprec,zprec>(img,col,alpha);
00070 }
00071 return;
00072 }
00073
00074 template<int aprec, int zprec>
00075 static inline void blurinner(unsigned char *bptr, int &zR, int &zG, int &zB, int &zA, int alpha)
00076 {
00077 int R,G,B,A;
00078 R = *bptr;
00079 G = *(bptr+1);
00080 B = *(bptr+2);
00081 A = *(bptr+3);
00082
00083 zR += (alpha * ((R<<zprec)-zR))>>aprec;
00084 zG += (alpha * ((G<<zprec)-zG))>>aprec;
00085 zB += (alpha * ((B<<zprec)-zB))>>aprec;
00086 zA += (alpha * ((A<<zprec)-zA))>>aprec;
00087
00088 *bptr = zR>>zprec;
00089 *(bptr+1) = zG>>zprec;
00090 *(bptr+2) = zB>>zprec;
00091 *(bptr+3) = zA>>zprec;
00092 }
00093
00094 template<int aprec,int zprec>
00095 static inline void blurrow( QImage & im, int line, int alpha)
00096 {
00097 int zR,zG,zB,zA;
00098
00099 QRgb *ptr = (QRgb *)im.scanLine(line);
00100
00101 zR = *((unsigned char *)ptr )<<zprec;
00102 zG = *((unsigned char *)ptr + 1)<<zprec;
00103 zB = *((unsigned char *)ptr + 2)<<zprec;
00104 zA = *((unsigned char *)ptr + 3)<<zprec;
00105
00106 for(int index=1; index<im.width(); index++)
00107 {
00108 blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
00109 }
00110 for(int index=im.width()-2; index>=0; index--)
00111 {
00112 blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
00113 }
00114
00115
00116 }
00117
00118 template<int aprec, int zprec>
00119 static inline void blurcol( QImage & im, int col, int alpha)
00120 {
00121 int zR,zG,zB,zA;
00122
00123 QRgb *ptr = (QRgb *)im.bits();
00124 ptr+=col;
00125
00126 zR = *((unsigned char *)ptr )<<zprec;
00127 zG = *((unsigned char *)ptr + 1)<<zprec;
00128 zB = *((unsigned char *)ptr + 2)<<zprec;
00129 zA = *((unsigned char *)ptr + 3)<<zprec;
00130
00131 for(int index=im.width(); index<(im.height()-1)*im.width(); index+=im.width())
00132 {
00133 blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
00134 }
00135
00136 for(int index=(im.height()-2)*im.width(); index>=0; index-=im.width())
00137 {
00138 blurinner<aprec,zprec>((unsigned char *)&ptr[index],zR,zG,zB,zA,alpha);
00139 }
00140
00141 }
00142
00143 template<class T>
00144 inline const T& qClamp(const T &x, const T &low, const T &high)
00145 {
00146 if (x < low) return low;
00147 else if (x > high) return high;
00148 else return x;
00149 }
00150
00151 #endif