From 0486cb39585a50632fc7d8ddbc9ea8be2ed52e37 Mon Sep 17 00:00:00 2001 From: Honfika Date: Wed, 29 Jan 2014 00:58:30 +0100 Subject: [PATCH] some sprite/frame rendering issue fixed, generic cache, serializableimages --- trunk/src/com/jpexs/decompiler/flash/SWF.java | 58 ++++---- .../flash/exporters/BitmapExporter.java | 87 +++++++---- .../decompiler/flash/exporters/Matrix.java | 27 ++++ .../flash/exporters/SVGShapeExporter.java | 6 +- .../decompiler/flash/gui/ImagePanel.java | 17 ++- .../decompiler/flash/gui/LoadingDialog.java | 2 +- .../decompiler/flash/gui/SWFPreviwPanel.java | 4 +- .../flash/gui/abc/DecompiledEditorPane.java | 2 +- .../flash/gui/action/ActionPanel.java | 2 +- .../flash/tags/DefineBitsJPEG2Tag.java | 6 +- .../flash/tags/DefineBitsJPEG3Tag.java | 10 +- .../flash/tags/DefineBitsJPEG4Tag.java | 10 +- .../flash/tags/DefineBitsLossless2Tag.java | 8 +- .../flash/tags/DefineBitsLosslessTag.java | 8 +- .../decompiler/flash/tags/DefineBitsTag.java | 6 +- .../flash/tags/DefineButton2Tag.java | 13 +- .../flash/tags/DefineButtonTag.java | 13 +- .../flash/tags/DefineMorphShape2Tag.java | 10 +- .../flash/tags/DefineMorphShapeTag.java | 10 +- .../flash/tags/DefineShape2Tag.java | 8 +- .../flash/tags/DefineShape3Tag.java | 8 +- .../flash/tags/DefineShape4Tag.java | 10 +- .../decompiler/flash/tags/DefineShapeTag.java | 8 +- .../flash/tags/DefineSpriteTag.java | 11 +- .../decompiler/flash/tags/DefineText2Tag.java | 7 +- .../decompiler/flash/tags/DefineTextTag.java | 7 +- .../flash/tags/base/DrawableTag.java | 6 +- .../decompiler/flash/tags/base/FontTag.java | 6 +- .../decompiler/flash/tags/base/ImageTag.java | 4 +- .../decompiler/flash/tags/base/TextTag.java | 29 ++-- .../flash/tags/gfx/DefineCompactedFont.java | 44 +----- .../jpexs/decompiler/flash/types/CXFORM.java | 4 +- .../flash/types/CXFORMWITHALPHA.java | 4 +- .../flash/types/filters/BEVELFILTER.java | 4 +- .../flash/types/filters/BLURFILTER.java | 4 +- .../types/filters/COLORMATRIXFILTER.java | 4 +- .../types/filters/CONVOLUTIONFILTER.java | 4 +- .../flash/types/filters/DROPSHADOWFILTER.java | 4 +- .../flash/types/filters/FILTER.java | 4 +- .../flash/types/filters/Filtering.java | 78 +++++----- .../flash/types/filters/GLOWFILTER.java | 4 +- .../types/filters/GRADIENTBEVELFILTER.java | 4 +- .../types/filters/GRADIENTGLOWFILTER.java | 4 +- .../flash/types/shaperecords/SHAPERECORD.java | 14 +- .../types/shaperecords/SerializableImage.java | 56 ------- .../decompiler/flash/xfl/XFLConverter.java | 6 +- trunk/src/com/jpexs/helpers/Cache.java | 29 ++-- .../com/jpexs/helpers/SerializableImage.java | 140 ++++++++++++++++++ 48 files changed, 470 insertions(+), 344 deletions(-) delete mode 100644 trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SerializableImage.java create mode 100644 trunk/src/com/jpexs/helpers/SerializableImage.java diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index 20b0a059b..e09e84ddd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -53,6 +53,7 @@ import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.ecma.Null; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.flv.AUDIODATA; import com.jpexs.decompiler.flash.flv.FLVOutputStream; import com.jpexs.decompiler.flash.flv.FLVTAG; @@ -116,15 +117,14 @@ import com.jpexs.helpers.Cache; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; import com.jpexs.helpers.ProgressListener; +import com.jpexs.helpers.SerializableImage; import com.jpexs.helpers.utf8.Utf8Helper; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; -import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -1531,7 +1531,7 @@ public final class SWF implements TreeItem { new RetryTask(new RunnableIOEx() { @Override public void run() throws IOException { - ImageIO.write(((ImageTag) t).getImage(ttags), ((ImageTag) t).getImageFormat().toUpperCase(Locale.ENGLISH), file); + ImageIO.write(((ImageTag) t).getImage(ttags).getBufferedImage(), ((ImageTag) t).getImageFormat().toUpperCase(Locale.ENGLISH), file); } }, handler).run(); ret.add(file); @@ -2057,7 +2057,7 @@ public final class SWF implements TreeItem { mat.translateX, mat.translateY); } - private static Cache frameCache = Cache.getInstance(false); + private static Cache frameCache = Cache.getInstance(false); public void clearImageCache() { frameCache.clear(); @@ -2097,20 +2097,20 @@ public final class SWF implements TreeItem { return ret; } - public static BufferedImage frameToImage(int containerId, int maxDepth, HashMap layers, Color backgroundColor, HashMap characters, int frame, List allTags, List controlTags, RECT displayRect, Stack visited) { - int fixX = 0; - int fixY = 0; - fixX = -displayRect.Xmin / 20; - fixY = -displayRect.Ymin / 20; + public static SerializableImage frameToImage(int containerId, int maxDepth, HashMap layers, Color backgroundColor, HashMap characters, int frame, List allTags, List controlTags, RECT displayRect, Stack visited) { + float unzoom = 20; + double fixX = 0; + double fixY = 0; + fixX = -displayRect.Xmin / unzoom; + fixY = -displayRect.Ymin / unzoom; displayRect = fixRect(displayRect); String key = "frame_" + frame + "_" + containerId; if (frameCache.contains(key)) { - BufferedImage ciret = ((BufferedImage) frameCache.get(key)); + SerializableImage ciret = ((SerializableImage) frameCache.get(key)); return ciret; } - float unzoom = 20; - BufferedImage ret = new BufferedImage((int) (displayRect.Xmax / unzoom), (int) (displayRect.Ymax / unzoom), BufferedImage.TYPE_INT_ARGB); + SerializableImage ret = new SerializableImage((int) (displayRect.getWidth() / unzoom), (int) (displayRect.getHeight() / unzoom), SerializableImage.TYPE_INT_ARGB); Graphics2D g = (Graphics2D) ret.getGraphics(); g.setPaint(backgroundColor); @@ -2131,19 +2131,16 @@ public final class SWF implements TreeItem { continue; } CharacterTag character = characters.get(layer.characterId); - MATRIX mat = new MATRIX(layer.matrix); - mat.translateX /= 20; - mat.translateY /= 20; - mat.translateX += fixX; - mat.translateY += fixY; + Matrix mat = new Matrix(layer.matrix); + mat.translate(fixX, fixY); - AffineTransform trans = matrixToTransform(mat); - - //trans.translate(transX, transY); - g.setTransform(trans); if (character instanceof DrawableTag) { DrawableTag drawable = (DrawableTag) character; - BufferedImage img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, displayRect, characters, visited); + SerializableImage img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, mat, characters, visited); + /*if (character instanceof BoundedTag) { + BoundedTag bounded = (BoundedTag) character; + RECT rect = bounded.getRect(characters, visited); + }*/ if (layer.filters != null) { for (FILTER filter : layer.filters) { img = filter.apply(img); @@ -2156,7 +2153,6 @@ public final class SWF implements TreeItem { if (layer.colorTransFormAlpha != null) { img = layer.colorTransFormAlpha.apply(img); } - Point imgPos = drawable.getImagePos(layer.ratio < 0 ? 0 : layer.ratio, characters, visited); switch (layer.blendMode) { case 0: case 1: @@ -2206,8 +2202,12 @@ public final class SWF implements TreeItem { break; } - g.drawImage(img, imgPos.x, imgPos.y, null); + AffineTransform trans = mat.toTransform(); + g.setTransform(trans); + g.drawImage(img.getBufferedImage(), 0, 0, null); } else if (character instanceof BoundedTag) { + AffineTransform trans = mat.toTransform(); + g.setTransform(trans); BoundedTag b = (BoundedTag) character; g.setPaint(new Color(255, 255, 255, 128)); g.setComposite(BlendComposite.Invert); @@ -2232,20 +2232,20 @@ public final class SWF implements TreeItem { return ret; } - public static BufferedImage frameToImage(int containerId, int frame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited) { - List ret = new ArrayList<>(); + public static SerializableImage frameToImage(int containerId, int frame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited) { + List ret = new ArrayList<>(); framesToImage(containerId, ret, frame, frame, allTags, controlTags, displayRect, totalFrameCount, visited); if (ret.isEmpty()) { - return new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB); + return new SerializableImage(1, 1, SerializableImage.TYPE_INT_ARGB); } return ret.get(0); } - public static void framesToImage(int containerId, List ret, int startFrame, int stopFrame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited) { + public static void framesToImage(int containerId, List ret, int startFrame, int stopFrame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited) { for (int i = startFrame; i <= stopFrame; i++) { String key = "frame_" + i + "_" + containerId; if (frameCache.contains(key)) { - BufferedImage g = (BufferedImage) frameCache.get(key); + SerializableImage g = (SerializableImage) frameCache.get(key); if (g == null) { break; } diff --git a/trunk/src/com/jpexs/decompiler/flash/exporters/BitmapExporter.java b/trunk/src/com/jpexs/decompiler/flash/exporters/BitmapExporter.java index 878e7d768..b316993e5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/exporters/BitmapExporter.java +++ b/trunk/src/com/jpexs/decompiler/flash/exporters/BitmapExporter.java @@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; import com.jpexs.helpers.Cache; +import com.jpexs.helpers.SerializableImage; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; @@ -42,9 +43,13 @@ import java.awt.Stroke; import java.awt.TexturePaint; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; -import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.imageio.ImageIO; /** * @@ -52,14 +57,16 @@ import java.util.List; */ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter { - private static final Cache cache = Cache.getInstance(false); + private static final Cache cache = Cache.getInstance(false); + private static final Cache cacheDeltaX = Cache.getInstance(false); + private static final Cache cacheDeltaY = Cache.getInstance(false); - private BufferedImage image; + private SerializableImage image; private Graphics2D graphics; private final Color defaultColor; private final boolean putToCache; - private double xMin; - private double yMin; + public double deltaX; + public double deltaY; private final SWF swf; private GeneralPath path; private Paint fillPathPaint; @@ -69,9 +76,18 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter private Stroke lineStroke; private Stroke defaultStroke; - public static BufferedImage export(SWF swf, SHAPE shape, Color defaultColor, boolean putToCache) { + static int imageid = 0; + + public static SerializableImage export(SWF swf, SHAPE shape, Color defaultColor, boolean putToCache) { + return export(swf, shape, defaultColor, putToCache, null); + } + + public static SerializableImage export(SWF swf, SHAPE shape, Color defaultColor, boolean putToCache, Matrix matrix) { BitmapExporter exporter = new BitmapExporter(swf, shape, defaultColor, putToCache); exporter.export(); + if (matrix != null) { + matrix.translate(exporter.deltaX, exporter.deltaY); + } return exporter.getImage(); } @@ -99,7 +115,9 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter List records = shape.shapeRecords; String key = "shape_" + records.hashCode() + "_" + (defaultColor == null ? "null" : defaultColor.hashCode()); if (cache.contains(key)) { - image = (BufferedImage) cache.get(key); + image = (SerializableImage) cache.get(key); + deltaX = (double) cacheDeltaX.get(key); + deltaY = (double) cacheDeltaY.get(key); return; } RECT bounds = SHAPERECORD.getBounds(records); @@ -113,22 +131,29 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter } } double maxLineWidth = maxLineWidthTwips / unitDivisor / 2; - xMin = bounds.Xmin / unitDivisor - maxLineWidth; - yMin = bounds.Ymin / unitDivisor - maxLineWidth; - image = new BufferedImage( - (int) (bounds.getWidth() / unitDivisor + 2 + maxLineWidth), (int) (bounds.getHeight() / unitDivisor + 2 + maxLineWidth), BufferedImage.TYPE_INT_ARGB); + deltaX = bounds.Xmin / unitDivisor - maxLineWidth; + deltaY = bounds.Ymin / unitDivisor - maxLineWidth; + image = new SerializableImage( + (int) (bounds.getWidth() / unitDivisor + 2 + maxLineWidth), (int) (bounds.getHeight() / unitDivisor + 2 + maxLineWidth), SerializableImage.TYPE_INT_ARGB); graphics = (Graphics2D) image.getGraphics(); graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); defaultStroke = graphics.getStroke(); super.export(); + try { + ImageIO.write(image.getBufferedImage(), "png", new File("c:\\10\\imageid" + imageid ++ + ".png")); + } catch (IOException ex) { + Logger.getLogger(BitmapExporter.class.getName()).log(Level.SEVERE, null, ex); + } if (putToCache) { cache.put(key, image); + cacheDeltaX.put(key, deltaX); + cacheDeltaY.put(key, deltaY); } } - public BufferedImage getImage() { + public SerializableImage getImage() { return image; } @@ -199,7 +224,9 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter fillPathPaint = null; fillPaint = new LinearGradientPaint(new java.awt.Point(-16384, 0), new java.awt.Point(16384, 0), ratiosArr, colorsArr, cm); - fillTransform = matrixToTransform(matrix); + matrix.translateX -= deltaX; + matrix.translateY -= deltaY; + fillTransform = matrix.toTransform(); } break; case FILLSTYLE.RADIAL_GRADIENT: { @@ -231,7 +258,9 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter Color endColor = gradientRecords[gradientRecords.length - 1].color.toColor(); fillPathPaint = endColor; fillPaint = new RadialGradientPaint(new java.awt.Point(0, 0), 16384, ratiosArr, colorsArr, cm); - fillTransform = matrixToTransform(matrix); + matrix.translateX -= deltaX; + matrix.translateY -= deltaY; + fillTransform = matrix.toTransform(); } break; case FILLSTYLE.FOCAL_RADIAL_GRADIENT: { @@ -263,7 +292,9 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter Color endColor = gradientRecords[gradientRecords.length - 1].color.toColor(); fillPathPaint = endColor; fillPaint = new RadialGradientPaint(new java.awt.Point(0, 0), 16384, new java.awt.Point((int) (focalPointRatio * 16384), 0), ratiosArr, colorsArr, cm); - fillTransform = matrixToTransform(matrix); + matrix.translateX -= deltaX; + matrix.translateY -= deltaY; + fillTransform = matrix.toTransform(); } break; } @@ -283,12 +314,12 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter } } if (image != null) { - BufferedImage img = image.getImage(swf.tags); + SerializableImage img = image.getImage(swf.tags); if (img != null) { - fillPaint = new TexturePaint(img, new java.awt.Rectangle(img.getWidth(), img.getHeight())); - matrix.translateX -= xMin; - matrix.translateY -= yMin; - fillTransform = matrixToTransform(matrix); + fillPaint = new TexturePaint(img.getBufferedImage(), new java.awt.Rectangle(img.getWidth(), img.getHeight())); + matrix.translateX -= deltaX; + matrix.translateY -= deltaY; + fillTransform = matrix.toTransform(); } } } @@ -340,17 +371,17 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter @Override public void moveTo(double x, double y) { - path.moveTo(x - xMin, y - yMin); + path.moveTo(x - deltaX, y - deltaY); } @Override public void lineTo(double x, double y) { - path.lineTo(x - xMin, y - yMin); + path.lineTo(x - deltaX, y - deltaY); } @Override public void curveTo(double controlX, double controlY, double anchorX, double anchorY) { - path.quadTo(controlX - xMin, controlY - yMin, anchorX - xMin, anchorY - yMin); + path.quadTo(controlX - deltaX, controlY - deltaY, anchorX - deltaX, anchorY - deltaY); } protected void finalizePath() { @@ -391,12 +422,8 @@ public class BitmapExporter extends ShapeExporterBase implements IShapeExporter } } path = new GeneralPath(); - } - - private static AffineTransform matrixToTransform(Matrix mat) { - AffineTransform transform = new AffineTransform(mat.scaleX, mat.rotateSkew0, - mat.rotateSkew1, mat.scaleY, - mat.translateX, mat.translateY); - return transform; + lineStroke = null; + lineColor = null; + fillPaint = null; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java b/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java index 75625b082..cf2f44ca1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java +++ b/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.exporters; import com.jpexs.decompiler.flash.types.MATRIX; +import java.awt.geom.AffineTransform; /** * @@ -32,6 +33,8 @@ public class Matrix { public double translateY; public Matrix() { + scaleX = 1; + scaleY = 1; } public Matrix(MATRIX matrix) { @@ -46,4 +49,28 @@ public class Matrix { rotateSkew1 = matrix.getRotateSkew1Float() / 20.0; } } + + @Override + public Matrix clone() { + Matrix mat = new Matrix(); + mat.translateX = translateX; + mat.translateY = translateY; + mat.scaleX = scaleX; + mat.scaleY = scaleY; + mat.rotateSkew0 = rotateSkew0; + mat.rotateSkew1 = rotateSkew1; + return mat; + } + + public void translate(double x, double y) { + translateX += x; + translateY += y; + } + + public AffineTransform toTransform() { + AffineTransform transform = new AffineTransform(scaleX, rotateSkew0, + rotateSkew1, scaleY, + translateX, translateY); + return transform; + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/exporters/SVGShapeExporter.java b/trunk/src/com/jpexs/decompiler/flash/exporters/SVGShapeExporter.java index b26dcadf7..53f2fc6a0 100644 --- a/trunk/src/com/jpexs/decompiler/flash/exporters/SVGShapeExporter.java +++ b/trunk/src/com/jpexs/decompiler/flash/exporters/SVGShapeExporter.java @@ -27,7 +27,7 @@ import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.helpers.Helper; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -169,7 +169,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter { } } if (image != null) { - BufferedImage img = image.getImage(swf.tags); + SerializableImage img = image.getImage(swf.tags); if (img != null) { int width = img.getWidth(); int height = img.getHeight(); @@ -183,7 +183,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter { } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { - ImageIO.write(img, format.toUpperCase(Locale.ENGLISH), baos); + ImageIO.write(img.getBufferedImage(), format.toUpperCase(Locale.ENGLISH), baos); } catch (IOException ex) { } imageData = baos.toByteArray(); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index 338085e1d..0114d72c1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -18,13 +18,14 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.AppStrings; import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.gui.player.FlashDisplay; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; +import com.jpexs.helpers.SerializableImage; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; -import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.HashMap; @@ -120,20 +121,23 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis } percent = 0; if (drawable.getNumFrames() == 1) { - setImage(drawable.toImage(0, swf.tags, swf.displayRect, characters, new Stack())); + Matrix mat = new Matrix(); + mat.translateX = swf.displayRect.Xmin; + mat.translateY = swf.displayRect.Ymin; + setImage(drawable.toImage(0, swf.tags, mat, characters, new Stack())); return; } play(); } - public void setImage(Image image) { + public void setImage(SerializableImage image) { setBackground(View.swfBackgroundColor); if (timer != null) { timer.cancel(); } drawable = null; loaded = true; - ImageIcon icon = new ImageIcon(image); + ImageIcon icon = new ImageIcon(image.getBufferedImage()); label.setIcon(icon); } @@ -171,7 +175,10 @@ public final class ImagePanel extends JPanel implements ActionListener, FlashDis } int nframe = percent * drawable.getNumFrames() / 100; if (nframe != frame) { - ImageIcon icon = new ImageIcon(drawable.toImage(nframe, swf.tags, swf.displayRect, characters, new Stack())); + Matrix mat = new Matrix(); + mat.translateX = swf.displayRect.Xmin; + mat.translateY = swf.displayRect.Ymin; + ImageIcon icon = new ImageIcon(drawable.toImage(nframe, swf.tags, mat, characters, new Stack()).getBufferedImage()); label.setIcon(icon); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java b/trunk/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java index aa08174ea..c36575530 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/LoadingDialog.java @@ -83,7 +83,7 @@ public class LoadingDialog extends AppDialog implements ImageObserver { JLabel loadingLabel = new JLabel(translate("loadingpleasewait")); //loadingLabel.setBounds(0, 30, 150, 20); loadingLabel.setHorizontalAlignment(SwingConstants.CENTER); - detailLabel = new JLabel("H", JLabel.CENTER); + detailLabel = new JLabel("", JLabel.CENTER); detailLabel.setPreferredSize(new Dimension(loadingLabel.getPreferredSize())); detailLabel.setHorizontalAlignment(SwingConstants.CENTER); //detailLabel.setBounds(0, 45, 150, 20); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviwPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviwPanel.java index 0e5de583f..b1d3a2061 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviwPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/SWFPreviwPanel.java @@ -20,8 +20,8 @@ import com.jpexs.decompiler.flash.AppStrings; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.gui.player.FlashDisplay; import com.jpexs.decompiler.flash.gui.player.PlayerControls; +import com.jpexs.helpers.SerializableImage; import java.awt.BorderLayout; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Stack; @@ -41,7 +41,7 @@ public class SWFPreviwPanel extends JPanel implements FlashDisplay { ImagePanel pan; Timer timer; int frame = 1; - List frameImages = new ArrayList<>(); + List frameImages = new ArrayList<>(); JLabel buffering = new JLabel(AppStrings.translate("work.buffering") + "..."); public SWFPreviwPanel() { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 288104225..46b670573 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -59,7 +59,7 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL private final ABCPanel abcPanel; private int classIndex = -1; private boolean isStatic = false; - private final Cache cache = Cache.getInstance(true); + private final Cache cache = Cache.getInstance(true); private Trait currentTrait = null; public Trait getCurrentTrait() { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java index 7960a1821..2c7e6b870 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/action/ActionPanel.java @@ -119,7 +119,7 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene private String lastDecompiled = ""; private ASMSource lastASM; public SearchPanel searchPanel; - private Cache cache = Cache.getInstance(true); + private Cache cache = Cache.getInstance(true); private CancellableWorker setSourceWorker; public void clearSource() { diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java index a6a711e11..e211c5ddd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java @@ -21,7 +21,7 @@ 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.ImageTag; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -55,9 +55,9 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { } @Override - public BufferedImage getImage(List tags) { + public SerializableImage getImage(List tags) { try { - return ImageIO.read(getImageData()); + return new SerializableImage(ImageIO.read(getImageData())); } catch (IOException ex) { } return null; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java index ce5099f6b..7118688ca 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java @@ -21,7 +21,7 @@ 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.ImageTag; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -45,7 +45,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { @Override public void setImage(byte[] data) throws IOException { if (ImageTag.getImageFormat(data).equals("jpg")) { - BufferedImage image = ImageIO.read(new ByteArrayInputStream(data)); + SerializableImage image = new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))); byte[] ba = new byte[image.getWidth() * image.getHeight()]; for (int i = 0; i < ba.length; i++) { ba[i] = (byte) 255; @@ -72,7 +72,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { } @Override - public BufferedImage getImage(List tags) { + public SerializableImage getImage(List tags) { try { InputStream stream; if (SWF.hasErrorHeader(imageData)) { @@ -80,11 +80,11 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { } else { stream = new ByteArrayInputStream(imageData); } - BufferedImage img = ImageIO.read(stream); + SerializableImage img = new SerializableImage(ImageIO.read(stream)); if (bitmapAlphaData.length == 0) { return img; } - BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); + SerializableImage img2 = new SerializableImage(img.getWidth(), img.getHeight(), SerializableImage.TYPE_INT_ARGB_PRE); for (int y = 0; y < img.getHeight(); y++) { for (int x = 0; x < img.getWidth(); x++) { int val = img.getRGB(x, y); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java index 3af8faa0a..ca0c03497 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java @@ -21,7 +21,7 @@ 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.ImageTag; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -62,7 +62,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { public void setImage(byte[] data) { imageData = data; if (ImageTag.getImageFormat(data).equals("jpg")) { - BufferedImage image = getImage(new ArrayList()); + SerializableImage image = getImage(new ArrayList()); byte[] ba = new byte[image.getWidth() * image.getHeight()]; for (int i = 0; i < ba.length; i++) { ba[i] = (byte) 255; @@ -79,13 +79,13 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { } @Override - public BufferedImage getImage(List tags) { + public SerializableImage getImage(List tags) { try { - BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageData)); + SerializableImage img = new SerializableImage(ImageIO.read(new ByteArrayInputStream(imageData))); if (bitmapAlphaData.length == 0) { return img; } - BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB); + SerializableImage img2 = new SerializableImage(img.getWidth(), img.getHeight(), SerializableImage.TYPE_INT_ARGB); for (int y = 0; y < img.getHeight(); y++) { for (int x = 0; x < img.getWidth(); x++) { int val = img.getRGB(x, y); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java index 54071cbcb..480e5465a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java @@ -24,8 +24,8 @@ 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.helpers.SerializableImage; import java.awt.Color; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -54,7 +54,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { @Override public void setImage(byte[] data) throws IOException { - BufferedImage image = ImageIO.read(new ByteArrayInputStream(data)); + SerializableImage image = new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))); ALPHABITMAPDATA bitmapData = new ALPHABITMAPDATA(); bitmapFormat = DefineBitsLosslessTag.FORMAT_24BIT_RGB; bitmapWidth = image.getWidth(); @@ -171,8 +171,8 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { } @Override - public BufferedImage getImage(List tags) { - BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_ARGB); + public SerializableImage getImage(List tags) { + SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_ARGB); ALPHACOLORMAPDATA colorMapData = null; ALPHABITMAPDATA bitmapData = null; if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED) { diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java index 889fff987..44bc38903 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java @@ -25,8 +25,8 @@ 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 com.jpexs.helpers.SerializableImage; import java.awt.Color; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -54,7 +54,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { @Override public void setImage(byte[] data) throws IOException { - BufferedImage image = ImageIO.read(new ByteArrayInputStream(data)); + SerializableImage image = new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))); bitmapFormat = FORMAT_24BIT_RGB; bitmapWidth = image.getWidth(); bitmapHeight = image.getHeight(); @@ -92,8 +92,8 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { } @Override - public BufferedImage getImage(List tags) { - BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_RGB); + public SerializableImage getImage(List tags) { + SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_RGB); COLORMAPDATA colorMapData = null; BITMAPDATA bitmapData = null; if (bitmapFormat == DefineBitsLosslessTag.FORMAT_8BIT_COLORMAPPED) { diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java index c6226dde5..8e6f43689 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java @@ -20,7 +20,7 @@ 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.ImageTag; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -71,7 +71,7 @@ public class DefineBitsTag extends ImageTag { } @Override - public BufferedImage getImage(List tags) { + public SerializableImage getImage(List tags) { getJPEGTables(tags); if ((jtt != null)) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { @@ -82,7 +82,7 @@ public class DefineBitsTag extends ImageTag { } else { baos.write(jpegData, 0, jpegData.length); } - return ImageIO.read(new ByteArrayInputStream(baos.toByteArray())); + return new SerializableImage(ImageIO.read(new ByteArrayInputStream(baos.toByteArray()))); } catch (IOException ex) { return null; } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java index 144aee603..c175898e2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButton2Tag.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.ButtonTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -32,9 +33,9 @@ import com.jpexs.decompiler.flash.types.BUTTONRECORD; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.helpers.Cache; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -202,7 +203,7 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded } return needed; } - private static final Cache rectCache = Cache.getInstance(true); + private static final Cache rectCache = Cache.getInstance(true); @Override public RECT getRect(HashMap allCharacters, Stack visited) { @@ -242,9 +243,9 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix mat, HashMap characters, Stack visited) { if (visited.contains(buttonId)) { - return new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR); + return new SerializableImage(1, 1, SerializableImage.TYPE_4BYTE_ABGR); } visited.push(buttonId); HashMap layers = new HashMap<>(); @@ -264,9 +265,9 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded } } visited.pop(); - displayRect = getRect(characters, visited); + RECT displayRect = getRect(characters, visited); visited.push(buttonId); - BufferedImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited); + SerializableImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited); return ret; } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java index d53fc1ddf..2bdec6edb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineButtonTag.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.ActionListReader; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.BoundedTag; @@ -37,9 +38,9 @@ import com.jpexs.decompiler.graph.ExportMode; import com.jpexs.helpers.Cache; import com.jpexs.helpers.Helper; import com.jpexs.helpers.MemoryInputStream; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -214,7 +215,7 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT } return needed; } - private static final Cache rectCache = Cache.getInstance(true); + private static final Cache rectCache = Cache.getInstance(true); @Override public RECT getRect(HashMap allCharacters, Stack visited) { @@ -265,9 +266,9 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { if (visited.contains(buttonId)) { - return new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR); + return new SerializableImage(1, 1, SerializableImage.TYPE_4BYTE_ABGR); } visited.push(buttonId); HashMap layers = new HashMap<>(); @@ -287,9 +288,9 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT } } visited.pop(); - displayRect = getRect(characters, visited); + RECT displayRect = getRect(characters, visited); visited.push(buttonId); - BufferedImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited); + SerializableImage ret = SWF.frameToImage(buttonId, maxDepth, layers, new Color(0, 0, 0, 0), characters, 1, tags, tags, displayRect, visited); visited.pop(); return ret; } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java index 901e45e18..e23499567 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShape2Tag.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; @@ -36,8 +37,8 @@ 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 com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -189,7 +190,7 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { List finalRecords = new ArrayList<>(); FILLSTYLEARRAY fillStyles = morphFillStyles.getFillStylesAt(frame); LINESTYLEARRAY lineStyles = morphLineStyles.getLineStylesAt(getShapeNum(), frame); @@ -263,7 +264,10 @@ public class DefineMorphShape2Tag extends CharacterTag implements BoundedTag, Mo shape.lineStyles = lineStyles; shape.shapeRecords = finalRecords; // shapeNum: 4 - return BitmapExporter.export(swf, shape, null, true); + // todo: Currently the generated image is not cached, because the cache + // key contains the hashCode of the finalRecord object, and it is always + // recreated + return BitmapExporter.export(swf, shape, null, false); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java index 09b6d82da..f33837834 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineMorphShapeTag.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; @@ -36,8 +37,8 @@ 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 com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -176,7 +177,7 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { List finalRecords = new ArrayList<>(); FILLSTYLEARRAY fillStyles = morphFillStyles.getFillStylesAt(frame); LINESTYLEARRAY lineStyles = morphLineStyles.getLineStylesAt(getShapeNum(), frame); @@ -250,7 +251,10 @@ public class DefineMorphShapeTag extends CharacterTag implements BoundedTag, Mor shape.lineStyles = lineStyles; shape.shapeRecords = finalRecords; // shapeNum: 3 - return BitmapExporter.export(swf, shape, null, true); + // todo: Currently the generated image is not cached, because the cache + // key contains the hashCode of the finalRecord object, and it is always + // recreated + return BitmapExporter.export(swf, shape, null, false); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java index 39f7218de..e9af1d8ef 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape2Tag.java @@ -19,14 +19,15 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.exporters.SVGShapeExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashMap; @@ -37,7 +38,7 @@ import java.util.Stack; public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTag { public int shapeId; - public RECT shapeBounds; + private RECT shapeBounds; public SHAPEWITHSTYLE shapes; public static final int ID = 22; @@ -69,9 +70,10 @@ public class DefineShape2Tag extends CharacterTag implements BoundedTag, ShapeTa } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { BitmapExporter exporter = new BitmapExporter(swf, getShapes()); exporter.export(); + matrix.translate(exporter.deltaX, exporter.deltaY); return exporter.getImage(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java index 941a9cb7a..b0d05d470 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape3Tag.java @@ -19,14 +19,15 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.exporters.SVGShapeExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashMap; @@ -37,7 +38,7 @@ import java.util.Stack; public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTag { public int shapeId; - public RECT shapeBounds; + private RECT shapeBounds; public SHAPEWITHSTYLE shapes; public static final int ID = 32; @@ -74,9 +75,10 @@ public class DefineShape3Tag extends CharacterTag implements BoundedTag, ShapeTa } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { BitmapExporter exporter = new BitmapExporter(swf, getShapes()); exporter.export(); + matrix.translate(exporter.deltaX, exporter.deltaY); return exporter.getImage(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java index 15f8774c1..c8ae0267f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShape4Tag.java @@ -19,14 +19,15 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.exporters.SVGShapeExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.HashMap; @@ -37,8 +38,8 @@ import java.util.Stack; public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTag { public int shapeId; - public RECT shapeBounds; - public RECT edgeBounds; + private RECT shapeBounds; + private RECT edgeBounds; public boolean usesFillWindingRule; public boolean usesNonScalingStrokes; public boolean usesScalingStrokes; @@ -73,9 +74,10 @@ public class DefineShape4Tag extends CharacterTag implements BoundedTag, ShapeTa } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { BitmapExporter exporter = new BitmapExporter(swf, getShapes()); exporter.export(); + matrix.translate(exporter.deltaX, exporter.deltaY); return exporter.getImage(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java index 12e20518b..2b0e1264f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineShapeTag.java @@ -20,14 +20,15 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.exporters.SVGShapeExporter; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.ShapeTag; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -39,7 +40,7 @@ import java.util.Stack; public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag { public int shapeId; - public RECT shapeBounds; + private RECT shapeBounds; public SHAPEWITHSTYLE shapes; public static final int ID = 2; @@ -103,9 +104,10 @@ public class DefineShapeTag extends CharacterTag implements BoundedTag, ShapeTag } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { BitmapExporter exporter = new BitmapExporter(swf, getShapes()); exporter.export(); + matrix.translate(exporter.deltaX, exporter.deltaY); return exporter.getImage(); } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java index 0d45e8773..39fff5fca 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineSpriteTag.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.abc.CopyOutputStream; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.base.BoundedTag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.Container; @@ -30,9 +31,9 @@ import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.helpers.Cache; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -101,7 +102,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT } return ret; } - private static final Cache rectCache = Cache.getInstance(true); + private static final Cache rectCache = Cache.getInstance(true); @Override public RECT getRect(HashMap characters, Stack visited) { @@ -271,9 +272,9 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { if (visited.contains(spriteId)) { - return new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR); + return new SerializableImage(1, 1, SerializableImage.TYPE_4BYTE_ABGR); } /* rect.Xmax=displayRect.Xmin+rect.getWidth(); @@ -284,7 +285,7 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT SWF.fixRect(rect);*/ RECT rect = getRect(characters, visited); visited.push(spriteId); - BufferedImage ret = SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount, visited); + SerializableImage ret = SWF.frameToImage(spriteId, frame, tags, subTags, rect, frameCount, visited); visited.pop(); return ret; } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java index a367b0171..ad3bd3d40 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java @@ -19,6 +19,7 @@ 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.exporters.Matrix; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.tags.base.FontTag; @@ -33,8 +34,8 @@ import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -488,8 +489,8 @@ public class DefineText2Tag extends TextTag implements DrawableTag { } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { - return staticTextToImage(swf, characters, textRecords, textBounds, 2); + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { + return staticTextToImage(swf, characters, textRecords, textBounds, matrix, 2); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java index 9be6fbc2f..b9d026933 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java @@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.AppStrings; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.base.CharacterTag; import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.tags.base.FontTag; @@ -34,8 +35,8 @@ import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -504,8 +505,8 @@ public class DefineTextTag extends TextTag implements DrawableTag { } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { - return staticTextToImage(swf, characters, textRecords, textBounds, 1); + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { + return staticTextToImage(swf, characters, textRecords, textBounds, matrix, 1); } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java index 372c1a264..6b9bf5ede 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/DrawableTag.java @@ -16,10 +16,10 @@ */ package com.jpexs.decompiler.flash.tags.base; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.Tag; -import com.jpexs.decompiler.flash.types.RECT; +import com.jpexs.helpers.SerializableImage; import java.awt.Point; -import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.List; import java.util.Stack; @@ -30,7 +30,7 @@ import java.util.Stack; */ public interface DrawableTag { - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited); + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited); public Point getImagePos(int frame, HashMap characters, Stack visited); diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index dff43b3bd..3fea91fd5 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -18,22 +18,22 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.helpers.FontHelper; import com.jpexs.decompiler.flash.tags.DefineText2Tag; import com.jpexs.decompiler.flash.tags.DefineTextTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.types.GLYPHENTRY; -import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Font; import java.awt.Point; import java.awt.font.FontRenderContext; import java.awt.font.GlyphMetrics; import java.awt.font.GlyphVector; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -247,7 +247,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { return SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), 500, 500, Color.black); } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java index bc6ec6e8a..7ab0cd200 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java @@ -18,8 +18,8 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; -import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.util.List; @@ -36,7 +36,7 @@ public abstract class ImageTag extends CharacterTag { public abstract InputStream getImageData(); - public abstract BufferedImage getImage(List tags); + public abstract SerializableImage getImage(List tags); public abstract void setImage(byte[] data) throws IOException; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/TextTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/TextTag.java index 6ede47b07..c02bce704 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/TextTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/TextTag.java @@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.tags.base; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.exporters.BitmapExporter; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.text.ParseException; import com.jpexs.decompiler.flash.types.GLYPHENTRY; @@ -26,6 +27,7 @@ import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; @@ -33,7 +35,6 @@ import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.font.LineMetrics; import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -100,7 +101,7 @@ public abstract class TextTag extends CharacterTag implements BoundedTag { List allLeftMargins = new ArrayList<>(); List allLetterSpacings = new ArrayList<>(); FontMetrics fontMetrics; - BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); + SerializableImage bi = new SerializableImage(5, 5, SerializableImage.TYPE_INT_RGB); Font aFont = null; int currentLeftMargin; for (int r = 0; r < list.size(); r++) { @@ -192,10 +193,12 @@ public abstract class TextTag extends CharacterTag implements BoundedTag { return att; } - public static BufferedImage staticTextToImage(SWF swf, HashMap characters, List textRecords, RECT textBounds, int numText) { - int fixX = -textBounds.Xmin; - int fixY = -textBounds.Ymin; - BufferedImage ret = new BufferedImage(textBounds.getWidth() / 20, textBounds.getHeight() / 20, BufferedImage.TYPE_INT_ARGB); + public static SerializableImage staticTextToImage(SWF swf, HashMap characters, List textRecords, RECT textBounds, Matrix matrix, int numText) { + float unzoom = 20; + double fixX = -textBounds.Xmin / unzoom; + double fixY = -textBounds.Ymin / unzoom; + matrix.translate(-fixX, -fixY); + SerializableImage ret = new SerializableImage(textBounds.getWidth() / 20, textBounds.getHeight() / 20, SerializableImage.TYPE_INT_ARGB); Color textColor = new Color(0, 0, 0); FontTag font = null; @@ -228,20 +231,16 @@ public abstract class TextTag extends CharacterTag implements BoundedTag { } for (GLYPHENTRY entry : rec.glyphEntries) { - RECT rect = SHAPERECORD.getBounds(glyphs.get(entry.glyphIndex).shapeRecords); - rect.Xmax /= font.getDivider(); - rect.Xmin /= font.getDivider(); - rect.Ymax /= font.getDivider(); - rect.Ymin /= font.getDivider(); // shapeNum: 1 - BufferedImage img = BitmapExporter.export(swf, glyphs.get(entry.glyphIndex), textColor, true); + Matrix matrix2 = new Matrix(); + SerializableImage img = BitmapExporter.export(swf, glyphs.get(entry.glyphIndex), textColor, true, matrix2); AffineTransform tr = new AffineTransform(); tr.setToIdentity(); float rat = textHeight / 1024f; - tr.scale(1 / 20f, 1 / 20f); - tr.translate(x + fixX, y + rat * rect.Ymin + fixY); + tr.translate(x / unzoom + matrix2.translateX + fixX, y / unzoom + rat * matrix2.translateY + fixY); + tr.scale(1.0 / font.getDivider(), 1.0 / font.getDivider()); tr.scale(rat, rat); - g.drawImage(img, tr, null); + g.drawImage(img.getBufferedImage(), tr, null); x += entry.glyphAdvance; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java b/trunk/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java index a90a3be81..9bc56b65c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.tags.gfx; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.DefineFont2Tag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.CharacterTag; @@ -40,24 +41,20 @@ import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.helpers.Cache; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Font; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.OutputStream; -import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Stack; import java.util.logging.Level; import java.util.logging.Logger; -import javax.imageio.ImageIO; import javax.swing.JPanel; /** @@ -71,34 +68,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { public int fontId; public List fonts; private List shapeCache; - private static final Cache imageCache = Cache.getInstance(false); - - private static class SerializableImage implements Serializable { - - transient BufferedImage image; - - public BufferedImage getImage() { - return image; - } - - public void setImage(BufferedImage image) { - this.image = image; - } - - public SerializableImage(BufferedImage image) { - this.image = image; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - ImageIO.write(image, "png", out); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - image = ImageIO.read(in); - } - } + private static final Cache imageCache = Cache.getInstance(false); /** * Gets data bytes @@ -148,9 +118,9 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { } @Override - public BufferedImage toImage(int frame, List tags, RECT displayRect, HashMap characters, Stack visited) { + public SerializableImage toImage(int frame, List tags, Matrix matrix, HashMap characters, Stack visited) { if (imageCache.contains("font" + fontId)) { - return ((SerializableImage) imageCache.get("font" + fontId)).getImage(); + return ((SerializableImage) imageCache.get("font" + fontId)); } List shapes = new ArrayList<>(); for (int i = 0; i < shapeCache.size(); i++) { @@ -161,8 +131,8 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { if (size / cols < 30) { size = cols * 30; } - BufferedImage ret = SHAPERECORD.shapeListToImage(swf, shapes, size, size, Color.black); - imageCache.put("font" + fontId, new SerializableImage(ret)); + SerializableImage ret = SHAPERECORD.shapeListToImage(swf, shapes, size, size, Color.black); + imageCache.put("font" + fontId, ret); return ret; } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/CXFORM.java b/trunk/src/com/jpexs/decompiler/flash/types/CXFORM.java index ee1e44c76..2957ce20e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/CXFORM.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/CXFORM.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.types; import com.jpexs.decompiler.flash.types.filters.Filtering; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Defines a transform that can be applied to the color space of a graphic @@ -61,7 +61,7 @@ public class CXFORM { */ public int blueAddTerm; - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { return Filtering.colorEffect(src, hasAddTerms ? redAddTerm : 0, hasAddTerms ? greenAddTerm : 0, hasAddTerms ? blueAddTerm : 0, 0, hasMultTerms ? redMultTerm : 255, hasMultTerms ? greenMultTerm : 255, hasMultTerms ? blueMultTerm : 255, 1); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java b/trunk/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java index 30b9f36bd..ed657b3b6 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/CXFORMWITHALPHA.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.types; import com.jpexs.decompiler.flash.types.filters.Filtering; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Defines a transform that can be applied to the color space of a graphic @@ -69,7 +69,7 @@ public class CXFORMWITHALPHA { public int alphaAddTerm; public int nbits; - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { return Filtering.colorEffect(src, hasAddTerms ? redAddTerm : 0, hasAddTerms ? greenAddTerm : 0, hasAddTerms ? blueAddTerm : 0, hasAddTerms ? alphaAddTerm : 0, hasMultTerms ? redMultTerm : 255, hasMultTerms ? greenMultTerm : 255, hasMultTerms ? blueMultTerm : 255, hasMultTerms ? alphaMultTerm : 255); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java index 5ef751efa..f8b07d2bb 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/BEVELFILTER.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.decompiler.flash.types.RGBA; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * The Bevel filter creates a smooth bevel on display list objects. @@ -83,7 +83,7 @@ public class BEVELFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { int type = Filtering.INNER; if (onTop && !innerShadow) { type = Filtering.FULL; diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java index 5c3cae7a3..624c344ac 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/BLURFILTER.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.types.filters; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Blur filter based on a sub-pixel precise median filter @@ -43,7 +43,7 @@ public class BLURFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { return Filtering.blur(src, (int) blurX, (int) blurY, passes); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java index bec4da80e..42e618f4e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/COLORMATRIXFILTER.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.types.filters; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Applies a color transformation on the pixels of a display list object @@ -38,7 +38,7 @@ public class COLORMATRIXFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { float[][] matrix2 = new float[4][4]; for (int y = 0; y < 4; y++) { for (int x = 0; x < 4; x++) { diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java index e9e8f6715..96979ad03 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/CONVOLUTIONFILTER.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.decompiler.flash.types.RGBA; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Two-dimensional discrete convolution filter. @@ -67,7 +67,7 @@ public class CONVOLUTIONFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { int height = matrix.length; int width = matrix[0].length; float[] matrix2 = new float[width * height]; diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java index c4493b7eb..c3278f19e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/DROPSHADOWFILTER.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.decompiler.flash.types.RGBA; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Drop shadow filter based on the same median filter as the blur filter @@ -75,7 +75,7 @@ public class DROPSHADOWFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { return Filtering.dropShadow(src, (int) blurX, (int) blurY, (int) (angle * 180 / Math.PI), distance, dropShadowColor.toColor(), innerShadow, passes, strength, knockout); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/FILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/FILTER.java index b38c61cd7..92b588350 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/FILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/FILTER.java @@ -16,7 +16,7 @@ */ package com.jpexs.decompiler.flash.types.filters; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Bitmap filter @@ -39,7 +39,7 @@ public class FILTER { this.id = id; } - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { return src; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/Filtering.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/Filtering.java index 1f6eb0d1d..42b8b3944 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/Filtering.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/Filtering.java @@ -16,6 +16,7 @@ */ package com.jpexs.decompiler.flash.types.filters; +import com.jpexs.helpers.SerializableImage; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; @@ -25,7 +26,6 @@ import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BandCombineOp; -import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; @@ -215,15 +215,15 @@ public class Filtering { } } - public static BufferedImage blur(BufferedImage src, int hRadius, int vRadius, int iterations) { + public static SerializableImage blur(SerializableImage src, int hRadius, int vRadius, int iterations) { return blur(src, hRadius, vRadius, iterations, null); } - private static BufferedImage blur(BufferedImage src, int hRadius, int vRadius, int iterations, int[] mask) { + private static SerializableImage blur(SerializableImage src, int hRadius, int vRadius, int iterations, int[] mask) { int width = src.getWidth(); int height = src.getHeight(); - BufferedImage dst = new BufferedImage(width, height, src.getType()); + SerializableImage dst = new SerializableImage(width, height, src.getType()); int[] inPixels = getRGB(src, 0, 0, width, height); premultiply(inPixels); @@ -237,7 +237,7 @@ public class Filtering { return dst; } - public static BufferedImage bevel(BufferedImage src, int blurX, int blurY, float strength, int type, Color highlightColor, Color shadowColor, float angle, float distance, boolean knockout, int iterations) { + public static SerializableImage bevel(SerializableImage src, int blurX, int blurY, float strength, int type, Color highlightColor, Color shadowColor, float angle, float distance, boolean knockout, int iterations) { return gradientBevel(src, new Color[]{ highlightColor, new Color(highlightColor.getRed(), highlightColor.getGreen(), highlightColor.getBlue(), 0), @@ -246,22 +246,22 @@ public class Filtering { }, new float[]{0, 127f / 255f, 128f / 255f, 1}, blurX, blurY, strength, type, angle, distance, knockout, iterations); } - public static BufferedImage gradientBevel(BufferedImage src, Color[] colors, float[] ratios, int blurX, int blurY, float strength, int type, float angle, float distance, boolean knockout, int iterations) { + public static SerializableImage gradientBevel(SerializableImage src, Color[] colors, float[] ratios, int blurX, int blurY, float strength, int type, float angle, float distance, boolean knockout, int iterations) { int width = src.getWidth(); int height = src.getHeight(); - BufferedImage retImg = new BufferedImage(width, height, src.getType()); + SerializableImage retImg = new SerializableImage(width, height, src.getType()); if (type == FULL) { - BufferedImage partIn = gradientBevel(src, colors, ratios, blurX, blurY, strength, INNER, angle, distance, true, iterations); - BufferedImage partOut = gradientBevel(src, colors, ratios, blurX, blurY, strength, OUTER, angle, distance, true, iterations); + SerializableImage partIn = gradientBevel(src, colors, ratios, blurX, blurY, strength, INNER, angle, distance, true, iterations); + SerializableImage partOut = gradientBevel(src, colors, ratios, blurX, blurY, strength, OUTER, angle, distance, true, iterations); Graphics2D g = (Graphics2D) retImg.getGraphics(); - g.drawImage(partIn, 0, 0, null); + g.drawImage(partIn.getBufferedImage(), 0, 0, null); g.setComposite(AlphaComposite.SrcOver); - g.drawImage(partOut, 0, 0, null); + g.drawImage(partOut.getBufferedImage(), 0, 0, null); } else { boolean inner = type == INNER; int[] srcPixels = getRGB(src, 0, 0, width, height); - BufferedImage gradient = new BufferedImage(512, 1, BufferedImage.TYPE_INT_ARGB); + SerializableImage gradient = new SerializableImage(512, 1, SerializableImage.TYPE_INT_ARGB); Graphics2D gg = (Graphics2D) gradient.getGraphics(); Point pnt1 = new Point(0, 0); Point pnt2 = new Point(512, 0); @@ -269,8 +269,8 @@ public class Filtering { gg.fill(new Rectangle(512, 1)); int[] gradientPixels = getRGB(gradient, 0, 0, gradient.getWidth(), gradient.getHeight()); - BufferedImage hilightIm = dropShadow(src, blurX, blurY, angle, distance, Color.black, inner, iterations, strength, true);//new DropShadowFilter(blurX, blurY, strength, inner ? highlightColor : shadowColor, angle, distance, inner, true, iterations).filter(src); - BufferedImage shadowIm = dropShadow(src, blurX, blurY, angle + 180, distance, Color.black, inner, iterations, strength, true); //new DropShadowFilter(blurX, blurY, strength, inner ? shadowColor : highlightColor, angle + 180, distance, inner, true, iterations).filter(src); + SerializableImage hilightIm = dropShadow(src, blurX, blurY, angle, distance, Color.black, inner, iterations, strength, true);//new DropShadowFilter(blurX, blurY, strength, inner ? highlightColor : shadowColor, angle, distance, inner, true, iterations).filter(src); + SerializableImage shadowIm = dropShadow(src, blurX, blurY, angle + 180, distance, Color.black, inner, iterations, strength, true); //new DropShadowFilter(blurX, blurY, strength, inner ? shadowColor : highlightColor, angle + 180, distance, inner, true, iterations).filter(src); int[] hilight = getRGB(hilightIm, 0, 0, width, height); int[] shadow = getRGB(shadowIm, 0, 0, width, height); for (int i = 0; i < srcPixels.length; i++) { @@ -307,35 +307,35 @@ public class Filtering { if (!knockout) { Graphics2D g = (Graphics2D) retImg.getGraphics(); g.setComposite(AlphaComposite.DstOver); - g.drawImage(src, 0, 0, null); + g.drawImage(src.getBufferedImage(), 0, 0, null); } return retImg; } - public static BufferedImage glow(BufferedImage src, int blurX, int blurY, float strength, Color color, boolean inner, boolean knockout, int iterations) { + public static SerializableImage glow(SerializableImage src, int blurX, int blurY, float strength, Color color, boolean inner, boolean knockout, int iterations) { return dropShadow(src, blurX, blurY, 45, 0, color, inner, iterations, strength, knockout); } - public static BufferedImage dropShadow(BufferedImage src, int blurX, int blurY, float angle, double distance, Color color, boolean inner, int iterations, float strength, boolean knockout) { + public static SerializableImage dropShadow(SerializableImage src, int blurX, int blurY, float angle, double distance, Color color, boolean inner, int iterations, float strength, boolean knockout) { return gradientGlow(src, blurX, blurY, angle, distance, new Color[]{new Color(color.getRed(), color.getGreen(), color.getBlue(), 0), color}, new float[]{0, 1}, inner ? INNER : OUTER, iterations, strength, knockout); } - public static BufferedImage gradientGlow(BufferedImage src, int blurX, int blurY, float angle, double distance, Color[] colors, float[] ratios, int type, int iterations, float strength, boolean knockout) { + public static SerializableImage gradientGlow(SerializableImage src, int blurX, int blurY, float angle, double distance, Color[] colors, float[] ratios, int type, int iterations, float strength, boolean knockout) { int width = src.getWidth(); int height = src.getHeight(); - BufferedImage retImg = new BufferedImage(width, height, src.getType()); + SerializableImage retImg = new SerializableImage(width, height, src.getType()); if (type == FULL) { - BufferedImage partIn = gradientGlow(src, blurX, blurY, angle, distance, colors, ratios, INNER, iterations, strength, true); - BufferedImage partOut = gradientGlow(src, blurX, blurY, angle, distance, colors, ratios, OUTER, iterations, strength, true); + SerializableImage partIn = gradientGlow(src, blurX, blurY, angle, distance, colors, ratios, INNER, iterations, strength, true); + SerializableImage partOut = gradientGlow(src, blurX, blurY, angle, distance, colors, ratios, OUTER, iterations, strength, true); Graphics2D g = (Graphics2D) retImg.getGraphics(); - g.drawImage(partIn, 0, 0, null); + g.drawImage(partIn.getBufferedImage(), 0, 0, null); g.setComposite(AlphaComposite.SrcOver); - g.drawImage(partOut, 0, 0, null); + g.drawImage(partOut.getBufferedImage(), 0, 0, null); } else { boolean inner = type == INNER; - BufferedImage gradient = new BufferedImage(256, 1, BufferedImage.TYPE_INT_ARGB); + SerializableImage gradient = new SerializableImage(256, 1, SerializableImage.TYPE_INT_ARGB); Graphics2D gg = (Graphics2D) gradient.getGraphics(); gg.setPaint(new LinearGradientPaint(new Point(0, 0), new Point(256, 0), ratios, colors)); gg.fill(new Rectangle(256, 1)); @@ -389,23 +389,23 @@ public class Filtering { Graphics2D g = (Graphics2D) retImg.getGraphics(); //g.setComposite(inner ? AlphaComposite.DstOver : AlphaComposite.SrcOver); g.setComposite(AlphaComposite.DstOver); - g.drawImage(src, 0, 0, null); + g.drawImage(src.getBufferedImage(), 0, 0, null); } return retImg; } - public static int[] getRGB(BufferedImage image, int x, int y, int width, int height) { + public static int[] getRGB(SerializableImage image, int x, int y, int width, int height) { int type = image.getType(); - if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) { + if (type == SerializableImage.TYPE_INT_ARGB || type == SerializableImage.TYPE_INT_RGB) { return (int[]) image.getRaster().getDataElements(x, y, width, height, null); } return image.getRGB(x, y, width, height, null, 0, width); } - public static void setRGB(BufferedImage image, int x, int y, int width, int height, int[] pixels) { + public static void setRGB(SerializableImage image, int x, int y, int width, int height, int[] pixels) { int type = image.getType(); - if (type == BufferedImage.TYPE_INT_ARGB || type == BufferedImage.TYPE_INT_RGB) { + if (type == SerializableImage.TYPE_INT_ARGB || type == SerializableImage.TYPE_INT_RGB) { image.getRaster().setDataElements(x, y, width, height, pixels); } else { image.setRGB(x, y, width, height, pixels, 0, width); @@ -413,9 +413,9 @@ public class Filtering { } private static int[] moveRGB(int width, int height, int[] rgb, double deltaX, double deltaY, Color fill) { - BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + SerializableImage img = new SerializableImage(width, height, SerializableImage.TYPE_INT_ARGB); setRGB(img, 0, 0, width, height, rgb); - BufferedImage retImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + SerializableImage retImg = new SerializableImage(width, height, SerializableImage.TYPE_INT_ARGB); Graphics2D g = (Graphics2D) retImg.getGraphics(); g.setPaint(fill); g.fillRect(0, 0, width, height); @@ -425,23 +425,23 @@ public class Filtering { g.setTransform(AffineTransform.getTranslateInstance(deltaX, deltaY)); g.setComposite(AlphaComposite.Src); - g.drawImage(img, 0, 0, null); + g.drawImage(img.getBufferedImage(), 0, 0, null); return getRGB(retImg, 0, 0, width, height); } - public static BufferedImage convolution(BufferedImage src, float[] matrix, int w, int h) { - BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), src.getType()); + public static SerializableImage convolution(SerializableImage src, float[] matrix, int w, int h) { + SerializableImage dst = new SerializableImage(src.getWidth(), src.getHeight(), src.getType()); BufferedImageOp op = new ConvolveOp(new Kernel(w, h, matrix), ConvolveOp.EDGE_ZERO_FILL, new RenderingHints(null)); - op.filter(src, dst); + op.filter(src.getBufferedImage(), dst.getBufferedImage()); return dst; } - public static BufferedImage colorMatrix(BufferedImage src, float[][] matrix) { + public static SerializableImage colorMatrix(SerializableImage src, float[][] matrix) { BandCombineOp changeColors = new BandCombineOp(matrix, new RenderingHints(null)); Raster sourceRaster = src.getRaster(); WritableRaster displayRaster = sourceRaster.createCompatibleWritableRaster(); changeColors.filter(sourceRaster, displayRaster); - return new BufferedImage(src.getColorModel(), displayRaster, true, null); + return new SerializableImage(src.getColorModel(), displayRaster, true, null); } private static int cut(double val) { @@ -455,10 +455,10 @@ public class Filtering { return i; } - public static BufferedImage colorEffect(BufferedImage src, + public static SerializableImage colorEffect(SerializableImage src, int redAddTerm, int greenAddTerm, int blueAddTerm, int alphaAddTerm, int redMultTerm, int greenMultTerm, int blueMultTerm, int alphaMultTerm) { - BufferedImage dst = new BufferedImage(src.getWidth(), src.getHeight(), src.getType()); + SerializableImage dst = new SerializableImage(src.getWidth(), src.getHeight(), src.getType()); int rgb[] = getRGB(src, 0, 0, src.getWidth(), src.getHeight()); for (int i = 0; i < rgb.length; i++) { int a = (rgb[i] >> 24) & 0xff; diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java index da655b5d1..6db56ebbe 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/GLOWFILTER.java @@ -17,7 +17,7 @@ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.decompiler.flash.types.RGBA; -import java.awt.image.BufferedImage; +import com.jpexs.helpers.SerializableImage; /** * Glow filter @@ -67,7 +67,7 @@ public class GLOWFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { return Filtering.glow(src, (int) blurX, (int) blurY, strength, glowColor.toColor(), innerGlow, knockout, passes); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java index 15789dc52..871037361 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTBEVELFILTER.java @@ -17,8 +17,8 @@ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; @@ -83,7 +83,7 @@ public class GRADIENTBEVELFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { List colors = new ArrayList<>(); List ratios = new ArrayList<>(); for (int i = 0; i < gradientColors.length; i++) { diff --git a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java index 1eaf820c3..b9adfafa7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/filters/GRADIENTGLOWFILTER.java @@ -17,8 +17,8 @@ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; @@ -86,7 +86,7 @@ public class GRADIENTGLOWFILTER extends FILTER { } @Override - public BufferedImage apply(BufferedImage src) { + public SerializableImage apply(SerializableImage src) { List colors = new ArrayList<>(); List ratios = new ArrayList<>(); for (int i = 0; i < gradientColors.length; i++) { diff --git a/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java b/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java index a9ec33757..b27574056 100644 --- a/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java +++ b/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SHAPERECORD.java @@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.tags.base.NeedsCharacters; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.helpers.Helper; +import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; @@ -31,7 +32,6 @@ import java.awt.Shape; import java.awt.font.GlyphVector; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; -import java.awt.image.BufferedImage; import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; @@ -114,13 +114,13 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali CurvedEdgeRecord ret = new CurvedEdgeRecord(); ret.controlDeltaX = ser.deltaX / 2; ret.controlDeltaY = ser.deltaY / 2; - ret.anchorDeltaX = ser.deltaX / 2; - ret.anchorDeltaY = ser.deltaY / 2; + ret.anchorDeltaX = ser.deltaX - ret.controlDeltaX; + ret.anchorDeltaY = ser.deltaY - ret.controlDeltaY; return ret; } - public static BufferedImage shapeListToImage(SWF swf, List shapes, int prevWidth, int prevHeight, Color color) { - BufferedImage ret = new BufferedImage(prevWidth, prevHeight, BufferedImage.TYPE_INT_ARGB); + public static SerializableImage shapeListToImage(SWF swf, List shapes, int prevWidth, int prevHeight, Color color) { + SerializableImage ret = new SerializableImage(prevWidth, prevHeight, SerializableImage.TYPE_INT_ARGB); Graphics g = ret.getGraphics(); int maxw = 0; @@ -161,7 +161,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali } // shapeNum: 1 - BufferedImage img = BitmapExporter.export(swf, shapes.get(pos), color, false); + SerializableImage img = BitmapExporter.export(swf, shapes.get(pos), color, false); int w1 = img.getWidth(); int h1 = img.getHeight(); @@ -170,7 +170,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali int h = Math.round(ratio * h1); int px = x * w2 + w2 / 2 - w / 2; int py = y * h2 + w2 - h; - g.drawImage(img, px, py, px + w, py + h, 0, 0, w1, h1, null); + g.drawImage(img.getBufferedImage(), px, py, px + w, py + h, 0, 0, w1, h1, null); pos++; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SerializableImage.java b/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SerializableImage.java deleted file mode 100644 index 219f7cefc..000000000 --- a/trunk/src/com/jpexs/decompiler/flash/types/shaperecords/SerializableImage.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010-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 . - */ - -package com.jpexs.decompiler.flash.types.shaperecords; - -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import javax.imageio.ImageIO; - -/** - * - * @author JPEXS - */ -public class SerializableImage implements Serializable { - - transient BufferedImage image; - - public BufferedImage getImage() { - return image; - } - - public void setImage(BufferedImage image) { - this.image = image; - } - - public SerializableImage(BufferedImage image) { - this.image = image; - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.defaultWriteObject(); - ImageIO.write(image, "png", out); - } - - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); - image = ImageIO.read(in); - } -} diff --git a/trunk/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/trunk/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java index 511992412..0735c0fbd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java +++ b/trunk/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java @@ -92,10 +92,10 @@ import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.decompiler.flash.types.sound.MP3FRAME; import com.jpexs.decompiler.graph.ExportMode; +import com.jpexs.helpers.SerializableImage; import com.jpexs.helpers.utf8.Utf8Helper; import java.awt.Font; import java.awt.Point; -import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -1273,10 +1273,10 @@ public class XFLConverter { } else if (symbol instanceof ImageTag) { ImageTag imageTag = (ImageTag) symbol; ByteArrayOutputStream baos = new ByteArrayOutputStream(); - BufferedImage image = imageTag.getImage(tags); + SerializableImage image = imageTag.getImage(tags); String format = imageTag.getImageFormat(); try { - ImageIO.write(image, format.toUpperCase(), baos); + ImageIO.write(image.getBufferedImage(), format.toUpperCase(), baos); } catch (IOException ex) { Logger.getLogger(XFLConverter.class.getName()).log(Level.SEVERE, null, ex); } diff --git a/trunk/src/com/jpexs/helpers/Cache.java b/trunk/src/com/jpexs/helpers/Cache.java index 077bb76a4..fccf5bd2e 100644 --- a/trunk/src/com/jpexs/helpers/Cache.java +++ b/trunk/src/com/jpexs/helpers/Cache.java @@ -16,8 +16,6 @@ */ package com.jpexs.helpers; -import com.jpexs.decompiler.flash.types.shaperecords.SerializableImage; -import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -37,16 +35,16 @@ import java.util.logging.Logger; * * @author JPEXS */ -public class Cache { +public class Cache { private final Map cacheFiles; - private final Map cacheMemory; + private final Map cacheMemory; private static final List instances = new ArrayList<>(); public static final int STORAGE_FILES = 1; public static final int STORAGE_MEMORY = 2; - public static Cache getInstance(boolean weak) { - Cache instance = new Cache(weak); + public static Cache getInstance(boolean weak) { + Cache instance = new Cache<>(weak); instances.add(instance); return instance; } @@ -122,7 +120,7 @@ public class Cache { } - public Object get(Object key) { + public E get(Object key) { if (storageType == STORAGE_FILES) { if (!cacheFiles.containsKey(key)) { return null; @@ -130,10 +128,8 @@ public class Cache { File f = cacheFiles.get(key); try (FileInputStream fis = new FileInputStream(f)) { ObjectInputStream ois = new ObjectInputStream(fis); - Object item = ois.readObject(); - if (item instanceof SerializableImage) { - item = ((SerializableImage) item).getImage(); - } + @SuppressWarnings("unchecked") + E item = (E) ois.readObject(); return item; } catch (IOException | ClassNotFoundException ex) { Logger.getLogger(Helper.class.getName()).log(Level.SEVERE, null, ex); @@ -148,7 +144,7 @@ public class Cache { return null; } - public void put(Object key, Object value) { + public void put(Object key, E value) { if (storageType == STORAGE_FILES) { File temp = null; try { @@ -168,13 +164,8 @@ public class Cache { if (value instanceof Serializable) { oos.writeObject(value); } else { - if (value instanceof BufferedImage) { - value = new SerializableImage((BufferedImage) value); - oos.writeObject(value); - } else { - // Object serialization not supported - return; - } + // Object serialization not supported + return; } oos.flush(); diff --git a/trunk/src/com/jpexs/helpers/SerializableImage.java b/trunk/src/com/jpexs/helpers/SerializableImage.java new file mode 100644 index 000000000..6f78a53a6 --- /dev/null +++ b/trunk/src/com/jpexs/helpers/SerializableImage.java @@ -0,0 +1,140 @@ +/* + * 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 . + */ + +package com.jpexs.helpers; + +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.ImageCapabilities; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.ImageObserver; +import java.awt.image.IndexColorModel; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; +import java.awt.image.TileObserver; +import java.awt.image.WritableRaster; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.Hashtable; +import java.util.Vector; +import javax.imageio.ImageIO; + +/** + * + * @author JPEXS + */ +public class SerializableImage implements Serializable { + + public static int TYPE_INT_ARGB = BufferedImage.TYPE_INT_ARGB; + public static int TYPE_INT_RGB = BufferedImage.TYPE_INT_RGB; + public static int TYPE_INT_ARGB_PRE = BufferedImage.TYPE_INT_ARGB_PRE; + public static int TYPE_4BYTE_ABGR = BufferedImage.TYPE_4BYTE_ABGR; + + private BufferedImage image; + + public SerializableImage() { + } + + public SerializableImage(BufferedImage image) { + this.image = image; + } + + public SerializableImage(int i, int i1, int i2) { + image = new BufferedImage(i, i1, i2); + } + + public SerializableImage(ColorModel cm, WritableRaster wr, boolean bln, Hashtable hshtbl) { + image = new BufferedImage(cm, wr, bln, hshtbl); + } + + public SerializableImage(int i, int i1, int i2, IndexColorModel icm) { + image = new BufferedImage(i, i1, i2, icm); + } + + public BufferedImage getBufferedImage() { + return image; + } + + @Override + protected Object clone() throws CloneNotSupportedException { + SerializableImage image = new SerializableImage(); + image.image = this.image; + return image; + } + + public Graphics getGraphics() { + return image.getGraphics(); + } + + public int getType() { + return image.getType(); + } + + public int getWidth() { + return image.getWidth(); + } + + public int getHeight() { + return image.getHeight(); + } + + public int getRGB(int i, int i1) { + return image.getRGB(i, i1); + } + + public int[] getRGB(int i, int i1, int i2, int i3, int[] ints, int i4, int i5) { + return image.getRGB(i, i1, i2, i3, ints, i4, i5); + } + + public synchronized void setRGB(int i, int i1, int i2) { + image.setRGB(i, i1, i2); + } + + public void setRGB(int i, int i1, int i2, int i3, int[] ints, int i4, int i5) { + image.setRGB(i, i1, i2, i3, ints, i4, i5); + } + + public ColorModel getColorModel() { + return image.getColorModel(); + } + + public WritableRaster getRaster() { + return image.getRaster(); + } + + @Override + public String toString() { + return image.toString(); + } + + private void writeObject(ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + ImageIO.write(image, "png", out); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + image = ImageIO.read(in); + } +}