1/*
2 * Copyright (C) 2012 The Android Open Source Project
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#include <math.h>
18#include <stdlib.h> /* For abs */
19#include "filters.h"
20
21double fastevalPoly(double *poly,int n, double x){
22
23    double f =x;
24    double sum = poly[0]+poly[1]*f;
25    int i;
26    for (i = 2; i < n; i++) {
27        f*=x;
28        sum += poly[i]*f;
29    }
30    return sum;
31}
32
33void rgb2hsv( unsigned char *rgb,int rgbOff,unsigned short *hsv,int hsvOff)
34{
35    int iMin,iMax,chroma;
36    int ABITS = 4;
37    int HSCALE = 256;
38
39    int k1=255 << ABITS;
40    int k2=HSCALE << ABITS;
41
42    int ri = rgb[rgbOff+0];
43    int gi = rgb[rgbOff+1];
44    int bi = rgb[rgbOff+2];
45    short rv,rs,rh;
46
47    if (ri > gi) {
48        iMax = MAX (ri, bi);
49        iMin = MIN (gi, bi);
50    } else {
51        iMax = MAX (gi, bi);
52        iMin = MIN (ri, bi);
53    }
54
55    chroma = iMax - iMin;
56    // set value
57    rv = (short)( iMax << ABITS);
58
59    // set saturation
60    if (rv == 0)
61        rs = 0;
62    else
63        rs = (short)((k1*chroma)/iMax);
64
65    // set hue
66    if (rs == 0)
67        rh = 0;
68    else {
69        if ( ri == iMax ) {
70            rh  = (short)( (k2*(6*chroma+gi - bi))/(6*chroma));
71            if (rh >= k2) rh -= k2;
72        } else if (gi  == iMax)
73            rh  = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma));
74        else // (bi == iMax )
75                    rh  = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
76    }
77    hsv[hsvOff+0] = rv;
78    hsv[hsvOff+1] = rs;
79    hsv[hsvOff+2] = rh;
80}
81
82void hsv2rgb(unsigned short *hsv,int hsvOff, unsigned char *rgb,int rgbOff)
83{
84    int ABITS = 4;
85    int HSCALE = 256;
86    int m;
87    int H,X,ih,is,iv;
88    int k1=255<<ABITS;
89    int k2=HSCALE<<ABITS;
90    int k3=1<<(ABITS-1);
91    int rr=0;
92    int rg=0;
93    int rb=0;
94    short cv = hsv[hsvOff+0];
95    short cs = hsv[hsvOff+1];
96    short ch = hsv[hsvOff+2];
97
98    // set chroma and min component value m
99    //chroma = ( cv * cs )/k1;
100    //m = cv - chroma;
101    m = ((int)cv*(k1 - (int)cs ))/k1;
102
103    // chroma  == 0 <-> cs == 0 --> m=cv
104    if (cs == 0) {
105        rb = ( rg = ( rr =( cv >> ABITS) ));
106    } else {
107        ih=(int)ch;
108        is=(int)cs;
109        iv=(int)cv;
110
111        H = (6*ih)/k2;
112        X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;
113
114        // removing additional bits --> unit8
115        X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
116        m=m >> ABITS;
117
118        // ( chroma + m ) --> cv ;
119        cv=(short) (cv >> ABITS);
120        switch (H) {
121        case 0:
122            rr = cv;
123            rg = X;
124            rb = m;
125            break;
126        case 1:
127            rr = X;
128            rg = cv;
129            rb = m;
130            break;
131        case 2:
132            rr = m;
133            rg = cv;
134            rb = X;
135            break;
136        case 3:
137            rr = m;
138            rg = X;
139            rb = cv;
140            break;
141        case 4:
142            rr = X;
143            rg = m;
144            rb = cv;
145            break;
146        case 5:
147            rr = cv;
148            rg = m ;
149            rb = X;
150            break;
151        }
152    }
153    rgb[rgbOff+0] =  rr;
154    rgb[rgbOff+1] =  rg;
155    rgb[rgbOff+2] =  rb;
156}
157
158