1572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams/* 2572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Copyright (C) 2012 The Android Open Source Project 3572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * 4572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 5572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * you may not use this file except in compliance with the License. 6572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * You may obtain a copy of the License at 7572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * 8572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 9572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * 10572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Unless required by applicable law or agreed to in writing, software 11572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 12572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * See the License for the specific language governing permissions and 14572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * limitations under the License. 15572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams */ 16572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 17572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams#include "ip.rsh" 18dc08c6d13a68aa8fd35ce5922c1c98b915f35f08Jason Sams#pragma rs_fp_relaxed 19572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 20572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic int histR[256] = {0}, histG[256] = {0}, histB[256] = {0}; 21572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsrs_allocation histogramSource; 23572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsuint32_t histogramHeight; 24572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsuint32_t histogramWidth; 25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 26ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Samsstatic float3 scale; 27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic uchar4 estimateWhite() { 29572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 30572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i = 0; i < 256; i++) { 31572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams histR[i] = 0; histG[i] = 0; histB[i] = 0; 32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (uint32_t i = 0; i < histogramHeight; i++) { 35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (uint32_t j = 0; j < histogramWidth; j++) { 36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams uchar4 in = rsGetElementAt_uchar4(histogramSource, j, i); 37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams histR[in.r]++; 38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams histG[in.g]++; 39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams histB[in.b]++; 40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int min_r = -1, min_g = -1, min_b = -1; 44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int max_r = 0, max_g = 0, max_b = 0; 45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int sum_r = 0, sum_g = 0, sum_b = 0; 46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i = 1; i < 255; i++) { 48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int r = histR[i]; 49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int g = histG[i]; 50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int b = histB[i]; 51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum_r += r; 52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum_g += g; 53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum_b += b; 54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (r>0){ 56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (min_r < 0) min_r = i; 57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams max_r = i; 58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (g>0){ 60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (min_g < 0) min_g = i; 61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams max_g = i; 62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (b>0){ 64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (min_b < 0) min_b = i; 65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams max_b = i; 66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int sum15r = 0, sum15g = 0, sum15b = 0; 70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int count15r = 0, count15g = 0, count15b = 0; 71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int tmp_r = 0, tmp_g = 0, tmp_b = 0; 72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i = 254; i >0; i--) { 74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int r = histR[i]; 75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int g = histG[i]; 76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int b = histB[i]; 77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams tmp_r += r; 78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams tmp_g += g; 79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams tmp_b += b; 80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((tmp_r > sum_r/20) && (tmp_r < sum_r/5)) { 82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum15r += r*i; 83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams count15r += r; 84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((tmp_g > sum_g/20) && (tmp_g < sum_g/5)) { 86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum15g += g*i; 87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams count15g += g; 88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((tmp_b > sum_b/20) && (tmp_b < sum_b/5)) { 90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum15b += b*i; 91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams count15b += b; 92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams uchar4 out; 97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((count15r>0) && (count15g>0) && (count15b>0) ){ 99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.r = sum15r/count15r; 100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.g = sum15g/count15g; 101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.b = sum15b/count15b; 102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams }else { 103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.r = out.g = out.b = 255; 104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 105572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 106572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams return out; 107572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 109572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 110572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsvoid prepareWhiteBalance() { 111572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams uchar4 estimation = estimateWhite(); 112572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int minimum = min(estimation.r, min(estimation.g, estimation.b)); 113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int maximum = max(estimation.r, max(estimation.g, estimation.b)); 114572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float avg = (minimum + maximum) / 2.f; 115572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 116ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams scale.r = avg/estimation.r; 117ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams scale.g = avg/estimation.g; 118ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams scale.b = avg/estimation.b; 119572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 120572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 121025b5f82971c431eb22df3c9d0f00b3cbe426bdbChris Wailesuchar4 RS_KERNEL whiteBalanceKernel(uchar4 in) { 122ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams float3 t = convert_float3(in.rgb); 123ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams t *= scale; 124ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams t = min(t, 255.f); 125572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 126ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams uchar4 out; 127ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams out.rgb = convert_uchar3(t); 128ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams out.a = 255; 129ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams return out; 130572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 131ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams 132