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 #include "kmeans.h" 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 /* 25 * For reasonable speeds: 26 * k < 30 27 * small_ds_bitmap width/height < 64 pixels. 28 * large_ds_bitmap width/height < 512 pixels 29 * 30 * bad for high-frequency image noise 31 */ 32 33 void JNIFUNCF(ImageFilterKMeans, nativeApplyFilter, jobject bitmap, jint width, jint height, 34 jobject large_ds_bitmap, jint lwidth, jint lheight, jobject small_ds_bitmap, 35 jint swidth, jint sheight, jint p, jint seed) 36 { 37 char* destination = 0; 38 char* larger_ds_dst = 0; 39 char* smaller_ds_dst = 0; 40 AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); 41 AndroidBitmap_lockPixels(env, large_ds_bitmap, (void**) &larger_ds_dst); 42 AndroidBitmap_lockPixels(env, small_ds_bitmap, (void**) &smaller_ds_dst); 43 unsigned char * dst = (unsigned char *) destination; 44 45 unsigned char * small_ds = (unsigned char *) smaller_ds_dst; 46 unsigned char * large_ds = (unsigned char *) larger_ds_dst; 47 48 // setting for small bitmap 49 int len = swidth * sheight * 4; 50 int dimension = 3; 51 int stride = 4; 52 int iterations = 20; 53 int k = p; 54 unsigned int s = seed; 55 unsigned char finalCentroids[k * stride]; 56 57 // get initial picks from small downsampled image 58 runKMeans<unsigned char, int>(k, finalCentroids, small_ds, len, dimension, 59 stride, iterations, s); 60 61 62 len = lwidth * lheight * 4; 63 iterations = 8; 64 unsigned char nextCentroids[k * stride]; 65 66 // run kmeans on large downsampled image 67 runKMeansWithPicks<unsigned char, int>(k, nextCentroids, large_ds, len, 68 dimension, stride, iterations, finalCentroids); 69 70 len = width * height * 4; 71 72 // apply to final image 73 applyCentroids<unsigned char, int>(k, nextCentroids, dst, len, dimension, stride); 74 75 AndroidBitmap_unlockPixels(env, small_ds_bitmap); 76 AndroidBitmap_unlockPixels(env, large_ds_bitmap); 77 AndroidBitmap_unlockPixels(env, bitmap); 78 } 79 #ifdef __cplusplus 80 } 81 #endif 82