1572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams/* 2572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Copyright (C) 2012 The Android Open Source Project 3572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * 4572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * you may not use this file except in compliance with the License. 6572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * You may obtain a copy of the License at 7572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * 8572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 9572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * 10572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Unless required by applicable law or agreed to in writing, software 11572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * See the License for the specific language governing permissions and 14572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * limitations under the License. 15572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams */ 16572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 17572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#include "ip.rsh" 186939f7bf32ab2765dcedb8a8d6fd352e7d08540fJason Sams#pragma rs_fp_relaxed 19572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 2023e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Samsstatic float shadowFilterMap[] = { 2123e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams -0.00591f, 0.0001f, 2223e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams 1.16488f, 0.01668f, 2323e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams -0.18027f, -0.06791f, 2423e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams -0.12625f, 0.09001f, 2523e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams 0.15065f, -0.03897f 26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams}; 27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 2823e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Samsstatic float poly[] = { 2923e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams 0.f, 0.f, 3023e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams 0.f, 0.f, 3123e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams 0.f 32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams}; 33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic const int ABITS = 4; 35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic const int HSCALE = 256; 36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic const int k1=255 << ABITS; 37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic const int k2=HSCALE << ABITS; 38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 3923e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Samsstatic float fastevalPoly(float *poly,int n, float x){ 40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 4123e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams float f =x; 4223e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams float sum = poly[0]+poly[1]*f; 43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int i; 44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (i = 2; i < n; i++) { 45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams f*=x; 46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum += poly[i]*f; 47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams return sum; 49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic ushort3 rgb2hsv( uchar4 rgb) 52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams{ 53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int iMin,iMax,chroma; 54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int ri = rgb.r; 56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int gi = rgb.g; 57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int bi = rgb.b; 58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams short rv,rs,rh; 59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (ri > gi) { 61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams iMax = max (ri, bi); 62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams iMin = min (gi, bi); 63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else { 64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams iMax = max (gi, bi); 65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams iMin = min (ri, bi); 66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams chroma = iMax - iMin; 69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // set value 70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rv = (short)( iMax << ABITS); 71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // set saturation 73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (rv == 0) 74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rs = 0; 75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams else 76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rs = (short)((k1*chroma)/iMax); 77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // set hue 79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (rs == 0) 80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rh = 0; 81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams else { 82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ( ri == iMax ) { 83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rh = (short)( (k2*(6*chroma+gi - bi))/(6*chroma)); 84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (rh >= k2) rh -= k2; 85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else if (gi == iMax) 86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rh = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma)); 87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams else // (bi == iMax ) 88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rh = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma)); 89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ushort3 out; 92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.x = rv; 93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.y = rs; 94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.z = rh; 95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams return out; 96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic uchar4 hsv2rgb(ushort3 hsv) 99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams{ 100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int ABITS = 4; 101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int HSCALE = 256; 102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int m; 103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int H,X,ih,is,iv; 104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int k1=255<<ABITS; 105572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int k2=HSCALE<<ABITS; 106572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int k3=1<<(ABITS-1); 107572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int rr=0; 108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int rg=0; 109572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int rb=0; 110572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams short cv = hsv.x; 111572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams short cs = hsv.y; 112572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams short ch = hsv.z; 113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 114572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // set chroma and min component value m 115572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams //chroma = ( cv * cs )/k1; 116572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams //m = cv - chroma; 117572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams m = ((int)cv*(k1 - (int)cs ))/k1; 118572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 119572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // chroma == 0 <-> cs == 0 --> m=cv 120572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (cs == 0) { 121572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = ( rg = ( rr =( cv >> ABITS) )); 122572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } else { 123572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams ih=(int)ch; 124572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams is=(int)cs; 125572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams iv=(int)cv; 126572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 127572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams H = (6*ih)/k2; 128572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ; 129572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 130572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // removing additional bits --> unit8 131572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS; 132572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams m=m >> ABITS; 133572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 134572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams // ( chroma + m ) --> cv ; 135572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams cv=(short) (cv >> ABITS); 136572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams switch (H) { 137572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams case 0: 138572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rr = cv; 139572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rg = X; 140572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = m; 141572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams break; 142572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams case 1: 143572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rr = X; 144572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rg = cv; 145572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = m; 146572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams break; 147572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams case 2: 148572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rr = m; 149572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rg = cv; 150572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = X; 151572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams break; 152572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams case 3: 153572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rr = m; 154572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rg = X; 155572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = cv; 156572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams break; 157572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams case 4: 158572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rr = X; 159572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rg = m; 160572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = cv; 161572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams break; 162572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams case 5: 163572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rr = cv; 164572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rg = m ; 165572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rb = X; 166572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams break; 167572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 168572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 169572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 170572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams uchar4 rgb; 171572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 172572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rgb.r = rr; 173572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rgb.g = rg; 174572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams rgb.b = rb; 175572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 176572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams return rgb; 177572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 178572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 179572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsvoid prepareShadows(float scale) { 18023e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams float s = (scale>=0) ? scale : scale / 5.f; 181572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i = 0; i < 5; i++) { 182572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s); 183572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 184572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 185572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 186025b5f82971c431eb22df3c9d0f00b3cbe426bdbChris Wailesuchar4 RS_KERNEL shadowsKernel(uchar4 in) { 18723e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams ushort3 hsv = rgb2hsv(in); 18823e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams float v = (fastevalPoly(poly, 5, hsv.x * (1.f / 4080.f)) * 4080.f); 18923e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams hsv.x = (unsigned short) clamp(v, 0.f, 4080.f); 19023e1074f29f431f68c6b3230c1315ea0f7c7bc86Jason Sams return hsv2rgb(hsv); 191572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 192