blob: f2f9a361fa9041716f0a44fa07f003c7d8227381 [file] [log] [blame]
Jason Samsc7f4e412010-07-20 15:09:00 -07001#pragma version(1)
2
Jason Samsc7f4e412010-07-20 15:09:00 -07003#include "ip.rsh"
4
5int height;
6int width;
7int radius;
8
9uchar4 * InPixel;
10uchar4 * OutPixel;
Jason Sams43c31422010-08-16 12:29:23 -070011float4 * ScratchPixel1;
12float4 * ScratchPixel2;
Jason Samsc7f4e412010-07-20 15:09:00 -070013
Jason Samsc7f4e412010-07-20 15:09:00 -070014rs_script vBlurScript;
15rs_script hBlurScript;
Jason Samsc7f4e412010-07-20 15:09:00 -070016
Jason Sams17966512010-07-28 11:17:53 -070017const int CMD_FINISHED = 1;
Jason Samsc7f4e412010-07-20 15:09:00 -070018
19// Store our coefficients here
20static float gaussian[MAX_RADIUS * 2 + 1];
21
22
23static void computeGaussianWeights() {
24 // Compute gaussian weights for the blur
25 // e is the euler's number
26 float e = 2.718281828459045f;
27 float pi = 3.1415926535897932f;
28 // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 )
29 // x is of the form [-radius .. 0 .. radius]
30 // and sigma varies with radius.
31 // Based on some experimental radius values and sigma's
32 // we approximately fit sigma = f(radius) as
33 // sigma = radius * 0.4 + 0.6
34 // The larger the radius gets, the more our gaussian blur
35 // will resemble a box blur since with large sigma
36 // the gaussian curve begins to lose its shape
37 float sigma = 0.4f * (float)radius + 0.6f;
38
39 // Now compute the coefficints
40 // We will store some redundant values to save some math during
41 // the blur calculations
42 // precompute some values
43 float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma);
44 float coeff2 = - 1.0f / (2.0f * sigma * sigma);
45
46 float normalizeFactor = 0.0f;
47 float floatR = 0.0f;
48 int r;
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080049 for (r = -radius; r <= radius; r ++) {
Jason Samsc7f4e412010-07-20 15:09:00 -070050 floatR = (float)r;
51 gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2);
52 normalizeFactor += gaussian[r + radius];
53 }
54
55 //Now we need to normalize the weights because all our coefficients need to add up to one
56 normalizeFactor = 1.0f / normalizeFactor;
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080057 for (r = -radius; r <= radius; r ++) {
Jason Samsc7f4e412010-07-20 15:09:00 -070058 floatR = (float)r;
59 gaussian[r + radius] *= normalizeFactor;
60 }
61}
62
63
Jason Sams43c31422010-08-16 12:29:23 -070064static void copyInput() {
Stephen Hinesbaa19bc2010-11-15 17:09:02 -080065 rs_allocation ain;
Stephen Hinesce13d942010-10-25 11:48:00 -070066 rsSetObject(&ain,rsGetAllocation(InPixel));
Jason Sams43c31422010-08-16 12:29:23 -070067 uint32_t dimx = rsAllocationGetDimX(ain);
68 uint32_t dimy = rsAllocationGetDimY(ain);
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080069 for (uint32_t y = 0; y < dimy; y++) {
70 for (uint32_t x = 0; x < dimx; x++) {
Jason Sams43c31422010-08-16 12:29:23 -070071 ScratchPixel1[x + y * dimx] = convert_float4(InPixel[x + y * dimx]);
72 }
73 }
Jason Sams43c31422010-08-16 12:29:23 -070074}
75
76void filter() {
77 copyInput();
Jason Samsc7f4e412010-07-20 15:09:00 -070078 computeGaussianWeights();
79
80 FilterStruct fs;
81 fs.gaussian = gaussian;
82 fs.width = width;
83 fs.height = height;
84 fs.radius = radius;
85
Jason Sams43c31422010-08-16 12:29:23 -070086 fs.ain = rsGetAllocation(ScratchPixel1);
87 rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel2), &fs);
Jason Samsc7f4e412010-07-20 15:09:00 -070088
Jason Sams43c31422010-08-16 12:29:23 -070089 fs.ain = rsGetAllocation(ScratchPixel2);
Jason Samsc7f4e412010-07-20 15:09:00 -070090 rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs);
Jason Sams17966512010-07-28 11:17:53 -070091 rsSendToClientBlocking(CMD_FINISHED);
Jason Samsc7f4e412010-07-20 15:09:00 -070092}
93