OSDN Git Service

Merge "Import translations. DO NOT MERGE" into mnc-dr2-dev am: d0bd0e96f7 -s ours
[android-x86/packages-apps-Gallery2.git] / jni / filters / wbalance.c
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 "filters.h"
18
19 void estmateWhite(unsigned char *src, int len, int *wr, int *wb, int *wg){
20
21     int STEP = 4;
22     int RANGE = 256;
23     int *histR = (int *) malloc(256*sizeof(int));
24     int *histG = (int *) malloc(256*sizeof(int));
25     int *histB = (int *) malloc(256*sizeof(int));
26     int i;
27     for (i = 0; i < 255; i++) {
28         histR[i] = histG[i] = histB[i] =0;
29     }
30
31     for (i = 0; i < len; i+=STEP) {
32         histR[(src[RED])]++;
33         histG[(src[GREEN])]++;
34         histB[(src[BLUE])]++;
35     }
36     int min_r = -1, min_g = -1,min_b = -1;
37     int max_r = 0, max_g = 0,max_b = 0;
38     int sum_r = 0,sum_g=0,sum_b=0;
39
40     for (i = 1; i < RANGE-1; i++) {
41         int r = histR[i];
42         int g = histG[i];
43         int b = histB[i];
44         sum_r += r;
45         sum_g += g;
46         sum_b += b;
47
48         if (r>0){
49             if (min_r < 0) min_r = i;
50             max_r = i;
51         }
52         if (g>0){
53             if (min_g < 0) min_g = i;
54             max_g = i;
55         }
56         if (b>0){
57             if (min_b < 0) min_b = i;
58             max_b = i;
59         }
60     }
61
62     int sum15r = 0,sum15g=0,sum15b=0;
63     int count15r = 0,count15g=0,count15b=0;
64     int tmp_r = 0,tmp_g=0,tmp_b=0;
65
66     for (i = RANGE-2; i >0; i--) {
67         int r = histR[i];
68         int g = histG[i];
69         int b = histB[i];
70         tmp_r += r;
71         tmp_g += g;
72         tmp_b += b;
73
74         if ((tmp_r > sum_r/20) && (tmp_r < sum_r/5)) {
75             sum15r += r*i;
76             count15r += r;
77         }
78         if ((tmp_g > sum_g/20) && (tmp_g < sum_g/5)) {
79             sum15g += g*i;
80             count15g += g;
81         }
82         if ((tmp_b > sum_b/20) && (tmp_b < sum_b/5)) {
83             sum15b += b*i;
84             count15b += b;
85         }
86
87     }
88     free(histR);
89     free(histG);
90     free(histB);
91
92     if ((count15r>0) && (count15g>0) && (count15b>0) ){
93         *wr = sum15r/count15r;
94         *wb = sum15g/count15g;
95         *wg = sum15b/count15b;
96     }else {
97         *wg  = *wb = *wr=255;
98     }
99 }
100
101 void estmateWhiteBox(unsigned char *src, int iw, int ih, int x,int y, int *wr, int *wb, int *wg){
102     int r;
103     int g;
104     int b;
105     int sum;
106     int xp,yp;
107     int bounds = 5;
108     if (x<0) x = bounds;
109     if (y<0) y = bounds;
110     if (x>=(iw-bounds)) x = (iw-bounds-1);
111     if (y>=(ih-bounds)) y = (ih-bounds-1);
112     int startx = x - bounds;
113     int starty = y - bounds;
114     int endx = x + bounds;
115     int endy = y + bounds;
116
117     for(yp= starty;yp<endy;yp++) {
118         for(xp= startx;xp<endx;xp++) {
119             int i = 4*(xp+yp*iw);
120             r += src[RED];
121             g += src[GREEN];
122             b += src[BLUE];
123             sum++;
124         }
125     }
126     *wr = r/sum;
127     *wg = g/sum;
128     *wb = b/sum;
129 }
130
131 void JNIFUNCF(ImageFilterWBalance, nativeApplyFilter, jobject bitmap, jint width, jint height, int locX,int locY)
132 {
133     char* destination = 0;
134     AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
135     int i;
136     int len = width * height * 4;
137     unsigned char * rgb = (unsigned char * )destination;
138     int wr;
139     int wg;
140     int wb;
141
142     if (locX==-1)
143         estmateWhite(rgb,len,&wr,&wg,&wb);
144     else
145         estmateWhiteBox(rgb, width, height,locX,locY,&wr,&wg,&wb);
146
147     int min = MIN(wr, MIN(wg, wb));
148     int max = MAX(wr, MAX(wg, wb));
149     float avg = (min+max)/2.f;
150     float scaleR =  avg/wr;
151     float scaleG =  avg/wg;
152     float scaleB =  avg/wb;
153
154     for (i = 0; i < len; i+=4)
155     {
156         int r = rgb[RED];
157         int g = rgb[GREEN];
158         int b = rgb[BLUE];
159
160         float Rc =  r*scaleR;
161         float Gc =  g*scaleG;
162         float Bc =  b*scaleB;
163
164         rgb[RED]   = clamp(Rc);
165         rgb[GREEN] = clamp(Gc);
166         rgb[BLUE]  = clamp(Bc);
167     }
168     AndroidBitmap_unlockPixels(env, bitmap);
169 }