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 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}