diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index 58ba8a284..4423c8a08 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -69,7 +69,6 @@ import com.jpexs.decompiler.flash.exporters.script.AS3ScriptExporter; import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; import com.jpexs.decompiler.flash.helpers.HighlightedText; import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; -import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.helpers.SWFDecompilerPlugin; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; @@ -1555,15 +1554,7 @@ public final class SWF implements SWFContainerItem, Timelined { if (ch instanceof ImageTag) { ImageTag image = (ImageTag) ch; ImageFormat format = image.getImageFormat(); - InputStream imageStream = image.getImageData(); - byte[] imageData; - if (imageStream != null) { - imageData = Helper.readStream(image.getImageData()); - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageHelper.write(image.getImage().getBufferedImage(), format, baos); - imageData = baos.toByteArray(); - } + byte[] imageData = Helper.readStream(image.getImageData()); String base64ImgData = Helper.byteArrayToBase64String(imageData); fos.write(Utf8Helper.getBytes("var imageObj" + c + " = document.createElement(\"img\");\r\nimageObj" + c + ".src=\"data:image/" + format + ";base64," + base64ImgData + "\";\r\n")); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ImageExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ImageExporter.java index 96453d508..be1a16d0d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ImageExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/ImageExporter.java @@ -28,8 +28,11 @@ import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; import com.jpexs.helpers.Helper; import com.jpexs.helpers.Path; +import java.io.BufferedOutputStream; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; import java.util.List; @@ -88,7 +91,9 @@ public class ImageExporter { new RetryTask(() -> { if (ffileFormat == originalFormat) { - + try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(file))) { + fos.write(Helper.readStream(imageTag.getImageData())); + } } else if (ffileFormat == ImageFormat.BMP) { BMPFile.saveBitmap(imageTag.getImage().getBufferedImage(), file); } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/SVGMorphShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/SVGMorphShapeExporter.java index d8bf43904..32b53d4fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/SVGMorphShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/morphshape/SVGMorphShapeExporter.java @@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.exporters.morphshape; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; -import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; import com.jpexs.decompiler.flash.types.ColorTransform; @@ -33,8 +32,6 @@ import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; import java.awt.Color; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; import org.w3c.dom.Element; /** @@ -116,15 +113,7 @@ public class SVGMorphShapeExporter extends DefaultSVGMorphShapeExporter { lastPatternId++; String patternId = "PatternID_" + lastPatternId; ImageFormat format = image.getImageFormat(); - InputStream imageStream = image.getImageData(); - byte[] imageData; - if (imageStream != null) { - imageData = Helper.readStream(image.getImageData()); - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageHelper.write(img.getBufferedImage(), format, baos); - imageData = baos.toByteArray(); - } + byte[] imageData = Helper.readStream(image.getImageData()); String base64ImgData = Helper.byteArrayToBase64String(imageData); path.setAttribute("style", "fill:url(#" + patternId + ")"); Element pattern = exporter.createElement("pattern"); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/SVGShapeExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/SVGShapeExporter.java index 45f064077..6bedf6253 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/SVGShapeExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/shape/SVGShapeExporter.java @@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.exporters.shape; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; -import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; import com.jpexs.decompiler.flash.types.ColorTransform; @@ -33,8 +32,6 @@ import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; import java.awt.Color; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; import org.w3c.dom.Element; /** @@ -114,15 +111,7 @@ public class SVGShapeExporter extends DefaultSVGShapeExporter { String patternId = "PatternID_"; patternId += lastPatternId; ImageFormat format = image.getImageFormat(); - InputStream imageStream = image.getImageData(); - byte[] imageData; - if (imageStream != null) { - imageData = Helper.readStream(image.getImageData()); - } else { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageHelper.write(img.getBufferedImage(), format, baos); - imageData = baos.toByteArray(); - } + byte[] imageData = Helper.readStream(image.getImageData()); String base64ImgData = Helper.byteArrayToBase64String(imageData); path.setAttribute("style", "fill:url(#" + patternId + ")"); Element pattern = exporter.createElement("pattern"); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java index b7ef635b5..db658f94b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG2Tag.java @@ -106,7 +106,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { } @Override - public InputStream getImageData() { + public InputStream getOriginalImageData() { int errorLength = hasErrorHeader(imageData) ? 4 : 0; return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength); } @@ -117,7 +117,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { return cachedImage; } try { - BufferedImage image = ImageHelper.read(getImageData()); + BufferedImage image = ImageHelper.read(getOriginalImageData()); if (image == null) { Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to load image"); return null; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java index 87391402a..27cf9a44e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG3Tag.java @@ -160,18 +160,13 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { } @Override - public InputStream getImageData() { - + public InputStream getOriginalImageData() { if (bitmapAlphaData.getLength() == 0) { //No alpha, then its JPEG int errorLength = hasErrorHeader(imageData) ? 4 : 0; return new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength); } - //Make PNG - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageHelper.write(getImage().getBufferedImage(), ImageFormat.PNG, baos); - return new ByteArrayInputStream(baos.toByteArray()); - + return null; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java index d60790d11..867571011 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsJPEG4Tag.java @@ -165,16 +165,12 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { } @Override - public InputStream getImageData() { - + public InputStream getOriginalImageData() { if (bitmapAlphaData.getLength() == 0) { //No alpha, then its JPEG return new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength()); } - //Make PNG - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ImageHelper.write(getImage().getBufferedImage(), ImageFormat.PNG, baos); - return new ByteArrayInputStream(baos.toByteArray()); + return null; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java index 8506ac6b1..d41a50e1b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLossless2Tag.java @@ -228,7 +228,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { } @Override - public InputStream getImageData() { + public InputStream getOriginalImageData() { return null; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java index 367d7d6f3..4110ce3ec 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsLosslessTag.java @@ -190,7 +190,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { } @Override - public InputStream getImageData() { + public InputStream getOriginalImageData() { return null; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java index fcfcd0980..fadf45e3b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineBitsTag.java @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -102,15 +103,7 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener { } @Override - public InputStream getImageData() { - return null; - } - - @Override - public SerializableImage getImage() { - if (cachedImage != null) { - return cachedImage; - } + public InputStream getOriginalImageData() { if (swf.getJtt() != null) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { byte[] jttdata = swf.getJtt().jpegData; @@ -122,7 +115,26 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener { int errorLength = hasErrorHeader(jpegData) ? 4 : 0; baos.write(jpegData.getArray(), jpegData.getPos() + errorLength, jpegData.getLength() - errorLength); - BufferedImage image = ImageHelper.read(baos.toByteArray()); + return new ByteArrayInputStream(baos.toByteArray()); + } catch (IOException ex) { + // this should never happen, since IOException comes from OutputStream, but ByteArrayOutputStream should never throw it + throw new Error(ex); + } + } + + return null; + } + + @Override + public SerializableImage getImage() { + if (cachedImage != null) { + return cachedImage; + } + + InputStream imageStream = getOriginalImageData(); + if (imageStream != null) { + try { + BufferedImage image = ImageHelper.read(imageStream); if (image == null) { Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to load image"); return null; @@ -138,6 +150,7 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener { Logger.getLogger(DefineBitsTag.class.getName()).log(Level.SEVERE, "Failed to get image", ex); } } + return null; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java index bdb66f278..7be657c57 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/ImageTag.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.exporters.shape.BitmapExporter; import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter; +import com.jpexs.decompiler.flash.helpers.ImageHelper; import com.jpexs.decompiler.flash.tags.TagInfo; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; import com.jpexs.decompiler.flash.types.BasicType; @@ -41,6 +42,8 @@ import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; import java.awt.Shape; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -61,7 +64,7 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { super(swf, id, name, data); } - public abstract InputStream getImageData(); + public abstract InputStream getOriginalImageData(); public abstract SerializableImage getImage(); @@ -97,6 +100,17 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { return ImageFormat.UNKNOWN; } + public InputStream getImageData() { + InputStream is = getOriginalImageData(); + if (is != null) { + return is; + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ImageHelper.write(getImage().getBufferedImage(), getImageFormat(), baos); + return new ByteArrayInputStream(baos.toByteArray()); + } + public static boolean hasErrorHeader(byte[] data) { return hasErrorHeader(new ByteArrayRange(data)); }