Home | History | Annotate | Download | only in image
      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 "ip.rsh"
     18 #pragma rs_fp_relaxed
     19 
     20 rs_allocation histogramValues;
     21 static float3 scale;
     22 
     23 static uchar4 estimateWhite() {
     24     int min_r = -1, min_g = -1, min_b = -1;
     25     int max_r =  0, max_g =  0, max_b =  0;
     26     int sum_r =  0, sum_g =  0, sum_b =  0;
     27 
     28     for (int i = 1; i < 255; i++) {
     29         int3 hv = rsGetElementAt_int3(histogramValues, i);
     30         int r = hv.r;
     31         int g = hv.g;
     32         int b = hv.b;
     33         sum_r += r;
     34         sum_g += g;
     35         sum_b += b;
     36 
     37         if (r>0){
     38             if (min_r < 0) min_r = i;
     39             max_r = i;
     40         }
     41         if (g>0){
     42             if (min_g < 0) min_g = i;
     43             max_g = i;
     44         }
     45         if (b>0){
     46             if (min_b < 0) min_b = i;
     47             max_b = i;
     48         }
     49     }
     50 
     51     int sum15r = 0, sum15g = 0, sum15b = 0;
     52     int count15r = 0, count15g = 0, count15b = 0;
     53     int tmp_r = 0, tmp_g = 0, tmp_b = 0;
     54 
     55     for (int i = 254; i >0; i--) {
     56         int3 hv = rsGetElementAt_int3(histogramValues, i);
     57         int r = hv.r;
     58         int g = hv.g;
     59         int b = hv.b;
     60         tmp_r += r;
     61         tmp_g += g;
     62         tmp_b += b;
     63 
     64         if ((tmp_r > sum_r/20) && (tmp_r < sum_r/5)) {
     65             sum15r += r*i;
     66             count15r += r;
     67         }
     68         if ((tmp_g > sum_g/20) && (tmp_g < sum_g/5)) {
     69             sum15g += g*i;
     70             count15g += g;
     71         }
     72         if ((tmp_b > sum_b/20) && (tmp_b < sum_b/5)) {
     73             sum15b += b*i;
     74             count15b += b;
     75         }
     76 
     77     }
     78 
     79     uchar4 out;
     80 
     81     if ((count15r>0) && (count15g>0) && (count15b>0) ){
     82         out.r = sum15r/count15r;
     83         out.g = sum15g/count15g;
     84         out.b = sum15b/count15b;
     85     }else {
     86         out.r = out.g = out.b = 255;
     87     }
     88 
     89     return out;
     90 
     91 }
     92 
     93 void prepareWhiteBalance() {
     94     uchar4 estimation = estimateWhite();
     95     int minimum = min(estimation.r, min(estimation.g, estimation.b));
     96     int maximum = max(estimation.r, max(estimation.g, estimation.b));
     97     float avg = (minimum + maximum) / 2.f;
     98 
     99     scale.r =  avg / estimation.r;
    100     scale.g =  avg / estimation.g;
    101     scale.b =  avg / estimation.b;
    102 }
    103 
    104 uchar4 RS_KERNEL whiteBalanceKernel(uchar4 in) {
    105     float3 t = convert_float3(in.rgb);
    106     t *= scale;
    107     t = min(t, 255.f);
    108 
    109     uchar4 out;
    110     out.rgb = convert_uchar3(t);
    111     out.a = 255;
    112     return out;
    113 }
    114