/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "filters.h" #include "kmeans.h" #ifdef __cplusplus extern "C" { #endif /* * For reasonable speeds: * k < 30 * small_ds_bitmap width/height < 64 pixels. * large_ds_bitmap width/height < 512 pixels * * bad for high-frequency image noise */ void JNIFUNCF(ImageFilterKMeans, nativeApplyFilter, jobject bitmap, jint width, jint height, jobject large_ds_bitmap, jint lwidth, jint lheight, jobject small_ds_bitmap, jint swidth, jint sheight, jint p, jint seed) { char* destination = 0; char* larger_ds_dst = 0; char* smaller_ds_dst = 0; AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); AndroidBitmap_lockPixels(env, large_ds_bitmap, (void**) &larger_ds_dst); AndroidBitmap_lockPixels(env, small_ds_bitmap, (void**) &smaller_ds_dst); unsigned char * dst = (unsigned char *) destination; unsigned char * small_ds = (unsigned char *) smaller_ds_dst; unsigned char * large_ds = (unsigned char *) larger_ds_dst; // setting for small bitmap int len = swidth * sheight * 4; int dimension = 3; int stride = 4; int iterations = 20; int k = p; unsigned int s = seed; unsigned char finalCentroids[k * stride]; // get initial picks from small downsampled image runKMeans(k, finalCentroids, small_ds, len, dimension, stride, iterations, s); len = lwidth * lheight * 4; iterations = 8; unsigned char nextCentroids[k * stride]; // run kmeans on large downsampled image runKMeansWithPicks(k, nextCentroids, large_ds, len, dimension, stride, iterations, finalCentroids); len = width * height * 4; // apply to final image applyCentroids(k, nextCentroids, dst, len, dimension, stride); AndroidBitmap_unlockPixels(env, small_ds_bitmap); AndroidBitmap_unlockPixels(env, large_ds_bitmap); AndroidBitmap_unlockPixels(env, bitmap); } #ifdef __cplusplus } #endif