From 369a722f74f373c6985dbe49d733b995754c53bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Mon, 2 Jun 2014 22:04:25 +0200 Subject: [PATCH] No frame caching during export => memory saving (like Issue #583) --- src/com/jpexs/decompiler/flash/SWF.java | 73 ++++++++++++------- .../console/CommandLineArgumentParser.java | 2 +- .../decompiler/flash/gui/PreviewImage.java | 2 +- 3 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/com/jpexs/decompiler/flash/SWF.java b/src/com/jpexs/decompiler/flash/SWF.java index c55061326..d48e94a22 100644 --- a/src/com/jpexs/decompiler/flash/SWF.java +++ b/src/com/jpexs/decompiler/flash/SWF.java @@ -175,6 +175,7 @@ import java.util.Arrays; import java.util.EmptyStackException; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; @@ -1314,15 +1315,16 @@ public final class SWF implements TreeItem, Timelined { fos.write(chunkBytes); } - private static void makeAVI(List images, int frameRate, File file) throws IOException { - if (images.isEmpty()) { + private static void makeAVI(Iterator images, int frameRate, File file) throws IOException { + if (!images.hasNext()) { return; } AVIWriter out = new AVIWriter(file); - out.addVideoTrack(VideoFormatKeys.ENCODING_AVI_PNG, 1, frameRate, images.get(0).getWidth(), images.get(0).getHeight(), 0, 0); + BufferedImage img0 = images.next(); + out.addVideoTrack(VideoFormatKeys.ENCODING_AVI_PNG, 1, frameRate, img0.getWidth(), img0.getHeight(), 0, 0); try { - for (BufferedImage img : images) { - out.write(0, img, 1); + while (images.hasNext()) { + out.write(0, images.next(), 1); } } finally { out.close(); @@ -1330,15 +1332,17 @@ public final class SWF implements TreeItem, Timelined { } - private static void makeGIF(List images, int frameRate, File file) throws IOException { - if (images.isEmpty()) { + private static void makeGIF(Iterator images, int frameRate, File file) throws IOException { + if (!images.hasNext()) { return; } try (ImageOutputStream output = new FileImageOutputStream(file)) { - GifSequenceWriter writer = new GifSequenceWriter(output, images.get(0).getType(), 1000 / frameRate, true); - - for (BufferedImage img : images) { - writer.writeToSequence(img); + BufferedImage img0=images.next(); + GifSequenceWriter writer = new GifSequenceWriter(output, img0.getType(), 1000 / frameRate, true); + writer.writeToSequence(img0); + + while (images.hasNext()) { + writer.writeToSequence(images.next()); } writer.close(); @@ -1573,11 +1577,27 @@ public final class SWF implements TreeItem, Timelined { return ret; } + + final Timeline ftim=tim; + final Color fbackgroundColor=backgroundColor; + final Iterator frameImages = new Iterator() { + + private int pos=0; + + @Override + public boolean hasNext() { + return fframes.size()>pos; + } + + @Override + public BufferedImage next() { + if(!hasNext()){ + return null; + } + return frameToImageGet(ftim, fframes.get(pos), 0, null, 0, ftim.displayRect, new Matrix(), new ColorTransform(), fbackgroundColor,false).getBufferedImage(); + } + }; - final List frameImages = new ArrayList<>(); - for (int frame : frames) { - frameImages.add(frameToImageGet(tim, frame, 0, null, 0, tim.displayRect, new Matrix(), new ColorTransform(), backgroundColor).getBufferedImage()); - } switch (settings.mode) { case GIF: new RetryTask(new RunnableIOEx() { @@ -1590,13 +1610,13 @@ public final class SWF implements TreeItem, Timelined { }, handler).run(); break; case PNG: - for (int i = 0; i < frameImages.size(); i++) { + for (int i = 0; frameImages.hasNext(); i++) { final int fi = i; new RetryTask(new RunnableIOEx() { @Override public void run() throws IOException { File f = new File(foutdir + File.separator + fframes.get(fi) + ".png"); - ImageIO.write(frameImages.get(fi), "PNG", f); + ImageIO.write(frameImages.next(), "PNG", f); ret.add(f); } }, handler).run(); @@ -1611,12 +1631,12 @@ public final class SWF implements TreeItem, Timelined { PageFormat pf = new PageFormat(); pf.setOrientation(PageFormat.PORTRAIT); Paper p = new Paper(); - - p.setSize(frameImages.get(0).getWidth() + 10, frameImages.get(0).getHeight() + 10); + BufferedImage img0 = frameImages.next(); + p.setSize(img0.getWidth() + 10, img0.getHeight() + 10); pf.setPaper(p); - for (int i = 0; i < frameImages.size(); i++) { - BufferedImage img = frameImages.get(i); + for (int i = 0; frameImages.hasNext(); i++) { + BufferedImage img = frameImages.next(); Graphics g = job.getGraphics(pf); g.drawImage(img, 5, 5, img.getWidth(), img.getHeight(), null); g.dispose(); @@ -2552,11 +2572,14 @@ public final class SWF implements TreeItem, Timelined { return exporter.getUniqueId("tag"); } - public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor) { + public static SerializableImage frameToImageGet(Timeline timeline, int frame, int time, DepthState stateUnderCursor, int mouseButton, RECT displayRect, Matrix transformation, ColorTransform colorTransform, Color backGroundColor, boolean useCache) { String key = "frame_" + frame + "_" + timeline.id + "_" + timeline.swf.hashCode(); - SerializableImage image = getFromCache(key); - if (image != null) { - return image; + SerializableImage image; + if(useCache){ + image = getFromCache(key); + if (image != null) { + return image; + } } if (timeline.frames.isEmpty()) { diff --git a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java index 74b5a7d52..ae4979dda 100644 --- a/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java +++ b/src/com/jpexs/decompiler/flash/console/CommandLineArgumentParser.java @@ -1206,7 +1206,7 @@ public class CommandLineArgumentParser { displayRect.Ymax *= zoom; Matrix m = new Matrix(); m.scale(zoom); - BufferedImage img = SWF.frameToImageGet(ds.getTimeline(), 0, 0, null, 0, displayRect, m, new ColorTransform(), Color.white).getBufferedImage(); + BufferedImage img = SWF.frameToImageGet(ds.getTimeline(), 0, 0, null, 0, displayRect, m, new ColorTransform(), Color.white, false).getBufferedImage(); PageFormat pf = new PageFormat(); pf.setOrientation(PageFormat.PORTRAIT); Paper p = new Paper(); diff --git a/src/com/jpexs/decompiler/flash/gui/PreviewImage.java b/src/com/jpexs/decompiler/flash/gui/PreviewImage.java index c36159843..437e9a5d2 100644 --- a/src/com/jpexs/decompiler/flash/gui/PreviewImage.java +++ b/src/com/jpexs/decompiler/flash/gui/PreviewImage.java @@ -176,7 +176,7 @@ public class PreviewImage extends JPanel { if (treeItem instanceof FrameNodeItem) { FrameNodeItem fn = (FrameNodeItem) treeItem; RECT rect = swf.displayRect; - imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.getFrame() - 1, 0, null, 0, rect, new Matrix(), new ColorTransform(), null); + imgSrc = SWF.frameToImageGet(swf.getTimeline(), fn.getFrame() - 1, 0, null, 0, rect, new Matrix(), new ColorTransform(), null, true); width = (imgSrc.getWidth()); height = (imgSrc.getHeight()); } else if (treeItem instanceof ImageTag) {