replacing images

This commit is contained in:
Jindra Petk
2013-05-01 15:01:05 +02:00
parent ee11a7e03f
commit 602cea1bbe
12 changed files with 1184 additions and 794 deletions

View File

@@ -52,12 +52,6 @@ import com.jpexs.decompiler.flash.gui.TagNode;
import com.jpexs.decompiler.flash.helpers.Helper;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag;
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag;
import com.jpexs.decompiler.flash.tags.DefineBitsLossless2Tag;
import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag;
import com.jpexs.decompiler.flash.tags.DefineBitsTag;
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
import com.jpexs.decompiler.flash.tags.DefineButtonTag;
import com.jpexs.decompiler.flash.tags.DefineSoundTag;
@@ -75,6 +69,7 @@ import com.jpexs.decompiler.flash.tags.VideoFrameTag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.Container;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.types.RECT;
@@ -560,24 +555,6 @@ public class SWF {
}
}
private static String getImageFormat(byte data[]) {
if (hasErrorHeader(data)) {
return "jpg";
}
if (data.length > 2 && ((data[0] & 0xff) == 0xff) && ((data[1] & 0xff) == 0xd8)) {
return "jpg";
}
if (data.length > 6 && ((data[0] & 0xff) == 0x47) && ((data[1] & 0xff) == 0x49) && ((data[2] & 0xff) == 0x46) && ((data[3] & 0xff) == 0x38) && ((data[4] & 0xff) == 0x39) && ((data[5] & 0xff) == 0x61)) {
return "gif";
}
if (data.length > 8 && ((data[0] & 0xff) == 0x89) && ((data[1] & 0xff) == 0x50) && ((data[2] & 0xff) == 0x4e) && ((data[3] & 0xff) == 0x47) && ((data[4] & 0xff) == 0x0d) && ((data[5] & 0xff) == 0x0a) && ((data[6] & 0xff) == 0x1a) && ((data[7] & 0xff) == 0x0a)) {
return "png";
}
return "unk";
}
public static boolean hasErrorHeader(byte data[]) {
if (data.length > 4) {
if ((data[0] & 0xff) == 0xff) {
@@ -864,7 +841,7 @@ public class SWF {
}
}
public static void exportImages(String outdir, List<Tag> tags, JPEGTablesTag jtt) throws IOException {
public void exportImages(String outdir, List<Tag> tags) throws IOException {
if (tags.isEmpty()) {
return;
}
@@ -872,64 +849,8 @@ public class SWF {
(new File(outdir)).mkdirs();
}
for (Tag t : tags) {
if ((t instanceof DefineBitsJPEG2Tag) || (t instanceof DefineBitsJPEG3Tag) || (t instanceof DefineBitsJPEG4Tag)) {
byte imageData[] = null;
int characterID = 0;
if (t instanceof DefineBitsJPEG2Tag) {
imageData = ((DefineBitsJPEG2Tag) t).imageData;
characterID = ((DefineBitsJPEG2Tag) t).characterID;
}
if (t instanceof DefineBitsJPEG3Tag) {
imageData = ((DefineBitsJPEG3Tag) t).imageData;
characterID = ((DefineBitsJPEG3Tag) t).characterID;
}
if (t instanceof DefineBitsJPEG4Tag) {
imageData = ((DefineBitsJPEG4Tag) t).imageData;
characterID = ((DefineBitsJPEG4Tag) t).characterID;
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outdir + File.separator + characterID + "." + getImageFormat(imageData));
if (hasErrorHeader(imageData)) {
fos.write(imageData, 4, imageData.length - 4);
} else {
fos.write(imageData);
}
} finally {
if (fos != null) {
try {
fos.close();
} catch (Exception ex) {
//ignore
}
}
}
}
if (t instanceof DefineBitsLosslessTag) {
DefineBitsLosslessTag dbl = (DefineBitsLosslessTag) t;
ImageIO.write(dbl.getImage(), "PNG", new File(outdir + File.separator + dbl.characterID + ".png"));
}
if (t instanceof DefineBitsLossless2Tag) {
DefineBitsLossless2Tag dbl = (DefineBitsLossless2Tag) t;
ImageIO.write(dbl.getImage(), "PNG", new File(outdir + File.separator + dbl.characterID + ".png"));
}
if ((jtt != null) && (t instanceof DefineBitsTag)) {
DefineBitsTag dbt = (DefineBitsTag) t;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outdir + File.separator + dbt.characterID + ".jpg");
fos.write(dbt.getFullImageData(jtt));
} finally {
if (fos != null) {
try {
fos.close();
} catch (Exception ex) {
//ignore
}
}
}
if (t instanceof ImageTag) {
ImageIO.write(((ImageTag) t).getImage(this.tags), ((ImageTag) t).getImageFormat().toUpperCase(), new File(outdir + File.separator + ((ImageTag) t).getCharacterID() + "." + ((ImageTag) t).getImageFormat()));
}
}
}
@@ -941,7 +862,7 @@ public class SWF {
jtt = (JPEGTablesTag) t;
}
}
exportImages(outdir, tags, jtt);
exportImages(outdir, tags);
}
public void exportShapes(String outdir) throws IOException {

View File

@@ -50,6 +50,7 @@ import com.jpexs.decompiler.flash.types.shaperecords.EndShapeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -61,6 +62,7 @@ import java.util.Scanner;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.InflaterInputStream;
/**
* Class for reading data from SWF file
@@ -394,6 +396,18 @@ public class SWFInputStream extends InputStream {
return ret;
}
public byte[] readBytesZlib(long count) throws IOException {
byte data[] = readBytes(count);
InflaterInputStream dis = new InflaterInputStream(new ByteArrayInputStream(data));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[4096];
int c = 0;
while ((c = dis.read(buf)) > 0) {
baos.write(buf, 0, c);
}
return baos.toByteArray();
}
/**
* Reads one EncodedU32 (Encoded unsigned 32bit value) value from the stream
*

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash;
import com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.*;
import com.jpexs.decompiler.flash.types.filters.BEVELFILTER;
@@ -36,6 +37,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.DeflaterOutputStream;
/**
* Class for writing data into SWF file
@@ -718,6 +720,19 @@ public class SWFOutputStream extends OutputStream {
writeUI8(value.alpha);
}
/**
* Writes ARGB value to the stream
*
* @param value ARGB value
* @throws IOException
*/
public void writeARGB(ARGB value) throws IOException {
writeUI8(value.alpha);
writeUI8(value.red);
writeUI8(value.green);
writeUI8(value.blue);
}
/**
* Writes RGB value to the stream
*
@@ -1585,4 +1600,79 @@ public class SWFOutputStream extends OutputStream {
writeUI16(value.alignmentCoordinate);
writeUI16(value.range);
}
public void writeBytesZlib(byte data[]) throws IOException {
DeflaterOutputStream deflater = new DeflaterOutputStream(this);
deflater.write(data);
deflater.flush();
}
/**
* Reads one BITMAPDATA value from the stream
*
* @throws IOException
*/
public void writeBITMAPDATA(BITMAPDATA value, int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException {
int dataLen = 0;
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
int x = 0;
for (; x < bitmapWidth; x++) {
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_15BIT_RGB) {
dataLen += 2;
writePIX15(value.bitmapPixelDataPix15[pos]);
}
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_24BIT_RGB) {
dataLen += 4;
writePIX24(value.bitmapPixelDataPix24[pos]);
}
pos++;
}
while ((dataLen % 4) != 0) {
dataLen++;
writeUI8(0);
}
}
}
/**
* Reads one ALPHABITMAPDATA value from the stream
*
* @throws IOException
*/
public void writeALPHABITMAPDATA(ALPHABITMAPDATA value, int bitmapFormat, int bitmapWidth, int bitmapHeight) throws IOException {
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
writeARGB(value.bitmapPixelData[pos]);
pos++;
}
}
}
/**
* Writes PIX24 value to the stream
*
* @param value PIX24 value
* @throws IOException
*/
public void writePIX24(PIX24 value) throws IOException {
writeUI8(0);
writeUI8(value.red);
writeUI8(value.green);
writeUI8(value.blue);
}
/**
* Writes PIX15 value to the stream
*
* @param value PIX15 value
* @throws IOException
*/
public void writePIX15(PIX15 value) throws IOException {
writeUB(1, 0);
writeUB(5, value.red);
writeUB(5, value.green);
writeUB(5, value.blue);
}
}

