diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/EventListener.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/EventListener.java index ac343b28b..116f60b31 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/EventListener.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/EventListener.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash; /** 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 d27970947..b37f6bf3a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -261,7 +261,7 @@ public final class SWF implements SWFContainerItem, Timelined { public boolean isAS3; public Map characters = new HashMap<>(); public List abcList; - public JPEGTablesTag jtt; + private JPEGTablesTag jtt; public Map sourceFontNamesMap = new HashMap<>(); public static final double unitDivisor = 20; private static final Logger logger = Logger.getLogger(SWF.class.getName()); @@ -287,6 +287,19 @@ public final class SWF implements SWFContainerItem, Timelined { return max + 1; } + public synchronized JPEGTablesTag getJtt() { + if (jtt == null) { + for (Tag t : tags) { + if (t instanceof JPEGTablesTag) { + jtt = (JPEGTablesTag) t; + break; + } + } + } + + return jtt; + } + public void fixCharactersOrder(boolean checkAll) { Set addedCharacterIds = new HashSet<>(); Set movedTags = new HashSet<>(); 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 25336d705..285fbedfe 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 @@ -43,6 +43,8 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { public static final int ID = 21; + private SerializableImage cachedImage; + @Override public int getCharacterId() { return characterID; @@ -63,9 +65,14 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { @Override public SerializableImage getImage() { + if (cachedImage != null) { + return cachedImage; + } try { BufferedImage image = ImageIO.read(getImageData()); - return image == null ? null : new SerializableImage(image); + SerializableImage ret = image == null ? null : new SerializableImage(image); + cachedImage = ret; + return ret; } catch (IOException ex) { } return null; @@ -97,6 +104,7 @@ public class DefineBitsJPEG2Tag extends ImageTag implements AloneTag { @Override public void setImage(byte[] data) { imageData = new ByteArrayRange(data); + cachedImage = null; setModified(true); } 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 628c47618..1e9af5bf0 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 @@ -45,6 +45,8 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { public byte[] bitmapAlphaData; public static final int ID = 35; + + private SerializableImage cachedImage; @Override public int getCharacterId() { @@ -64,6 +66,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { bitmapAlphaData = new byte[0]; } imageData = new ByteArrayRange(data); + cachedImage = null; setModified(true); } @@ -83,6 +86,9 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { @Override public SerializableImage getImage() { + if (cachedImage != null) { + return cachedImage; + } try { InputStream stream; if (SWF.hasErrorHeader(imageData)) { @@ -104,6 +110,7 @@ public class DefineBitsJPEG3Tag extends ImageTag implements AloneTag { img2.setRGB(x, y, colorToInt(multiplyAlpha(intToColor(val)))); } } + cachedImage = img2; return img2; } catch (IOException ex) { } 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 c20974535..fe7f79bc4 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 @@ -54,6 +54,8 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { public static final int ID = 90; + private SerializableImage cachedImage; + @Override public int getCharacterId() { return characterID; @@ -91,6 +93,9 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { @Override public SerializableImage getImage() { + if (cachedImage != null) { + return cachedImage; + } try { BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageData.getArray(), imageData.getPos(), imageData.getLength())); SerializableImage img = image == null ? null : new SerializableImage(image); @@ -106,6 +111,7 @@ public class DefineBitsJPEG4Tag extends ImageTag implements AloneTag { img2.setRGB(x, y, colorToInt(multiplyAlpha(intToColor(val)))); } } + cachedImage = img2; return img2; } catch (IOException ex) { } 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 1a01e4782..39c683516 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 @@ -66,6 +66,8 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { public static final int ID = 36; + private SerializableImage cachedImage; + @Override public int getCharacterId() { return characterID; @@ -127,6 +129,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { sos2.writeBytesZlib(bitmapDataOS.toByteArray()); zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray()); decompressed = false; + cachedImage = null; setModified(true); } @@ -224,6 +227,9 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { @Override public SerializableImage getImage() { + if (cachedImage != null) { + return cachedImage; + } SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_ARGB); ALPHACOLORMAPDATA colorMapData = null; ALPHABITMAPDATA bitmapData = null; @@ -252,6 +258,7 @@ public class DefineBitsLossless2Tag extends ImageTag implements AloneTag { pos32aligned++; } } + cachedImage = bi; return bi; } } 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 82b866924..9939a2adf 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 @@ -75,6 +75,8 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { public static final int ID = 20; + private SerializableImage cachedImage; + private byte[] createEmptyImage() { try { BITMAPDATA bitmapData = new BITMAPDATA(); @@ -126,6 +128,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { sos2.writeBytesZlib(bitmapDataOS.toByteArray()); zlibBitmapData = new ByteArrayRange(zlibOS.toByteArray()); decompressed = false; + cachedImage = null; setModified(true); } @@ -136,6 +139,9 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { @Override public SerializableImage getImage() { + if (cachedImage != null) { + return cachedImage; + } SerializableImage bi = new SerializableImage(bitmapWidth, bitmapHeight, SerializableImage.TYPE_INT_RGB); COLORMAPDATA colorMapData = null; BITMAPDATA bitmapData = null; @@ -168,6 +174,7 @@ public class DefineBitsLosslessTag extends ImageTag implements AloneTag { pos32aligned++; } } + cachedImage = bi; return bi; } 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 93ac590a4..b18be36f0 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 @@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.ImageTag; import com.jpexs.decompiler.flash.types.BasicType; -import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; import com.jpexs.helpers.SerializableImage; @@ -32,7 +31,7 @@ import java.io.InputStream; import java.io.OutputStream; import javax.imageio.ImageIO; -public class DefineBitsTag extends ImageTag { +public class DefineBitsTag extends ImageTag implements TagChangedListener { @SWFType(BasicType.UI16) public int characterID; @@ -40,10 +39,10 @@ public class DefineBitsTag extends ImageTag { @SWFType(BasicType.UI8) public ByteArrayRange jpegData; - @Internal - private JPEGTablesTag jtt = null; public static final int ID = 6; + private SerializableImage cachedImage; + @Override public void setImage(byte[] data) { throw new UnsupportedOperationException("Set image is not supported for DefineBits"); @@ -72,17 +71,6 @@ public class DefineBitsTag extends ImageTag { jpegData = sis.readByteRangeEx(sis.available(), "jpegData"); } - private void getJPEGTables() { - if (jtt == null) { - for (Tag t : swf.tags) { - if (t instanceof JPEGTablesTag) { - jtt = (JPEGTablesTag) t; - break; - } - } - } - } - @Override public InputStream getImageData() { return null; @@ -90,10 +78,12 @@ public class DefineBitsTag extends ImageTag { @Override public SerializableImage getImage() { - getJPEGTables(); - if ((jtt != null)) { + if (cachedImage != null) { + return cachedImage; + } + if (swf.getJtt() != null) { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { - byte[] jttdata = jtt.jpegData; + byte[] jttdata = swf.getJtt().jpegData; if (jttdata.length != 0) { boolean jttError = SWF.hasErrorHeader(jttdata); baos.write(jttdata, jttError ? 4 : 0, jttdata.length - (jttError ? 6 : 2)); @@ -101,7 +91,9 @@ public class DefineBitsTag extends ImageTag { } else { baos.write(jpegData.getArray(), jpegData.getPos(), jpegData.getLength()); } - return new SerializableImage(ImageIO.read(new ByteArrayInputStream(baos.toByteArray()))); + SerializableImage ret = new SerializableImage(ImageIO.read(new ByteArrayInputStream(baos.toByteArray()))); + cachedImage = ret; + return ret; } catch (IOException ex) { return null; } @@ -137,4 +129,9 @@ public class DefineBitsTag extends ImageTag { public String getImageFormat() { return "jpg"; } + + @Override + public void handleEvent(Tag tag) { + cachedImage = null; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java index 5528d033f..0a4fc94b1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/Tag.java @@ -70,6 +70,8 @@ public abstract class Tag implements NeedsCharacters, Exportable, ContainerItem, @Internal private ByteArrayRange originalRange; + private final HashSet listeners = new HashSet<>(); + public String getTagName() { return tagName; } @@ -407,6 +409,23 @@ public abstract class Tag implements NeedsCharacters, Exportable, ContainerItem, public void setModified(boolean value) { modified = value; + if (value) { + informListeners(); + } + } + + public final void addEventListener(TagChangedListener listener) { + listeners.add(listener); + } + + public final void removeEventListener(TagChangedListener listener) { + listeners.remove(listener); + } + + protected void informListeners() { + for (TagChangedListener listener : listeners) { + listener.handleEvent(this); + } } public void createOriginalData() { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/TagChangedListener.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/TagChangedListener.java new file mode 100644 index 000000000..ab49a33ab --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/TagChangedListener.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-2014 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.tags; + +/** + * + * @author JPEXS + */ +public interface TagChangedListener { + + public void handleEvent(Tag tag); +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java index 58b4bbb05..2b75b92d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -509,7 +509,11 @@ public class Timeline { int dframe = 0; if (c instanceof Timelined) { - dframe = (time + ds.time) % ((Timelined) c).getTimeline().frames.size(); + int frameCount = ((Timelined) c).getTimeline().frames.size(); + if (frameCount < 1) { + frameCount = 1; + } + dframe = (time + ds.time) % frameCount; if (c instanceof ButtonTag) { ButtonTag bt = (ButtonTag) c; dframe = ButtonTag.FRAME_UP; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/MATRIX.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/MATRIX.java index 49a5e206c..c516a8d0b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/MATRIX.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/MATRIX.java @@ -16,7 +16,6 @@ */ package com.jpexs.decompiler.flash.types; -import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.types.annotations.Calculated; import com.jpexs.decompiler.flash.types.annotations.Conditional; import com.jpexs.decompiler.flash.types.annotations.SWFType; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java index cba04e48f..8ba87cd75 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/filters/Filtering.java @@ -12,7 +12,8 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library. */ + * License along with this library. + */ package com.jpexs.decompiler.flash.types.filters; import com.jpexs.helpers.SerializableImage; diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index e179944ca..ed64c3e0a 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -589,7 +589,7 @@ public class Main { case SAVE: case SAVEAS: if (swf.file != null) { - ext = Path.getExtension(swf.file); + ext = Path.getExtension(swf.file); } break; case EXE: @@ -1256,7 +1256,7 @@ public class Main { checkForUpdates(); return null; } - }.execute(); + }.execute(); } } } diff --git a/src/com/jpexs/decompiler/flash/gui/View.java b/src/com/jpexs/decompiler/flash/gui/View.java index 04817d90f..4a9b21154 100644 --- a/src/com/jpexs/decompiler/flash/gui/View.java +++ b/src/com/jpexs/decompiler/flash/gui/View.java @@ -579,8 +579,8 @@ public class View { return false; } - - public static JTable autoResizeColWidth(final JTable table, final TableModel model) { + + public static JTable autoResizeColWidth(final JTable table, final TableModel model) { View.execInEventDispatch(new Runnable() { @Override public void run() { diff --git a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java index cbdfbfc4b..1f577a540 100644 --- a/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/player/FlashPlayerPanel.java @@ -100,10 +100,10 @@ public class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { @Override public synchronized int getTotalFrames() { - if(flash==null){ + if (flash == null) { return 0; } - if(flash.getReadyState() == 4){ + if (flash.getReadyState() == 4) { return flash.getTotalFrames(); } return 0; @@ -176,7 +176,7 @@ public class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { if (bgColor != null) { setBackground(bgColor); } - flash.setMovie(flashName); + flash.setMovie(flashName); //play stopped = false; @@ -184,7 +184,7 @@ public class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { @Override public void close() throws IOException { - + } @Override diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java index 3a3512f89..f448b3681 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTreeModel.java @@ -305,8 +305,8 @@ public class TagTreeModel implements TreeModel { return null; } - - public TreeItem getFolderNode(SWF swf,String folderType) { + + public TreeItem getFolderNode(SWF swf, String folderType) { int childCount = getChildCount(swf); for (int i = 0; i < childCount; i++) { TreeItem child = getChild(swf, i); @@ -320,48 +320,46 @@ public class TagTreeModel implements TreeModel { return null; } - - - private Frame searchForFrame(Object parent,SWF swf,Timelined t, int frame){ + + private Frame searchForFrame(Object parent, SWF swf, Timelined t, int frame) { int childCount = getChildCount(parent); Frame lastVisibleFrame = null; for (int i = 0; i < childCount; i++) { TreeItem child = getChild(parent, i); - if((child instanceof DefineSpriteTag)&& child==t){ - Frame si=searchForFrame(child, swf, t,frame); - if(si!=null){ + if ((child instanceof DefineSpriteTag) && child == t) { + Frame si = searchForFrame(child, swf, t, frame); + if (si != null) { return si; } } - if(child instanceof Frame){ - Frame f = (Frame)child; - if(f.frame<=frame){ + if (child instanceof Frame) { + Frame f = (Frame) child; + if (f.frame <= frame) { lastVisibleFrame = f; } } if (child instanceof FolderItem) { FolderItem folder = (FolderItem) child; - if (folder.getName().equals(FOLDER_FRAMES) && t==swf) { - Frame si=searchForFrame(folder, swf, t,frame); - if(si!=null){ + if (folder.getName().equals(FOLDER_FRAMES) && t == swf) { + Frame si = searchForFrame(folder, swf, t, frame); + if (si != null) { return si; } } - if(folder.getName().equals(FOLDER_SPRITES)){ - Frame si=searchForFrame(folder, swf, t,frame); - if(si!=null){ + if (folder.getName().equals(FOLDER_SPRITES)) { + Frame si = searchForFrame(folder, swf, t, frame); + if (si != null) { return si; } } - } + } } return lastVisibleFrame; } - - public Frame getFrame(SWF swf,Timelined t, int frame) { - return searchForFrame(swf, swf, t,frame); + + public Frame getFrame(SWF swf, Timelined t, int frame) { + return searchForFrame(swf, swf, t, frame); } - private List searchTag(TreeItem obj, TreeItem parent, List path) { List ret = null;