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