View File

@@ -75,6 +75,7 @@ import com.jpexs.decompiler.flash.tags.base.BoundedTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.Container;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.tags.text.ParseException;
import com.jpexs.decompiler.flash.types.GLYPHENTRY;
@@ -111,8 +112,6 @@ import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
@@ -126,18 +125,17 @@ import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeModel;
@@ -186,6 +184,8 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
private JButton textCancelButton;
private JPanel parametersPanel;
private JSplitPane previewSplitPane;
private JButton imageReplaceButton;
private JPanel imageButtonsPanel;
public void setPercent(int percent) {
progressBar.setValue(percent);
@@ -500,7 +500,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
JPanel textTopPanel = new JPanel(new BorderLayout());
textValue = new LineMarkedEditorPane();
textTopPanel.add(new JScrollPane(textValue), BorderLayout.CENTER);
textValue.setEditable(false);
textValue.setEditable(false);
//textValue.setFont(UIManager.getFont("TextField.font"));
/*JPanel textBottomPanel = new JPanel();
@@ -554,10 +554,10 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
displayWithPreview.add(textPanel, CARDTEXTPANEL);
//displayWithPreview.setVisible(false);
Component leftComponent = null;
try {
@@ -565,40 +565,55 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
} catch (FlashUnsupportedException fue) {
}
displayPanel = new JPanel(new CardLayout());
if (flashPanel != null) {
leftComponent=flashPanel;
leftComponent = flashPanel;
} else {
JPanel swtPanel = new JPanel(new BorderLayout());
swtPanel.add(new JLabel("<html><center>Preview of this object is not available on this platform. (Windows only)</center></html>", JLabel.CENTER), BorderLayout.CENTER);
swtPanel.setBackground(Color.white);
leftComponent = swtPanel;
leftComponent = swtPanel;
}
textValue.setContentType("text/swf_text");
previewSplitPane=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
previewSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
previewSplitPane.setDividerLocation(300);
JPanel pan=new JPanel(new BorderLayout());
JLabel prevLabel=new JLabel("SWF preview");
JPanel pan = new JPanel(new BorderLayout());
JLabel prevLabel = new JLabel("SWF preview");
prevLabel.setHorizontalAlignment(SwingConstants.CENTER);
prevLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
JLabel paramsLabel=new JLabel("Parameters");
JLabel paramsLabel = new JLabel("Parameters");
paramsLabel.setHorizontalAlignment(SwingConstants.CENTER);
paramsLabel.setBorder(new BevelBorder(BevelBorder.RAISED));
pan.add(prevLabel,BorderLayout.NORTH);
pan.add(leftComponent,BorderLayout.CENTER);
pan.add(prevLabel, BorderLayout.NORTH);
pan.add(leftComponent, BorderLayout.CENTER);
previewSplitPane.setLeftComponent(pan);
parametersPanel=new JPanel(new BorderLayout());
parametersPanel.add(paramsLabel,BorderLayout.NORTH);
parametersPanel.add(displayWithPreview,BorderLayout.CENTER);
parametersPanel = new JPanel(new BorderLayout());
parametersPanel.add(paramsLabel, BorderLayout.NORTH);
parametersPanel.add(displayWithPreview, BorderLayout.CENTER);
previewSplitPane.setRightComponent(parametersPanel);
parametersPanel.setVisible(false);
displayPanel.add(previewSplitPane, CARDFLASHPANEL);
imagePanel = new ImagePanel();
displayPanel.add(imagePanel, CARDIMAGEPANEL);
JPanel imagesCard = new JPanel(new BorderLayout());
imagesCard.add(imagePanel, BorderLayout.CENTER);
imageReplaceButton = new JButton("Replace...", View.getIcon("edit16"));
imageReplaceButton.setMargin(new Insets(3, 3, 3, 10));
imageReplaceButton.setActionCommand("REPLACEIMAGE");
imageReplaceButton.addActionListener(this);
imageButtonsPanel = new JPanel(new FlowLayout());
imageButtonsPanel.add(imageReplaceButton);
imagesCard.add(imageButtonsPanel, BorderLayout.SOUTH);
displayPanel.add(imagesCard, CARDIMAGEPANEL);
displayPanel.add(new JPanel(), CARDEMPTYPANEL);
if (actionPanel != null) {
displayPanel.add(actionPanel, CARDACTIONSCRIPTPANEL);
@@ -1106,6 +1121,53 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("REPLACEIMAGE")) {
Object tagObj = tagTree.getLastSelectedPathComponent();
if (tagObj == null) {
return;
}
if (tagObj instanceof TagNode) {
tagObj = ((TagNode) tagObj).tag;
}
if (tagObj instanceof ImageTag) {
ImageTag it = (ImageTag) tagObj;
if (it.importSupported()) {
JFileChooser fc = new JFileChooser();
fc.setCurrentDirectory(new File((String) Configuration.getConfig("lastOpenDir", ".")));
fc.setFileFilter(new FileFilter() {
@Override
public boolean accept(File f) {
return (f.getName().toLowerCase().endsWith(".jpg"))
|| (f.getName().toLowerCase().endsWith(".jpeg"))
|| (f.getName().toLowerCase().endsWith(".gif"))
|| (f.getName().toLowerCase().endsWith(".png"))
|| (f.isDirectory());
}
@Override
public String getDescription() {
return "Images (*.jpg,*.gif,*.png)";
}
});
JFrame f = new JFrame();
View.setWindowIcon(f);
int returnVal = fc.showOpenDialog(f);
if (returnVal == JFileChooser.APPROVE_OPTION) {
Configuration.setConfig("lastOpenDir", fc.getSelectedFile().getParentFile().getAbsolutePath());
File selfile = fc.getSelectedFile();
byte data[] = Helper.readFile(selfile.getAbsolutePath());
try {
it.setImage(data);
} catch (IOException ex) {
Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, "message", ex);
JOptionPane.showMessageDialog(null, "Invalid image.","Error",JOptionPane.ERROR_MESSAGE);
}
reload(true);
}
}
}
}
if (e.getActionCommand().equals("REMOVEITEM")) {
Object tagObj = tagTree.getLastSelectedPathComponent();
if (tagObj == null) {
@@ -1286,7 +1348,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
}
}
}
SWF.exportImages(selFile + File.separator + "images", images, jtt);
swf.exportImages(selFile + File.separator + "images", images);
SWF.exportShapes(selFile + File.separator + "shapes", shapes);
swf.exportTexts(selFile + File.separator + "texts", texts, isFormatted);
swf.exportMovies(selFile + File.separator + "movies", movies);
@@ -1632,24 +1694,10 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
} else if (tagObj instanceof ASMSource) {
showCard(CARDACTIONSCRIPTPANEL);
actionPanel.setSource((ASMSource) tagObj);
} else if (tagObj instanceof DefineBitsTag) {
} else if (tagObj instanceof ImageTag) {
imageButtonsPanel.setVisible(((ImageTag) tagObj).importSupported());
showCard(CARDIMAGEPANEL);
imagePanel.setImage(((DefineBitsTag) tagObj).getFullImageData(jtt));
} else if (tagObj instanceof DefineBitsJPEG2Tag) {
showCard(CARDIMAGEPANEL);
imagePanel.setImage(((DefineBitsJPEG2Tag) tagObj).imageData);
} else if (tagObj instanceof DefineBitsJPEG3Tag) {
showCard(CARDIMAGEPANEL);
imagePanel.setImage(((DefineBitsJPEG3Tag) tagObj).imageData);
} else if (tagObj instanceof DefineBitsJPEG4Tag) {
showCard(CARDIMAGEPANEL);
imagePanel.setImage(((DefineBitsJPEG4Tag) tagObj).imageData);
} else if (tagObj instanceof DefineBitsLosslessTag) {
showCard(CARDIMAGEPANEL);
imagePanel.setImage(((DefineBitsLosslessTag) tagObj).getImage());
} else if (tagObj instanceof DefineBitsLossless2Tag) {
showCard(CARDIMAGEPANEL);
imagePanel.setImage(((DefineBitsLossless2Tag) tagObj).getImage());
imagePanel.setImage(((ImageTag) tagObj).getImage(swf.tags));
} else if ((tagObj instanceof FrameNode && ((FrameNode) tagObj).isDisplayed()) || (((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag))) {
try {
@@ -1834,7 +1882,7 @@ public class MainFrame extends JFrame implements ActionListener, TreeSelectionLi
if (tagObj instanceof TextTag) {
parametersPanel.setVisible(true);
previewSplitPane.setDividerLocation(previewSplitPane.getWidth()/2);
previewSplitPane.setDividerLocation(previewSplitPane.getWidth() / 2);
showDetailWithPreview(CARDTEXTPANEL);
textValue.setText(((TextTag) tagObj).getFormattedText(swf.tags));
} else {

View File

@@ -18,11 +18,14 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import javax.imageio.ImageIO;
public class DefineBitsJPEG2Tag extends CharacterTag implements AloneTag {
public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag {
public int characterID;
public byte[] imageData;
@@ -32,10 +35,29 @@ public class DefineBitsJPEG2Tag extends CharacterTag implements AloneTag {
return characterID;
}
@Override
public String getImageFormat() {
return ImageTag.getImageFormat(imageData);
}
@Override
public BufferedImage getImage(List<Tag> tags) {
try {
return ImageIO.read(new ByteArrayInputStream(imageData));
} catch (IOException ex) {
}
return null;
}
public DefineBitsJPEG2Tag(byte[] data, int version, long pos) throws IOException {
super(21, "DefineBitsJPEG2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
imageData = sis.readBytes(sis.available());
}
@Override
public void setImage(byte data[]) {
imageData = data;
}
}

View File

@@ -19,13 +19,17 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
public class DefineBitsJPEG3Tag extends CharacterTag implements AloneTag {
public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag {
public int characterID;
public byte imageData[];
@@ -36,13 +40,41 @@ public class DefineBitsJPEG3Tag extends CharacterTag implements AloneTag {
return characterID;
}
@Override
public void setImage(byte data[]) {
imageData = data;
if (ImageTag.getImageFormat(data).equals("jpg")) {
BufferedImage image = getImage(new ArrayList<Tag>());
bitmapAlphaData = new byte[image.getWidth() * image.getHeight()];
for (int i = 0; i < bitmapAlphaData.length; i++) {
bitmapAlphaData[i] = (byte) 255;
}
} else {
bitmapAlphaData = new byte[0];
}
}
@Override
public String getImageFormat() {
return ImageTag.getImageFormat(imageData);
}
@Override
public BufferedImage getImage(List<Tag> tags) {
try {
return ImageIO.read(new ByteArrayInputStream(imageData));
} catch (IOException ex) {
}
return null;
}
public DefineBitsJPEG3Tag(byte[] data, int version, long pos) throws IOException {
super(35, "DefineBitsJPEG3", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
characterID = sis.readUI16();
long alphaDataOffset = sis.readUI32();
imageData = sis.readBytes(alphaDataOffset);
bitmapAlphaData = sis.readBytes(sis.available());
bitmapAlphaData = sis.readBytesZlib(sis.available());
}
/**
@@ -60,7 +92,7 @@ public class DefineBitsJPEG3Tag extends CharacterTag implements AloneTag {
sos.writeUI16(characterID);
sos.writeUI32(imageData.length);
sos.write(imageData);
sos.write(bitmapAlphaData);
sos.writeBytesZlib(bitmapAlphaData);
} catch (IOException e) {
}
return baos.toByteArray();

View File

@@ -19,18 +19,22 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
/**
*
*
* @author JPEXS
*/
public class DefineBitsJPEG4Tag extends CharacterTag implements AloneTag {
public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag {
public int characterID;
public int deblockParam;
@@ -42,6 +46,34 @@ public class DefineBitsJPEG4Tag extends CharacterTag implements AloneTag {
return characterID;
}
@Override
public String getImageFormat() {
return ImageTag.getImageFormat(imageData);
}
@Override
public void setImage(byte data[]) {
imageData = data;
if (ImageTag.getImageFormat(data).equals("jpg")) {
BufferedImage image = getImage(new ArrayList<Tag>());
bitmapAlphaData = new byte[image.getWidth() * image.getHeight()];
for (int i = 0; i < bitmapAlphaData.length; i++) {
bitmapAlphaData[i] = (byte) 255;
}
} else {
bitmapAlphaData = new byte[0];
}
}
@Override
public BufferedImage getImage(List<Tag> tags) {
try {
return ImageIO.read(new ByteArrayInputStream(imageData));
} catch (IOException ex) {
}
return null;
}
/**
* Gets data bytes
*

View File

@@ -16,12 +16,15 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import static com.jpexs.decompiler.flash.tags.DefineBitsLosslessTag.FORMAT_24BIT_RGB;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
import com.jpexs.decompiler.flash.types.ARGB;
import com.jpexs.decompiler.flash.types.RGBA;
import java.awt.Color;
import java.awt.Graphics;
@@ -30,9 +33,11 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.InflaterInputStream;
import javax.imageio.ImageIO;
public class DefineBitsLossless2Tag extends CharacterTag implements AloneTag {
public class DefineBitsLossless2Tag extends ImageTag implements AloneTag {
public int characterID;
public int bitmapFormat;
@@ -41,14 +46,46 @@ public class DefineBitsLossless2Tag extends CharacterTag implements AloneTag {
public int bitmapColorTableSize;
public byte zlibBitmapData[]; //TODO: Parse ALPHACOLORMAPDATA,ALPHABITMAPDATA
public static final int FORMAT_8BIT_COLORMAPPED = 3;
public static final int FORMAT_15BIT_RGB = 4;
public static final int FORMAT_24BIT_RGB = 5;
public static final int FORMAT_32BIT_ARGB = 5;
@Override
public int getCharacterID() {
return characterID;
}
@Override
public void setImage(byte data[]) throws IOException {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
ALPHABITMAPDATA bitmapData = new ALPHABITMAPDATA();
bitmapFormat = FORMAT_24BIT_RGB;
bitmapWidth = image.getWidth();
bitmapHeight = image.getHeight();
bitmapData.bitmapPixelData = new ARGB[bitmapWidth * bitmapHeight];
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int argb = image.getRGB(x, y);
int a = (argb >> 24) & 0xff;
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb >> 0) & 0xff;
bitmapData.bitmapPixelData[pos] = new ARGB();
bitmapData.bitmapPixelData[pos].alpha = a;
bitmapData.bitmapPixelData[pos].red = r;
bitmapData.bitmapPixelData[pos].green = g;
bitmapData.bitmapPixelData[pos].blue = b;
pos++;
}
}
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, SWF.DEFAULT_VERSION);
sos.writeALPHABITMAPDATA(bitmapData, bitmapFormat, bitmapWidth, bitmapHeight);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, SWF.DEFAULT_VERSION);
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
zlibBitmapData = zlibOS.toByteArray();
}
public DefineBitsLossless2Tag(byte[] data, int version, long pos) throws IOException {
super(36, "DefineBitsLossless2", data, pos);
SWFInputStream sis = new SWFInputStream(new ByteArrayInputStream(data), version);
@@ -85,7 +122,7 @@ public class DefineBitsLossless2Tag extends CharacterTag implements AloneTag {
if (bitmapFormat == FORMAT_8BIT_COLORMAPPED) {
colorMapData = sis.readALPHACOLORMAPDATA(bitmapColorTableSize, bitmapWidth, bitmapHeight);
}
if ((bitmapFormat == FORMAT_15BIT_RGB) || (bitmapFormat == FORMAT_24BIT_RGB)) {
if (bitmapFormat == FORMAT_32BIT_ARGB) {
bitmapData = sis.readALPHABITMAPDATA(bitmapFormat, bitmapWidth, bitmapHeight);
}
} catch (IOException ex) {
@@ -118,7 +155,13 @@ public class DefineBitsLossless2Tag extends CharacterTag implements AloneTag {
return baos.toByteArray();
}
public BufferedImage getImage() {
@Override
public String getImageFormat() {
return "png";
}
@Override
public BufferedImage getImage(List<Tag> tags) {
BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.getGraphics();
ALPHACOLORMAPDATA colorMapData = null;
@@ -126,7 +169,7 @@ public class DefineBitsLossless2Tag extends CharacterTag implements AloneTag {
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED) {
colorMapData = getColorMapData();
}
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_15BIT_RGB) || (bitmapFormat == DefineBitsLossless2Tag.FORMAT_24BIT_RGB)) {
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB) {
bitmapData = getBitmapData();
}
int pos32aligned = 0;
@@ -137,7 +180,7 @@ public class DefineBitsLossless2Tag extends CharacterTag implements AloneTag {
RGBA color = colorMapData.colorTableRGB[colorMapData.colorMapPixelData[pos32aligned] & 0xff];
g.setColor(new Color(color.red, color.green, color.blue, color.alpha));
}
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_15BIT_RGB) || (bitmapFormat == DefineBitsLossless2Tag.FORMAT_24BIT_RGB)) {
if ((bitmapFormat == DefineBitsLossless2Tag.FORMAT_32BIT_ARGB)) {
g.setColor(new Color(bitmapData.bitmapPixelData[pos].red, bitmapData.bitmapPixelData[pos].green, bitmapData.bitmapPixelData[pos].blue, bitmapData.bitmapPixelData[pos].alpha));
}
g.fillRect(x, y, 1, 1);

View File

@@ -16,12 +16,14 @@
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.AloneTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.types.BITMAPDATA;
import com.jpexs.decompiler.flash.types.COLORMAPDATA;
import com.jpexs.decompiler.flash.types.PIX24;
import com.jpexs.decompiler.flash.types.RGB;
import java.awt.Color;
import java.awt.Graphics;
@@ -30,9 +32,11 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.InflaterInputStream;
import javax.imageio.ImageIO;
public class DefineBitsLosslessTag extends CharacterTag implements AloneTag {
public class DefineBitsLosslessTag extends ImageTag implements AloneTag {
public int characterID;
public int bitmapFormat;
@@ -47,7 +51,39 @@ public class DefineBitsLosslessTag extends CharacterTag implements AloneTag {
private BITMAPDATA bitmapData;
private boolean decompressed = false;
public BufferedImage getImage() {
@Override
public void setImage(byte data[]) throws IOException {
BufferedImage image = ImageIO.read(new ByteArrayInputStream(data));
bitmapFormat = FORMAT_24BIT_RGB;
bitmapWidth = image.getWidth();
bitmapHeight = image.getHeight();
bitmapData.bitmapPixelDataPix24 = new PIX24[bitmapWidth * bitmapHeight];
int pos = 0;
for (int y = 0; y < bitmapHeight; y++) {
for (int x = 0; x < bitmapWidth; x++) {
int argb = image.getRGB(x, y);
//int a = (argb >> 24) & 0xff;
int r = (argb >> 16) & 0xff;
int g = (argb >> 8) & 0xff;
int b = (argb >> 0) & 0xff;
bitmapData.bitmapPixelDataPix24[pos] = new PIX24();
bitmapData.bitmapPixelDataPix24[pos].red = r;
bitmapData.bitmapPixelDataPix24[pos].green = g;
bitmapData.bitmapPixelDataPix24[pos].blue = b;
pos++;
}
}
ByteArrayOutputStream bitmapDataOS = new ByteArrayOutputStream();
SWFOutputStream sos = new SWFOutputStream(bitmapDataOS, SWF.DEFAULT_VERSION);
sos.writeBITMAPDATA(bitmapData, bitmapFormat, bitmapWidth, bitmapHeight);
ByteArrayOutputStream zlibOS = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(zlibOS, SWF.DEFAULT_VERSION);
sos2.writeBytesZlib(bitmapDataOS.toByteArray());
zlibBitmapData = zlibOS.toByteArray();
}
@Override
public BufferedImage getImage(List<Tag> tags) {
BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
COLORMAPDATA colorMapData = null;
@@ -153,4 +189,9 @@ public class DefineBitsLosslessTag extends CharacterTag implements AloneTag {
}
return baos.toByteArray();
}
@Override
public String getImageFormat() {
return "png";
}
}

View File

@@ -19,16 +19,30 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import javax.imageio.ImageIO;
public class DefineBitsTag extends CharacterTag {
public class DefineBitsTag extends ImageTag {
public int characterID;
public byte jpegData[];
private JPEGTablesTag jtt = null;
@Override
public void setImage(byte data[]) {
throw new UnsupportedOperationException("Set image is not supported for DefineBits");
}
@Override
public boolean importSupported() {
return false;
}
public DefineBitsTag(byte[] data, int version, long pos) throws IOException {
super(6, "DefineBits", data, pos);
@@ -37,7 +51,20 @@ public class DefineBitsTag extends CharacterTag {
jpegData = sis.readBytes(sis.available());
}
public byte[] getFullImageData(JPEGTablesTag jtt) {
private void getJPEGTables(List<Tag> tags) {
if (jtt == null) {
for (Tag t : tags) {
if (t instanceof JPEGTablesTag) {
jtt = (JPEGTablesTag) t;
break;
}
}
}
}
@Override
public BufferedImage getImage(List<Tag> tags) {
getJPEGTables(tags);
if ((jtt != null)) {
ByteArrayOutputStream baos = null;
@@ -60,7 +87,14 @@ public class DefineBitsTag extends CharacterTag {
}
}
}
return baos.toByteArray();
if (baos == null) {
return null;
}
try {
return ImageIO.read(new ByteArrayInputStream(baos.toByteArray()));
} catch (IOException ex) {
return null;
}
}
return null;
}
@@ -88,4 +122,9 @@ public class DefineBitsTag extends CharacterTag {
public int getCharacterID() {
return characterID;
}
@Override
public String getImageFormat() {
return "jpg";
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2013 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.tags.base;
import static com.jpexs.decompiler.flash.SWF.hasErrorHeader;
import com.jpexs.decompiler.flash.tags.Tag;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.List;
/**
*
* @author JPEXS
*/
public abstract class ImageTag extends CharacterTag {
public ImageTag(int id, String name, byte[] data, long pos) {
super(id, name, data, pos);
}
public abstract BufferedImage getImage(List<Tag> tags);
public abstract void setImage(byte data[]) throws IOException;
public abstract String getImageFormat();
public boolean importSupported() {
return true;
}
public static String getImageFormat(byte data[]) {
if (hasErrorHeader(data)) {
return "jpg";
}
if (data.length > 2 && ((data[0] & 0xff) == 0xff) && ((data[1] & 0xff) == 0xd8)) {
return "jpg";
}
if (data.length > 6 && ((data[0] & 0xff) == 0x47) && ((data[1] & 0xff) == 0x49) && ((data[2] & 0xff) == 0x46) && ((data[3] & 0xff) == 0x38) && ((data[4] & 0xff) == 0x39) && ((data[5] & 0xff) == 0x61)) {
return "gif";
}
if (data.length > 8 && ((data[0] & 0xff) == 0x89) && ((data[1] & 0xff) == 0x50) && ((data[2] & 0xff) == 0x4e) && ((data[3] & 0xff) == 0x47) && ((data[4] & 0xff) == 0x0d) && ((data[5] & 0xff) == 0x0a) && ((data[6] & 0xff) == 0x1a) && ((data[7] & 0xff) == 0x0a)) {
return "png";
}
return "unk";
}
}

File diff suppressed because it is too large Load Diff