Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 1 | #pragma version(1) |
| 2 | |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 3 | #include "ip.rsh" |
| 4 | |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 5 | static float inBlack; |
| 6 | static float outBlack; |
| 7 | static float inWhite; |
| 8 | static float outWhite; |
| 9 | static float3 gamma; |
| 10 | static float saturation; |
| 11 | |
| 12 | static float inWMinInB; |
| 13 | static float outWMinOutB; |
| 14 | static float overInWMinInB; |
| 15 | static rs_matrix3x3 colorMat; |
| 16 | |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 17 | void setLevels(float iBlk, float oBlk, float iWht, float oWht) { |
| 18 | inBlack = iBlk; |
| 19 | outBlack = oBlk; |
| 20 | inWhite = iWht; |
| 21 | outWhite = oWht; |
| 22 | |
| 23 | inWMinInB = inWhite - inBlack; |
| 24 | outWMinOutB = outWhite - outBlack; |
| 25 | overInWMinInB = 1.f / inWMinInB; |
| 26 | } |
| 27 | |
| 28 | void setSaturation(float sat) { |
| 29 | saturation = sat; |
| 30 | |
| 31 | // Saturation |
| 32 | // Linear weights |
| 33 | //float rWeight = 0.3086f; |
| 34 | //float gWeight = 0.6094f; |
| 35 | //float bWeight = 0.0820f; |
| 36 | |
| 37 | // Gamma 2.2 weights (we haven't converted our image to linear space yet for perf reasons) |
| 38 | float rWeight = 0.299f; |
| 39 | float gWeight = 0.587f; |
| 40 | float bWeight = 0.114f; |
| 41 | |
| 42 | float oneMinusS = 1.0f - saturation; |
| 43 | rsMatrixSet(&colorMat, 0, 0, oneMinusS * rWeight + saturation); |
| 44 | rsMatrixSet(&colorMat, 0, 1, oneMinusS * rWeight); |
| 45 | rsMatrixSet(&colorMat, 0, 2, oneMinusS * rWeight); |
| 46 | rsMatrixSet(&colorMat, 1, 0, oneMinusS * gWeight); |
| 47 | rsMatrixSet(&colorMat, 1, 1, oneMinusS * gWeight + saturation); |
| 48 | rsMatrixSet(&colorMat, 1, 2, oneMinusS * gWeight); |
| 49 | rsMatrixSet(&colorMat, 2, 0, oneMinusS * bWeight); |
| 50 | rsMatrixSet(&colorMat, 2, 1, oneMinusS * bWeight); |
| 51 | rsMatrixSet(&colorMat, 2, 2, oneMinusS * bWeight + saturation); |
| 52 | } |
| 53 | |
| 54 | void setGamma(float g) { |
| 55 | gamma = (float3)g; |
| 56 | } |
| 57 | |
Shih-wei Liao | 16095fc | 2011-01-12 01:13:01 -0800 | [diff] [blame] | 58 | //sliao |
Shih-wei Liao | 0e7be13 | 2011-01-16 15:38:13 -0800 | [diff] [blame] | 59 | extern uchar3 __attribute__((overloadable)) convert2uchar3(float3 xyz); |
Shih-wei Liao | 16095fc | 2011-01-12 01:13:01 -0800 | [diff] [blame] | 60 | |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 61 | void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { |
| 62 | uchar4 *output = (uchar4 *)v_out; |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 63 | const FilterStruct *fs = (const FilterStruct *)usrData; |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 64 | const float4 *input = (const float4 *)rsGetElementAt(fs->ain, x, 0); |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 65 | |
Jason Sams | f46f25a | 2010-07-22 14:44:04 -0700 | [diff] [blame] | 66 | float3 blurredPixel = 0; |
Jason Sams | f46f25a | 2010-07-22 14:44:04 -0700 | [diff] [blame] | 67 | const float *gPtr = fs->gaussian; |
| 68 | if ((y > fs->radius) && (y < (fs->height - fs->radius))) { |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 69 | const float4 *i = input + ((y - fs->radius) * fs->width); |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 70 | for (int r = -fs->radius; r <= fs->radius; r ++) { |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 71 | blurredPixel += i->xyz * gPtr[0]; |
Jason Sams | f46f25a | 2010-07-22 14:44:04 -0700 | [diff] [blame] | 72 | gPtr++; |
| 73 | i += fs->width; |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 74 | } |
Jason Sams | f46f25a | 2010-07-22 14:44:04 -0700 | [diff] [blame] | 75 | } else { |
Alex Sakhartchouk | ed9f210 | 2010-11-09 17:00:54 -0800 | [diff] [blame] | 76 | for (int r = -fs->radius; r <= fs->radius; r ++) { |
Jason Sams | 05716aa | 2010-08-09 12:09:00 -0700 | [diff] [blame] | 77 | int validH = rsClamp(y + r, (uint)0, (uint)(fs->height - 1)); |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 78 | const float4 *i = input + validH * fs->width; |
| 79 | blurredPixel += i->xyz * gPtr[0]; |
Jason Sams | f46f25a | 2010-07-22 14:44:04 -0700 | [diff] [blame] | 80 | gPtr++; |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 81 | } |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 82 | } |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 83 | |
| 84 | float3 temp = rsMatrixMultiply(&colorMat, blurredPixel); |
| 85 | temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB; |
| 86 | if (gamma.x != 1.0f) |
| 87 | temp = pow(temp, (float3)gamma); |
| 88 | temp = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f); |
| 89 | |
Shih-wei Liao | 2aad562 | 2011-01-17 01:17:39 -0800 | [diff] [blame] | 90 | output->xyz = convert_uchar3(temp); |
Jason Sams | 43c3142 | 2010-08-16 12:29:23 -0700 | [diff] [blame] | 91 | //output->w = input->w; |
Jason Sams | 8f8a572 | 2010-07-15 17:11:13 -0700 | [diff] [blame] | 92 | } |
| 93 | |