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
22static const int ABITS = 4;
23static const int HSCALE = 256;
24static const int k1=255 << ABITS;
25static const int k2=HSCALE << ABITS;
26
27static const float Rf = 0.2999f;
28static const float Gf = 0.587f;
29static const float Bf = 0.114f;
30
31rs_matrix3x3 colorMatrix_min;
32rs_matrix3x3 colorMatrix_max;
33
34int mNumberOfLines;
35// input data
36int saturation[MAX_CHANELS];
37float sat[MAX_CHANELS];
38
39float satLut[MAX_HUE];
40// generated data
41
42
43void 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
104static 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
148uchar4 __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