| /* |
| * Copyright (C) 2012 Unknown |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma version(1) |
| #pragma rs java_package_name(com.android.gallery3d.filtershow.filters) |
| |
| #define MAX_CHANELS 7 |
| #define MAX_HUE 4096 |
| static const int ABITS = 4; |
| static const int HSCALE = 256; |
| static const int k1=255 << ABITS; |
| static const int k2=HSCALE << ABITS; |
| |
| static const float Rf = 0.2999f; |
| static const float Gf = 0.587f; |
| static const float Bf = 0.114f; |
| |
| rs_matrix3x3 colorMatrix_min; |
| rs_matrix3x3 colorMatrix_max; |
| |
| int mNumberOfLines; |
| // input data |
| int saturation[MAX_CHANELS]; |
| float sat[MAX_CHANELS]; |
| |
| float satLut[MAX_HUE]; |
| // generated data |
| |
| |
| void setupGradParams() { |
| |
| int master = saturation[0]; |
| int max = master+saturation[1]; |
| int min = max; |
| |
| // calculate the minimum and maximum saturation |
| for (int i = 1; i < MAX_CHANELS; i++) { |
| int v = master+saturation[i]; |
| if (max < v) { |
| max = v; |
| } |
| else if (min > v) { |
| min = v; |
| } |
| } |
| // generate a lookup table for all hue 0 to 4K which goes from 0 to 1 0=min sat 1 = max sat |
| min = min - 1; |
| for(int i = 0; i < MAX_HUE ; i++) { |
| float p = i * 6 / (float)MAX_HUE; |
| int ip = ((int)(p + .5f)) % 6; |
| int v = master + saturation[ip + 1]; |
| satLut[i] = (v - min)/(float)(max - min); |
| } |
| |
| float S = 1 + max / 100.f; |
| float MS = 1 - S; |
| float Rt = Rf * MS; |
| float Gt = Gf * MS; |
| float Bt = Bf * MS; |
| float b = 1.f; |
| |
| // Generate 2 color matrix one at min sat and one at max |
| rsMatrixSet(&colorMatrix_max, 0, 0, b * (Rt + S)); |
| rsMatrixSet(&colorMatrix_max, 1, 0, b * Gt); |
| rsMatrixSet(&colorMatrix_max, 2, 0, b * Bt); |
| rsMatrixSet(&colorMatrix_max, 0, 1, b * Rt); |
| rsMatrixSet(&colorMatrix_max, 1, 1, b * (Gt + S)); |
| rsMatrixSet(&colorMatrix_max, 2, 1, b * Bt); |
| rsMatrixSet(&colorMatrix_max, 0, 2, b * Rt); |
| rsMatrixSet(&colorMatrix_max, 1, 2, b * Gt); |
| rsMatrixSet(&colorMatrix_max, 2, 2, b * (Bt + S)); |
| |
| S = 1 + min / 100.f; |
| MS = 1-S; |
| Rt = Rf * MS; |
| Gt = Gf * MS; |
| Bt = Bf * MS; |
| b = 1; |
| |
| rsMatrixSet(&colorMatrix_min, 0, 0, b * (Rt + S)); |
| rsMatrixSet(&colorMatrix_min, 1, 0, b * Gt); |
| rsMatrixSet(&colorMatrix_min, 2, 0, b * Bt); |
| rsMatrixSet(&colorMatrix_min, 0, 1, b * Rt); |
| rsMatrixSet(&colorMatrix_min, 1, 1, b * (Gt + S)); |
| rsMatrixSet(&colorMatrix_min, 2, 1, b * Bt); |
| rsMatrixSet(&colorMatrix_min, 0, 2, b * Rt); |
| rsMatrixSet(&colorMatrix_min, 1, 2, b * Gt); |
| rsMatrixSet(&colorMatrix_min, 2, 2, b * (Bt + S)); |
| } |
| |
| static ushort rgb2hue( uchar4 rgb) |
| { |
| int iMin,iMax,chroma; |
| |
| int ri = rgb.r; |
| int gi = rgb.g; |
| int bi = rgb.b; |
| short rv,rs,rh; |
| |
| if (ri > gi) { |
| iMax = max (ri, bi); |
| iMin = min (gi, bi); |
| } else { |
| iMax = max (gi, bi); |
| iMin = min (ri, bi); |
| } |
| |
| rv = (short) (iMax << ABITS); |
| |
| if (rv == 0) { |
| return 0; |
| } |
| |
| chroma = iMax - iMin; |
| rs = (short) ((k1 * chroma) / iMax); |
| if (rs == 0) { |
| return 0; |
| } |
| |
| if ( ri == iMax ) { |
| rh = (short) ((k2 * (6 * chroma + gi - bi))/(6 * chroma)); |
| if (rh >= k2) { |
| rh -= k2; |
| } |
| return rh; |
| } |
| |
| if (gi == iMax) { |
| return(short) ((k2 * (2 * chroma + bi - ri)) / (6 * chroma)); |
| } |
| |
| return (short) ((k2 * (4 * chroma + ri - gi)) / (6 * chroma)); |
| } |
| |
| uchar4 __attribute__((kernel)) selectiveAdjust(const uchar4 in, uint32_t x, |
| uint32_t y) { |
| float4 pixel = rsUnpackColor8888(in); |
| |
| float4 wsum = pixel; |
| int hue = rgb2hue(in); |
| |
| float t = satLut[hue]; |
| pixel.xyz = rsMatrixMultiply(&colorMatrix_min ,pixel.xyz) * (1 - t) + |
| t * (rsMatrixMultiply(&colorMatrix_max ,pixel.xyz)); |
| |
| pixel.a = 1.0f; |
| return rsPackColorTo8888(clamp(pixel, 0.f, 1.0f)); |
| } |