2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 void JNIFUNCF(ImageFilterEdge, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat p)
22 char* destination = 0;
23 AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
25 // using contrast function:
26 // f(v) = exp(-alpha * v^beta)
29 float const alpha = 5.0f;
31 float const c_min = 100.0f;
32 float const c_max = 500.0f;
34 // pixels must be 4 bytes
35 char * dst = destination;
38 char * ptr = destination;
39 int row_stride = 4 * width;
41 // set 2 row buffer (avoids bitmap copy)
42 int buf_len = 2 * row_stride;
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
53 for (j = 1; j < height - 1; j++) {
55 for (k = 1; k < width - 1; k++){
56 int loc = j * row_stride + k * 4;
60 for (l = 0; l < 3; l++) {
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)) {
74 for (l = 0; l < 3; l++) {
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)) {
87 // compute gradient magnitude
88 float mag = sqrt(bestx * bestx + besty * besty);
91 mag = MIN(MAX(c_min, mag), c_max);
94 mag = (mag - c_min) / (c_max - c_min);
96 float ret = 1.0f - exp (- alpha * pow(mag, beta));
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);
106 buf_row_ring += row_stride;
107 buf_row_ring %= buf_len;
110 memcpy((dst + row_stride * (j - 1)), (buf + buf_row_ring), row_stride * sizeof(char));
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));
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
125 AndroidBitmap_unlockPixels(env, bitmap);