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 206b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Samsrs_allocation histogramValues; 21ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Samsstatic float3 scale; 22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 23572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsstatic uchar4 estimateWhite() { 24572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int min_r = -1, min_g = -1, min_b = -1; 25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int max_r = 0, max_g = 0, max_b = 0; 26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int sum_r = 0, sum_g = 0, sum_b = 0; 27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i = 1; i < 255; i++) { 296b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int4 hv = rsGetElementAt_int4(histogramValues, i); 306b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int r = hv.r; 316b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int g = hv.g; 326b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int b = hv.b; 33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum_r += r; 34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum_g += g; 35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum_b += b; 36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (r>0){ 38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (min_r < 0) min_r = i; 39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams max_r = i; 40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (g>0){ 42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (min_g < 0) min_g = i; 43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams max_g = i; 44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (b>0){ 46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if (min_b < 0) min_b = i; 47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams max_b = i; 48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int sum15r = 0, sum15g = 0, sum15b = 0; 52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int count15r = 0, count15g = 0, count15b = 0; 53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int tmp_r = 0, tmp_g = 0, tmp_b = 0; 54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams for (int i = 254; i >0; i--) { 566b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int4 hv = rsGetElementAt_int4(histogramValues, i); 576b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int r = hv.r; 586b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int g = hv.g; 596b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams int b = hv.b; 60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams tmp_r += r; 61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams tmp_g += g; 62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams tmp_b += b; 63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((tmp_r > sum_r/20) && (tmp_r < sum_r/5)) { 65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum15r += r*i; 66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams count15r += r; 67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((tmp_g > sum_g/20) && (tmp_g < sum_g/5)) { 69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum15g += g*i; 70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams count15g += g; 71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((tmp_b > sum_b/20) && (tmp_b < sum_b/5)) { 73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams sum15b += b*i; 74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams count15b += b; 75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams uchar4 out; 80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams if ((count15r>0) && (count15g>0) && (count15b>0) ){ 82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.r = sum15r/count15r; 83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.g = sum15g/count15g; 84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.b = sum15b/count15b; 85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams }else { 86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams out.r = out.g = out.b = 255; 87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams } 88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams return out; 90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsvoid prepareWhiteBalance() { 94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams uchar4 estimation = estimateWhite(); 95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int minimum = min(estimation.r, min(estimation.g, estimation.b)); 96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams int maximum = max(estimation.r, max(estimation.g, estimation.b)); 97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams float avg = (minimum + maximum) / 2.f; 98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 996b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams scale.r = avg / estimation.r; 1006b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams scale.g = avg / estimation.g; 1016b9cb41efc17c2731a2762c1ac6071ba5684af63Jason Sams scale.b = avg / estimation.b; 102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 104025b5f82971c431eb22df3c9d0f00b3cbe426bdbChris Wailesuchar4 RS_KERNEL whiteBalanceKernel(uchar4 in) { 105ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams float3 t = convert_float3(in.rgb); 106ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams t *= scale; 107ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams t = min(t, 255.f); 108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams 109ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams uchar4 out; 110ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams out.rgb = convert_uchar3(t); 111ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams out.a = 255; 112ab84c3968abce348c212bc9d466c534bc2a03cd6Jason Sams return out; 113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams} 114