// Near Infinity - An Infinity Engine Browser and Editor
// Copyright (C) 2001 - 2005 Jon Olav Hauglid
// See LICENSE.txt for license information
package org.infinity.gui.converter;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.IndexColorModel;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.infinity.gui.ButtonPopupWindow;
import org.infinity.gui.ViewerUtil;
import org.infinity.icon.Icons;
import org.infinity.resource.graphics.PseudoBamDecoder.PseudoBamFrameEntry;
/**
* Color filter: create negatives of each color.
*/
public class BamFilterColorInvert extends BamFilterBaseColor
implements ChangeListener, ActionListener
{
private static final String FilterName = "Invert colors";
private static final String FilterDesc = "This filter inverts the colors of all frames.";
public static String getFilterName() { return FilterName; }
public static String getFilterDesc() { return FilterDesc; }
private ButtonPopupWindow bpwExclude;
private BamFilterBaseColor.ExcludeColorsPanel pExcludeColors;
public BamFilterColorInvert(ConvertToBam parent)
{
super(parent, FilterName, FilterDesc);
}
@Override
public BufferedImage process(BufferedImage frame) throws Exception
{
return applyEffect(frame);
}
@Override
public PseudoBamFrameEntry updatePreview(PseudoBamFrameEntry entry)
{
if (entry != null) {
entry.setFrame(applyEffect(entry.getFrame()));
}
return entry;
}
@Override
public void updateControls()
{
bpwExclude.setEnabled(getConverter().isBamV1Selected());
}
@Override
public String getConfiguration()
{
StringBuilder sb = new StringBuilder();
sb.append(encodeColorList(pExcludeColors.getSelectedIndices()));
return sb.toString();
}
@Override
public boolean setConfiguration(String config)
{
if (config != null) {
config = config.trim();
if (!config.isEmpty()) {
String[] params = config.trim().split(";");
int[] indices = null;
if (params.length > 0) {
indices = decodeColorList(params[0]);
if (indices == null) {
return false;
}
}
if (indices != null) {
pExcludeColors.setSelectedIndices(indices);
}
}
return true;
}
return false;
}
@Override
protected JPanel loadControls()
{
GridBagConstraints c = new GridBagConstraints();
// JLabel l = new JLabel("No settings available.", SwingConstants.CENTER);
JLabel l1 = new JLabel("Exclude colors:");
pExcludeColors = new BamFilterBaseColor.ExcludeColorsPanel(
getConverter().getPaletteDialog().getPalette(getConverter().getPaletteDialog().getPaletteType()));
pExcludeColors.addChangeListener(this);
bpwExclude = new ButtonPopupWindow("Palette", Icons.getIcon(Icons.ICON_ARROW_DOWN_15), pExcludeColors);
bpwExclude.setIconTextGap(8);
bpwExclude.addActionListener(this);
bpwExclude.setEnabled(getConverter().isBamV1Selected());
JPanel pExclude = new JPanel(new GridBagLayout());
ViewerUtil.setGBC(c, 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0);
pExclude.add(l1, c);
ViewerUtil.setGBC(c, 1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START,
GridBagConstraints.NONE, new Insets(0, 8, 0, 0), 0, 0);
pExclude.add(bpwExclude, c);
ViewerUtil.setGBC(c, 2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.LINE_START,
GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0);
pExclude.add(new JPanel(), c);
JPanel panel = new JPanel(new GridBagLayout());
ViewerUtil.setGBC(c, 0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0);
panel.add(pExclude, c);
return panel;
}
//--------------------- Begin Interface ChangeListener ---------------------
@Override
public void stateChanged(ChangeEvent event)
{
if (event.getSource() == pExcludeColors) {
fireChangeListener();
}
}
//--------------------- End Interface ChangeListener ---------------------
//--------------------- Begin Interface ActionListener ---------------------
@Override
public void actionPerformed(ActionEvent event)
{
if (event.getSource() == bpwExclude) {
pExcludeColors.updatePalette(getConverter().getPaletteDialog().getPalette(
getConverter().getPaletteDialog().getPaletteType()));
}
}
//--------------------- End Interface ActionListener ---------------------
private BufferedImage applyEffect(BufferedImage srcImage)
{
if (srcImage != null) {
int[] buffer;
IndexColorModel cm = null;
if (srcImage.getType() == BufferedImage.TYPE_BYTE_INDEXED) {
// paletted image
cm = (IndexColorModel)srcImage.getColorModel();
buffer = new int[1 << cm.getPixelSize()];
cm.getRGBs(buffer);
// applying proper alpha
if (!cm.hasAlpha()) {
final int Green = 0x0000ff00;
boolean greenFound = false;
for (int i = 0; i < buffer.length; i++) {
if (!greenFound && buffer[i] == Green) {
greenFound = true;
buffer[i] &= 0x00ffffff;
} else {
buffer[i] |= 0xff000000;
}
}
}
} else if (srcImage.getRaster().getDataBuffer().getDataType() == DataBuffer.TYPE_INT) {
// truecolor image
buffer = ((DataBufferInt)srcImage.getRaster().getDataBuffer()).getData();
} else {
buffer = new int[0];
}
for (int i = 0; i < buffer.length; i++) {
if ((cm == null || (cm != null && !pExcludeColors.isSelectedIndex(i))) &&
(buffer[i] & 0xff000000) != 0) {
buffer[i] = (buffer[i] & 0xff000000) | (~buffer[i] & 0x00ffffff);
}
}
if (cm != null) {
// recreating paletted image
IndexColorModel cm2 = new IndexColorModel(cm.getPixelSize(), buffer.length, buffer, 0,
cm.hasAlpha(), cm.getTransparentPixel(), DataBuffer.TYPE_BYTE);
int width = srcImage.getWidth();
int height = srcImage.getHeight();
BufferedImage dstImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED, cm2);
byte[] srcPixels = ((DataBufferByte)srcImage.getRaster().getDataBuffer()).getData();
byte[] dstPixels = ((DataBufferByte)dstImage.getRaster().getDataBuffer()).getData();
System.arraycopy(srcPixels, 0, dstPixels, 0, srcPixels.length);
srcImage = dstImage;
srcPixels = null; dstPixels = null;
}
}
return srcImage;
}
}