OSDN Git Service

Import translations. DO NOT MERGE
[android-x86/packages-apps-Gallery2.git] / jni / filters / edge.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 <math.h>
18 #include "filters.h"
19
20 void JNIFUNCF(ImageFilterEdge, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat p)
21 {
22     char* destination = 0;
23     AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
24
25     // using contrast function:
26     // f(v) = exp(-alpha * v^beta)
27     // use beta ~ 1
28
29     float const alpha = 5.0f;
30     float const beta = p;
31     float const c_min = 100.0f;
32     float const c_max = 500.0f;
33
34     // pixels must be 4 bytes
35     char * dst = destination;
36
37     int j, k;
38     char * ptr = destination;
39     int row_stride = 4 * width;
40
41     // set 2 row buffer (avoids bitmap copy)
42     int buf_len = 2 * row_stride;
43     char buf[buf_len];
44     int buf_row_ring = 0;
45
46     // set initial buffer to black
47     memset(buf, 0, buf_len * sizeof(char));
48     for (j = 3; j < buf_len; j+=4) {
49         *(buf + j) = 255;  // set initial alphas
50     }
51
52     // apply sobel filter
53     for (j = 1; j < height - 1; j++) {
54
55         for (k = 1; k < width - 1; k++){
56             int loc = j * row_stride + k * 4;
57
58             float bestx = 0.0f;
59             int l;
60             for (l = 0; l < 3; l++) {
61                 float tmp = 0.0f;
62                 tmp += *(ptr + (loc - row_stride + 4 + l));
63                 tmp += *(ptr + (loc + 4 + l)) * 2.0f;
64                 tmp += *(ptr + (loc + row_stride + 4 + l));
65                 tmp -= *(ptr + (loc - row_stride - 4 + l));
66                 tmp -= *(ptr + (loc - 4 + l)) * 2.0f;
67                 tmp -= *(ptr + (loc + row_stride - 4 + l));
68                 if (fabs(tmp) > fabs(bestx)) {
69                     bestx = tmp;
70                 }
71             }
72
73             float besty = 0.0f;
74             for (l = 0; l < 3; l++) {
75                 float tmp = 0.0f;
76                 tmp -= *(ptr + (loc - row_stride - 4 + l));
77                 tmp -= *(ptr + (loc - row_stride + l)) * 2.0f;
78                 tmp -= *(ptr + (loc - row_stride + 4 + l));
79                 tmp += *(ptr + (loc + row_stride - 4 + l));
80                 tmp += *(ptr + (loc + row_stride + l)) * 2.0f;
81                 tmp += *(ptr + (loc + row_stride + 4 + l));
82                 if (fabs(tmp) > fabs(besty)) {
83                     besty = tmp;
84                 }
85             }
86
87             // compute gradient magnitude
88             float mag = sqrt(bestx * bestx + besty * besty);
89
90             // clamp
91             mag = MIN(MAX(c_min, mag), c_max);
92
93             // scale to [0, 1]
94             mag = (mag - c_min) / (c_max - c_min);
95
96             float ret = 1.0f - exp (- alpha * pow(mag, beta));
97             ret = 255 * ret;
98
99             int off = k * 4;
100             *(buf + buf_row_ring + off) = ret;
101             *(buf + buf_row_ring + off + 1) = ret;
102             *(buf + buf_row_ring + off + 2) = ret;
103             *(buf + buf_row_ring + off + 3) = *(ptr + loc + 3);
104         }
105
106         buf_row_ring += row_stride;
107         buf_row_ring %= buf_len;
108
109         if (j - 1 >= 0) {
110             memcpy((dst + row_stride * (j - 1)), (buf + buf_row_ring), row_stride * sizeof(char));
111         }
112
113     }
114     buf_row_ring += row_stride;
115     buf_row_ring %= buf_len;
116     int second_last_row = row_stride * (height - 2);
117     memcpy((dst + second_last_row), (buf + buf_row_ring), row_stride * sizeof(char));
118
119     // set last row to black
120     int last_row = row_stride * (height - 1);
121     memset((dst + last_row), 0, row_stride * sizeof(char));
122     for (j = 3; j < row_stride; j+=4) {
123         *(dst + last_row + j) = 255;  // set alphas
124     }
125     AndroidBitmap_unlockPixels(env, bitmap);
126 }