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