diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedTextWriter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedTextWriter.java index 638d69341..d5d974b00 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedTextWriter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/HighlightedTextWriter.java @@ -181,7 +181,7 @@ public class HighlightedTextWriter extends GraphTextWriter { HighlightData ndata = new HighlightData(); ndata.merge(itemPos.data); ndata.merge(data); - ndata.offset = src.getOffset() + pos + 1; + ndata.offset = src.getOffset() + pos; h = new Highlighting(sb.length() - newLineCount, ndata, HighlightType.OFFSET, str); instructionHilights.add(h); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/ImageHelper.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/ImageHelper.java index 536f2d4f2..982f7b1b9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/ImageHelper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/ImageHelper.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.helpers; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.tags.enums.ImageFormat; import com.jpexs.helpers.Helper; +import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -26,10 +27,12 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.Iterator; import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; +import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import org.monte.media.jpeg.CMYKJPEGImageReader; import org.monte.media.jpeg.CMYKJPEGImageReaderSpi; @@ -136,4 +139,23 @@ public class ImageHelper { throw new Error("Unsuported image format: " + format); } + + public static Dimension getDimesion(InputStream input) throws IOException { + try (ImageInputStream in = ImageIO.createImageInputStream(input)) { + final Iterator readers = ImageIO.getImageReaders(in); + if (readers.hasNext()) { + ImageReader reader = readers.next(); + try { + reader.setInput(in); + return new Dimension(reader.getWidth(0), reader.getHeight(0)); + } finally { + reader.dispose(); + } + } + } catch (IOException ex) { + } + + BufferedImage image = read(input); + return new Dimension(image.getWidth(), image.getHeight()); + } } 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 62ec8b4b2..698bc632a 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 @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -145,4 +146,19 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { } return null; } + + @Override + public Dimension getImageDimension() { + if (cachedImage != null) { + return new Dimension(cachedImage.getWidth(), cachedImage.getHeight()); + } + + try { + return ImageHelper.getDimesion(getOriginalImageData()); + } catch (IOException ex) { + Logger.getLogger(DefineBitsJPEG2Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex); + } + + 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 4980ca712..2b2323bb2 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 @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.ByteArrayInputStream; @@ -140,8 +141,8 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { throw new IOException("Only Jpeg can have alpha channel."); } - SerializableImage image = getImage(); - if (data == null || data.length != image.getWidth() * image.getHeight()) { + Dimension dimension = getImageDimension(); + if (data == null || data.length != dimension.getWidth() * dimension.getHeight()) { throw new IOException("Data length must match the size of the image."); } @@ -210,4 +211,21 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { } return null; } + + @Override + public Dimension getImageDimension() { + if (cachedImage != null) { + return new Dimension(cachedImage.getWidth(), cachedImage.getHeight()); + } + + try { + int errorLength = hasErrorHeader(imageData) ? 4 : 0; + ByteArrayInputStream bis = new ByteArrayInputStream(imageData.getArray(), imageData.getPos() + errorLength, imageData.getLength() - errorLength); + return ImageHelper.getDimesion(bis); + } catch (IOException ex) { + Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex); + } + + return null; + } } 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 07eb0a8ad..38e7a6baf 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 @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.io.ByteArrayInputStream; @@ -145,8 +146,8 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { throw new IOException("Only Jpeg can have alpha channel."); } - SerializableImage image = getImage(); - if (data == null || data.length != image.getWidth() * image.getHeight()) { + Dimension dimension = getImageDimension(); + if (data == null || data.length != dimension.getWidth() * dimension.getHeight()) { throw new IOException("Data length must match the size of the image."); } @@ -179,7 +180,6 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { return cachedImage; } try { - BufferedImage image = ImageHelper.read(new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength())); if (image == null) { Logger.getLogger(DefineBitsJPEG4Tag.class.getName()).log(Level.SEVERE, "Failed to load image"); @@ -212,4 +212,20 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { } return null; } + + @Override + public Dimension getImageDimension() { + if (cachedImage != null) { + return new Dimension(cachedImage.getWidth(), cachedImage.getHeight()); + } + + try { + ByteArrayInputStream bis = new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength()); + return ImageHelper.getDimesion(bis); + } catch (IOException ex) { + Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex); + } + + return null; + } } 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 142580f64..023d10908 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 @@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.image.DataBufferInt; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -271,4 +272,9 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { return bi; } + + @Override + public Dimension getImageDimension() { + return new Dimension(bitmapWidth, bitmapHeight); + } } 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 465facd4e..3c82b2a60 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 @@ -34,6 +34,7 @@ import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.image.DataBufferInt; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -275,4 +276,9 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { return bi; } + + @Override + public Dimension getImageDimension() { + return new Dimension(bitmapWidth, bitmapHeight); + } } 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 5948832c8..f619f37e4 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 @@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.types.BasicType; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -158,6 +159,24 @@ public class DefineBitsTag extends ImageTag implements TagChangedListener { return null; } + @Override + public Dimension getImageDimension() { + if (cachedImage != null) { + return new Dimension(cachedImage.getWidth(), cachedImage.getHeight()); + } + + InputStream imageStream = getOriginalImageData(); + if (imageStream != null) { + try { + return ImageHelper.getDimesion(imageStream); + } catch (IOException ex) { + Logger.getLogger(DefineBitsJPEG3Tag.class.getName()).log(Level.SEVERE, "Failed to get image dimension", ex); + } + } + + return null; + } + @Override public void handleEvent(Tag tag) { // cache should be cleared when Jtt tag changes 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 c9168033a..784f2c3a4 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 @@ -41,6 +41,7 @@ import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord; import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; +import java.awt.Dimension; import java.awt.Shape; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -68,6 +69,8 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { public abstract SerializableImage getImage(); + public abstract Dimension getImageDimension(); + public abstract void setImage(byte[] data) throws IOException; public abstract ImageFormat getImageFormat(); @@ -231,9 +234,9 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { @Override public RECT getRect(Set added) { - SerializableImage image = getImage(); - int widthInTwips = (int) (image.getWidth() * SWF.unitDivisor); - int heightInTwips = (int) (image.getHeight() * SWF.unitDivisor); + Dimension dimension = getImageDimension(); + int widthInTwips = (int) (dimension.getWidth() * SWF.unitDivisor); + int heightInTwips = (int) (dimension.getHeight() * SWF.unitDivisor); return new RECT(0, widthInTwips, 0, heightInTwips); } @@ -282,9 +285,9 @@ public abstract class ImageTag extends CharacterTag implements DrawableTag { @Override public void getTagInfo(TagInfo tagInfo) { super.getTagInfo(tagInfo); - SerializableImage image = getImage(); - tagInfo.addInfo("general", "width", image.getWidth()); - tagInfo.addInfo("general", "height", image.getHeight()); + Dimension dimension = getImageDimension(); + tagInfo.addInfo("general", "width", dimension.getWidth()); + tagInfo.addInfo("general", "height", dimension.getHeight()); } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index d7054e3ae..13fb2182d 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -408,17 +408,18 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL int bi = abc.findBodyIndex(mi); Highlighting h = Highlighting.searchPos(highlights, pos); if (h != null) { + long highlightOffset = h.getProperties().offset; List list = abc.bodies.get(bi).getCode().code; AVM2Instruction lastIns = null; long inspos = 0; AVM2Instruction selIns = null; for (AVM2Instruction ins : list) { - if (h.getProperties().offset == ins.getOffset()) { + if (highlightOffset == ins.getOffset()) { selIns = ins; break; } - if (ins.getOffset() > h.getProperties().offset) { - inspos = h.getProperties().offset - lastIns.offset; + if (ins.getOffset() > highlightOffset) { + inspos = highlightOffset - lastIns.offset; selIns = lastIns; break; }