summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Hoford <hoford@google.com>2013-07-30 14:40:18 -0700
committerJohn Hoford <hoford@google.com>2013-08-01 16:13:52 -0700
commit014bbe68d6e407269a0d843083be56f8df58adba (patch)
treeb3e8d645c4b01057044353340bdf3c24aaf65230
parent203eb404a7cd6a80397535e63d22b3772939f03d (diff)
downloadandroid_packages_apps_Snap-014bbe68d6e407269a0d843083be56f8df58adba.zip
android_packages_apps_Snap-014bbe68d6e407269a0d843083be56f8df58adba.tar.gz
android_packages_apps_Snap-014bbe68d6e407269a0d843083be56f8df58adba.tar.bz2
add Per Channel Saturation
Change-Id: Icfd24c817674b81ac9caecc2d73348dc7734f037
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java2
-rw-r--r--src/com/android/gallery3d/filtershow/controller/BasicParameterInt.java8
-rw-r--r--src/com/android/gallery3d/filtershow/editors/EditorChanSat.java227
-rw-r--r--src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java3
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterChanSatRepresentation.java211
-rw-r--r--src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java1
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterChanSat.java161
-rw-r--r--src/com/android/gallery3d/filtershow/filters/saturation.rs161
-rw-r--r--src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java2
-rw-r--r--src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java1
10 files changed, 774 insertions, 3 deletions
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index f0b1aa8..ab508b6 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -59,6 +59,7 @@ import android.widget.Toast;
import com.android.gallery3d.R;
import com.android.gallery3d.app.PhotoPage;
import com.android.gallery3d.data.LocalAlbum;
+import com.android.gallery3d.filtershow.editors.EditorChanSat;
import com.android.gallery3d.filtershow.editors.EditorGrad;
import com.android.gallery3d.filtershow.data.FilterStackSource;
import com.android.gallery3d.filtershow.data.UserPresetsManager;
@@ -386,6 +387,7 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL
}
private void fillEditors() {
+ mEditorPlaceHolder.addEditor(new EditorChanSat());
mEditorPlaceHolder.addEditor(new EditorGrad());
mEditorPlaceHolder.addEditor(new EditorDraw());
mEditorPlaceHolder.addEditor(new BasicEditor());
diff --git a/src/com/android/gallery3d/filtershow/controller/BasicParameterInt.java b/src/com/android/gallery3d/filtershow/controller/BasicParameterInt.java
index 777bc43..92145e9 100644
--- a/src/com/android/gallery3d/filtershow/controller/BasicParameterInt.java
+++ b/src/com/android/gallery3d/filtershow/controller/BasicParameterInt.java
@@ -45,6 +45,14 @@ public class BasicParameterInt implements ParameterInteger {
ID = id;
mValue = value;
}
+
+ public BasicParameterInt(int id, int value, int min, int max) {
+ ID = id;
+ mValue = value;
+ mMinimum = min;
+ mMaximum = max;
+ }
+
@Override
public String getParameterName() {
return mParameterName;
diff --git a/src/com/android/gallery3d/filtershow/editors/EditorChanSat.java b/src/com/android/gallery3d/filtershow/editors/EditorChanSat.java
new file mode 100644
index 0000000..7e31f09
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/editors/EditorChanSat.java
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+package com.android.gallery3d.filtershow.editors;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.os.Handler;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.LinearLayout;
+import android.widget.PopupMenu;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.controller.BasicParameterStyle;
+import com.android.gallery3d.filtershow.controller.FilterView;
+import com.android.gallery3d.filtershow.controller.Parameter;
+import com.android.gallery3d.filtershow.filters.FilterChanSatRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
+import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.pipeline.ImagePreset;
+import com.android.gallery3d.filtershow.pipeline.RenderingRequest;
+import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller;
+
+public class EditorChanSat extends ParametricEditor implements OnSeekBarChangeListener, FilterView {
+ public static final int ID = R.id.editorChanSat;
+ private final String LOGTAG = "EditorGrunge";
+ private SwapButton mButton;
+ private final Handler mHandler = new Handler();
+
+ int[] mMenuStrings = {
+ R.string.editor_chan_sat_main,
+ R.string.editor_chan_sat_red,
+ R.string.editor_chan_sat_yellow,
+ R.string.editor_chan_sat_green,
+ R.string.editor_chan_sat_cyan,
+ R.string.editor_chan_sat_blue,
+ R.string.editor_chan_sat_magenta
+ };
+
+ String mCurrentlyEditing = null;
+
+ public EditorChanSat() {
+ super(ID, R.layout.filtershow_default_editor, R.id.basicEditor);
+ }
+
+ @Override
+ public String calculateUserMessage(Context context, String effectName, Object parameterValue) {
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep == null || !(rep instanceof FilterChanSatRepresentation)) {
+ return "";
+ }
+ FilterChanSatRepresentation csrep = (FilterChanSatRepresentation) rep;
+ int mode = csrep.getParameterMode();
+ String paramString;
+
+ paramString = mContext.getString(mMenuStrings[mode]);
+
+ int val = csrep.getCurrentParameter();
+ return paramString + ((val > 0) ? " +" : " ") + val;
+ }
+
+ @Override
+ public void openUtilityPanel(final LinearLayout accessoryViewList) {
+ mButton = (SwapButton) accessoryViewList.findViewById(R.id.applyEffect);
+ mButton.setText(mContext.getString(R.string.editor_chan_sat_main));
+
+ final PopupMenu popupMenu = new PopupMenu(mImageShow.getActivity(), mButton);
+
+ popupMenu.getMenuInflater().inflate(R.menu.filtershow_menu_chan_sat, popupMenu.getMenu());
+
+ popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ selectMenuItem(item);
+ return true;
+ }
+ });
+ mButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View arg0) {
+ popupMenu.show();
+ }
+ });
+ mButton.setListener(this);
+
+ FilterChanSatRepresentation csrep = getChanSatRep();
+ String menuString = mContext.getString(mMenuStrings[0]);
+ switchToMode(csrep, FilterChanSatRepresentation.MODE_MASTER, menuString);
+
+ }
+
+ public int getParameterIndex(int id) {
+ switch (id) {
+ case R.id.editor_chan_sat_main:
+ return FilterChanSatRepresentation.MODE_MASTER;
+ case R.id.editor_chan_sat_red:
+ return FilterChanSatRepresentation.MODE_RED;
+ case R.id.editor_chan_sat_yellow:
+ return FilterChanSatRepresentation.MODE_YELLOW;
+ case R.id.editor_chan_sat_green:
+ return FilterChanSatRepresentation.MODE_GREEN;
+ case R.id.editor_chan_sat_cyan:
+ return FilterChanSatRepresentation.MODE_CYAN;
+ case R.id.editor_chan_sat_blue:
+ return FilterChanSatRepresentation.MODE_BLUE;
+ case R.id.editor_chan_sat_magenta:
+ return FilterChanSatRepresentation.MODE_MAGENTA;
+ }
+ return -1;
+ }
+
+ @Override
+ public void detach() {
+ mButton.setListener(null);
+ mButton.setOnClickListener(null);
+ }
+
+ private void updateSeekBar(FilterChanSatRepresentation rep) {
+ mControl.updateUI();
+ }
+
+ @Override
+ protected Parameter getParameterToEdit(FilterRepresentation rep) {
+ if (rep instanceof FilterChanSatRepresentation) {
+ FilterChanSatRepresentation csrep = (FilterChanSatRepresentation) rep;
+ Parameter param = csrep.getFilterParameter(csrep.getParameterMode());
+ if (param instanceof BasicParameterStyle) {
+ param.setFilterView(EditorChanSat.this);
+ }
+ return param;
+ }
+ return null;
+ }
+
+ private FilterChanSatRepresentation getChanSatRep() {
+ FilterRepresentation rep = getLocalRepresentation();
+ if (rep != null
+ && rep instanceof FilterChanSatRepresentation) {
+ FilterChanSatRepresentation csrep = (FilterChanSatRepresentation) rep;
+ return csrep;
+ }
+ return null;
+ }
+
+ @Override
+ public void computeIcon(int n, RenderingRequestCaller caller) {
+ FilterChanSatRepresentation rep = getChanSatRep();
+ if (rep == null) return;
+ rep = (FilterChanSatRepresentation) rep.copy();
+ ImagePreset preset = new ImagePreset();
+ preset.addFilter(rep);
+ Bitmap src = MasterImage.getImage().getThumbnailBitmap();
+ RenderingRequest.post(null, src, preset, RenderingRequest.STYLE_ICON_RENDERING,
+ caller);
+ }
+
+ protected void selectMenuItem(MenuItem item) {
+ if (getLocalRepresentation() != null
+ && getLocalRepresentation() instanceof FilterChanSatRepresentation) {
+ FilterChanSatRepresentation csrep =
+ (FilterChanSatRepresentation) getLocalRepresentation();
+
+ switchToMode(csrep, getParameterIndex(item.getItemId()), item.getTitle().toString());
+
+ }
+ }
+
+ protected void switchToMode(FilterChanSatRepresentation csrep, int mode, String title) {
+ csrep.setParameterMode(mode);
+ mCurrentlyEditing = title;
+ mButton.setText(mCurrentlyEditing);
+ {
+ Parameter param = getParameterToEdit(csrep);
+
+ control(param, mEditControl);
+ }
+ updateSeekBar(csrep);
+ mView.invalidate();
+ }
+
+ @Override
+ public void swapLeft(MenuItem item) {
+ super.swapLeft(item);
+ mButton.setTranslationX(0);
+ mButton.animate().translationX(mButton.getWidth()).setDuration(SwapButton.ANIM_DURATION);
+ Runnable updateButton = new Runnable() {
+ @Override
+ public void run() {
+ mButton.animate().cancel();
+ mButton.setTranslationX(0);
+ }
+ };
+ mHandler.postDelayed(updateButton, SwapButton.ANIM_DURATION);
+ selectMenuItem(item);
+ }
+
+ @Override
+ public void swapRight(MenuItem item) {
+ super.swapRight(item);
+ mButton.setTranslationX(0);
+ mButton.animate().translationX(-mButton.getWidth()).setDuration(SwapButton.ANIM_DURATION);
+ Runnable updateButton = new Runnable() {
+ @Override
+ public void run() {
+ mButton.animate().cancel();
+ mButton.setTranslationX(0);
+ }
+ };
+ mHandler.postDelayed(updateButton, SwapButton.ANIM_DURATION);
+ selectMenuItem(item);
+ }
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
index 4708abb..3fa9191 100644
--- a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
+++ b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java
@@ -133,6 +133,7 @@ public abstract class BaseFiltersManager implements FiltersManagerInterface {
filters.add(ImageFilterCurves.class);
filters.add(ImageFilterDraw.class);
filters.add(ImageFilterHue.class);
+ filters.add(ImageFilterChanSat.class);
filters.add(ImageFilterSaturated.class);
filters.add(ImageFilterBwFilter.class);
filters.add(ImageFilterNegative.class);
@@ -232,7 +233,7 @@ public abstract class BaseFiltersManager implements FiltersManagerInterface {
mEffects.add(getRepresentation(ImageFilterSharpen.class));
mEffects.add(getRepresentation(ImageFilterCurves.class));
mEffects.add(getRepresentation(ImageFilterHue.class));
- mEffects.add(getRepresentation(ImageFilterSaturated.class));
+ mEffects.add(getRepresentation(ImageFilterChanSat.class));
mEffects.add(getRepresentation(ImageFilterBwFilter.class));
mEffects.add(getRepresentation(ImageFilterNegative.class));
mEffects.add(getRepresentation(ImageFilterEdge.class));
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterChanSatRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterChanSatRepresentation.java
new file mode 100644
index 0000000..7ce67dd
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/FilterChanSatRepresentation.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package com.android.gallery3d.filtershow.filters;
+
+import android.util.JsonReader;
+import android.util.JsonWriter;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.controller.BasicParameterInt;
+import com.android.gallery3d.filtershow.controller.Parameter;
+import com.android.gallery3d.filtershow.controller.ParameterSet;
+import com.android.gallery3d.filtershow.editors.EditorChanSat;
+import com.android.gallery3d.filtershow.imageshow.ControlPoint;
+import com.android.gallery3d.filtershow.imageshow.Spline;
+
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * Representation for a filter that has per channel & Master saturation
+ */
+public class FilterChanSatRepresentation extends FilterRepresentation implements ParameterSet {
+ private static final String LOGTAG = "FilterChanSatRepresentation";
+ private static final String ARGS = "ARGS";
+ private static final String SERIALIZATION_NAME = "channelsaturation";
+
+ public static final int MODE_MASTER = 0;
+ public static final int MODE_RED = 1;
+ public static final int MODE_YELLOW = 2;
+ public static final int MODE_GREEN = 3;
+ public static final int MODE_CYAN = 4;
+ public static final int MODE_BLUE = 5;
+ public static final int MODE_MAGENTA = 6;
+ private int mParameterMode = MODE_MASTER;
+
+ private static int MINSAT = -100;
+ private static int MAXSAT = 100;
+ private BasicParameterInt mParamMaster = new BasicParameterInt(MODE_MASTER, 0, MINSAT, MAXSAT);
+ private BasicParameterInt mParamRed = new BasicParameterInt(MODE_RED, 0, MINSAT, MAXSAT);
+ private BasicParameterInt mParamYellow = new BasicParameterInt(MODE_YELLOW, 0, MINSAT, MAXSAT);
+ private BasicParameterInt mParamGreen = new BasicParameterInt(MODE_GREEN, 0, MINSAT, MAXSAT);
+ private BasicParameterInt mParamCyan = new BasicParameterInt(MODE_CYAN, 0, MINSAT, MAXSAT);
+ private BasicParameterInt mParamBlue = new BasicParameterInt(MODE_BLUE, 0, MINSAT, MAXSAT);
+ private BasicParameterInt mParamMagenta = new BasicParameterInt(MODE_MAGENTA, 0, MINSAT, MAXSAT);
+
+ private BasicParameterInt[] mAllParam = {
+ mParamMaster,
+ mParamRed,
+ mParamYellow,
+ mParamGreen,
+ mParamCyan,
+ mParamBlue,
+ mParamMagenta};
+
+ public FilterChanSatRepresentation() {
+ super("ChannelSaturation");
+ setTextId(R.string.saturation);
+ setFilterType(FilterRepresentation.TYPE_NORMAL);
+ setSerializationName(SERIALIZATION_NAME);
+ setFilterClass(ImageFilterChanSat.class);
+ setEditorId(EditorChanSat.ID);
+ }
+
+ public String toString() {
+ return getName() + " : " + mParamRed + ", " + mParamCyan + ", " + mParamRed
+ + ", " + mParamGreen + ", " + mParamMaster + ", " + mParamYellow;
+ }
+
+ @Override
+ public FilterRepresentation copy() {
+ FilterChanSatRepresentation representation = new FilterChanSatRepresentation();
+ copyAllParameters(representation);
+ return representation;
+ }
+
+ @Override
+ protected void copyAllParameters(FilterRepresentation representation) {
+ super.copyAllParameters(representation);
+ representation.useParametersFrom(this);
+ }
+
+ public void useParametersFrom(FilterRepresentation a) {
+ if (a instanceof FilterChanSatRepresentation) {
+ FilterChanSatRepresentation representation = (FilterChanSatRepresentation) a;
+
+ for (int i = 0; i < mAllParam.length; i++) {
+ mAllParam[i].copyFrom(representation.mAllParam[i]);
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(FilterRepresentation representation) {
+ if (!super.equals(representation)) {
+ return false;
+ }
+ if (representation instanceof FilterChanSatRepresentation) {
+ FilterChanSatRepresentation rep = (FilterChanSatRepresentation) representation;
+ for (int i = 0; i < mAllParam.length; i++) {
+ if (rep.getValue(i) != getValue(i))
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ public int getValue(int mode) {
+ return mAllParam[mode].getValue();
+ }
+
+ public void setValue(int mode, int value) {
+ mAllParam[mode].setValue(value);
+ }
+
+ public int getMinimum() {
+ return mParamMaster.getMinimum();
+ }
+
+ public int getMaximum() {
+ return mParamMaster.getMaximum();
+ }
+
+ public int getParameterMode() {
+ return mParameterMode;
+ }
+
+ public void setParameterMode(int parameterMode) {
+ mParameterMode = parameterMode;
+ }
+
+ public int getCurrentParameter() {
+ return getValue(mParameterMode);
+ }
+
+ public void setCurrentParameter(int value) {
+ setValue(mParameterMode, value);
+ }
+
+ @Override
+ public int getNumberOfParameters() {
+ return 6;
+ }
+
+ @Override
+ public Parameter getFilterParameter(int index) {
+ return mAllParam[index];
+ }
+
+ @Override
+ public void serializeRepresentation(JsonWriter writer) throws IOException {
+ writer.beginObject();
+
+ writer.name(ARGS);
+ writer.beginArray();
+ writer.value(getValue(MODE_MASTER));
+ writer.value(getValue(MODE_RED));
+ writer.value(getValue(MODE_YELLOW));
+ writer.value(getValue(MODE_GREEN));
+ writer.value(getValue(MODE_CYAN));
+ writer.value(getValue(MODE_BLUE));
+ writer.value(getValue(MODE_MAGENTA));
+ writer.endArray();
+ writer.endObject();
+ }
+
+ @Override
+ public void deSerializeRepresentation(JsonReader sreader) throws IOException {
+ sreader.beginObject();
+
+ while (sreader.hasNext()) {
+ String name = sreader.nextName();
+ if (name.startsWith(ARGS)) {
+ sreader.beginArray();
+ sreader.hasNext();
+ setValue(MODE_MASTER, sreader.nextInt());
+ sreader.hasNext();
+ setValue(MODE_RED, sreader.nextInt());
+ sreader.hasNext();
+ setValue(MODE_YELLOW, sreader.nextInt());
+ sreader.hasNext();
+ setValue(MODE_GREEN, sreader.nextInt());
+ sreader.hasNext();
+ setValue(MODE_CYAN, sreader.nextInt());
+ sreader.hasNext();
+ setValue(MODE_BLUE, sreader.nextInt());
+ sreader.hasNext();
+ setValue(MODE_MAGENTA, sreader.nextInt());
+ sreader.hasNext();
+ sreader.endArray();
+ } else {
+ sreader.skipValue();
+ }
+ }
+ sreader.endObject();
+ }
+} \ No newline at end of file
diff --git a/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java
index 64e7fb0..0c272d4 100644
--- a/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java
+++ b/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java
@@ -419,7 +419,6 @@ public class FilterGradRepresentation extends FilterRepresentation
public float getPoint1Y() {
return mCurrentBand.yPos1;
}
-
@Override
public float getPoint2X() {
return mCurrentBand.xPos2;
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterChanSat.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterChanSat.java
new file mode 100644
index 0000000..1ea8edf
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterChanSat.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+package com.android.gallery3d.filtershow.filters;
+
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.support.v8.renderscript.Allocation;
+import android.support.v8.renderscript.Element;
+import android.support.v8.renderscript.RenderScript;
+import android.support.v8.renderscript.Script.LaunchOptions;
+import android.support.v8.renderscript.Type;
+
+import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.pipeline.FilterEnvironment;
+
+public class ImageFilterChanSat extends ImageFilterRS {
+ private static final String LOGTAG = "ImageFilterChanSat";
+ private ScriptC_saturation mScript;
+ private Bitmap mSourceBitmap;
+
+ private static final int STRIP_SIZE = 64;
+
+ FilterChanSatRepresentation mParameters = new FilterChanSatRepresentation();
+ private Bitmap mOverlayBitmap;
+
+ public ImageFilterChanSat() {
+ mName = "ChannelSat";
+ }
+
+ @Override
+ public FilterRepresentation getDefaultRepresentation() {
+ return new FilterChanSatRepresentation();
+ }
+
+ @Override
+ public void useRepresentation(FilterRepresentation representation) {
+ mParameters = (FilterChanSatRepresentation) representation;
+ }
+
+ @Override
+ protected void resetAllocations() {
+
+ }
+
+ @Override
+ public void resetScripts() {
+ if (mScript != null) {
+ mScript.destroy();
+ mScript = null;
+ }
+ }
+ @Override
+ protected void createFilter(android.content.res.Resources res, float scaleFactor,
+ int quality) {
+ createFilter(res, scaleFactor, quality, getInPixelsAllocation());
+ }
+
+ @Override
+ protected void createFilter(android.content.res.Resources res, float scaleFactor,
+ int quality, Allocation in) {
+ RenderScript rsCtx = getRenderScriptContext();
+
+ Type.Builder tb_float = new Type.Builder(rsCtx, Element.F32_4(rsCtx));
+ tb_float.setX(in.getType().getX());
+ tb_float.setY(in.getType().getY());
+ mScript = new ScriptC_saturation(rsCtx, res, R.raw.saturation);
+ }
+
+
+ private Bitmap getSourceBitmap() {
+ assert (mSourceBitmap != null);
+ return mSourceBitmap;
+ }
+
+ @Override
+ public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
+ if (SIMPLE_ICONS && FilterEnvironment.QUALITY_ICON == quality) {
+ return bitmap;
+ }
+
+ mSourceBitmap = bitmap;
+ Bitmap ret = super.apply(bitmap, scaleFactor, quality);
+ mSourceBitmap = null;
+
+ return ret;
+ }
+
+ @Override
+ protected void bindScriptValues() {
+ int width = getInPixelsAllocation().getType().getX();
+ int height = getInPixelsAllocation().getType().getY();
+ }
+
+
+
+ @Override
+ protected void runFilter() {
+ int []sat = new int[7];
+ for(int i = 0;i<sat.length ;i ++){
+ sat[i] = mParameters.getValue(i);
+ }
+
+
+ int width = getInPixelsAllocation().getType().getX();
+ int height = getInPixelsAllocation().getType().getY();
+ Matrix m = getOriginalToScreenMatrix(width, height);
+
+
+ mScript.set_saturation(sat);
+
+ mScript.invoke_setupGradParams();
+ runSelectiveAdjust(
+ getInPixelsAllocation(), getOutPixelsAllocation());
+
+ }
+
+ private void runSelectiveAdjust(Allocation in, Allocation out) {
+ int width = in.getType().getX();
+ int height = in.getType().getY();
+
+ LaunchOptions options = new LaunchOptions();
+ int ty;
+ options.setX(0, width);
+
+ for (ty = 0; ty < height; ty += STRIP_SIZE) {
+ int endy = ty + STRIP_SIZE;
+ if (endy > height) {
+ endy = height;
+ }
+ options.setY(ty, endy);
+ mScript.forEach_selectiveAdjust(in, out, options);
+ if (checkStop()) {
+ return;
+ }
+ }
+ }
+
+ private boolean checkStop() {
+ RenderScript rsCtx = getRenderScriptContext();
+ rsCtx.finish();
+ if (getEnvironment().needsStop()) {
+ return true;
+ }
+ return false;
+ }
+}
+
diff --git a/src/com/android/gallery3d/filtershow/filters/saturation.rs b/src/com/android/gallery3d/filtershow/filters/saturation.rs
new file mode 100644
index 0000000..5210e34
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/saturation.rs
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2012 Unknown
+ *
+ * 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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(com.android.gallery3d.filtershow.filters)
+
+#define MAX_CHANELS 7
+#define MAX_HUE 4096
+static const int ABITS = 4;
+static const int HSCALE = 256;
+static const int k1=255 << ABITS;
+static const int k2=HSCALE << ABITS;
+
+static const float Rf = 0.2999f;
+static const float Gf = 0.587f;
+static const float Bf = 0.114f;
+
+rs_matrix3x3 colorMatrix_min;
+rs_matrix3x3 colorMatrix_max;
+
+int mNumberOfLines;
+// input data
+int saturation[MAX_CHANELS];
+float sat[MAX_CHANELS];
+
+float satLut[MAX_HUE];
+// generated data
+
+
+void setupGradParams() {
+
+ int master = saturation[0];
+ int max = master+saturation[1];
+ int min = max;
+
+ // calculate the minimum and maximum saturation
+ for (int i = 1; i < MAX_CHANELS; i++) {
+ int v = master+saturation[i];
+ if (max < v) {
+ max = v;
+ }
+ else if (min > v) {
+ min = v;
+ }
+ }
+ // generate a lookup table for all hue 0 to 4K which goes from 0 to 1 0=min sat 1 = max sat
+ min = min - 1;
+ for(int i = 0; i < MAX_HUE ; i++) {
+ float p = i * 6 / (float)MAX_HUE;
+ int ip = ((int)(p + .5f)) % 6;
+ int v = master + saturation[ip + 1];
+ satLut[i] = (v - min)/(float)(max - min);
+ }
+
+ float S = 1 + max / 100.f;
+ float MS = 1 - S;
+ float Rt = Rf * MS;
+ float Gt = Gf * MS;
+ float Bt = Bf * MS;
+ float b = 1.f;
+
+ // Generate 2 color matrix one at min sat and one at max
+ rsMatrixSet(&colorMatrix_max, 0, 0, b * (Rt + S));
+ rsMatrixSet(&colorMatrix_max, 1, 0, b * Gt);
+ rsMatrixSet(&colorMatrix_max, 2, 0, b * Bt);
+ rsMatrixSet(&colorMatrix_max, 0, 1, b * Rt);
+ rsMatrixSet(&colorMatrix_max, 1, 1, b * (Gt + S));
+ rsMatrixSet(&colorMatrix_max, 2, 1, b * Bt);
+ rsMatrixSet(&colorMatrix_max, 0, 2, b * Rt);
+ rsMatrixSet(&colorMatrix_max, 1, 2, b * Gt);
+ rsMatrixSet(&colorMatrix_max, 2, 2, b * (Bt + S));
+
+ S = 1 + min / 100.f;
+ MS = 1-S;
+ Rt = Rf * MS;
+ Gt = Gf * MS;
+ Bt = Bf * MS;
+ b = 1;
+
+ rsMatrixSet(&colorMatrix_min, 0, 0, b * (Rt + S));
+ rsMatrixSet(&colorMatrix_min, 1, 0, b * Gt);
+ rsMatrixSet(&colorMatrix_min, 2, 0, b * Bt);
+ rsMatrixSet(&colorMatrix_min, 0, 1, b * Rt);
+ rsMatrixSet(&colorMatrix_min, 1, 1, b * (Gt + S));
+ rsMatrixSet(&colorMatrix_min, 2, 1, b * Bt);
+ rsMatrixSet(&colorMatrix_min, 0, 2, b * Rt);
+ rsMatrixSet(&colorMatrix_min, 1, 2, b * Gt);
+ rsMatrixSet(&colorMatrix_min, 2, 2, b * (Bt + S));
+}
+
+static ushort rgb2hue( uchar4 rgb)
+{
+ int iMin,iMax,chroma;
+
+ int ri = rgb.r;
+ int gi = rgb.g;
+ int bi = rgb.b;
+ short rv,rs,rh;
+
+ if (ri > gi) {
+ iMax = max (ri, bi);
+ iMin = min (gi, bi);
+ } else {
+ iMax = max (gi, bi);
+ iMin = min (ri, bi);
+ }
+
+ rv = (short) (iMax << ABITS);
+
+ if (rv == 0) {
+ return 0;
+ }
+
+ chroma = iMax - iMin;
+ rs = (short) ((k1 * chroma) / iMax);
+ if (rs == 0) {
+ return 0;
+ }
+
+ if ( ri == iMax ) {
+ rh = (short) ((k2 * (6 * chroma + gi - bi))/(6 * chroma));
+ if (rh >= k2) {
+ rh -= k2;
+ }
+ return rh;
+ }
+
+ if (gi == iMax) {
+ return(short) ((k2 * (2 * chroma + bi - ri)) / (6 * chroma));
+ }
+
+ return (short) ((k2 * (4 * chroma + ri - gi)) / (6 * chroma));
+}
+
+uchar4 __attribute__((kernel)) selectiveAdjust(const uchar4 in, uint32_t x,
+ uint32_t y) {
+ float4 pixel = rsUnpackColor8888(in);
+
+ float4 wsum = pixel;
+ int hue = rgb2hue(in);
+
+ float t = satLut[hue];
+ pixel.xyz = rsMatrixMultiply(&colorMatrix_min ,pixel.xyz) * (1 - t) +
+ t * (rsMatrixMultiply(&colorMatrix_max ,pixel.xyz));
+
+ pixel.a = 1.0f;
+ return rsPackColorTo8888(clamp(pixel, 0.f, 1.0f));
+} \ No newline at end of file
diff --git a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java
index 64643e4..d34216a 100644
--- a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java
@@ -613,7 +613,7 @@ public class ImagePreset {
writer.endObject();
} catch (IOException e) {
- e.printStackTrace();
+ Log.e(LOGTAG,"Error encoding JASON",e);
}
}
diff --git a/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java b/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
index 8ea21ad..3266425 100644
--- a/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
+++ b/src_pd/com/android/gallery3d/filtershow/editors/EditorManager.java
@@ -25,6 +25,7 @@ public class EditorManager {
public static void addEditors(EditorPlaceHolder editorPlaceHolder) {
editorPlaceHolder.addEditor(new EditorGrad());
+ editorPlaceHolder.addEditor(new EditorChanSat());
editorPlaceHolder.addEditor(new EditorZoom());
editorPlaceHolder.addEditor(new EditorCurves());
editorPlaceHolder.addEditor(new EditorTinyPlanet());