15ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni/* 25ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * Copyright (C) 2012 The Android Open Source Project 35ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * 45ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * Licensed under the Apache License, Version 2.0 (the "License"); 55ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * you may not use this file except in compliance with the License. 65ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * You may obtain a copy of the License at 75ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * 85ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * http://www.apache.org/licenses/LICENSE-2.0 95ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * 105ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * Unless required by applicable law or agreed to in writing, software 115ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * distributed under the License is distributed on an "AS IS" BASIS, 125ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * See the License for the specific language governing permissions and 145ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni * limitations under the License. 155ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni */ 165ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 175ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni#include "ip.rsh" 185ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni#pragma rs_fp_relaxed 195ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 205ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic float shadowFilterMap[] = { 215ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni -0.00591f, 0.0001f, 225ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1.16488f, 0.01668f, 235ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni -0.18027f, -0.06791f, 245ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni -0.12625f, 0.09001f, 255ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 0.15065f, -0.03897f 265ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni}; 275ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 285ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic float poly[] = { 295ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 0.f, 0.f, 305ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 0.f, 0.f, 315ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 0.f 325ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni}; 335ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 345ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic const int ABITS = 4; 355ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic const int HSCALE = 256; 365ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic const int k1=255 << ABITS; 375ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic const int k2=HSCALE << ABITS; 385ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 395ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic float fastevalPoly(float *poly,int n, float x){ 405ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 415ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni float f =x; 425ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni float sum = poly[0]+poly[1]*f; 435ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int i; 445ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni for (i = 2; i < n; i++) { 455ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni f*=x; 465ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni sum += poly[i]*f; 475ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } 485ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni return sum; 495ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni} 505ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 515ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic ushort3 rgb2hsv( float4 rgb) 525ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni{ 535ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int iMin,iMax,chroma; 545ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 555ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int ri = rgb.r; 565ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int gi = rgb.g; 575ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int bi = rgb.b; 585ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni short rv,rs,rh; 595ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 605ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni if (ri > gi) { 615ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni iMax = max (ri, bi); 625ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni iMin = min (gi, bi); 635ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } else { 645ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni iMax = max (gi, bi); 655ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni iMin = min (ri, bi); 665ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } 675ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 685ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni chroma = iMax - iMin; 695ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // set value 705ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rv = (short)( iMax << ABITS); 715ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 725ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // set saturation 735ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni if (rv == 0) 745ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rs = 0; 755ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni else 765ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rs = (short)((k1*chroma)/iMax); 775ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 785ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // set hue 795ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni if (rs == 0) 805ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rh = 0; 815ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni else { 825ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni if ( ri == iMax ) { 835ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rh = (short)( (k2*(6*chroma+gi - bi))/(6*chroma)); 845ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni if (rh >= k2) rh -= k2; 855ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } else if (gi == iMax) 865ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rh = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma)); 875ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni else // (bi == iMax ) 885ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rh = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma)); 895ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } 905ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 915ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni ushort3 out; 925ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni out.x = rv; 935ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni out.y = rs; 945ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni out.z = rh; 955ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni return out; 965ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni} 975ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 985ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nistatic float4 hsv2rgb(ushort3 hsv) 995ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni{ 1005ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int ABITS = 4; 1015ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int HSCALE = 256; 1025ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int m; 1035ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int H,X,ih,is,iv; 1045ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int k1=255<<ABITS; 1055ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int k2=HSCALE<<ABITS; 1065ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int k3=1<<(ABITS-1); 1075ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int rr=0; 1085ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int rg=0; 1095ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni int rb=0; 1105ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni short cv = hsv.x; 1115ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni short cs = hsv.y; 1125ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni short ch = hsv.z; 1135ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1145ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // set chroma and min component value m 1155ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni //chroma = ( cv * cs )/k1; 1165ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni //m = cv - chroma; 1175ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni m = ((int)cv*(k1 - (int)cs ))/k1; 1185ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1195ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // chroma == 0 <-> cs == 0 --> m=cv 1205ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni if (cs == 0) { 1215ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = ( rg = ( rr =( cv >> ABITS) )); 1225ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } else { 1235ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni ih=(int)ch; 1245ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni is=(int)cs; 1255ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni iv=(int)cv; 1265ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1275ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni H = (6*ih)/k2; 1285ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ; 1295ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1305ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // removing additional bits --> unit8 1315ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS; 1325ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni m=m >> ABITS; 1335ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1345ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni // ( chroma + m ) --> cv ; 1355ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni cv=(short) (cv >> ABITS); 1365ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni switch (H) { 1375ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni case 0: 1385ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rr = cv; 1395ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rg = X; 1405ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = m; 1415ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni break; 1425ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni case 1: 1435ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rr = X; 1445ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rg = cv; 1455ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = m; 1465ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni break; 1475ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni case 2: 1485ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rr = m; 1495ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rg = cv; 1505ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = X; 1515ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni break; 1525ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni case 3: 1535ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rr = m; 1545ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rg = X; 1555ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = cv; 1565ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni break; 1575ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni case 4: 1585ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rr = X; 1595ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rg = m; 1605ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = cv; 1615ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni break; 1625ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni case 5: 1635ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rr = cv; 1645ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rg = m ; 1655ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rb = X; 1665ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni break; 1675ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } 1685ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } 1695ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1705ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni float4 rgb; 1715ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1725ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rgb.r = rr; 1735ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rgb.g = rg; 1745ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni rgb.b = rb; 1755ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1765ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni return rgb; 1775ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni} 1785ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1795ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nivoid prepareShadows(float scale) { 1805ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni float s = (scale>=0) ? scale : scale / 5.f; 1815ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni for (int i = 0; i < 5; i++) { 1825ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s); 1835ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni } 1845ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni} 1855ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni 1865ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Nifloat4 RS_KERNEL shadowsKernel(float4 in) { 1875ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni ushort3 hsv = rgb2hsv(in); 1885ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni float v = (fastevalPoly(poly, 5, hsv.x * (1.f / 4080.f)) * 4080.f); 1895ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni hsv.x = (unsigned short) clamp(v, 0.f, 4080.f); 1905ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni return hsv2rgb(hsv); 1915ab5155f7e0e0904f8c11cd0dbdbf7832e3ac948Yang Ni} 192