blob: 928c3eae9bc12f4364231afc4908ff9c9638a10d [file] [log] [blame]
/*
* 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.Rect;
import android.util.JsonReader;
import android.util.JsonWriter;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.editors.EditorGrad;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.imageshow.Line;
import java.io.IOException;
import java.util.Vector;
public class FilterGradRepresentation extends FilterRepresentation
implements Line {
private static final String LOGTAG = "FilterGradRepresentation";
public static final int MAX_POINTS = 16;
public static final int PARAM_BRIGHTNESS = 0;
public static final int PARAM_SATURATION = 1;
public static final int PARAM_CONTRAST = 2;
private static final double ADD_MIN_DIST = .05;
private static String LINE_NAME = "Point";
private static final String SERIALIZATION_NAME = "grad";
public FilterGradRepresentation() {
super("Grad");
setSerializationName(SERIALIZATION_NAME);
creatExample();
setOverlayId(R.drawable.filtershow_button_grad);
setFilterClass(ImageFilterGrad.class);
setTextId(R.string.grad);
setEditorId(EditorGrad.ID);
}
public void trimVector(){
int n = mBands.size();
for (int i = n; i < MAX_POINTS; i++) {
mBands.add(new Band());
}
for (int i = MAX_POINTS; i < n; i++) {
mBands.remove(i);
}
}
Vector<Band> mBands = new Vector<Band>();
Band mCurrentBand;
static class Band {
private boolean mask = true;
private int xPos1 = -1;
private int yPos1 = 100;
private int xPos2 = -1;
private int yPos2 = 100;
private int brightness = -40;
private int contrast = 0;
private int saturation = 0;
public Band() {
}
public Band(int x, int y) {
xPos1 = x;
yPos1 = y+30;
xPos2 = x;
yPos2 = y-30;
}
public Band(Band copy) {
mask = copy.mask;
xPos1 = copy.xPos1;
yPos1 = copy.yPos1;
xPos2 = copy.xPos2;
yPos2 = copy.yPos2;
brightness = copy.brightness;
contrast = copy.contrast;
saturation = copy.saturation;
}
}
@Override
public String toString() {
int count = 0;
for (Band point : mBands) {
if (!point.mask) {
count++;
}
}
return "c=" + mBands.indexOf(mCurrentBand) + "[" + mBands.size() + "]" + count;
}
private void creatExample() {
Band p = new Band();
p.mask = false;
p.xPos1 = -1;
p.yPos1 = 100;
p.xPos2 = -1;
p.yPos2 = 100;
p.brightness = -50;
p.contrast = 0;
p.saturation = 0;
mBands.add(0, p);
mCurrentBand = p;
trimVector();
}
@Override
public void useParametersFrom(FilterRepresentation a) {
FilterGradRepresentation rep = (FilterGradRepresentation) a;
Vector<Band> tmpBands = new Vector<Band>();
int n = (rep.mCurrentBand == null) ? 0 : rep.mBands.indexOf(rep.mCurrentBand);
for (Band band : rep.mBands) {
tmpBands.add(new Band(band));
}
mCurrentBand = null;
mBands = tmpBands;
mCurrentBand = mBands.elementAt(n);
}
@Override
public FilterRepresentation copy() {
FilterGradRepresentation representation = new FilterGradRepresentation();
copyAllParameters(representation);
return representation;
}
@Override
protected void copyAllParameters(FilterRepresentation representation) {
super.copyAllParameters(representation);
representation.useParametersFrom(this);
}
@Override
public boolean equals(FilterRepresentation representation) {
if (representation instanceof FilterGradRepresentation) {
FilterGradRepresentation rep = (FilterGradRepresentation) representation;
int n = getNumberOfBands();
if (rep.getNumberOfBands() != n) {
return false;
}
for (int i = 0; i < mBands.size(); i++) {
Band b1 = mBands.get(i);
Band b2 = rep.mBands.get(i);
if (b1.mask != b2.mask
|| b1.brightness != b2.brightness
|| b1.contrast != b2.contrast
|| b1.saturation != b2.saturation
|| b1.xPos1 != b2.xPos1
|| b1.xPos2 != b2.xPos2
|| b1.yPos1 != b2.yPos1
|| b1.yPos2 != b2.yPos2) {
return false;
}
}
return true;
}
return false;
}
public int getNumberOfBands() {
int count = 0;
for (Band point : mBands) {
if (!point.mask) {
count++;
}
}
return count;
}
public int addBand(Rect rect) {
mBands.add(0, mCurrentBand = new Band(rect.centerX(), rect.centerY()));
mCurrentBand.mask = false;
int x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2;
int y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2;
double addDelta = ADD_MIN_DIST * Math.max(rect.width(), rect.height());
boolean moved = true;
int count = 0;
int toMove = mBands.indexOf(mCurrentBand);
while (moved) {
moved = false;
count++;
if (count > 14) {
break;
}
for (Band point : mBands) {
if (point.mask) {
break;
}
}
for (Band point : mBands) {
if (point.mask) {
break;
}
int index = mBands.indexOf(point);
if (toMove != index) {
double dist = Math.hypot(point.xPos1 - x, point.yPos1 - y);
if (dist < addDelta) {
moved = true;
mCurrentBand.xPos1 += addDelta;
mCurrentBand.yPos1 += addDelta;
mCurrentBand.xPos2 += addDelta;
mCurrentBand.yPos2 += addDelta;
x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2;
y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2;
if (mCurrentBand.yPos1 > rect.bottom) {
mCurrentBand.yPos1 = (int) (rect.top + addDelta);
}
if (mCurrentBand.xPos1 > rect.right) {
mCurrentBand.xPos1 = (int) (rect.left + addDelta);
}
}
}
}
}
trimVector();
return 0;
}
public void deleteCurrentBand() {
int index = mBands.indexOf(mCurrentBand);
mBands.remove(mCurrentBand);
trimVector();
if (getNumberOfBands() == 0) {
addBand(MasterImage.getImage().getOriginalBounds());
}
mCurrentBand = mBands.get(0);
}
public void nextPoint(){
int index = mBands.indexOf(mCurrentBand);
int tmp = index;
Band point;
int k = 0;
do {
index = (index+1)% mBands.size();
point = mBands.get(index);
if (k++ >= mBands.size()) {
break;
}
}
while (point.mask == true);
mCurrentBand = mBands.get(index);
}
public void setSelectedPoint(int pos) {
mCurrentBand = mBands.get(pos);
}
public int getSelectedPoint() {
return mBands.indexOf(mCurrentBand);
}
public boolean[] getMask() {
boolean[] ret = new boolean[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = !point.mask;
}
return ret;
}
public int[] getXPos1() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.xPos1;
}
return ret;
}
public int[] getYPos1() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.yPos1;
}
return ret;
}
public int[] getXPos2() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.xPos2;
}
return ret;
}
public int[] getYPos2() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.yPos2;
}
return ret;
}
public int[] getBrightness() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.brightness;
}
return ret;
}
public int[] getContrast() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.contrast;
}
return ret;
}
public int[] getSaturation() {
int[] ret = new int[mBands.size()];
int i = 0;
for (Band point : mBands) {
ret[i++] = point.saturation;
}
return ret;
}
public int getParameter(int type) {
switch (type){
case PARAM_BRIGHTNESS:
return mCurrentBand.brightness;
case PARAM_SATURATION:
return mCurrentBand.saturation;
case PARAM_CONTRAST:
return mCurrentBand.contrast;
}
throw new IllegalArgumentException("no such type " + type);
}
public int getParameterMax(int type) {
switch (type) {
case PARAM_BRIGHTNESS:
return 100;
case PARAM_SATURATION:
return 100;
case PARAM_CONTRAST:
return 100;
}
throw new IllegalArgumentException("no such type " + type);
}
public int getParameterMin(int type) {
switch (type) {
case PARAM_BRIGHTNESS:
return -100;
case PARAM_SATURATION:
return -100;
case PARAM_CONTRAST:
return -100;
}
throw new IllegalArgumentException("no such type " + type);
}
public void setParameter(int type, int value) {
mCurrentBand.mask = false;
switch (type) {
case PARAM_BRIGHTNESS:
mCurrentBand.brightness = value;
break;
case PARAM_SATURATION:
mCurrentBand.saturation = value;
break;
case PARAM_CONTRAST:
mCurrentBand.contrast = value;
break;
default:
throw new IllegalArgumentException("no such type " + type);
}
}
@Override
public void setPoint1(float x, float y) {
mCurrentBand.xPos1 = (int)x;
mCurrentBand.yPos1 = (int)y;
}
@Override
public void setPoint2(float x, float y) {
mCurrentBand.xPos2 = (int)x;
mCurrentBand.yPos2 = (int)y;
}
@Override
public float getPoint1X() {
return mCurrentBand.xPos1;
}
@Override
public float getPoint1Y() {
return mCurrentBand.yPos1;
}
@Override
public float getPoint2X() {
return mCurrentBand.xPos2;
}
@Override
public float getPoint2Y() {
return mCurrentBand.yPos2;
}
@Override
public void serializeRepresentation(JsonWriter writer) throws IOException {
writer.beginObject();
int len = mBands.size();
int count = 0;
for (int i = 0; i < len; i++) {
Band point = mBands.get(i);
if (point.mask) {
continue;
}
writer.name(LINE_NAME + count);
count++;
writer.beginArray();
writer.value(point.xPos1);
writer.value(point.yPos1);
writer.value(point.xPos2);
writer.value(point.yPos2);
writer.value(point.brightness);
writer.value(point.contrast);
writer.value(point.saturation);
writer.endArray();
}
writer.endObject();
}
@Override
public void deSerializeRepresentation(JsonReader sreader) throws IOException {
sreader.beginObject();
Vector<Band> points = new Vector<Band>();
while (sreader.hasNext()) {
String name = sreader.nextName();
if (name.startsWith(LINE_NAME)) {
int pointNo = Integer.parseInt(name.substring(LINE_NAME.length()));
sreader.beginArray();
Band p = new Band();
p.mask = false;
sreader.hasNext();
p.xPos1 = sreader.nextInt();
sreader.hasNext();
p.yPos1 = sreader.nextInt();
sreader.hasNext();
p.xPos2 = sreader.nextInt();
sreader.hasNext();
p.yPos2 = sreader.nextInt();
sreader.hasNext();
p.brightness = sreader.nextInt();
sreader.hasNext();
p.contrast = sreader.nextInt();
sreader.hasNext();
p.saturation = sreader.nextInt();
sreader.hasNext();
sreader.endArray();
points.add(p);
} else {
sreader.skipValue();
}
}
mBands = points;
trimVector();
mCurrentBand = mBands.get(0);
sreader.endObject();
}
}