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 
fastevalPoly(double * poly,int n,double x)21 double 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 
rgb2hsv(unsigned char * rgb,int rgbOff,unsigned short * hsv,int hsvOff)33 void 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 
hsv2rgb(unsigned short * hsv,int hsvOff,unsigned char * rgb,int rgbOff)82 void 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