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