/* Copyright (C) 2005-2011 Fabio Riccardi */
package com.lightcrafts.model.ImageEditor;
import com.lightcrafts.model.OperationType;
import com.lightcrafts.model.SliderConfig;
import com.lightcrafts.utils.ColorMatrix2;
import com.lightcrafts.jai.utils.Transform;
import com.lightcrafts.jai.JAIContext;
import com.lightcrafts.jai.opimage.IntVibranceOpImage;
import com.lightcrafts.jai.opimage.HueRotateOpImage;
import com.lightcrafts.mediax.jai.*;
import java.awt.image.renderable.ParameterBlock;
import java.text.DecimalFormat;
/**
* Copyright (C) 2007 Light Crafts, Inc.
* User: fabio
* Date: Mar 15, 2005
* Time: 3:33:17 PM
*/
public class HueSaturationOperation extends BlendedOperation {
static final String HUE = "Hue";
static final String SATURATION = "Saturation";
static final String VIBRANCE = "Vibrance";
static final String LUMINOSITY = "Luminosity";
public HueSaturationOperation(Rendering rendering, OperationType type) {
super(rendering, type);
colorInputOnly = true;
if (type != typeV2)
addSliderKey(HUE);
addSliderKey(SATURATION);
if (type != typeV1)
addSliderKey(VIBRANCE);
if (type != typeV2)
addSliderKey(LUMINOSITY);
if (type == typeV2)
addSliderKey(HUE);
DecimalFormat format = new DecimalFormat("0");
setSliderConfig(HUE, new SliderConfig(-180, 180, hue, 1, false, format));
setSliderConfig(SATURATION, new SliderConfig(-100, 100, saturation, 1, false, format));
if (type != typeV1)
setSliderConfig(VIBRANCE, new SliderConfig(-100, 100, vibrance, 1, false, format));
if (type != typeV2)
setSliderConfig(LUMINOSITY, new SliderConfig(-100, 100, intensity, 1, false, format));
}
public boolean neutralDefault() {
return true;
}
static final OperationType typeV1 = new OperationTypeImpl("Hue/Saturation");
static final OperationType typeV2 = new OperationTypeImpl("Hue/Saturation V2");
static final OperationType typeV3 = new OperationTypeImpl("Hue/Saturation V3");
private float hue = 0;
private float saturation = 0;
private float vibrance = 0;
private float intensity = 0;
public void setSliderValue(String key, double value) {
value = roundValue(key, value);
if (key == HUE && hue != value) {
hue = (float) value;
} else if (key == SATURATION && saturation != value) {
saturation = (float) value;
} else if (key == VIBRANCE && vibrance != value) {
vibrance = (float) value;
} else if (key == LUMINOSITY && intensity != value) {
intensity = (float) value;
} else
return;
super.setSliderValue(key, value);
}
private double[][] computeTransform() {
float matrix[][] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
};
if (saturation != 0.0)
ColorMatrix2.saturatemat(matrix, saturation / 100 + 1);
// if (hue != 0.0)
// ColorMatrix2.huerotatemat(matrix, hue);
if (intensity != 0.0) {
float lit = intensity / 100 + 1;
ColorMatrix2.cscalemat(matrix, lit, lit, lit);
}
double transform[][] = new double[3][4];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
transform[i][j] = matrix[j][i];
return transform;
}
private float[][] computeVibranceTransform() {
float matrix[][] = {
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
};
if (vibrance != 0.0)
ColorMatrix2.saturatemat(matrix, vibrance / 100 + 1);
float transform[][] = new float[3][4];
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++)
transform[i][j] = matrix[j][i];
return transform;
}
private class HueSaturation extends BlendedTransform {
HueSaturation(PlanarImage source) {
super(source);
}
public PlanarImage setFront() {
double hslTransform[][] = computeTransform();
ParameterBlock pb = new ParameterBlock();
pb.addSource(back);
pb.add(hslTransform);
PlanarImage image = JAI.create("BandCombine", pb, JAIContext.noCacheHint);
if (vibrance != 0.0)
image = new IntVibranceOpImage(image, computeVibranceTransform(), null);
if (hue != 0.0)
image = new HueRotateOpImage(image, (float) (hue / 360), null);
return image;
}
}
protected void updateOp(Transform op) {
op.update();
}
protected BlendedTransform createBlendedOp(PlanarImage source) {
return new HueSaturation(source);
}
public OperationType getType() {
return type;
}
}