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