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