Home | History | Annotate | Download | only in filters
      1 /*
      2  * Copyright (C) 2012 Unknown
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #pragma version(1)
     18 #pragma rs java_package_name(com.android.gallery3d.filtershow.filters)
     19 
     20 #define MAX_CHANELS 7
     21 #define MAX_HUE 4096
     22 static const int ABITS = 4;
     23 static const int HSCALE = 256;
     24 static const int k1=255 << ABITS;
     25 static const int k2=HSCALE << ABITS;
     26 
     27 static const float Rf = 0.2999f;
     28 static const float Gf = 0.587f;
     29 static const float Bf = 0.114f;
     30 
     31 rs_matrix3x3 colorMatrix_min;
     32 rs_matrix3x3 colorMatrix_max;
     33 
     34 int mNumberOfLines;
     35 // input data
     36 int saturation[MAX_CHANELS];
     37 float sat[MAX_CHANELS];
     38 
     39 float satLut[MAX_HUE];
     40 // generated data
     41 
     42 
     43 void setupGradParams() {
     44 
     45     int master = saturation[0];
     46     int max = master+saturation[1];
     47     int min = max;
     48 
     49     // calculate the minimum and maximum saturation
     50     for (int i = 1; i < MAX_CHANELS; i++) {
     51        int v = master+saturation[i];
     52        if (max < v) {
     53          max = v;
     54        }
     55        else if (min > v) {
     56          min = v;
     57        }
     58     }
     59     // generate a lookup table for all hue 0 to 4K  which goes from 0 to 1 0=min sat 1 = max sat
     60     min = min - 1;
     61     for(int i = 0; i < MAX_HUE ; i++) {
     62        float p =  i * 6 / (float)MAX_HUE;
     63        int ip = ((int)(p + .5f)) % 6;
     64        int v = master + saturation[ip + 1];
     65        satLut[i] = (v - min)/(float)(max - min);
     66     }
     67 
     68     float S = 1 + max / 100.f;
     69     float MS = 1 - S;
     70     float Rt = Rf * MS;
     71     float Gt = Gf * MS;
     72     float Bt = Bf * MS;
     73     float b = 1.f;
     74 
     75     // Generate 2 color matrix one at min sat and one at max
     76     rsMatrixSet(&colorMatrix_max, 0, 0, b * (Rt + S));
     77     rsMatrixSet(&colorMatrix_max, 1, 0, b * Gt);
     78     rsMatrixSet(&colorMatrix_max, 2, 0, b * Bt);
     79     rsMatrixSet(&colorMatrix_max, 0, 1, b * Rt);
     80     rsMatrixSet(&colorMatrix_max, 1, 1, b * (Gt + S));
     81     rsMatrixSet(&colorMatrix_max, 2, 1, b * Bt);
     82     rsMatrixSet(&colorMatrix_max, 0, 2, b * Rt);
     83     rsMatrixSet(&colorMatrix_max, 1, 2, b * Gt);
     84     rsMatrixSet(&colorMatrix_max, 2, 2, b * (Bt + S));
     85 
     86     S = 1 + min / 100.f;
     87     MS = 1-S;
     88     Rt = Rf * MS;
     89     Gt = Gf * MS;
     90     Bt = Bf * MS;
     91     b = 1;
     92 
     93     rsMatrixSet(&colorMatrix_min, 0, 0, b * (Rt + S));
     94     rsMatrixSet(&colorMatrix_min, 1, 0, b * Gt);
     95     rsMatrixSet(&colorMatrix_min, 2, 0, b * Bt);
     96     rsMatrixSet(&colorMatrix_min, 0, 1, b * Rt);
     97     rsMatrixSet(&colorMatrix_min, 1, 1, b * (Gt + S));
     98     rsMatrixSet(&colorMatrix_min, 2, 1, b * Bt);
     99     rsMatrixSet(&colorMatrix_min, 0, 2, b * Rt);
    100     rsMatrixSet(&colorMatrix_min, 1, 2, b * Gt);
    101     rsMatrixSet(&colorMatrix_min, 2, 2, b * (Bt + S));
    102 }
    103 
    104 static ushort rgb2hue( uchar4 rgb)
    105 {
    106     int iMin,iMax,chroma;
    107 
    108     int ri = rgb.r;
    109     int gi = rgb.g;
    110     int bi = rgb.b;
    111     short rv,rs,rh;
    112 
    113     if (ri > gi) {
    114         iMax = max (ri, bi);
    115         iMin = min (gi, bi);
    116     } else {
    117         iMax = max (gi, bi);
    118         iMin = min (ri, bi);
    119     }
    120 
    121     rv = (short) (iMax << ABITS);
    122 
    123     if (rv == 0) {
    124         return 0;
    125     }
    126 
    127     chroma = iMax - iMin;
    128     rs = (short) ((k1 * chroma) / iMax);
    129     if (rs == 0) {
    130         return 0;
    131     }
    132 
    133     if ( ri == iMax ) {
    134         rh  = (short) ((k2 * (6 * chroma + gi - bi))/(6 * chroma));
    135         if (rh >= k2) {
    136            rh -= k2;
    137         }
    138         return rh;
    139     }
    140 
    141     if (gi  == iMax) {
    142         return(short) ((k2 * (2 * chroma + bi - ri)) / (6 * chroma));
    143     }
    144 
    145     return (short) ((k2 * (4 * chroma + ri - gi)) / (6 * chroma));
    146 }
    147 
    148 uchar4 __attribute__((kernel)) selectiveAdjust(const uchar4 in, uint32_t x,
    149     uint32_t y) {
    150     float4 pixel = rsUnpackColor8888(in);
    151 
    152     int hue = rgb2hue(in);
    153 
    154     float t = satLut[hue];
    155         pixel.xyz = rsMatrixMultiply(&colorMatrix_min ,pixel.xyz) * (1 - t) +
    156             t * (rsMatrixMultiply(&colorMatrix_max ,pixel.xyz));
    157 
    158     pixel.a = 1.0f;
    159     return rsPackColorTo8888(clamp(pixel, 0.f, 1.0f));
    160 }
    161