OSDN Git Service

5210e34a306da056a383ffccb8aba13acf9d0995
[android-x86/packages-apps-Gallery2.git] / src / com / android / gallery3d / filtershow / filters / saturation.rs
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     float4 wsum = pixel;
153     int hue = rgb2hue(in);
154
155     float t = satLut[hue];
156         pixel.xyz = rsMatrixMultiply(&colorMatrix_min ,pixel.xyz) * (1 - t) +
157             t * (rsMatrixMultiply(&colorMatrix_max ,pixel.xyz));
158
159     pixel.a = 1.0f;
160     return rsPackColorTo8888(clamp(pixel, 0.f, 1.0f));
161 }