some sprite/frame rendering issue fixed, generic cache, serializableimages

This commit is contained in:
Honfika
2014-01-29 00:58:30 +01:00
parent 7c2311ed30
commit 0486cb3958
48 changed files with 470 additions and 344 deletions

View File

@@ -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<SerializableImage> 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<Integer, Layer> layers, Color backgroundColor, HashMap<Integer, CharacterTag> characters, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, Stack<Integer> visited) {
int fixX = 0;
int fixY = 0;
fixX = -displayRect.Xmin / 20;
fixY = -displayRect.Ymin / 20;
public static SerializableImage frameToImage(int containerId, int maxDepth, HashMap<Integer, Layer> layers, Color backgroundColor, HashMap<Integer, CharacterTag> characters, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, Stack<Integer> 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<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited) {
List<BufferedImage> ret = new ArrayList<>();
public static SerializableImage frameToImage(int containerId, int frame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited) {
List<SerializableImage> 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<BufferedImage> ret, int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> visited) {
public static void framesToImage(int containerId, List<SerializableImage> ret, int startFrame, int stopFrame, List<Tag> allTags, List<Tag> controlTags, RECT displayRect, int totalFrameCount, Stack<Integer> 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;
}

View File

@@ -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<SerializableImage> cache = Cache.getInstance(false);
private static final Cache<Double> cacheDeltaX = Cache.getInstance(false);
private static final Cache<Double> 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<SHAPERECORD> 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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();

View File

@@ -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<Integer>()));
Matrix mat = new Matrix();
mat.translateX = swf.displayRect.Xmin;
mat.translateY = swf.displayRect.Ymin;
setImage(drawable.toImage(0, swf.tags, mat, characters, new Stack<Integer>()));
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<Integer>()));
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<Integer>()).getBufferedImage());
label.setIcon(icon);
}
}

View File

@@ -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);

View File

@@ -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<BufferedImage> frameImages = new ArrayList<>();
List<SerializableImage> frameImages = new ArrayList<>();
JLabel buffering = new JLabel(AppStrings.translate("work.buffering") + "...");
public SWFPreviwPanel() {

View File

@@ -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<CachedDecompilation> cache = Cache.getInstance(true);
private Trait currentTrait = null;
public Trait getCurrentTrait() {

View File

@@ -119,7 +119,7 @@ public class ActionPanel extends JPanel implements ActionListener, SearchListene
private String lastDecompiled = "";
private ASMSource lastASM;
public SearchPanel<ASMSource> searchPanel;
private Cache cache = Cache.getInstance(true);
private Cache<CachedScript> cache = Cache.getInstance(true);
private CancellableWorker setSourceWorker;
public void clearSource() {

View File

@@ -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<Tag> tags) {
public SerializableImage getImage(List<Tag> tags) {
try {
return ImageIO.read(getImageData());
return new SerializableImage(ImageIO.read(getImageData()));
} catch (IOException ex) {
}
return null;

View File

@@ -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<Tag> tags) {
public SerializableImage getImage(List<Tag> 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);

View File

@@ -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<Tag>());
SerializableImage image = getImage(new ArrayList<Tag>());
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<Tag> tags) {
public SerializableImage getImage(List<Tag> 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);

View File

@@ -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<Tag> tags) {
BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_ARGB);
public SerializableImage getImage(List<Tag> tags) {
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_ARGB);
ALPHACOLORMAPDATA colorMapData = null;
ALPHABITMAPDATA bitmapData = null;
if (bitmapFormat == DefineBitsLossless2Tag.FORMAT_8BIT_COLORMAPPED) {

View File

@@ -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<Tag> tags) {
BufferedImage bi = new BufferedImage(bitmapWidth, bitmapHeight, BufferedImage.TYPE_INT_RGB);
public SerializableImage getImage(List<Tag> tags) {
SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_RGB);
COLORMAPDATA colorMapData = null;
BITMAPDATA bitmapData = null;
if (bitmapFormat == DefineBitsLosslessTag.FORMAT_8BIT_COLORMAPPED) {

View File

@@ -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<Tag> tags) {
public SerializableImage getImage(List<Tag> 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;
}

View File

@@ -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<RECT> rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
@@ -242,9 +243,9 @@ public class DefineButton2Tag extends CharacterTag implements Container, Bounded
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix mat, HashMap<Integer, CharacterTag> characters, Stack<Integer> 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<Integer, Layer> 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;
}

View File

@@ -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<RECT> rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> allCharacters, Stack<Integer> visited) {
@@ -265,9 +266,9 @@ public class DefineButtonTag extends CharacterTag implements ASMSource, BoundedT
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> 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<Integer, Layer> 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;
}

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
List<SHAPERECORD> 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

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
List<SHAPERECORD> 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

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
BitmapExporter exporter = new BitmapExporter(swf, getShapes());
exporter.export();
matrix.translate(exporter.deltaX, exporter.deltaY);
return exporter.getImage();
}

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
BitmapExporter exporter = new BitmapExporter(swf, getShapes());
exporter.export();
matrix.translate(exporter.deltaX, exporter.deltaY);
return exporter.getImage();
}

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
BitmapExporter exporter = new BitmapExporter(swf, getShapes());
exporter.export();
matrix.translate(exporter.deltaX, exporter.deltaY);
return exporter.getImage();
}

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
BitmapExporter exporter = new BitmapExporter(swf, getShapes());
exporter.export();
matrix.translate(exporter.deltaX, exporter.deltaY);
return exporter.getImage();
}

