Merge "Add scale factor / quality parameters in filters" into gb-ub-photos-arches
diff --git a/src/com/android/gallery3d/filtershow/cache/BitmapCache.java b/src/com/android/gallery3d/filtershow/cache/BitmapCache.java
index 93d57ed..e04c366 100644
--- a/src/com/android/gallery3d/filtershow/cache/BitmapCache.java
+++ b/src/com/android/gallery3d/filtershow/cache/BitmapCache.java
@@ -1,25 +1,24 @@
 
 package com.android.gallery3d.filtershow.cache;
 
-import java.nio.ByteBuffer;
+import android.graphics.Bitmap;
 
 import com.android.gallery3d.filtershow.presets.ImagePreset;
 
-import android.graphics.Bitmap;
-import android.util.Log;
+import java.nio.ByteBuffer;
 
 public class BitmapCache {
 
     private static final String LOGTAG = "BitmapCache";
     static int mNbItems = 20;
-    private Bitmap[] mBitmaps = new Bitmap[mNbItems];
-    private Object[] mKeys = new Object[mNbItems];
-    private long[] mIndices = new long[mNbItems];
-    private boolean[] mBusyStatus = new boolean[mNbItems];
+    private final Bitmap[] mBitmaps = new Bitmap[mNbItems];
+    private final Object[] mKeys = new Object[mNbItems];
+    private final long[] mIndices = new long[mNbItems];
+    private final boolean[] mBusyStatus = new boolean[mNbItems];
 
     private Bitmap mOriginalBitmap = null;
     private ByteBuffer mBuffer = null;
-    private Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
+    private final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
     private long mIndex = 0;
 
     public void setOriginalBitmap(Bitmap original) {
@@ -57,8 +56,7 @@
     public Bitmap put(ImagePreset preset, int pos) {
         mBitmaps[pos] = mOriginalBitmap.copy(mConfig, true);
         Bitmap bitmap = mBitmaps[pos];
-
-        preset.apply(bitmap);
+        bitmap = preset.apply(bitmap);
         mKeys[pos] = preset;
         mIndices[pos] = mIndex++;
         return bitmap;
@@ -80,7 +78,7 @@
         ImagePreset preset = (ImagePreset) mKeys[pos];
         mBitmaps[pos] = mOriginalBitmap.copy(mConfig, true);
         Bitmap bitmap = mBitmaps[pos];
-        preset.apply(bitmap);
+        bitmap = preset.apply(bitmap);
         mIndices[pos] = mIndex++;
     }
 
diff --git a/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java
index 8acb539..361190b 100644
--- a/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java
+++ b/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java
@@ -14,7 +14,7 @@
     private final static int COMPUTE_PRESET = 1;
 
     private Handler mProcessingHandler = null;
-    private Handler mUIHandler = new Handler() {
+    private final Handler mUIHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
@@ -41,13 +41,14 @@
         return false;
     }
 
-    public DelayedPresetCache(int size) {
-        super(size);
+    public DelayedPresetCache(ImageLoader loader, int size) {
+        super(loader, size);
         mHandlerThread = new HandlerThread("ImageProcessing", Process.THREAD_PRIORITY_BACKGROUND);
         mHandlerThread.start();
         mProcessingHandler = new Handler(mHandlerThread.getLooper(), this);
     }
 
+    @Override
     protected void willCompute(CachedPreset cache) {
         if (cache == null) {
             return;
diff --git a/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java
index 1ba8356..67bd49b 100644
--- a/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java
+++ b/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java
@@ -1,23 +1,23 @@
 
 package com.android.gallery3d.filtershow.cache;
 
-import java.util.Vector;
-
 import android.graphics.Bitmap;
-import android.util.Log;
 
 import com.android.gallery3d.filtershow.imageshow.ImageShow;
 import com.android.gallery3d.filtershow.presets.ImagePreset;
 
+import java.util.Vector;
+
 public class DirectPresetCache implements Cache {
 
     private static final String LOGTAG = "DirectPresetCache";
     private Bitmap mOriginalBitmap = null;
-    private Vector<ImageShow> mObservers = new Vector<ImageShow>();
-    private Vector<CachedPreset> mCache = new Vector<CachedPreset>();
+    private final Vector<ImageShow> mObservers = new Vector<ImageShow>();
+    private final Vector<CachedPreset> mCache = new Vector<CachedPreset>();
     private int mCacheSize = 1;
-    private Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
+    private final Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
     private long mGlobalAge = 0;
+    private ImageLoader mLoader = null;
 
     protected class CachedPreset {
         private Bitmap mBitmap = null;
@@ -34,10 +34,12 @@
         }
     }
 
-    public DirectPresetCache(int size) {
+    public DirectPresetCache(ImageLoader loader, int size) {
+        mLoader = loader;
         mCacheSize = size;
     }
 
+    @Override
     public void setOriginalBitmap(Bitmap bitmap) {
         mOriginalBitmap = bitmap;
         notifyObservers();
@@ -50,6 +52,7 @@
         }
     }
 
+    @Override
     public void addObserver(ImageShow observer) {
         if (!mObservers.contains(observer)) {
             mObservers.add(observer);
@@ -66,6 +69,7 @@
         return null;
     }
 
+    @Override
     public Bitmap get(ImagePreset preset) {
         // Log.v(LOGTAG, "get preset " + preset.name() + " : " + preset);
         CachedPreset cache = getCachedPreset(preset);
@@ -77,6 +81,7 @@
         return null;
     }
 
+    @Override
     public void reset(ImagePreset preset) {
         CachedPreset cache = getCachedPreset(preset);
         if (cache != null && !cache.mBusy) {
@@ -120,10 +125,16 @@
     protected void compute(CachedPreset cache) {
         cache.mBitmap = null;
         cache.mBitmap = mOriginalBitmap.copy(mBitmapConfig, true);
-        cache.mPreset.apply(cache.mBitmap);
+        float scaleFactor = (float) cache.mBitmap.getWidth() / (float) mLoader.getOriginalBounds().width();
+        if (scaleFactor < 1.0f) {
+            cache.mPreset.setIsHighQuality(false);
+        }
+        cache.mPreset.setScaleFactor(scaleFactor);
+        cache.mBitmap = cache.mPreset.apply(cache.mBitmap);
         cache.mAge = mGlobalAge++;
     }
 
+    @Override
     public void prepare(ImagePreset preset) {
         // Log.v(LOGTAG, "prepare preset " + preset.name() + " : " + preset);
         CachedPreset cache = getCachedPreset(preset);
diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
index 9944f5f..8d8024e 100644
--- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
+++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java
@@ -35,16 +35,16 @@
 public class ImageLoader {
 
     private static final String LOGTAG = "ImageLoader";
-    private Vector<ImageShow> mListeners = new Vector<ImageShow>();
+    private final Vector<ImageShow> mListeners = new Vector<ImageShow>();
     private Bitmap mOriginalBitmapSmall = null;
     private Bitmap mOriginalBitmapLarge = null;
     private Bitmap mBackgroundBitmap = null;
     private Bitmap mFullOriginalBitmap = null;
     private Bitmap mSaveCopy = null;
 
-    private Cache mCache = new DelayedPresetCache(30);
-    private Cache mHiresCache = new DelayedPresetCache(2);
-    private ZoomCache mZoomCache = new ZoomCache();
+    private Cache mCache = null;
+    private Cache mHiresCache = null;
+    private final ZoomCache mZoomCache = new ZoomCache();
 
     private int mOrientation = 0;
     private HistoryAdapter mAdapter = null;
@@ -57,6 +57,8 @@
 
     public ImageLoader(Context context) {
         mContext = context;
+        mCache = new DelayedPresetCache(this, 30);
+        mHiresCache = new DelayedPresetCache(this, 2);
     }
 
     public void loadBitmap(Uri uri) {
@@ -230,7 +232,7 @@
             if (bmp != null) {
                 // TODO: this workaround for RS might not be needed ultimately
                 Bitmap bmp2 = bmp.copy(Bitmap.Config.ARGB_8888, true);
-                imagePreset.apply(bmp2);
+                bmp2 = imagePreset.apply(bmp2);
                 mZoomCache.setImage(imagePreset, bounds, bmp2);
                 return bmp2;
             }
@@ -289,6 +291,8 @@
             // TODO: on <3.x we need a copy of the bitmap (inMutable doesn't
             // exist)
             mSaveCopy = mFullOriginalBitmap;
+            preset.setIsHighQuality(true);
+            preset.setScaleFactor(1.0f);
             ProcessedBitmap processedBitmap = new ProcessedBitmap(mSaveCopy, preset);
             new SaveCopyTask(mContext, mUri, destination, new SaveCopyTask.Callback() {
 
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
index c039fce..662e8ed 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
@@ -2,7 +2,6 @@
 package com.android.gallery3d.filtershow.filters;
 
 import android.graphics.Bitmap;
-import android.util.Log;
 
 public class ImageFilter implements Cloneable {
 
@@ -26,8 +25,9 @@
         return mName;
     }
 
-    public void apply(Bitmap bitmap) {
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         // do nothing here, subclasses will implement filtering here
+        return bitmap;
     }
 
     public int getParameter() {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBW.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBW.java
index bc3dd09..bdbd1d5 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBW.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBW.java
@@ -11,10 +11,12 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         nativeApplyFilter(bitmap, w, h);
+        return bitmap;
     }
 
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBWBlue.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBWBlue.java
index 7368be5..b3c8a9e 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBWBlue.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBWBlue.java
@@ -11,10 +11,12 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         nativeApplyFilter(bitmap, w, h);
+        return bitmap;
     }
 
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBWGreen.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBWGreen.java
index f4e6c61..e3963dc 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBWGreen.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBWGreen.java
@@ -11,10 +11,12 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         nativeApplyFilter(bitmap, w, h);
+        return bitmap;
     }
 
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBWRed.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBWRed.java
index bb7d661..19b3c6b 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBWRed.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBWRed.java
@@ -11,10 +11,12 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         nativeApplyFilter(bitmap, w, h);
+        return bitmap;
     }
 
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
index 7df7a2b..67904c6 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterBorder.java
@@ -1,13 +1,10 @@
 
 package com.android.gallery3d.filtershow.filters;
 
-import com.android.gallery3d.R;
-
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.NinePatchDrawable;
 
 public class ImageFilterBorder extends ImageFilter {
     Drawable mNinePatch = null;
@@ -24,6 +21,7 @@
         mNinePatch = ninePatch;
     }
 
+    @Override
     public boolean same(ImageFilter filter) {
         boolean isBorderFilter = super.same(filter);
         if (!isBorderFilter) {
@@ -41,9 +39,10 @@
         mNinePatch = ninePatch;
     }
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         if (mNinePatch == null) {
-            return;
+            return bitmap;
         }
 
         int w = bitmap.getWidth();
@@ -53,5 +52,6 @@
         Canvas canvas = new Canvas(bitmap);
         mNinePatch.setBounds(bounds);
         mNinePatch.draw(canvas);
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
index b3ef74d..5117f60 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterContrast.java
@@ -11,11 +11,13 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         float p = mParameter;
         float value = p;
         nativeApplyFilter(bitmap, w, h, value);
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java
index 5de8ff4..01b280b 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterCurves.java
@@ -1,16 +1,15 @@
 
 package com.android.gallery3d.filtershow.filters;
 
-import com.android.gallery3d.filtershow.ui.Spline;
-
 import android.graphics.Bitmap;
-import android.util.Log;
+
+import com.android.gallery3d.filtershow.ui.Spline;
 
 public class ImageFilterCurves extends ImageFilter {
 
     private static final String LOGTAG = "ImageFilterCurves";
 
-    private float[] mCurve = new float[256];
+    private final float[] mCurve = new float[256];
 
     private boolean mUseRed = true;
     private boolean mUseGreen = true;
@@ -49,6 +48,7 @@
         }
     }
 
+    @Override
     public boolean same(ImageFilter filter) {
         boolean isCurveFilter = super.same(filter);
         if (!isCurveFilter) {
@@ -69,8 +69,8 @@
         }
     }
 
-    public void apply(Bitmap bitmap) {
-
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int[] redGradient = null;
         if (mUseRed) {
             redGradient = new int[256];
@@ -89,6 +89,7 @@
 
         nativeApplyGradientFilter(bitmap, bitmap.getWidth(), bitmap.getHeight(),
                 redGradient, greenGradient, blueGradient);
+        return bitmap;
     }
 
     public void setSpline(Spline spline) {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
index 85b6e4f..ee87413 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterExposure.java
@@ -12,11 +12,12 @@
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float bright);
 
     @Override
-    public void apply(Bitmap bitmap) {
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         int p = mParameter;
         float value = p;
         nativeApplyFilter(bitmap, w, h, value);
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterGradient.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterGradient.java
index d27dd34..4fbd086 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterGradient.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterGradient.java
@@ -10,8 +10,6 @@
 import android.graphics.Paint.Style;
 import android.graphics.Shader.TileMode;
 
-import com.android.gallery3d.filtershow.ui.Spline;
-
 public class ImageFilterGradient extends ImageFilter {
 
     private Bitmap mGradientBitmap = null;
@@ -50,8 +48,8 @@
         mPositions = positions;
     }
 
-    public void apply(Bitmap bitmap) {
-
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         createGradient();
         int[] gradient = new int[256];
         int[] redGradient = new int[256];
@@ -66,6 +64,7 @@
         }
         nativeApplyGradientFilter(bitmap, bitmap.getWidth(), bitmap.getHeight(),
                 redGradient, greenGradient, blueGradient);
+        return bitmap;
     }
 
     public void createGradient() {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
index 874e7ec..6f6f9e8 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterHue.java
@@ -20,7 +20,8 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float []matrix);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         float p = mParameter;
@@ -29,5 +30,7 @@
         cmatrix.setHue(value);
 
         nativeApplyFilter(bitmap, w, h, cmatrix.getMatrix());
+
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
index ab2d304..ab92e4e 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
@@ -31,9 +31,10 @@
         mOutPixelsAllocation.copyTo(bitmap);
     }
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         if (bitmap == null) {
-            return;
+            return bitmap;
         }
         try {
             prepare(bitmap);
@@ -45,6 +46,7 @@
         } catch (android.renderscript.RSRuntimeException e) {
             Log.e(LOGTAG, "RS runtime exception ? " + e);
         }
+        return bitmap;
     }
 
     public static RenderScript getRenderScriptContext() {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
index d3db441..9047056 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterSaturated.java
@@ -11,11 +11,13 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float saturation);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         int p = mParameter;
         float value = 1 +  p / 100.0f;
         nativeApplyFilter(bitmap, w, h, value);
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
index 39c9506..9b379a1 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterShadows.java
@@ -11,8 +11,8 @@
     private final float MID = .5f;
     private final float HIGHLIGHT = .9f;
 
-    private float []baseX = {0f,SHADOW,MID,HIGHLIGHT,1f};
-    private float []baseY = {0f,SHADOW,MID,HIGHLIGHT,1f};
+    private final float []baseX = {0f,SHADOW,MID,HIGHLIGHT,1f};
+    private final float []baseY = {0f,SHADOW,MID,HIGHLIGHT,1f};
 
     public ImageFilterShadows() {
         mName = "Shadows";
@@ -50,12 +50,14 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short []valMap);
 
-    public void apply(Bitmap bitmap) {
+    @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());
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java
index 483d901..db85292 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterStraighten.java
@@ -1,16 +1,13 @@
 
 package com.android.gallery3d.filtershow.filters;
 
-import java.nio.ByteBuffer;
-
 import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.graphics.Rect;
 
 public class ImageFilterStraighten extends ImageFilter {
-    private Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
+    private final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
     private float mRotation;
     private float mZoomFactor;
 
@@ -39,7 +36,8 @@
         mZoomFactor = zoomFactor;
     }
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         // TODO: implement bilinear or bicubic here... for now, just use
         // canvas to do a simple implementation...
         // TODO: and be more memory efficient! (do it in native?)
@@ -64,6 +62,7 @@
         temp.recycle();
         temp = null;
         pixels = null;
+        return bitmap;
     }
 
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
index fd437ee..8281573 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVibrance.java
@@ -12,11 +12,13 @@
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float bright);
 
     @Override
-    public void apply(Bitmap bitmap) {
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         int p = mParameter;
         float value = p;
         nativeApplyFilter(bitmap, w, h, value);
+
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
index 24699a2..4c43410 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java
@@ -11,11 +11,14 @@
 
     native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, float strength);
 
-    public void apply(Bitmap bitmap) {
+    @Override
+    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         float p = mParameter;
         float value = p / 100.0f;
         nativeApplyFilter(bitmap, w, h, value);
+
+        return bitmap;
     }
 }
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
index 8dd81d4..c0c3103 100644
--- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
@@ -32,6 +32,9 @@
     protected boolean mVerticalFlip = false;
     protected RectF mCrop = null;
 
+    private float mScaleFactor = 1.0f;
+    private boolean mIsHighQuality = false;
+
     public ImagePreset() {
         setup();
     }
@@ -50,6 +53,9 @@
 
         mStraightenRotate = source.mStraightenRotate;
         mStraightenZoom = source.mStraightenZoom;
+
+        mScaleFactor = source.mScaleFactor;
+        mIsHighQuality = source.mIsHighQuality;
     }
 
     public void setStraightenRotation(float rotate, float zoom) {
@@ -57,7 +63,7 @@
         mStraightenZoom = zoom;
     }
 
-    private Bitmap applyGeometry(Bitmap original) {
+    private Bitmap applyGeometry(Bitmap original, float scaleFactor, boolean highQuality) {
         Bitmap bitmap = original;
 
         if (mFullRotate != FullRotate.ZERO) {
@@ -67,7 +73,7 @@
         if (mStraightenRotate != 0) {
             // TODO: keep the instances around
             ImageFilter straighten = new ImageFilterStraighten(mStraightenRotate, mStraightenZoom);
-            straighten.apply(bitmap);
+            bitmap = straighten.apply(bitmap, scaleFactor, highQuality);
             straighten = null;
         }
 
@@ -154,7 +160,7 @@
 
     public Bitmap apply(Bitmap original) {
         // First we apply any transform -- 90 rotate, flip, straighten, crop
-        Bitmap bitmap = applyGeometry(original);
+        Bitmap bitmap = applyGeometry(original, mScaleFactor, mIsHighQuality);
 
         // TODO -- apply borders separately
         ImageFilter borderFilter = null;
@@ -164,11 +170,11 @@
                 // TODO don't use the name as an id
                 borderFilter = filter;
             } else {
-                filter.apply(bitmap);
+                bitmap = filter.apply(bitmap, mScaleFactor, mIsHighQuality);
             }
         }
         if (borderFilter != null) {
-            borderFilter.apply(bitmap);
+            bitmap = borderFilter.apply(bitmap, mScaleFactor, mIsHighQuality);
         }
         if (mEndPoint != null) {
             mEndPoint.updateFilteredImage(bitmap);
@@ -185,4 +191,19 @@
         imageStateAdapter.notifyDataSetChanged();
     }
 
+    public float getScaleFactor() {
+        return mScaleFactor;
+    }
+
+    public boolean isHighQuality() {
+        return mIsHighQuality;
+    }
+
+    public void setIsHighQuality(boolean value) {
+        mIsHighQuality = value;
+    }
+
+    public void setScaleFactor(float value) {
+        mScaleFactor = value;
+    }
 }
diff --git a/src/com/android/gallery3d/filtershow/tools/ProcessedBitmap.java b/src/com/android/gallery3d/filtershow/tools/ProcessedBitmap.java
index 2e23b92..24e38fb 100644
--- a/src/com/android/gallery3d/filtershow/tools/ProcessedBitmap.java
+++ b/src/com/android/gallery3d/filtershow/tools/ProcessedBitmap.java
@@ -6,13 +6,13 @@
 
 public class ProcessedBitmap {
     private Bitmap mBitmap;
-    private ImagePreset mPreset;
+    private final ImagePreset mPreset;
     public ProcessedBitmap(Bitmap bitmap, ImagePreset preset) {
         mBitmap = bitmap;
         mPreset = preset;
     }
     public Bitmap apply() {
-        mPreset.apply(mBitmap);
+        mBitmap = mPreset.apply(mBitmap);
         return mBitmap;
     }
 }
\ No newline at end of file