OSDN Git Service

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