diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index 6b0653d55..400435541 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -117,7 +117,6 @@ import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.filters.BlendComposite; import com.jpexs.decompiler.flash.types.filters.FILTER; -import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; import com.jpexs.decompiler.flash.types.sound.SoundFormat; import com.jpexs.decompiler.flash.xfl.FLAVersion; import com.jpexs.decompiler.flash.xfl.XFLConverter; @@ -133,9 +132,7 @@ import com.jpexs.helpers.ProgressListener; import com.jpexs.helpers.SerializableImage; import com.jpexs.helpers.utf8.Utf8Helper; import java.awt.AlphaComposite; -import java.awt.BasicStroke; import java.awt.Color; -import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; @@ -2352,12 +2349,12 @@ public final class SWF implements TreeItem, Timelined { drawable.toImage(dframe, layer.ratio, stateUnderCursor, mouseButton, img, m, clrTrans); //if(stateUnderCursor == layer){ /* if(true){ - Graphics2D gg = (Graphics2D)img.getGraphics(); - gg.setStroke(new BasicStroke(3)); - gg.setPaint(Color.red); - gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); - gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m))); - }*/ + Graphics2D gg = (Graphics2D)img.getGraphics(); + gg.setStroke(new BasicStroke(3)); + gg.setPaint(Color.red); + gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); + gg.draw(SHAPERECORD.twipToPixelShape(drawable.getOutline(frame, layer.ratio, stateUnderCursor, mouseButton, m))); + }*/ } else if (drawable instanceof FontTag) { // only DefineFont tags FontTag fontTag = (FontTag) drawable; @@ -2470,9 +2467,7 @@ public final class SWF implements TreeItem, Timelined { g.setComposite(AlphaComposite.Dst); } } - - - + g.setTransform(AffineTransform.getScaleInstance(1, 1)); } diff --git a/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java b/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java index f2974452b..01edf6521 100644 --- a/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java +++ b/trunk/src/com/jpexs/decompiler/flash/exporters/Matrix.java @@ -102,12 +102,11 @@ public class Matrix { public Point transform(Point point) { return transform(point.x, point.y); } - + public java.awt.Point transform(java.awt.Point point) { - Point p= transform(point.x, point.y); - return new java.awt.Point((int)p.x,(int)p.y); + Point p = transform(point.x, point.y); + return new java.awt.Point((int) p.x, (int) p.y); } - public ExportRectangle transform(ExportRectangle rect) { double minX = Double.MAX_VALUE; diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java index f56628839..7d22e01ae 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/ImagePanel.java @@ -40,8 +40,6 @@ import java.awt.Cursor; import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.GridBagConstraints; -import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; @@ -63,8 +61,8 @@ import java.util.TimerTask; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; -import javax.swing.Icon; -import javax.swing.ImageIcon; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JLabel; @@ -95,9 +93,8 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis private Rectangle rect = null; private List dss; private List outlines; - - public void setImg(SerializableImage img,List dss, List outlines) { + public void setImg(SerializableImage img, List dss, List outlines) { this.img = img; this.dss = dss; this.outlines = outlines; @@ -105,22 +102,22 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis repaint(); } - public List getObjectsUnderPoint(Point p){ - List ret=new ArrayList<>(); - for(int i=0;i getObjectsUnderPoint(Point p) { + List ret = new ArrayList<>(); + for (int i = 0; i < outlines.size(); i++) { + if (outlines.get(i).contains(p)) { ret.add(dss.get(i)); } } return ret; } - + public Rectangle getRect() { return rect; } - - public Point toImagePoint(Point p){ - return new Point((p.x-rect.x)*img.getWidth()/rect.width,(p.y-rect.y)*img.getHeight()/rect.height); + + public Point toImagePoint(Point p) { + return new Point((p.x - rect.x) * img.getWidth() / rect.width, (p.y - rect.y) * img.getHeight() / rect.height); } private void calcRect() { @@ -162,7 +159,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis if (img != null) { calcRect(); g2d.setComposite(AlphaComposite.SrcOver); - g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x+rect.width, rect.y+rect.height, 0, 0, img.getWidth(), img.getHeight(), null); + g2d.drawImage(img.getBufferedImage(), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height, 0, 0, img.getWidth(), img.getHeight(), null); } } @@ -210,24 +207,24 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis int width = rect.getWidth(); double scale = 1.0; /*if (width > swf.displayRect.getWidth()) { - scale = (double) swf.displayRect.getWidth() / (double) width; - }*/ + scale = (double) swf.displayRect.getWidth() / (double) width; + }*/ Matrix m = new Matrix(); m.translate(-rect.Xmin, -rect.Ymin); m.scale(scale); - Point p=e.getPoint(); + Point p = e.getPoint(); p = iconPanel.toImagePoint(p); - int x = p.x; + int x = p.x; int y = p.y; List objs = new ArrayList<>(); - objs=iconPanel.getObjectsUnderPoint(p); + objs = iconPanel.getObjectsUnderPoint(p); String ret = ""; ret += " [" + x + "," + y + "] : "; boolean first = true; - for (int i=0;i(),new ArrayList()); + iconPanel.setImg(new SerializableImage(ImageIO.read(new ByteArrayInputStream(data))), new ArrayList(), new ArrayList()); } catch (IOException ex) { Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, null, ex); } @@ -372,7 +369,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis loaded = true; if (drawable.getTimeline().frames.isEmpty()) { - iconPanel.setImg(null, new ArrayList(),new ArrayList()); + iconPanel.setImg(null, new ArrayList(), new ArrayList()); return; } frame = 0; @@ -387,7 +384,7 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis timelined = null; loaded = true; stillFrame = true; - iconPanel.setImg(image,new ArrayList(),new ArrayList()); + iconPanel.setImg(image, new ArrayList(), new ArrayList()); } @Override @@ -449,50 +446,50 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis int height = rect.getHeight(); double scale = 1.0; /*if (width > swf.displayRect.getWidth() || height > swf.displayRect.getHeight()) { - //scale = (double) swf.displayRect.getWidth() / (double) width; - //width = swf.displayRect.getWidth(); + //scale = (double) swf.displayRect.getWidth() / (double) width; + //width = swf.displayRect.getWidth(); - int w1 = width; - int h1 = height; - int w2 = swf.displayRect.getWidth(); - int h2 = swf.displayRect.getHeight(); + int w1 = width; + int h1 = height; + int w2 = swf.displayRect.getWidth(); + int h2 = swf.displayRect.getHeight(); - int w; - int h = h1 * w2 / w1; - if (h > h2) { - w = w1 * h2 / h1; - h = h2; - } else { - w = w2; - } - scale = (double) w / (double) width; + int w; + int h = h1 * w2 / w1; + if (h > h2) { + w = w1 * h2 / h1; + h = h2; + } else { + w = w2; + } + scale = (double) w / (double) width; - width = w; - height = h; - }*/ + width = w; + height = h; + }*/ SerializableImage image = new SerializableImage((int) (width / SWF.unitDivisor) + 1, (int) (height / SWF.unitDivisor) + 1, SerializableImage.TYPE_INT_ARGB); image.fillTransparent(); Matrix m = new Matrix(); m.translate(-rect.Xmin, -rect.Ymin); /*m.translate(-rect.getWidth(), -rect.getHeight()); - m.scale(scale); - m.translate(rect.getWidth()*scale, rect.getHeight()*scale);*/ + m.scale(scale); + m.translate(rect.getWidth()*scale, rect.getHeight()*scale);*/ drawable.getTimeline().toImage(frame, frame, stateUnderCursor, mouseButton, image, m, new ColorTransform()); - Graphics2D gg = (Graphics2D)image.getGraphics(); - gg.setStroke(new BasicStroke(3)); - gg.setPaint(Color.green); - gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); - List dss=new ArrayList<>(); - List os=new ArrayList<>(); - /*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os); + Graphics2D gg = (Graphics2D) image.getGraphics(); + gg.setStroke(new BasicStroke(3)); + gg.setPaint(Color.green); + gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); + List dss = new ArrayList<>(); + List os = new ArrayList<>(); + /*drawable.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, dss, os); //gg.setTransform(AffineTransform.getTranslateInstance(0, 0)); for(Shape s:os){ - gg.draw(SHAPERECORD.twipToPixelShape(s)); + gg.draw(SHAPERECORD.twipToPixelShape(s)); }*/ - + img = image; } else if (drawable instanceof FontTag) { // only DefineFont tags @@ -517,34 +514,40 @@ public final class ImagePanel extends JPanel implements ActionListener, MediaDis CharacterTag c = swf.characters.get(sndId); if (c instanceof SoundTag) { SoundTag st = (SoundTag) c; - final SoundTagPlayer sp = new SoundTagPlayer(st, 1); - synchronized (ImagePanel.class) { - soundPlayers.add(sp); - } - sp.addListener(new PlayerListener() { + final SoundTagPlayer sp; + try { + sp = new SoundTagPlayer(st, 1); - @Override - public void playingFinished() { - synchronized (ImagePanel.class) { - soundPlayers.remove(sp); - } + synchronized (ImagePanel.class) { + soundPlayers.add(sp); } - }); - sp.play(); + sp.addListener(new PlayerListener() { + + @Override + public void playingFinished() { + synchronized (ImagePanel.class) { + soundPlayers.remove(sp); + } + } + }); + sp.play(); + } catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) { + Logger.getLogger(ImagePanel.class.getName()).log(Level.SEVERE, "Error during playing sound", ex); + } } } Matrix m = new Matrix(); - RECT rect= timelined.getTimeline().displayRect; - m.translate(-rect.Xmin, -rect.Ymin); - m.scale(1); - List objs = new ArrayList<>(); - List outlines=new ArrayList<>(); - timelined.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, objs, outlines); - for(int i=0;i objs = new ArrayList<>(); + List outlines = new ArrayList<>(); + timelined.getTimeline().getObjectsOutlines(frame, frame, stateUnderCursor, mouseButton, m, objs, outlines); + for (int i = 0; i < outlines.size(); i++) { + outlines.set(i, SHAPERECORD.twipToPixelShape(outlines.get(i))); + } + iconPanel.setImg(new SerializableImage(img), objs, outlines); } public void stop() { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java index e4f529818..0ccddecb1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -154,7 +154,6 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.BufferedOutputStream; @@ -176,6 +175,8 @@ import java.util.concurrent.CancellationException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; @@ -2705,11 +2706,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec previewImagePanel.setTimelined(timelined, swf, fn.getFrame() - 1); } else if (((tagObj instanceof SoundTag) && mainMenu.isInternalFlashViewerSelected() && (Arrays.asList("mp3", "wav").contains(((SoundTag) tagObj).getExportFormat())))) { showCard(CARDDRAWPREVIEWPANEL); - previewImagePanel.setImage(new SerializableImage(1, 1, BufferedImage.TYPE_INT_ARGB)); - - soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE); - imagePlayControls.setMedia(soundThread); - soundThread.play(); + previewImagePanel.setImage(new SerializableImage(View.loadImage("sound32"))); + try { + soundThread = new SoundTagPlayer((SoundTag) tagObj, Integer.MAX_VALUE); + imagePlayControls.setMedia(soundThread); + soundThread.play(); + } catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) { + Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex); + } } else if (((tagObj instanceof FrameNodeItem) && ((FrameNodeItem) tagObj).isDisplayed()) || ((tagObj instanceof CharacterTag) || (tagObj instanceof FontTag)) && (tagObj instanceof Tag) || (tagObj instanceof SoundStreamHeadTypeTag)) { ((CardLayout) viewerCards.getLayout()).show(viewerCards, FLASH_VIEWER_CARD); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java b/trunk/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java index ecf8f12ea..ce91f32d9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/SoundTagPlayer.java @@ -18,13 +18,17 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.gui.player.MediaDisplay; import com.jpexs.decompiler.flash.tags.base.SoundTag; -import com.jpexs.helpers.sound.SoundPlayer; -import com.jpexs.helpers.sound.WavPlayer; +import com.jpexs.helpers.SoundPlayer; import java.awt.Color; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.sound.sampled.LineUnavailableException; +import javax.sound.sampled.UnsupportedAudioFileException; /** * @@ -36,9 +40,7 @@ public class SoundTagPlayer implements MediaDisplay { private Thread thr; private int actualPos = 0; - private boolean playing = false; private SoundTag tag; - private byte data[]; private List listeners = new ArrayList<>(); public void addListener(PlayerListener l) { @@ -55,39 +57,39 @@ public class SoundTagPlayer implements MediaDisplay { } } - private static final int FRAME_DIVISOR = 1024; + private static final int FRAME_DIVISOR = 8000; private int loops; + private boolean paused = true; + private Object myLock = new Object(); + private final Object playLock = new Object(); - public SoundTagPlayer(SoundTag tag, int loops) { + public SoundTagPlayer(SoundTag tag, int loops) throws LineUnavailableException, IOException, UnsupportedAudioFileException { this.tag = tag; this.loops = loops; ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayInputStream bais = new ByteArrayInputStream(tag.getRawSoundData()); tag.getSoundFormat().createWav(bais, baos); - this.data = baos.toByteArray(); + player = new SoundPlayer(new ByteArrayInputStream(baos.toByteArray())); } @Override public synchronized int getCurrentFrame() { - if (player == null) { - return 0; - } - if (!playing) { + if (!isPlaying()) { return actualPos; } - actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR); + synchronized (playLock) { + actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR); + } return actualPos; } @Override public synchronized int getTotalFrames() { //System.out.println("getTotalFrames"); - if (player == null) { - return 0; - } + int ret = (int) (player.samplesCount() / FRAME_DIVISOR); //System.out.println("/getTotalFrames"); @@ -96,39 +98,70 @@ public class SoundTagPlayer implements MediaDisplay { @Override public synchronized void pause() { - if (!playing) { + if (!isPlaying()) { + paused = true; return; } - playing = false; - actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR); - player.stop(); + + synchronized (playLock) { + actualPos = (int) (player.getSamplePosition() / FRAME_DIVISOR); + paused = true; + player.stop(); + try { + playLock.wait(); + } catch (InterruptedException ex) { + Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex); + } + } } public void play(boolean async) { - if (player != null) { - player.stop(); - } - player = new WavPlayer(new ByteArrayInputStream(data)); - final int startPos = actualPos * FRAME_DIVISOR; + synchronized (playLock) { + if (!paused) { + paused = true; + player.stop(); + try { + playLock.wait(); + } catch (InterruptedException ex) { + Logger.getLogger(SoundTagPlayer.class.getName()).log(Level.SEVERE, null, ex); + } + } + } + ; Runnable r = new Runnable() { @Override public void run() { - player.skip(startPos); - player.play(); - fireFinished(); - if (loops > 0) { - loops--; + int startPos = 0; + synchronized (playLock) { + startPos = actualPos * FRAME_DIVISOR; + paused = false; } - if (playing && loops > 0) { + player.setPosition(startPos); + player.play(); + + boolean playAgain = false; + synchronized (playLock) { + playAgain = !paused; + paused = true; + if (loops > 0) { + loops--; + } + } + if (playAgain && loops > 0) { gotoFrame(0); - play(); + run(); + return; + } else { + fireFinished(); + } + synchronized (playLock) { + playLock.notifyAll(); } } }; - playing = true; if (async) { thr = new Thread(r); thr.start(); @@ -145,21 +178,20 @@ public class SoundTagPlayer implements MediaDisplay { @Override public void rewind() { - actualPos = 0; + gotoFrame(0); } @Override public boolean isPlaying() { - return playing; + return player.isPlaying(); } @Override public synchronized void gotoFrame(int frame) { - if (playing) { - playing = false; - player.stop(); + pause(); + synchronized (playLock) { + actualPos = frame; } - actualPos = frame; } @Override diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/View.java b/trunk/src/com/jpexs/decompiler/flash/gui/View.java index 1f8208132..5263a7e37 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/View.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/View.java @@ -26,7 +26,6 @@ import java.awt.GraphicsEnvironment; import java.awt.Image; import java.awt.Rectangle; import java.awt.TexturePaint; -import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; @@ -222,9 +221,13 @@ public class View { * @param name Name of the image * @return loaded Image */ - public static Image loadImage(String name) { + public static BufferedImage loadImage(String name) { java.net.URL imageURL = View.class.getResource("/com/jpexs/decompiler/flash/gui/graphics/" + name + ".png"); - return Toolkit.getDefaultToolkit().createImage(imageURL); + try { + return ImageIO.read(imageURL); + } catch (IOException ex) { + return null; + } } /** diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound32.png b/trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound32.png new file mode 100644 index 000000000..8c2baf043 Binary files /dev/null and b/trunk/src/com/jpexs/decompiler/flash/gui/graphics/sound32.png differ diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java b/trunk/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java index a00cb970b..a5ac833d1 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/player/PlayerControls.java @@ -86,9 +86,9 @@ public class PlayerControls extends JPanel implements ActionListener { @Override public void mousePressed(MouseEvent e) { int frame = (int) Math.floor(e.getX() * t.display.getTotalFrames() / (double) progress.getWidth()); - boolean p = paused; + boolean p = t.display.isPlaying(); t.display.gotoFrame(frame); - if (!p) { + if (p) { t.display.play(); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java b/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java index a685dffdd..ae0e7ac55 100644 --- a/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java +++ b/trunk/src/com/jpexs/decompiler/flash/timeline/Frame.java @@ -16,20 +16,12 @@ */ package com.jpexs.decompiler.flash.timeline; -import com.jpexs.decompiler.flash.exporters.Matrix; import com.jpexs.decompiler.flash.tags.DoActionTag; -import com.jpexs.decompiler.flash.tags.base.ButtonTag; -import com.jpexs.decompiler.flash.tags.base.CharacterTag; -import com.jpexs.decompiler.flash.tags.base.DrawableTag; import com.jpexs.decompiler.flash.types.RGB; import com.jpexs.decompiler.flash.types.RGBA; -import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; -import java.awt.Point; import java.awt.Shape; -import java.awt.geom.Area; import java.util.ArrayList; import java.util.List; -import java.util.Stack; import java.util.TreeMap; /** diff --git a/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java b/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java index a37eac3bf..4f23ff014 100644 --- a/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java +++ b/trunk/src/com/jpexs/decompiler/flash/timeline/Timeline.java @@ -206,8 +206,8 @@ public class Timeline { } return ret; } - - public void getObjectsOutlines(int frame, int ratio,DepthState stateUnderCursor, int mouseButton, Matrix transformation,List objs,List outlines){ + + public void getObjectsOutlines(int frame, int ratio, DepthState stateUnderCursor, int mouseButton, Matrix transformation, List objs, List outlines) { Frame fr = this.frames.get(frame); Stack clips = new Stack<>(); for (int d = this.getMaxDepth(); d >= 0; d--) { @@ -234,8 +234,8 @@ public class Timeline { m = m.preConcatenate(transformation); int dframe = 0; - if(c instanceof Timelined){ - dframe = ds.time % ((Timelined) c).getTimeline().frames.size(); + if (c instanceof Timelined) { + dframe = ds.time % ((Timelined) c).getTimeline().frames.size(); if (c instanceof ButtonTag) { ButtonTag bt = (ButtonTag) c; dframe = ButtonTag.FRAME_UP; @@ -249,7 +249,7 @@ public class Timeline { } } Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.ratio, stateUnderCursor, mouseButton, m); - + Area addArea = new Area(cshape); if (currentClip != null) { Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight())); @@ -261,10 +261,10 @@ public class Timeline { clips.push(clip); } else { objs.add(ds); - outlines.add(addArea); + outlines.add(addArea); } - if(c instanceof Timelined){ - ((Timelined)c).getTimeline().getObjectsOutlines(dframe, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines); + if (c instanceof Timelined) { + ((Timelined) c).getTimeline().getObjectsOutlines(dframe, ds.ratio, stateUnderCursor, mouseButton, m, objs, outlines); } } } @@ -298,8 +298,8 @@ public class Timeline { m = m.preConcatenate(transformation); int dframe = 0; - if(c instanceof Timelined){ - dframe = ds.time % ((Timelined) c).getTimeline().frames.size(); + if (c instanceof Timelined) { + dframe = ds.time % ((Timelined) c).getTimeline().frames.size(); if (c instanceof ButtonTag) { ButtonTag bt = (ButtonTag) c; dframe = ButtonTag.FRAME_UP; @@ -313,7 +313,7 @@ public class Timeline { } } Shape cshape = ((DrawableTag) c).getOutline(dframe, ds.ratio, stateUnderCursor, mouseButton, m); - + Area addArea = new Area(cshape); if (currentClip != null) { Area a = new Area(new Rectangle(displayRect.Xmin, displayRect.Ymin, displayRect.getWidth(), displayRect.getHeight())); diff --git a/trunk/src/com/jpexs/helpers/sound/WavPlayer.java b/trunk/src/com/jpexs/helpers/SoundPlayer.java similarity index 58% rename from trunk/src/com/jpexs/helpers/sound/WavPlayer.java rename to trunk/src/com/jpexs/helpers/SoundPlayer.java index 00e946ece..0d18cf202 100644 --- a/trunk/src/com/jpexs/helpers/sound/WavPlayer.java +++ b/trunk/src/com/jpexs/helpers/SoundPlayer.java @@ -14,13 +14,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package com.jpexs.helpers.sound; +package com.jpexs.helpers; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.Clip; import javax.sound.sampled.Line; @@ -33,51 +31,29 @@ import javax.sound.sampled.UnsupportedAudioFileException; * * @author JPEXS */ -public class WavPlayer extends SoundPlayer { +public class SoundPlayer { private Clip clip; - private boolean complete = false; - private long startPos = 0; - public WavPlayer(InputStream is) { - super(is); - try { - clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class)); - } catch (LineUnavailableException ex) { - Logger.getLogger(WavPlayer.class.getName()).log(Level.SEVERE, null, ex); - } - - if (clip == null) { - return; - } - try { - clip.open(AudioSystem.getAudioInputStream(new BufferedInputStream(is))); - } catch (LineUnavailableException | IOException | UnsupportedAudioFileException ex) { - Logger.getLogger(WavPlayer.class.getName()).log(Level.SEVERE, "Error opening", ex); - clip = null; - } + public SoundPlayer(InputStream is) throws LineUnavailableException, IOException, UnsupportedAudioFileException { + clip = (Clip) AudioSystem.getLine(new Line.Info(Clip.class)); + clip.open(AudioSystem.getAudioInputStream(new BufferedInputStream(is))); } - @Override public long samplesCount() { return clip.getMicrosecondLength(); } - @Override public void play() { - if (clip == null) { - return; - } - clip.setMicrosecondPosition(startPos);//startPos); - final WavPlayer t = this; + + final SoundPlayer t = this; clip.addLineListener(new LineListener() { @Override public void update(LineEvent event) { if (event.getType() == LineEvent.Type.STOP) { - complete = true; - startPos = 0; - clip.close(); + //clip.close(); + synchronized (t) { t.notifyAll(); } @@ -94,29 +70,31 @@ public class WavPlayer extends SoundPlayer { } } - @Override public long getSamplePosition() { return clip.getMicrosecondPosition(); } - @Override - public void skip(long frames) { - startPos = getSamplePosition() + frames; + public void setPosition(long frames) { + clip.setMicrosecondPosition(frames); } - @Override public void stop() { clip.stop(); } - @Override public boolean isPlaying() { - return !complete; + return clip.isActive(); } - @Override public long getFrameRate() { return 1000000L; } + @Override + protected void finalize() throws Throwable { + if (clip != null) { + clip.close(); + } + } + } diff --git a/trunk/src/com/jpexs/helpers/sound/MP3Player.java b/trunk/src/com/jpexs/helpers/sound/MP3Player.java deleted file mode 100644 index 40a5f411c..000000000 --- a/trunk/src/com/jpexs/helpers/sound/MP3Player.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2010-2014 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 . - */ -package com.jpexs.helpers.sound; - -/** - * - * @author JPEXS - */ -import java.io.InputStream; -import java.util.logging.Level; -import java.util.logging.Logger; -import javazoom.jl.decoder.Bitstream; -import javazoom.jl.decoder.Decoder; -import javazoom.jl.decoder.Header; -import javazoom.jl.decoder.JavaLayerException; -import javazoom.jl.decoder.SampleBuffer; -import javazoom.jl.player.AudioDevice; -import javazoom.jl.player.FactoryRegistry; - -public class MP3Player extends SoundPlayer { - - private Bitstream bitstream; - - private Decoder decoder; - - private AudioDevice audio; - - private boolean closed = false; - - private boolean complete = false; - - private int positionSamples = 0; - private long sampleCount; - private int frameRate; - private int positionFrames = 0; - - public MP3Player(InputStream stream, long sampleCount, int frameRate) throws JavaLayerException { - this(stream, null); - this.sampleCount = sampleCount; - this.frameRate = frameRate; - } - - private MP3Player(InputStream stream, AudioDevice device) throws JavaLayerException { - super(stream); - bitstream = new Bitstream(stream); - decoder = new Decoder(); - - if (device != null) { - audio = device; - } else { - FactoryRegistry r = FactoryRegistry.systemRegistry(); - audio = r.createAudioDevice(); - } - audio.open(decoder); - } - - @Override - public void play() { - try { - play(Integer.MAX_VALUE); - } catch (JavaLayerException ex) { - Logger.getLogger(MP3Player.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private boolean play(int frames) throws JavaLayerException { - if (complete) { - return false; - } - boolean ret = true; - - while (frames-- > 0 && ret) { - ret = decodeFrame(); - } - - if (!ret) { - // last frame, ensure all data flushed to the audio device. - AudioDevice out = audio; - if (out != null) { - out.flush(); - synchronized (this) { - complete = (!closed); - stop(); - } - } - } - return ret; - } - - @Override - public synchronized void skip(long samples) { - if (complete) { - return; - } - long endPosition = positionSamples + samples; - if (samples == 0) { - return; - } - try { - while (true) { - Header h = bitstream.readFrame(); - if (h == null) { - complete = true; - return; - } - SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream); - positionSamples += output.getBufferLength(); - positionFrames++; - bitstream.closeFrame(); - if (positionSamples >= endPosition) { - break; - } - } - } catch (Exception ex) { - //ingore - } - - } - - @Override - public synchronized void stop() { - AudioDevice out = audio; - if (out != null) { - closed = true; - audio = null; - out.close(); - } - } - - @Override - public synchronized boolean isPlaying() { - return !complete; - } - - @Override - public long getSamplePosition() { - return positionSamples; - } - - private boolean decodeFrame() throws JavaLayerException { - try { - AudioDevice out = audio; - if (out == null) { - return false; - } - - Header h = bitstream.readFrame(); - if (h == null) { - return false; - } - - SampleBuffer output = (SampleBuffer) decoder.decodeFrame(h, bitstream); - positionSamples += output.getBufferLength(); - positionFrames++; - - synchronized (this) { - out = audio; - if (out != null) { - out.write(output.getBuffer(), 0, output.getBufferLength()); - } - } - - bitstream.closeFrame(); - } catch (RuntimeException ex) { - return true; - } - return true; - } - - @Override - public long samplesCount() { - return sampleCount; - } - - @Override - public long getFrameRate() { - return frameRate; - } - -} diff --git a/trunk/test/com/jpexs/decompiler/flash/ActionScript2AssemblerTest.java b/trunk/test/com/jpexs/decompiler/flash/ActionScript2AssemblerTest.java index e5563d384..1f5119792 100644 --- a/trunk/test/com/jpexs/decompiler/flash/ActionScript2AssemblerTest.java +++ b/trunk/test/com/jpexs/decompiler/flash/ActionScript2AssemblerTest.java @@ -20,10 +20,10 @@ import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.parser.ParseException; import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.CodeFormatting; import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; import com.jpexs.decompiler.flash.tags.DoActionTag; -import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException;