From c3d751a2c2fe39bb0613ce139205bb59e1beb527 Mon Sep 17 00:00:00 2001 From: nicolasroard Date: Tue, 25 Sep 2012 14:27:56 -0700 Subject: Initial import of the new image editor bug:7165910 Change-Id: I756d6594f5bddd233772c979410362ca22e232a3 --- jni/Android.mk | 17 ++++++++ jni/filters/bw.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++ jni/filters/filters.h | 46 +++++++++++++++++++++ jni/filters/gradient.c | 65 +++++++++++++++++++++++++++++ jni/filters/saturated.c | 53 ++++++++++++++++++++++++ jni/filters/vignette.c | 69 +++++++++++++++++++++++++++++++ 6 files changed, 357 insertions(+) create mode 100644 jni/filters/bw.c create mode 100644 jni/filters/filters.h create mode 100644 jni/filters/gradient.c create mode 100644 jni/filters/saturated.c create mode 100644 jni/filters/vignette.c diff --git a/jni/Android.mk b/jni/Android.mk index 099b9bacd..01dd728f0 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -14,4 +14,21 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libjni_eglfence + +include $(BUILD_SHARED_LIBRARY) + +# Filtershow + +include $(CLEAR_VARS) + +LOCAL_LDLIBS := -llog -ljnigraphics +LOCAL_MODULE := filters +LOCAL_SRC_FILES := filters/bw.c \ + filters/gradient.c \ + filters/saturated.c \ + filters/vignette.c + +LOCAL_CFLAGS += -ffast-math -O3 -funroll-loops +LOCAL_ARM_MODE := arm + include $(BUILD_SHARED_LIBRARY) diff --git a/jni/filters/bw.c b/jni/filters/bw.c new file mode 100644 index 000000000..f075d307e --- /dev/null +++ b/jni/filters/bw.c @@ -0,0 +1,107 @@ +/* + * 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" + +void JNIFUNCF(ImageFilterBW, nativeApplyFilter, jobject bitmap, jint width, jint height) +{ + char* destination = 0; + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + int i; + int len = width * height * 4; + float Rf = 0.2999f; + float Gf = 0.587f; + float Bf = 0.114f; + + for (i = 0; i < len; i+=4) + { + int r = destination[RED]; + int g = destination[GREEN]; + int b = destination[BLUE]; + int t = CLAMP(Rf * r + Gf * g + Bf *b); + + destination[RED] = t; + destination[GREEN] = t; + destination[BLUE] = t; + } + AndroidBitmap_unlockPixels(env, bitmap); +} + +void JNIFUNCF(ImageFilterBWRed, nativeApplyFilter, jobject bitmap, jint width, jint height) +{ + char* destination = 0; + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + int i; + int len = width * height * 4; + for (i = 0; i < len; i+=4) + { + int r = destination[RED]; + int g = destination[GREEN]; + int b = destination[BLUE]; + int t = (g + b) / 2; + r = t; + g = t; + b = t; + destination[RED] = r; + destination[GREEN] = g; + destination[BLUE] = b; + } + AndroidBitmap_unlockPixels(env, bitmap); +} + +void JNIFUNCF(ImageFilterBWGreen, nativeApplyFilter, jobject bitmap, jint width, jint height) +{ + char* destination = 0; + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + int i; + int len = width * height * 4; + for (i = 0; i < len; i+=4) + { + int r = destination[RED]; + int g = destination[GREEN]; + int b = destination[BLUE]; + int t = (r + b) / 2; + r = t; + g = t; + b = t; + destination[RED] = r; + destination[GREEN] = g; + destination[BLUE] = b; + } + AndroidBitmap_unlockPixels(env, bitmap); +} + +void JNIFUNCF(ImageFilterBWBlue, nativeApplyFilter, jobject bitmap, jint width, jint height) +{ + char* destination = 0; + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + int i; + int len = width * height * 4; + for (i = 0; i < len; i+=4) + { + int r = destination[RED]; + int g = destination[GREEN]; + int b = destination[BLUE]; + int t = (r + g) / 2; + r = t; + g = t; + b = t; + destination[RED] = r; + destination[GREEN] = g; + destination[BLUE] = b; + } + AndroidBitmap_unlockPixels(env, bitmap); +} diff --git a/jni/filters/filters.h b/jni/filters/filters.h new file mode 100644 index 000000000..f8c4c5d08 --- /dev/null +++ b/jni/filters/filters.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +#ifndef FILTERS_H +#define FILTERS_H + +#include +#include +#include +#include + +typedef unsigned int Color; + +#define SetColor(a, r, g, b) ((a << 24) | (b << 16) | (g << 8) | (r << 0)); +#define GetA(color) (((color) >> 24) & 0xFF) +#define GetB(color) (((color) >> 16) & 0xFF) +#define GetG(color) (((color) >> 8) & 0xFF) +#define GetR(color) (((color) >> 0) & 0xFF) + +#define MIN(a, b) (a < b ? a : b) +#define MAX(a, b) (a > b ? a : b) + +#define LOG(msg...) __android_log_print(ANDROID_LOG_VERBOSE, "NativeFilters", msg) + +#define JNIFUNCF(cls, name, vars...) Java_com_android_gallery3d_filtershow_filters_ ## cls ## _ ## name(JNIEnv* env, jobject this, vars) + +#define RED i +#define GREEN i+1 +#define BLUE i+2 +#define ALPHA i+3 +#define CLAMP(c) (MAX(0, MIN(255, c))) + +#endif // FILTERS_H diff --git a/jni/filters/gradient.c b/jni/filters/gradient.c new file mode 100644 index 000000000..1a8569786 --- /dev/null +++ b/jni/filters/gradient.c @@ -0,0 +1,65 @@ +/* + * 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" + +void JNIFUNCF(ImageFilter, nativeApplyGradientFilter, jobject bitmap, jint width, jint height, + jintArray redGradient, jintArray greenGradient, jintArray blueGradient) +{ + char* destination = 0; + jint* redGradientArray = 0; + jint* greenGradientArray = 0; + jint* blueGradientArray = 0; + if (redGradient) + redGradientArray = (*env)->GetIntArrayElements(env, redGradient, NULL); + if (greenGradient) + greenGradientArray = (*env)->GetIntArrayElements(env, greenGradient, NULL); + if (blueGradient) + blueGradientArray = (*env)->GetIntArrayElements(env, blueGradient, NULL); + + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + int i; + int len = width * height * 4; + for (i = 0; i < len; i+=4) + { + if (redGradient) + { + int r = destination[RED]; + r = redGradientArray[r]; + destination[RED] = r; + } + if (greenGradient) + { + int g = destination[GREEN]; + g = greenGradientArray[g]; + destination[GREEN] = g; + } + if (blueGradient) + { + int b = destination[BLUE]; + b = blueGradientArray[b]; + destination[BLUE] = b; + } + } + if (redGradient) + (*env)->ReleaseIntArrayElements(env, redGradient, redGradientArray, 0); + if (greenGradient) + (*env)->ReleaseIntArrayElements(env, greenGradient, greenGradientArray, 0); + if (blueGradient) + (*env)->ReleaseIntArrayElements(env, blueGradient, blueGradientArray, 0); + AndroidBitmap_unlockPixels(env, bitmap); +} + diff --git a/jni/filters/saturated.c b/jni/filters/saturated.c new file mode 100644 index 000000000..1bc0cc56b --- /dev/null +++ b/jni/filters/saturated.c @@ -0,0 +1,53 @@ +/* + * 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" + +void JNIFUNCF(ImageFilterSaturated, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat saturation) +{ + char* destination = 0; + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + int i; + int len = width * height * 4; + float Rf = 0.2999f; + float Gf = 0.587f; + float Bf = 0.114f; + float S = saturation;; + float MS = 1.0f - S; + float Rt = Rf * MS; + float Gt = Gf * MS; + float Bt = Bf * MS; + float R, G, B; + for (i = 0; i < len; i+=4) + { + int r = destination[RED]; + int g = destination[GREEN]; + int b = destination[BLUE]; + int t = (r + g) / 2; + R = r; + G = g; + B = b; + + float Rc = R * (Rt + S) + G * Gt + B * Bt; + float Gc = R * Rt + G * (Gt + S) + B * Bt; + float Bc = R * Rt + G * Gt + B * (Bt + S); + + destination[RED] = CLAMP(Rc); + destination[GREEN] = CLAMP(Gc); + destination[BLUE] = CLAMP(Bc); + } + AndroidBitmap_unlockPixels(env, bitmap); +} diff --git a/jni/filters/vignette.c b/jni/filters/vignette.c new file mode 100644 index 000000000..7cff517b6 --- /dev/null +++ b/jni/filters/vignette.c @@ -0,0 +1,69 @@ +/* + * 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" + +static int* gVignetteMap = 0; +static int gVignetteWidth = 0; +static int gVignetteHeight = 0; + +void __inline__ createVignetteMap(int w, int h) +{ + if (gVignetteMap && (gVignetteWidth != w || gVignetteHeight != h)) + { + free(gVignetteMap); + gVignetteMap = 0; + } + if (gVignetteMap == 0) + { + gVignetteWidth = w; + gVignetteHeight = h; + + int cx = w / 2; + int cy = h / 2; + int i, j; + + gVignetteMap = malloc(w * h * sizeof(int)); + float maxDistance = cx * cx * 2.0f; + for (i = 0; i < w; i++) + { + for (j = 0; j < h; j++) + { + float distance = (cx - i) * (cx - i) + (cy - j) * (cy - j); + gVignetteMap[j * w + i] = (int) (distance / maxDistance * 255); + } + } + } +} + +void JNIFUNCF(ImageFilterVignette, nativeApplyFilter, jobject bitmap, jint width, jint height, jfloat strength) +{ + char* destination = 0; + AndroidBitmap_lockPixels(env, bitmap, (void**) &destination); + createVignetteMap(width, height); + int i; + int len = width * height * 4; + int vignette = 0; + + for (i = 0; i < len; i += 4) + { + vignette = (int) (strength * gVignetteMap[i / 4]); + destination[RED] = CLAMP(destination[RED] - vignette); + destination[GREEN] = CLAMP(destination[GREEN] - vignette); + destination[BLUE] = CLAMP(destination[BLUE] - vignette); + } + AndroidBitmap_unlockPixels(env, bitmap); +} -- cgit v1.2.3