1c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford/*
2c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * Copyright (C) 2012 The Android Open Source Project
3c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford *
4c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * Licensed under the Apache License, Version 2.0 (the "License");
5c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * you may not use this file except in compliance with the License.
6c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * You may obtain a copy of the License at
7c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford *
8c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford *      http://www.apache.org/licenses/LICENSE-2.0
9c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford *
10c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * Unless required by applicable law or agreed to in writing, software
11c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * distributed under the License is distributed on an "AS IS" BASIS,
12c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * See the License for the specific language governing permissions and
14c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford * limitations under the License.
15c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford */
16c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford
17c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford#include <math.h>
18a2818d95445cde63d679e5678803417c475fc719Kévin PETIT#include <stdlib.h> /* For abs */
19c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford#include "filters.h"
20c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford
2190b1d251973bfa748d435896fc277cb4024451adJohn Hoforddouble fastevalPoly(double *poly,int n, double x){
2290b1d251973bfa748d435896fc277cb4024451adJohn Hoford
2390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    double f =x;
2490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    double sum = poly[0]+poly[1]*f;
2590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int i;
2690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    for (i = 2; i < n; i++) {
2790b1d251973bfa748d435896fc277cb4024451adJohn Hoford        f*=x;
2890b1d251973bfa748d435896fc277cb4024451adJohn Hoford        sum += poly[i]*f;
2990b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
3090b1d251973bfa748d435896fc277cb4024451adJohn Hoford    return sum;
3190b1d251973bfa748d435896fc277cb4024451adJohn Hoford}
3290b1d251973bfa748d435896fc277cb4024451adJohn Hoford
33c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hofordvoid rgb2hsv( unsigned char *rgb,int rgbOff,unsigned short *hsv,int hsvOff)
34c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford{
3590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int iMin,iMax,chroma;
3690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int ABITS = 4;
3790b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int HSCALE = 256;
3890b1d251973bfa748d435896fc277cb4024451adJohn Hoford
3990b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int k1=255 << ABITS;
4090b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int k2=HSCALE << ABITS;
4190b1d251973bfa748d435896fc277cb4024451adJohn Hoford
4290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int ri = rgb[rgbOff+0];
4390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int gi = rgb[rgbOff+1];
4490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int bi = rgb[rgbOff+2];
4590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    short rv,rs,rh;
4690b1d251973bfa748d435896fc277cb4024451adJohn Hoford
4790b1d251973bfa748d435896fc277cb4024451adJohn Hoford    if (ri > gi) {
4890b1d251973bfa748d435896fc277cb4024451adJohn Hoford        iMax = MAX (ri, bi);
4990b1d251973bfa748d435896fc277cb4024451adJohn Hoford        iMin = MIN (gi, bi);
5090b1d251973bfa748d435896fc277cb4024451adJohn Hoford    } else {
5190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        iMax = MAX (gi, bi);
5290b1d251973bfa748d435896fc277cb4024451adJohn Hoford        iMin = MIN (ri, bi);
5390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
5490b1d251973bfa748d435896fc277cb4024451adJohn Hoford
5590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    chroma = iMax - iMin;
5690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    // set value
5790b1d251973bfa748d435896fc277cb4024451adJohn Hoford    rv = (short)( iMax << ABITS);
5890b1d251973bfa748d435896fc277cb4024451adJohn Hoford
5990b1d251973bfa748d435896fc277cb4024451adJohn Hoford    // set saturation
6090b1d251973bfa748d435896fc277cb4024451adJohn Hoford    if (rv == 0)
61c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford        rs = 0;
6290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    else
63c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford        rs = (short)((k1*chroma)/iMax);
64c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford
6590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    // set hue
6690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    if (rs == 0)
6790b1d251973bfa748d435896fc277cb4024451adJohn Hoford        rh = 0;
6890b1d251973bfa748d435896fc277cb4024451adJohn Hoford    else {
6990b1d251973bfa748d435896fc277cb4024451adJohn Hoford        if ( ri == iMax ) {
70c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford            rh  = (short)( (k2*(6*chroma+gi - bi))/(6*chroma));
71c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford            if (rh >= k2) rh -= k2;
7290b1d251973bfa748d435896fc277cb4024451adJohn Hoford        } else if (gi  == iMax)
73c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford            rh  = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma));
7490b1d251973bfa748d435896fc277cb4024451adJohn Hoford        else // (bi == iMax )
7590b1d251973bfa748d435896fc277cb4024451adJohn Hoford                    rh  = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
76c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford    }
7790b1d251973bfa748d435896fc277cb4024451adJohn Hoford    hsv[hsvOff+0] = rv;
7890b1d251973bfa748d435896fc277cb4024451adJohn Hoford    hsv[hsvOff+1] = rs;
7990b1d251973bfa748d435896fc277cb4024451adJohn Hoford    hsv[hsvOff+2] = rh;
8090b1d251973bfa748d435896fc277cb4024451adJohn Hoford}
8190b1d251973bfa748d435896fc277cb4024451adJohn Hoford
8290b1d251973bfa748d435896fc277cb4024451adJohn Hofordvoid hsv2rgb(unsigned short *hsv,int hsvOff, unsigned char *rgb,int rgbOff)
8390b1d251973bfa748d435896fc277cb4024451adJohn Hoford{
8490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int ABITS = 4;
8590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int HSCALE = 256;
8690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int m;
8790b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int H,X,ih,is,iv;
8890b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int k1=255<<ABITS;
8990b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int k2=HSCALE<<ABITS;
9090b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int k3=1<<(ABITS-1);
9190b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int rr=0;
9290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int rg=0;
9390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    int rb=0;
9490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    short cv = hsv[hsvOff+0];
9590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    short cs = hsv[hsvOff+1];
9690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    short ch = hsv[hsvOff+2];
9790b1d251973bfa748d435896fc277cb4024451adJohn Hoford
9890b1d251973bfa748d435896fc277cb4024451adJohn Hoford    // set chroma and min component value m
9990b1d251973bfa748d435896fc277cb4024451adJohn Hoford    //chroma = ( cv * cs )/k1;
10090b1d251973bfa748d435896fc277cb4024451adJohn Hoford    //m = cv - chroma;
10190b1d251973bfa748d435896fc277cb4024451adJohn Hoford    m = ((int)cv*(k1 - (int)cs ))/k1;
102c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford
10390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    // chroma  == 0 <-> cs == 0 --> m=cv
10490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    if (cs == 0) {
10590b1d251973bfa748d435896fc277cb4024451adJohn Hoford        rb = ( rg = ( rr =( cv >> ABITS) ));
10690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    } else {
10790b1d251973bfa748d435896fc277cb4024451adJohn Hoford        ih=(int)ch;
10890b1d251973bfa748d435896fc277cb4024451adJohn Hoford        is=(int)cs;
10990b1d251973bfa748d435896fc277cb4024451adJohn Hoford        iv=(int)cv;
11090b1d251973bfa748d435896fc277cb4024451adJohn Hoford
11190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        H = (6*ih)/k2;
11290b1d251973bfa748d435896fc277cb4024451adJohn Hoford        X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;
11390b1d251973bfa748d435896fc277cb4024451adJohn Hoford
11490b1d251973bfa748d435896fc277cb4024451adJohn Hoford        // removing additional bits --> unit8
11590b1d251973bfa748d435896fc277cb4024451adJohn Hoford        X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
11690b1d251973bfa748d435896fc277cb4024451adJohn Hoford        m=m >> ABITS;
11790b1d251973bfa748d435896fc277cb4024451adJohn Hoford
11890b1d251973bfa748d435896fc277cb4024451adJohn Hoford        // ( chroma + m ) --> cv ;
11990b1d251973bfa748d435896fc277cb4024451adJohn Hoford        cv=(short) (cv >> ABITS);
12090b1d251973bfa748d435896fc277cb4024451adJohn Hoford        switch (H) {
12190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        case 0:
12290b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rr = cv;
12390b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rg = X;
12490b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rb = m;
12590b1d251973bfa748d435896fc277cb4024451adJohn Hoford            break;
12690b1d251973bfa748d435896fc277cb4024451adJohn Hoford        case 1:
12790b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rr = X;
12890b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rg = cv;
12990b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rb = m;
13090b1d251973bfa748d435896fc277cb4024451adJohn Hoford            break;
13190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        case 2:
13290b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rr = m;
13390b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rg = cv;
13490b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rb = X;
13590b1d251973bfa748d435896fc277cb4024451adJohn Hoford            break;
13690b1d251973bfa748d435896fc277cb4024451adJohn Hoford        case 3:
13790b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rr = m;
13890b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rg = X;
13990b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rb = cv;
14090b1d251973bfa748d435896fc277cb4024451adJohn Hoford            break;
14190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        case 4:
14290b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rr = X;
14390b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rg = m;
14490b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rb = cv;
14590b1d251973bfa748d435896fc277cb4024451adJohn Hoford            break;
14690b1d251973bfa748d435896fc277cb4024451adJohn Hoford        case 5:
14790b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rr = cv;
14890b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rg = m ;
14990b1d251973bfa748d435896fc277cb4024451adJohn Hoford            rb = X;
15090b1d251973bfa748d435896fc277cb4024451adJohn Hoford            break;
15190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        }
15290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
15390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    rgb[rgbOff+0] =  rr;
15490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    rgb[rgbOff+1] =  rg;
15590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    rgb[rgbOff+2] =  rb;
15690b1d251973bfa748d435896fc277cb4024451adJohn Hoford}
157c7b2c287bfbe3f53a4d65800c3884b0082ad683cJohn Hoford
158