summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jni/Android.mk4
-rw-r--r--jni/filters/filters.h3
-rw-r--r--jni/filters/hsv.c240
-rw-r--r--jni/filters/redEyeMath.c172
-rw-r--r--jni/filters/redeye.c31
-rw-r--r--jni/filters/shadows.c58
-rw-r--r--res/layout/filtershow_activity.xml6
-rw-r--r--res/values/filtershow_strings.xml2
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java1
-rw-r--r--src/com/android/gallery3d/filtershow/PanelController.java11
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java42
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java39
12 files changed, 437 insertions, 172 deletions
diff --git a/jni/Android.mk b/jni/Android.mk
index 213663ce1..92789c157 100644
--- a/jni/Android.mk
+++ b/jni/Android.mk
@@ -34,7 +34,9 @@ LOCAL_SRC_FILES := filters/bw.c \
filters/hsv.c \
filters/vibrance.c \
filters/geometry.c \
- filters/vignette.c
+ filters/vignette.c \
+ filters/redEyeMath.c \
+ filters/redeye.c
LOCAL_CFLAGS += -ffast-math -O3 -funroll-loops
LOCAL_ARM_MODE := arm
diff --git a/jni/filters/filters.h b/jni/filters/filters.h
index 954d02ddd..d8728f0d4 100644
--- a/jni/filters/filters.h
+++ b/jni/filters/filters.h
@@ -47,5 +47,6 @@ __inline__ unsigned char clamp(int c);
extern void rgb2hsv( unsigned char *rgb,int rgbOff,unsigned short *hsv,int hsvOff);
extern void hsv2rgb(unsigned short *hsv,int hsvOff,unsigned char *rgb,int rgbOff);
-
+extern void filterRedEye(unsigned char *src, unsigned char *dest, int iw, int ih, short *rect);
+extern double fastevalPoly(double *poly,int n, double x);
#endif // FILTERS_H
diff --git a/jni/filters/hsv.c b/jni/filters/hsv.c
index af438f87a..aabd053fe 100644
--- a/jni/filters/hsv.c
+++ b/jni/filters/hsv.c
@@ -17,128 +17,140 @@
#include <math.h>
#include "filters.h"
+double fastevalPoly(double *poly,int n, double x){
+
+ double f =x;
+ double sum = poly[0]+poly[1]*f;
+ int i;
+ for (i = 2; i < n; i++) {
+ f*=x;
+ sum += poly[i]*f;
+ }
+ return sum;
+}
+
void rgb2hsv( unsigned char *rgb,int rgbOff,unsigned short *hsv,int hsvOff)
{
- int iMin,iMax,chroma;
- int ABITS = 4;
- int HSCALE = 256;
-
- int k1=255 << ABITS;
- int k2=HSCALE << ABITS;
-
- int ri = rgb[rgbOff+0];
- int gi = rgb[rgbOff+1];
- int bi = rgb[rgbOff+2];
- short rv,rs,rh;
-
- if (ri > gi) {
- iMax = MAX (ri, bi);
- iMin = MIN (gi, bi);
- } else {
- iMax = MAX (gi, bi);
- iMin = MIN (ri, bi);
- }
-
- chroma = iMax - iMin;
- // set value
- rv = (short)( iMax << ABITS);
-
- // set saturation
- if (rv == 0)
+ int iMin,iMax,chroma;
+ int ABITS = 4;
+ int HSCALE = 256;
+
+ int k1=255 << ABITS;
+ int k2=HSCALE << ABITS;
+
+ int ri = rgb[rgbOff+0];
+ int gi = rgb[rgbOff+1];
+ int bi = rgb[rgbOff+2];
+ short rv,rs,rh;
+
+ if (ri > gi) {
+ iMax = MAX (ri, bi);
+ iMin = MIN (gi, bi);
+ } else {
+ iMax = MAX (gi, bi);
+ iMin = MIN (ri, bi);
+ }
+
+ chroma = iMax - iMin;
+ // set value
+ rv = (short)( iMax << ABITS);
+
+ // set saturation
+ if (rv == 0)
rs = 0;
- else
+ else
rs = (short)((k1*chroma)/iMax);
- // set hue
- if (rs == 0)
- rh = 0;
- else {
- if ( ri == iMax ) {
+ // set hue
+ if (rs == 0)
+ rh = 0;
+ else {
+ if ( ri == iMax ) {
rh = (short)( (k2*(6*chroma+gi - bi))/(6*chroma));
if (rh >= k2) rh -= k2;
- } else if (gi == iMax)
+ } else if (gi == iMax)
rh = (short)( (k2*(2*chroma+bi - ri ))/(6*chroma));
- else // (bi == iMax )
- rh = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
- }
- hsv[hsvOff+0] = rv;
- hsv[hsvOff+1] = rs;
- hsv[hsvOff+2] = rh;
+ else // (bi == iMax )
+ rh = (short)( (k2*(4*chroma+ri - gi ))/(6*chroma));
}
+ hsv[hsvOff+0] = rv;
+ hsv[hsvOff+1] = rs;
+ hsv[hsvOff+2] = rh;
+}
+
+void hsv2rgb(unsigned short *hsv,int hsvOff, unsigned char *rgb,int rgbOff)
+{
+ int ABITS = 4;
+ int HSCALE = 256;
+ int m;
+ int H,X,ih,is,iv;
+ int k1=255<<ABITS;
+ int k2=HSCALE<<ABITS;
+ int k3=1<<(ABITS-1);
+ int rr=0;
+ int rg=0;
+ int rb=0;
+ short cv = hsv[hsvOff+0];
+ short cs = hsv[hsvOff+1];
+ short ch = hsv[hsvOff+2];
+
+ // set chroma and min component value m
+ //chroma = ( cv * cs )/k1;
+ //m = cv - chroma;
+ m = ((int)cv*(k1 - (int)cs ))/k1;
- void hsv2rgb(unsigned short *hsv,int hsvOff, unsigned char *rgb,int rgbOff)
- {
- int ABITS = 4;
- int HSCALE = 256;
- int m;
- int H,X,ih,is,iv;
- int k1=255<<ABITS;
- int k2=HSCALE<<ABITS;
- int k3=1<<(ABITS-1);
- int rr=0;
- int rg=0;
- int rb=0;
- short cv = hsv[hsvOff+0];
- short cs = hsv[hsvOff+1];
- short ch = hsv[hsvOff+2];
-
- // set chroma and min component value m
- //chroma = ( cv * cs )/k1;
- //m = cv - chroma;
- m = ((int)cv*(k1 - (int)cs ))/k1;
-
- // chroma == 0 <-> cs == 0 --> m=cv
- if (cs == 0) {
- rb = ( rg = ( rr =( cv >> ABITS) ));
- } else {
- ih=(int)ch;
- is=(int)cs;
- iv=(int)cv;
-
- H = (6*ih)/k2;
- X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;
-
- // removing additional bits --> unit8
- X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
- m=m >> ABITS;
-
- // ( chroma + m ) --> cv ;
- cv=(short) (cv >> ABITS);
- switch (H) {
- case 0:
- rr = cv;
- rg = X;
- rb = m;
- break;
- case 1:
- rr = X;
- rg = cv;
- rb = m;
- break;
- case 2:
- rr = m;
- rg = cv;
- rb = X;
- break;
- case 3:
- rr = m;
- rg = X;
- rb = cv;
- break;
- case 4:
- rr = X;
- rg = m;
- rb = cv;
- break;
- case 5:
- rr = cv;
- rg = m ;
- rb = X;
- break;
- }
- }
- rgb[rgbOff+0] = rr;
- rgb[rgbOff+1] = rg;
- rgb[rgbOff+2] = rb;
- }
+ // chroma == 0 <-> cs == 0 --> m=cv
+ if (cs == 0) {
+ rb = ( rg = ( rr =( cv >> ABITS) ));
+ } else {
+ ih=(int)ch;
+ is=(int)cs;
+ iv=(int)cv;
+
+ H = (6*ih)/k2;
+ X = ((iv*is)/k2)*(k2- abs(6*ih- 2*(H>>1)*k2 - k2)) ;
+
+ // removing additional bits --> unit8
+ X=( (X+iv*(k1 - is ))/k1 + k3 ) >> ABITS;
+ m=m >> ABITS;
+
+ // ( chroma + m ) --> cv ;
+ cv=(short) (cv >> ABITS);
+ switch (H) {
+ case 0:
+ rr = cv;
+ rg = X;
+ rb = m;
+ break;
+ case 1:
+ rr = X;
+ rg = cv;
+ rb = m;
+ break;
+ case 2:
+ rr = m;
+ rg = cv;
+ rb = X;
+ break;
+ case 3:
+ rr = m;
+ rg = X;
+ rb = cv;
+ break;
+ case 4:
+ rr = X;
+ rg = m;
+ rb = cv;
+ break;
+ case 5:
+ rr = cv;
+ rg = m ;
+ rb = X;
+ break;
+ }
+ }
+ rgb[rgbOff+0] = rr;
+ rgb[rgbOff+1] = rg;
+ rgb[rgbOff+2] = rb;
+}
diff --git a/jni/filters/redEyeMath.c b/jni/filters/redEyeMath.c
new file mode 100644
index 000000000..26f3f76a4
--- /dev/null
+++ b/jni/filters/redEyeMath.c
@@ -0,0 +1,172 @@
+/*
+ * 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 <math.h>
+#include "filters.h"
+
+int value(int r, int g, int b) {
+ return MAX(r, MAX(g, b));
+}
+
+int isRed(unsigned char *src, int p) {
+ int b = src[p + 2];
+ int g = src[p + 1];
+ int r = src[p];
+ int max = MAX(g, b);
+
+ return ((r * 100 / (max + 2) > 160) & (max < 80));
+}
+
+void findPossible(unsigned char *src, unsigned char *mask, int iw, int ih,
+ short *rect) {
+ int recX = rect[0], recY = rect[1], recW = rect[2], recH = rect[3];
+ int y, x;
+
+ for (y = 0; y < recH; y++) {
+ int sy = (recY + y) * iw;
+ for (x = 0; x < recW; x++) {
+ int p = (recX + x + sy) * 4;
+
+ int b = src[p + 2];
+ int g = src[p + 1];
+ int r = src[p];
+ mask[x + y * recW] = (
+ mask[x + y * recW] > 0 && (value(r, g, b) > 240) ? 1 : 0);
+
+ }
+
+ }
+}
+
+void findReds(unsigned char *src, unsigned char *mask, int iw, int ih,
+ short *rect) {
+ int recX = rect[0], recY = rect[1], recW = rect[2], recH = rect[3];
+ int y, x;
+
+ for (y = 0; y < recH; y++) {
+ int sy = (recY + y) * iw;
+ for (x = 0; x < recW; x++) {
+ int p = (recX + x + sy) * 4;
+
+ mask[x + y * recW] = ((isRed(src, p)) ? 1 : 0);
+
+ }
+
+ }
+}
+
+void dialateMaskIfRed(unsigned char *src, int iw, int ih, unsigned char *mask,
+ unsigned char *out, short *rect) {
+ int recX = rect[0], recY = rect[1], recW = rect[2], recH = rect[3];
+ int y, x;
+
+ for (y = 1; y < recH - 1; y++) {
+ int row = recW * y;
+ int sy = (recY + y) * iw;
+ for (x = 1; x < recW - 1; x++) {
+ int p = (recX + x + sy) * 4;
+
+ char b = (mask[row + x] | mask[row + x + 1] | mask[row + x - 1]
+ | mask[row + x - recW] | mask[row + x + recW]);
+ if (b != 0 && isRed(src, p))
+ out[row + x] = 1;
+ else
+ out[row + x] = mask[row + x];
+ }
+ }
+}
+
+void dialateMask(unsigned char *mask, unsigned char *out, int mw, int mh) {
+ int y, x;
+ for (y = 1; y < mh - 1; y++) {
+ int row = mw * y;
+ for (x = 1; x < mw - 1; x++) {
+ out[row + x] = (mask[row + x] | mask[row + x + 1]
+ | mask[row + x - 1] | mask[row + x - mw]
+ | mask[row + x + mw]);
+ }
+ }
+}
+
+void stuff(int r, int g, int b, unsigned char *img, int off) {
+ img[off + 2] = b;
+ img[off + 1] = g;
+ img[off] = r;
+}
+
+void filterRedEye(unsigned char *src, unsigned char *dest, int iw, int ih, short *rect) {
+ int recX = rect[0], recY = rect[1], recW = rect[2], recH = rect[3];
+ unsigned char *mask1 = (unsigned char *) malloc(recW * recH);
+ unsigned char *mask2 = (unsigned char *)malloc(recW*recH);
+ int QUE_LEN = 100;
+ int y, x, i;
+
+ rect[0] = MAX(rect[0],0);
+ rect[1] = MAX(rect[1],0);
+ rect[2] = MIN(rect[2]+rect[0],iw)-rect[0];
+ rect[3] = MIN(rect[3]+rect[1],ih)-rect[1];
+
+ findReds(src, mask2, iw, ih, rect);
+ dialateMask(mask2, mask1, recW, recH);
+ dialateMask(mask1, mask2, recW, recH);
+ dialateMask(mask2, mask1, recW, recH);
+ dialateMask(mask1, mask2, recW, recH);
+ findPossible(src, mask2, iw, ih, rect);
+ dialateMask(mask2, mask1, recW, recH);
+
+ for (i = 0; i < 12; i++) {
+ dialateMaskIfRed(src, iw, ih, mask1, mask2, rect);
+ dialateMaskIfRed(src, iw, ih, mask2, mask1, rect);
+ }
+ dialateMask(mask1, mask2, recW, recH);
+ dialateMask(mask2, mask1, recW, recH);
+
+ for (y = 3; y < recH-3; y++) {
+ int sy = (recY + y) * iw;
+ for (x = 3; x < recW-3; x++) {
+ int p = (recX + x + sy) * 4;
+
+ int b = src[p + 2];
+ int g = src[p + 1];
+ int r = src[p];
+
+ if (mask1[x + y * recW] != 0) {
+ int m = MAX(g,b);
+ float rr = (r - m) / (float) m;
+ if (rr > .7f && g < 60 && b < 60) {
+ dest[p + 2] = (0);
+ dest[p + 1] = (0);
+ dest[p] = (0);
+ } else {
+ if (mask2[x + y * recW] != 0) {
+ stuff(r / 2, g / 2, b / 2, dest, p);
+ } else
+ stuff((2 * r) / 3, (2 * g) / 3, (2 * b) / 3, dest, p);
+ }
+
+ } else
+ stuff(r, g, b, dest, p);
+
+ //dest[p + 2] = dest[p + 1] =dest[p]=src[p];
+ }
+
+ }
+
+ free(mask1);
+ free(mask2);
+}
+
+
diff --git a/jni/filters/redeye.c b/jni/filters/redeye.c
new file mode 100644
index 000000000..9a358dd3d
--- /dev/null
+++ b/jni/filters/redeye.c
@@ -0,0 +1,31 @@
+/*
+ * 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 <math.h>
+#include "filters.h"
+
+ void JNIFUNCF(ImageFilterRedEye, nativeApplyFilter, jobject bitmap, jint width, jint height, jshortArray vrect)
+ {
+ char* destination = 0;
+ AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
+ unsigned char * rgb = (unsigned char * )destination;
+ short* rect = (*env)->GetShortArrayElements(env, vrect,0);
+
+ filterRedEye(rgb,rgb,width,height,rect);
+
+ (*env)->ReleaseShortArrayElements(env, vrect, rect, 0);
+ AndroidBitmap_unlockPixels(env, bitmap);
+ }
diff --git a/jni/filters/shadows.c b/jni/filters/shadows.c
index f812b93f8..38d64c8b5 100644
--- a/jni/filters/shadows.c
+++ b/jni/filters/shadows.c
@@ -17,23 +17,41 @@
#include <math.h>
#include "filters.h"
- void JNIFUNCF(ImageFilterShadows, nativeApplyFilter, jobject bitmap, jint width, jint height, jshortArray vlut)
- {
- char* destination = 0;
- AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
- unsigned char * rgb = (unsigned char * )destination;
- int i;
- int len = width * height * 4;
- short* lut = (*env)->GetShortArrayElements(env, vlut,0);
- unsigned short * hsv = (unsigned short *)malloc(3*sizeof(short));
- for (i = 0; i < len; i+=4)
- {
- rgb2hsv(rgb,i,hsv,0);
- hsv[0] = lut[hsv[0]];
- hsv2rgb(hsv,0, rgb,i);
- }
-
- (*env)->ReleaseShortArrayElements(env, vlut, lut, 0);
- free(hsv);
- AndroidBitmap_unlockPixels(env, bitmap);
- }
+void JNIFUNCF(ImageFilterShadows, nativeApplyFilter, jobject bitmap, jint width, jint height, float scale){
+ double shadowFilterMap[] = {
+ -0.00591, 0.0001,
+ 1.16488, 0.01668,
+ -0.18027, -0.06791,
+ -0.12625, 0.09001,
+ 0.15065, -0.03897
+ };
+
+ char* destination = 0;
+ AndroidBitmap_lockPixels(env, bitmap, (void**) &destination);
+ unsigned char * rgb = (unsigned char * )destination;
+ int i;
+ double s = (scale>=0)?scale:scale/5;
+ int len = width * height * 4;
+
+ double *poly = (double *) malloc(5*sizeof(double));
+ for (i = 0; i < 5; i++) {
+ poly[i] = fastevalPoly(shadowFilterMap+i*2,2 , s);
+ }
+
+ unsigned short * hsv = (unsigned short *)malloc(3*sizeof(short));
+
+ for (i = 0; i < len; i+=4)
+ {
+ rgb2hsv(rgb,i,hsv,0);
+
+ double v = (fastevalPoly(poly,5,hsv[0]/4080.)*4080);
+ if (v>4080) v = 4080;
+ hsv[0] = (unsigned short) ((v>0)?v:0);
+
+ hsv2rgb(hsv,0, rgb,i);
+ }
+
+ free(poly);
+ free(hsv);
+ AndroidBitmap_unlockPixels(env, bitmap);
+}
diff --git a/res/layout/filtershow_activity.xml b/res/layout/filtershow_activity.xml
index a3e402371..7915371b1 100644
--- a/res/layout/filtershow_activity.xml
+++ b/res/layout/filtershow_activity.xml
@@ -271,6 +271,12 @@
style="@style/FilterShowBottomButton"
android:src="@drawable/filtershow_button_geometry_flip"
android:text="@string/flip" />
+
+ <com.android.gallery3d.filtershow.ui.ImageButtonTitle
+ android:id="@+id/redEyeButton"
+ style="@style/FilterShowBottomButton"
+ android:src="@drawable/photoeditor_effect_redeye"
+ android:text="@string/redeye" />
</LinearLayout>
</HorizontalScrollView>
diff --git a/res/values/filtershow_strings.xml b/res/values/filtershow_strings.xml
index 9fd5b92d5..50235669d 100644
--- a/res/values/filtershow_strings.xml
+++ b/res/values/filtershow_strings.xml
@@ -81,6 +81,8 @@
<string name="curvesRGB">Curves</string>
<!-- Label for the vignette filter button [CHAR LIMIT=15] -->
<string name="vignette">Vignette</string>
+ <!-- Name for the photo effect that removes redeye. [CHAR LIMIT=15] -->
+ <string name="redeye">Red Eye</string>
<!-- Labels for the curves tool -->
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index 664b67f5c..6d61441eb 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -202,6 +202,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
mPanelController.addComponent(mColorsButton, findViewById(R.id.tintButton));
mPanelController.addComponent(mColorsButton, findViewById(R.id.exposureButton));
mPanelController.addComponent(mColorsButton, findViewById(R.id.shadowRecoveryButton));
+ mPanelController.addComponent(mColorsButton, findViewById(R.id.redEyeButton));
mPanelController.addView(findViewById(R.id.resetEffect));
mPanelController.addView(findViewById(R.id.applyEffect));
diff --git a/src/com/android/gallery3d/filtershow/PanelController.java b/src/com/android/gallery3d/filtershow/PanelController.java
index dbb6f27b3..0c50046df 100644
--- a/src/com/android/gallery3d/filtershow/PanelController.java
+++ b/src/com/android/gallery3d/filtershow/PanelController.java
@@ -13,6 +13,7 @@ import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.filters.ImageFilterContrast;
import com.android.gallery3d.filtershow.filters.ImageFilterExposure;
import com.android.gallery3d.filtershow.filters.ImageFilterHue;
+import com.android.gallery3d.filtershow.filters.ImageFilterRedEye;
import com.android.gallery3d.filtershow.filters.ImageFilterSaturated;
import com.android.gallery3d.filtershow.filters.ImageFilterShadows;
import com.android.gallery3d.filtershow.filters.ImageFilterSharpen;
@@ -368,6 +369,9 @@ public class PanelController implements OnClickListener {
if (filter == null && name.equalsIgnoreCase("Shadows")) {
filter = setImagePreset(new ImageFilterShadows(), name);
}
+ if (filter == null && name.equalsIgnoreCase("Redeye")) {
+ filter = setImagePreset(new ImageFilterRedEye(), name);
+ }
mMasterImage.setCurrentFilter(filter);
}
@@ -480,6 +484,13 @@ public class PanelController implements OnClickListener {
ensureFilter("Shadows");
break;
}
+ case R.id.redEyeButton: {
+ mCurrentImage = showImageView(R.id.imageShow).setShowControls(true);
+ mUtilityPanel.setEffectName("Redeye");
+ mUtilityPanel.setGeometryEffect(false);
+ ensureFilter("Redeye");
+ break;
+ }
case R.id.resetEffect: {
mCurrentImage.resetParameter();
break;
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java
new file mode 100644
index 000000000..c990c1870
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRedEye.java
@@ -0,0 +1,42 @@
+
+package com.android.gallery3d.filtershow.filters;
+
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import java.util.Arrays;
+
+public class ImageFilterRedEye extends ImageFilter {
+ private static final String TAG = "ImageFilterRedEye";
+
+
+ public ImageFilterRedEye() {
+ mName = "Redeye";
+
+ }
+
+ @Override
+ public ImageFilter clone() throws CloneNotSupportedException {
+ ImageFilterRedEye filter = (ImageFilterRedEye) super.clone();
+
+ return filter;
+ }
+
+ native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short []matrix);
+
+ public void apply(Bitmap bitmap) {
+ int w = bitmap.getWidth();
+ int h = bitmap.getHeight();
+ float p = mParameter;
+ float value = p;
+ int box = Math.min(w, h);
+ int sizex = Math.min((int)((p+100)*box/400),w/2);
+ int sizey = Math.min((int)((p+100)*box/800),h/2);
+
+ short [] rect = new short[]{
+ (short) (w/2-sizex),(short) (w/2-sizey),
+ (short) (2*sizex),(short) (2*sizey)};
+
+ nativeApplyFilter(bitmap, w, h, rect);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
index 9b379a1ff..ee621966d 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
@@ -3,61 +3,28 @@ package com.android.gallery3d.filtershow.filters;
import android.graphics.Bitmap;
-import com.android.gallery3d.filtershow.ui.ControlPoint;
-import com.android.gallery3d.filtershow.ui.Spline;
-
public class ImageFilterShadows extends ImageFilter {
- private final float SHADOW = .1f;
- private final float MID = .5f;
- private final float HIGHLIGHT = .9f;
-
- private final float []baseX = {0f,SHADOW,MID,HIGHLIGHT,1f};
- private final float []baseY = {0f,SHADOW,MID,HIGHLIGHT,1f};
public ImageFilterShadows() {
mName = "Shadows";
}
- short [] calcMap(){
- Spline sp = new Spline();
- for (int i = 0; i < baseX.length; i++) {
- sp.addPoint(baseX[i], baseY[i]);
- }
- int max = 4080;
- int w = 40800;
- float []px = new float[w+1];
- float []py = new float[w+1];
- short []vlut = new short[4080+1];
- for (int i = 0; i < px.length; i++) {
- float t = i/(float)(w);
-
- ControlPoint p = sp.getPoint(t);
- px[i] = p.x;
- py[i] = p.y;
- }
- for (int i = 0; i < py.length; i++) {
- short x = (short)Math.min(4080,Math.max(0,((int)(px[i]*max))));
- short y = (short)Math.min(4082,Math.max(0,((int)(py[i]*max))));
- vlut[x] = y;
- }
- return vlut;
- }
+
@Override
public ImageFilter clone() throws CloneNotSupportedException {
ImageFilterShadows filter = (ImageFilterShadows) super.clone();
return filter;
}
- native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short []valMap);
+ native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float factor);
@Override
public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
float p = mParameter;
- baseY[1] = (float)(SHADOW*Math.pow(4, mParameter/100.));
- nativeApplyFilter(bitmap, w, h, calcMap());
+ nativeApplyFilter(bitmap, w, h, p);
return bitmap;
}
}