5 #include "extensions.h"
15 template<int aprec
, int zprec
>
16 static inline void blurinner(unsigned char *bptr
, int &zR
,
17 int &zG
, int &zB
, int &zA
, int alpha
);
19 template<int aprec
,int zprec
>
20 static inline void blurrow(QImage
& im
, int line
, int alpha
);
22 template<int aprec
, int zprec
>
23 static inline void blurcol(QImage
& im
, int col
, int alpha
);
26 * expblur(QImage &img, int radius)
28 * In-place blur of image 'img' with kernel
29 * of approximate radius 'radius'.
31 * Blurs with two sided exponential impulse
34 * aprec = precision of alpha parameter
35 * in fixed-point format 0.aprec
37 * zprec = precision of state parameters
38 * zR,zG,zB and zA in fp format 8.zprec
40 template<int aprec
,int zprec
>
41 static void expblur(QImage
&img
, int radius
)
46 /* Calculate the alpha such that 90% of
47 the kernel is within the radius.
48 (Kernel extends to infinity)
50 int alpha
= (int)((1<<aprec
)*(1.0f
-expf(-2.3f
/(radius
+1.f
))));
52 for(int row
=0;row
<img
.height();row
++) {
53 blurrow
<aprec
,zprec
>(img
,row
,alpha
);
56 for(int col
=0;col
<img
.width();col
++) {
57 blurcol
<aprec
,zprec
>(img
,col
,alpha
);
62 template<int aprec
, int zprec
>
63 static inline void blurinner(unsigned char *bptr
,
64 int &zR
, int &zG
, int &zB
, int &zA
, int alpha
)
72 zR
+= (alpha
* ((R
<<zprec
)-zR
))>>aprec
;
73 zG
+= (alpha
* ((G
<<zprec
)-zG
))>>aprec
;
74 zB
+= (alpha
* ((B
<<zprec
)-zB
))>>aprec
;
75 zA
+= (alpha
* ((A
<<zprec
)-zA
))>>aprec
;
78 *(bptr
+1) = zG
>>zprec
;
79 *(bptr
+2) = zB
>>zprec
;
80 *(bptr
+3) = zA
>>zprec
;
83 template<int aprec
,int zprec
>
84 static inline void blurrow( QImage
& im
, int line
, int alpha
)
88 QRgb
*ptr
= (QRgb
*)im
.scanLine(line
);
90 zR
= *((unsigned char *)ptr
)<<zprec
;
91 zG
= *((unsigned char *)ptr
+ 1)<<zprec
;
92 zB
= *((unsigned char *)ptr
+ 2)<<zprec
;
93 zA
= *((unsigned char *)ptr
+ 3)<<zprec
;
95 for(int index
=1; index
<im
.width(); index
++) {
96 blurinner
<aprec
,zprec
>((unsigned char *)&ptr
[index
],
97 zR
, zG
, zB
, zA
, alpha
);
99 for(int index
=im
.width()-2; index
>=0; index
--) {
100 blurinner
<aprec
,zprec
>((unsigned char *)&ptr
[index
],
101 zR
, zG
, zB
, zA
, alpha
);
107 template<int aprec
, int zprec
>
108 static inline void blurcol(QImage
& im
, int col
, int alpha
)
112 QRgb
*ptr
= (QRgb
*)im
.bits();
115 zR
= *((unsigned char *)ptr
)<<zprec
;
116 zG
= *((unsigned char *)ptr
+ 1)<<zprec
;
117 zB
= *((unsigned char *)ptr
+ 2)<<zprec
;
118 zA
= *((unsigned char *)ptr
+ 3)<<zprec
;
120 for(int index
=im
.width(); index
<(im
.height()-1)*im
.width();
122 blurinner
<aprec
,zprec
>((unsigned char *)&ptr
[index
],
123 zR
, zG
, zB
, zA
, alpha
);
126 for(int index
=(im
.height()-2)*im
.width(); index
>=0;
128 blurinner
<aprec
,zprec
>((unsigned char *)&ptr
[index
],
129 zR
, zG
, zB
, zA
, alpha
);
134 void Extensions::exp_blur(QImage
* img
, int radius
) const {
135 return expblur
<15,7>(*img
, radius
);
140 static ruby_object* get_object(VALUE val) {
141 if (TYPE(val) != T_DATA) {
146 Data_Get_Struct(val, ruby_object, o);
150 extern "C" VALUE test_expblur(VALUE self, VALUE val, VALUE radius) {
151 ruby_object* o = get_object(val);
153 QImage* img = (QImage*)o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QImage"));
154 expblur<15,7>(*img, NUM2INT(radius));
160 extern "C" void Init_expblur() {
161 rb_define_method(Qnil, "expblur", (VALUE (*)(...))test_expblur, 2);