// Near Infinity - An Infinity Engine Browser and Editor // Copyright (C) 2001 - 2005 Jon Olav Hauglid // See LICENSE.txt for license information package org.infinity.resource.graphics; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import org.infinity.gui.ButtonPanel; import org.infinity.gui.RenderCanvas; import org.infinity.resource.Resource; import org.infinity.resource.ResourceFactory; import org.infinity.resource.ViewableContainer; import org.infinity.resource.key.ResourceEntry; import org.infinity.util.DynamicArray; public final class PltResource implements Resource, ActionListener { private static final ButtonPanel.Control CtrlColorList = ButtonPanel.Control.CUSTOM_1; private final ResourceEntry entry; private final ByteBuffer buffer; private final ButtonPanel buttonPanel = new ButtonPanel(); private RenderCanvas rcCanvas; private JPanel panel; public PltResource(ResourceEntry entry) throws Exception { this.entry = entry; buffer = entry.getResourceBuffer(); } // --------------------- Begin Interface ActionListener --------------------- @Override public void actionPerformed(ActionEvent event) { if (buttonPanel.getControlByType(CtrlColorList) == event.getSource()) { rcCanvas.setImage(getImage()); } else if (buttonPanel.getControlByType(ButtonPanel.Control.EXPORT_BUTTON) == event.getSource()) { ResourceFactory.exportResource(entry, panel.getTopLevelAncestor()); } } // --------------------- End Interface ActionListener --------------------- // --------------------- Begin Interface Resource --------------------- @Override public ResourceEntry getResourceEntry() { return entry; } // --------------------- End Interface Resource --------------------- // --------------------- Begin Interface Viewable --------------------- @Override public JComponent makeViewer(ViewableContainer container) { JComboBox<Object> cbColorBMP = new JComboBox<>(); cbColorBMP.addItem("None"); List<ResourceEntry> bmps = ResourceFactory.getResources("BMP"); for (final ResourceEntry re: bmps) { if (re.getResourceName().startsWith("PLT")) { cbColorBMP.addItem(re); } } cbColorBMP.setEditable(false); cbColorBMP.setSelectedIndex(0); cbColorBMP.addActionListener(this); buttonPanel.addControl(new JLabel("Colors: ")); buttonPanel.addControl(cbColorBMP, CtrlColorList); ((JButton)buttonPanel.addControl(ButtonPanel.Control.EXPORT_BUTTON)).addActionListener(this); rcCanvas = new RenderCanvas(getImage()); JScrollPane scroll = new JScrollPane(rcCanvas); panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(scroll, BorderLayout.CENTER); panel.add(buttonPanel, BorderLayout.SOUTH); scroll.setBorder(BorderFactory.createLoweredBevelBorder()); return panel; } // --------------------- End Interface Viewable --------------------- private BufferedImage getImage() { Palette palette = null; Object item = ((JComboBox<?>)buttonPanel.getControlByType(CtrlColorList)).getSelectedItem(); if (!item.toString().equalsIgnoreCase("None")) { try { palette = new GraphicsResource((ResourceEntry)item).getPalette(); } catch (Exception e) { e.printStackTrace(); palette = null; } } int width = buffer.getInt(16); int height = buffer.getInt(20); int offset = 24; BufferedImage image = ColorConvert.createCompatibleImage(width, height, true); for (int y = height - 1; y >= 0; y--) { for (int x = 0; x < width; x++) { short colorIndex = (short)(buffer.get(offset++) & 0xff); short paletteIndex = (short)(buffer.get(offset++) & 0xff); if (palette == null) { short alpha = (short)((colorIndex == 255) ? 0 : 255); image.setRGB(x, y, DynamicArray.getInt(new byte[]{(byte)colorIndex, (byte)colorIndex, (byte)colorIndex, (byte)alpha}, 0)); } else { short colors[] = palette.getColorBytes((int)paletteIndex); double factor = (double)colorIndex / 256.0; for (int i = 0; i < 3; i++) { colors[i] = (short)((double)colors[i] * factor); } colors[3] = (short)((colors[0] == 0 && colors[1] >= 254 && colors[2] == 0) ? 0 : 255); image.setRGB(x, y, DynamicArray.getInt(new byte[]{(byte)colors[0], (byte)colors[1], (byte)colors[2], (byte)colors[3]}, 0)); } } } return image; } }