Home | History | Annotate | Download | only in image
      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