View File

@@ -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<RECT> rectCache = Cache.getInstance(true);
@Override
public RECT getRect(HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
@@ -271,9 +272,9 @@ public class DefineSpriteTag extends CharacterTag implements Container, BoundedT
}
@Override
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> 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;
}

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return staticTextToImage(swf, characters, textRecords, textBounds, 2);
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return staticTextToImage(swf, characters, textRecords, textBounds, matrix, 2);
}
@Override

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return staticTextToImage(swf, characters, textRecords, textBounds, 1);
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return staticTextToImage(swf, characters, textRecords, textBounds, matrix, 1);
}
@Override

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);
public Point getImagePos(int frame, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited);

View File

@@ -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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
return SHAPERECORD.shapeListToImage(swf, getGlyphShapeTable(), 500, 500, Color.black);
}

View File

@@ -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<Tag> tags);
public abstract SerializableImage getImage(List<Tag> tags);
public abstract void setImage(byte[] data) throws IOException;

View File

@@ -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<Integer> allLeftMargins = new ArrayList<>();
List<Integer> 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<Integer, CharacterTag> characters, List<TEXTRECORD> 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<Integer, CharacterTag> characters, List<TEXTRECORD> 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;
}
}

View File

@@ -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<FontType> fonts;
private List<SHAPE> 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<SerializableImage> 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<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
public SerializableImage toImage(int frame, List<Tag> tags, Matrix matrix, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
if (imageCache.contains("font" + fontId)) {
return ((SerializableImage) imageCache.get("font" + fontId)).getImage();
return ((SerializableImage) imageCache.get("font" + fontId));
}
List<SHAPE> 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;
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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++) {

View File

@@ -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];

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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<Color> colors = new ArrayList<>();
List<Float> ratios = new ArrayList<>();
for (int i = 0; i < gradientColors.length; i++) {

View File

@@ -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<Color> colors = new ArrayList<>();
List<Float> ratios = new ArrayList<>();
for (int i = 0; i < gradientColors.length; i++) {

View File

@@ -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<SHAPE> shapes, int prevWidth, int prevHeight, Color color) {
BufferedImage ret = new BufferedImage(prevWidth, prevHeight, BufferedImage.TYPE_INT_ARGB);
public static SerializableImage shapeListToImage(SWF swf, List<SHAPE> 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++;
}
}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}

View File

@@ -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);
}

View File

@@ -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<E> {
private final Map<Object, File> cacheFiles;
private final Map<Object, Object> cacheMemory;
private final Map<Object, E> cacheMemory;
private static final List<Cache> 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 <E> Cache<E> getInstance(boolean weak) {
Cache<E> 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();

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}