mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-05 14:15:09 +00:00
framerate is float
This commit is contained in:
@@ -206,7 +206,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
/**
|
||||
* Movie frame rate
|
||||
*/
|
||||
public int frameRate;
|
||||
public float frameRate;
|
||||
|
||||
/**
|
||||
* Number of frames in movie
|
||||
@@ -767,8 +767,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
sos.writeUI8(version);
|
||||
sos.writeUI32(0); // placeholder for file length
|
||||
sos.writeRECT(displayRect);
|
||||
sos.writeUI8(0);
|
||||
sos.writeUI8(frameRate);
|
||||
sos.writeFIXED8(frameRate);
|
||||
sos.writeUI16(frameCount);
|
||||
|
||||
sos.writeTags(tags);
|
||||
@@ -1037,9 +1036,7 @@ public final class SWF implements SWFContainerItem, Timelined {
|
||||
}
|
||||
sis.setPercentMax(fileSize);
|
||||
displayRect = sis.readRECT("displayRect");
|
||||
// FIXED8 (16 bit fixed point) frameRate
|
||||
sis.readUI8("tmpFirstByetOfFrameRate"); // tmpFirstByetOfFrameRate
|
||||
frameRate = sis.readUI8("frameRate");
|
||||
frameRate = sis.readFIXED8("frameRate");
|
||||
frameCount = sis.readUI16("frameCount");
|
||||
List<Tag> tags = sis.readTagList(this, 0, parallelRead, true, !checkOnly, lazy);
|
||||
if (tags.size() > 0 && tags.get(tags.size() - 1).getId() == EndTag.ID) {
|
||||
|
||||
@@ -617,11 +617,22 @@ public class SWFInputStream implements AutoCloseable {
|
||||
*/
|
||||
public int readSI8(String name) throws IOException {
|
||||
newDumpLevel(name, "SI8");
|
||||
int ret = readSI8Internal();
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one SI8 (Signed 8bit integer) value from the stream
|
||||
*
|
||||
* @return SI8 value
|
||||
* @throws IOException
|
||||
*/
|
||||
public int readSI8Internal() throws IOException {
|
||||
int uval = readEx();
|
||||
if (uval >= 0x80) {
|
||||
uval = -(((~uval) & 0xff) + 1);
|
||||
}
|
||||
endDumpLevel(uval);
|
||||
return uval;
|
||||
}
|
||||
|
||||
@@ -636,13 +647,13 @@ public class SWFInputStream implements AutoCloseable {
|
||||
newDumpLevel(name, "FIXED");
|
||||
int afterPoint = readUI16Internal();
|
||||
int beforePoint = readUI16Internal();
|
||||
double ret = ((double) ((beforePoint << 16) + afterPoint)) / 65536;
|
||||
double ret = beforePoint + ((double) (afterPoint)) / 65536;
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one FIXED8 (Fixed point 8.8) value from the stream
|
||||
* Reads one FIXED8 (Fixed point 8.8) signed value from the stream
|
||||
*
|
||||
* @param name
|
||||
* @return FIXED8 value
|
||||
@@ -651,8 +662,13 @@ public class SWFInputStream implements AutoCloseable {
|
||||
public float readFIXED8(String name) throws IOException {
|
||||
newDumpLevel(name, "FIXED8");
|
||||
int afterPoint = readEx();
|
||||
int beforePoint = readEx();
|
||||
float ret = beforePoint + (((float) afterPoint) / 256);
|
||||
int beforePoint = readSI8Internal();
|
||||
float ret;
|
||||
if (beforePoint < 0) {
|
||||
ret = beforePoint - ((float) afterPoint) / 256;
|
||||
} else {
|
||||
ret = beforePoint + ((float) afterPoint) / 256;
|
||||
}
|
||||
endDumpLevel(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,6 @@ public class SWFOutputStream extends OutputStream {
|
||||
public void writeFIXED(double value) throws IOException {
|
||||
long valueLong = (long) (value * (1 << 16));
|
||||
int beforePoint = (int) valueLong >> 16;
|
||||
|
||||
int afterPoint = (int) valueLong % (1 << 16);
|
||||
writeUI16(afterPoint);
|
||||
writeUI16(beforePoint);
|
||||
@@ -308,10 +307,11 @@ public class SWFOutputStream extends OutputStream {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeFIXED8(float value) throws IOException {
|
||||
int beforePoint = (int) getIntPart(value);
|
||||
int afterPoint = (int) getIntPart((value + (value < 0 ? beforePoint : -beforePoint)) * 256);
|
||||
final int divisor = 1 << 8;
|
||||
int beforePoint = (int) value;
|
||||
int afterPoint = Math.abs((int) (value * divisor)) % divisor;
|
||||
writeUI8(afterPoint);
|
||||
writeUI8(beforePoint);
|
||||
writeSI8(beforePoint);
|
||||
}
|
||||
|
||||
private void writeLong(long value) throws IOException {
|
||||
@@ -578,13 +578,6 @@ public class SWFOutputStream extends OutputStream {
|
||||
return nBits;
|
||||
}
|
||||
|
||||
private static long getIntPart(double value) {
|
||||
if (value < 0) {
|
||||
return (long) Math.ceil(value);
|
||||
}
|
||||
return (long) Math.floor(value);
|
||||
}
|
||||
|
||||
public static int unsignedSize(final int value) {
|
||||
|
||||
final int val = (value < 0) ? -value - 1 : value;
|
||||
|
||||
@@ -438,14 +438,14 @@ public class FrameExporter {
|
||||
return "[" + rgb.red + "," + rgb.green + "," + rgb.blue + "," + ((rgb instanceof RGBA) ? ((RGBA) rgb).getAlphaFloat() : 1) + "]";
|
||||
}
|
||||
|
||||
public static void makeAVI(Iterator<BufferedImage> images, int frameRate, File file, EventListener evl) throws IOException {
|
||||
public static void makeAVI(Iterator<BufferedImage> images, float frameRate, File file, EventListener evl) throws IOException {
|
||||
if (!images.hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AVIWriter out = new AVIWriter(file);
|
||||
BufferedImage img0 = images.next();
|
||||
out.addVideoTrack(VideoFormatKeys.ENCODING_AVI_PNG, 1, frameRate, img0.getWidth(), img0.getHeight(), 0, 0);
|
||||
out.addVideoTrack(VideoFormatKeys.ENCODING_AVI_PNG, 1, (int) frameRate, img0.getWidth(), img0.getHeight(), 0, 0);
|
||||
try {
|
||||
out.write(0, img0, 1);
|
||||
while (images.hasNext()) {
|
||||
@@ -456,7 +456,7 @@ public class FrameExporter {
|
||||
}
|
||||
}
|
||||
|
||||
public static void makeGIF(Iterator<BufferedImage> images, int frameRate, File file, EventListener evl) throws IOException {
|
||||
public static void makeGIF(Iterator<BufferedImage> images, float frameRate, File file, EventListener evl) throws IOException {
|
||||
if (!images.hasNext()) {
|
||||
return;
|
||||
}
|
||||
@@ -464,7 +464,7 @@ public class FrameExporter {
|
||||
AnimatedGifEncoder encoder = new AnimatedGifEncoder();
|
||||
encoder.setRepeat(0); // repeat forever
|
||||
encoder.start(file.getAbsolutePath());
|
||||
encoder.setDelay(1000 / frameRate);
|
||||
encoder.setDelay((int) (1000.0 / frameRate));
|
||||
while (images.hasNext()) {
|
||||
encoder.addFrame(images.next());
|
||||
}
|
||||
@@ -472,14 +472,14 @@ public class FrameExporter {
|
||||
encoder.finish();
|
||||
}
|
||||
|
||||
public static void makeGIFOld(Iterator<BufferedImage> images, int frameRate, File file, EventListener evl) throws IOException {
|
||||
public static void makeGIFOld(Iterator<BufferedImage> images, float frameRate, File file, EventListener evl) throws IOException {
|
||||
if (!images.hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (ImageOutputStream output = new FileImageOutputStream(file)) {
|
||||
BufferedImage img0 = images.next();
|
||||
GifSequenceWriter writer = new GifSequenceWriter(output, img0.getType(), 1000 / frameRate, true);
|
||||
GifSequenceWriter writer = new GifSequenceWriter(output, img0.getType(), (int) (1000.0 / frameRate), true);
|
||||
writer.writeToSequence(img0);
|
||||
|
||||
while (images.hasNext()) {
|
||||
|
||||
@@ -180,7 +180,7 @@ public class MovieExporter {
|
||||
}
|
||||
|
||||
baos.write(tag.videoData.getRangeData());
|
||||
flv.writeTag(new FLVTAG((int) Math.floor(i * 1000.0f / ((float) swf.frameRate)), new VIDEODATA(frameType, videoStream.codecID, baos.toByteArray())));
|
||||
flv.writeTag(new FLVTAG((int) Math.floor(i * 1000.0 / swf.frameRate), new VIDEODATA(frameType, videoStream.codecID, baos.toByteArray())));
|
||||
}
|
||||
return fos.toByteArray();
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public class SoundExporter {
|
||||
flv.writeHeader(true, false);
|
||||
List<SoundStreamBlockTag> blocks = sh.getBlocks();
|
||||
|
||||
int ms = (int) (1000.0f / ((float) ((Tag) st).getSwf().frameRate));
|
||||
int ms = (int) (1000.0 / ((Tag) st).getSwf().frameRate);
|
||||
for (int b = 0; b < blocks.size(); b++) {
|
||||
byte[] data = blocks.get(b).streamSoundData.getRangeData();
|
||||
if (st.getSoundFormatId() == 2) { //MP3
|
||||
|
||||
@@ -66,7 +66,7 @@ public class Timeline {
|
||||
|
||||
public RECT displayRect;
|
||||
|
||||
public int frameRate;
|
||||
public float frameRate;
|
||||
|
||||
public Timelined timelined;
|
||||
|
||||
|
||||
@@ -1577,10 +1577,10 @@ public class XFLConverter {
|
||||
mediaLinkStr = "<DOMVideoItem name=\"" + symbolFile + "\" sourceLastImported=\"" + getTimestamp(swf) + "\" externalFileSize=\"" + data.length + "\"";
|
||||
mediaLinkStr += " href=\"" + symbolFile + "\"";
|
||||
mediaLinkStr += " videoType=\"" + videoType + "\"";
|
||||
mediaLinkStr += " fps=\"" + swf.frameRate + "\"";
|
||||
mediaLinkStr += " fps=\"" + (int) swf.frameRate + "\""; // todo: is the cast to in needed?
|
||||
mediaLinkStr += " width=\"" + video.width + "\"";
|
||||
mediaLinkStr += " height=\"" + video.height + "\"";
|
||||
double len = ((double) video.numFrames) / ((double) swf.frameRate);
|
||||
double len = (double) video.numFrames / swf.frameRate;
|
||||
mediaLinkStr += " length=\"" + len + "\"";
|
||||
boolean linkageExportForAS = false;
|
||||
if (characterClasses.containsKey(symbol.getCharacterId())) {
|
||||
@@ -2694,7 +2694,7 @@ public class XFLConverter {
|
||||
}
|
||||
domDocument.append("<DOMDocument xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://ns.adobe.com/xfl/2008/\" currentTimeline=\"1\" xflVersion=\"").append(flaVersion.xflVersion()).append("\" creatorInfo=\"").append(generator).append("\" platform=\"Windows\" versionInfo=\"Saved by ").append(generatorVerName).append("\" majorVersion=\"").append(generatorVersion).append("\" buildNumber=\"\" nextSceneIdentifier=\"2\" playOptionsPlayLoop=\"false\" playOptionsPlayPages=\"false\" playOptionsPlayFrameActions=\"false\" autoSaveHasPrompted=\"true\"");
|
||||
domDocument.append(" backgroundColor=\"").append(backgroundColor).append("\"");
|
||||
domDocument.append(" frameRate=\"").append(swf.frameRate).append("\"");
|
||||
domDocument.append(" frameRate=\"").append((int) swf.frameRate).append("\"");
|
||||
|
||||
double width = twipToPixel(swf.displayRect.getWidth());
|
||||
double height = twipToPixel(swf.displayRect.getHeight());
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2015 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.
|
||||
* License along with this library.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
//import com.jpexs.decompiler.flash.gui.Main;
|
||||
@@ -136,23 +137,47 @@ public class SWFStreamTest {
|
||||
assertTrue(Double.compare(7.5, sis.readFIXED("test")) == 0);
|
||||
sis.close();
|
||||
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
double dd = 5.25;
|
||||
sos.writeFIXED(dd);
|
||||
sos.close();
|
||||
sis = new SWFInputStream(null, baos.toByteArray());
|
||||
assertTrue(Double.compare(dd, sis.readFIXED("test")) == 0);
|
||||
double[] dds = new double[]{5.25, 65535.25};
|
||||
for (double dd : dds) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
sos.writeFIXED(dd);
|
||||
sos.close();
|
||||
sis = new SWFInputStream(null, baos.toByteArray());
|
||||
double dd2 = sis.readFIXED("test");
|
||||
assertTrue(Double.compare(dd, dd2) == 0, "Written and read value not equals. Written: " + dd + " read: " + dd2);
|
||||
sis.close();
|
||||
}
|
||||
|
||||
|
||||
baos = new ByteArrayOutputStream();
|
||||
sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
float ff = 5.25f;
|
||||
sos.writeFIXED8(ff);
|
||||
sos.close();
|
||||
sis = new SWFInputStream(null, baos.toByteArray());
|
||||
assertEquals(ff, sis.readFIXED8("test"));
|
||||
float[] ffs = new float[]{5.25f, -5.25f, 127.75f, -128f};
|
||||
for (float ff : ffs) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
sos.writeFIXED8(ff);
|
||||
sos.close();
|
||||
sis = new SWFInputStream(null, baos.toByteArray());
|
||||
float ff2 = sis.readFIXED8("test");
|
||||
assertEquals(ff, ff2, "Written and read value not equals. Written: " + ff + " read: " + ff2);
|
||||
sis.close();
|
||||
}
|
||||
}
|
||||
|
||||
//@Test
|
||||
public void testAllFIXED8() throws IOException {
|
||||
for (int i = 0; i < 65536; i++) {
|
||||
byte[] data = new byte[]{(byte) (i % 256), (byte) (i / 256)};
|
||||
SWFInputStream sis = new SWFInputStream(null, data);
|
||||
float d = sis.readFIXED8("test");
|
||||
sis.close();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
SWFOutputStream sos = new SWFOutputStream(baos, SWF.DEFAULT_VERSION);
|
||||
sos.writeFIXED8(d);
|
||||
sos.close();
|
||||
byte[] data2 = baos.toByteArray();
|
||||
|
||||
assertTrue(data[0] == data2[0] && data[1] == data2[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -225,7 +225,7 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
swf.compression = getCompression();
|
||||
swf.version = getVersionNumber();
|
||||
swf.gfx = gfxCheckBox.isSelected();
|
||||
swf.frameRate = (int) frameRateEditor.getModel().getValue();
|
||||
swf.frameRate = ((Number) (frameRateEditor.getModel().getValue())).floatValue();
|
||||
swf.displayRect.Xmin = (int) xMinEditor.getModel().getValue();
|
||||
swf.displayRect.Xmax = (int) xMaxEditor.getModel().getValue();
|
||||
swf.displayRect.Ymin = (int) yMinEditor.getModel().getValue();
|
||||
@@ -266,7 +266,7 @@ public class HeaderInfoPanel extends JPanel implements TagEditorPanel {
|
||||
|
||||
fileSizeLabel.setText(Long.toString(swf.fileSize));
|
||||
|
||||
frameRateLabel.setText(Integer.toString(swf.frameRate));
|
||||
frameRateLabel.setText(Float.toString(swf.frameRate));
|
||||
frameRateEditor.setModel(new SpinnerNumberModel(swf.frameRate, -0x80000000, 0x7fffffff, 1));
|
||||
|
||||
frameCountLabel.setText("" + swf.frameCount);
|
||||
|
||||
@@ -958,8 +958,8 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
|
||||
private void startTimer(Timeline timeline, boolean playing) {
|
||||
|
||||
int frameRate = timeline.frameRate;
|
||||
int msPerFrame = frameRate == 0 ? 1000 : 1000 / frameRate;
|
||||
float frameRate = timeline.frameRate;
|
||||
int msPerFrame = frameRate == 0 ? 1000 : (int) (1000.0 / frameRate);
|
||||
final boolean singleFrame = !playing || (timeline.getRealFrameCount() <= 1 && timeline.isSingleFrame());
|
||||
|
||||
timer = new Timer();
|
||||
@@ -1043,7 +1043,7 @@ public final class ImagePanel extends JPanel implements MediaDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized int getFrameRate() {
|
||||
public synchronized float getFrameRate() {
|
||||
if (timelined == null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -3293,7 +3293,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
private void initTimeline(Timeline timeline) {
|
||||
if (tag instanceof MorphShapeTag) {
|
||||
tim.frameRate = MORPH_SHAPE_ANIMATION_FRAME_RATE;
|
||||
int framesCnt = tim.frameRate * MORPH_SHAPE_ANIMATION_LENGTH;
|
||||
int framesCnt = (int) (tim.frameRate * MORPH_SHAPE_ANIMATION_LENGTH);
|
||||
for (int i = 0; i < framesCnt; i++) {
|
||||
Frame f = new Frame(tim, i);
|
||||
DepthState ds = new DepthState(tag.getSwf(), f);
|
||||
|
||||
@@ -618,7 +618,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
|
||||
int frameCount = 1;
|
||||
int frameRate = swf.frameRate;
|
||||
float frameRate = swf.frameRate;
|
||||
HashMap<Integer, VideoFrameTag> videoFrames = new HashMap<>();
|
||||
if (tagObj instanceof DefineVideoStreamTag) {
|
||||
DefineVideoStreamTag vs = (DefineVideoStreamTag) tagObj;
|
||||
@@ -634,7 +634,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
if ((tagObj instanceof DefineMorphShapeTag) || (tagObj instanceof DefineMorphShape2Tag)) {
|
||||
frameRate = MainPanel.MORPH_SHAPE_ANIMATION_FRAME_RATE;
|
||||
frameCount = MainPanel.MORPH_SHAPE_ANIMATION_LENGTH * frameRate;
|
||||
frameCount = (int) (MainPanel.MORPH_SHAPE_ANIMATION_LENGTH * frameRate);
|
||||
}
|
||||
|
||||
if (tagObj instanceof DefineSoundTag) {
|
||||
@@ -660,8 +660,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
int height = outrect.getHeight();
|
||||
|
||||
sos2.writeRECT(outrect);
|
||||
sos2.writeUI8(0);
|
||||
sos2.writeUI8(frameRate);
|
||||
sos2.writeFIXED8(frameRate);
|
||||
sos2.writeUI16(frameCount); //framecnt
|
||||
|
||||
/*FileAttributesTag fa = new FileAttributesTag();
|
||||
|
||||
@@ -299,7 +299,7 @@ public class SoundTagPlayer implements MediaDisplay {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFrameRate() {
|
||||
public float getFrameRate() {
|
||||
return (int) (1000000L / FRAME_DIVISOR);
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public interface MediaDisplay extends Closeable {
|
||||
|
||||
public void setBackground(Color color);
|
||||
|
||||
public int getFrameRate();
|
||||
public float getFrameRate();
|
||||
|
||||
public boolean isLoaded();
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
|
||||
if (currentFrame >= totalFrames) {
|
||||
currentFrame = totalFrames - 1;
|
||||
}
|
||||
int frameRate = display.getFrameRate();
|
||||
float frameRate = display.getFrameRate();
|
||||
if (totalFrames == 0) {
|
||||
progress.setIndeterminate(true);
|
||||
} else {
|
||||
@@ -360,8 +360,8 @@ public class PlayerControls extends JPanel implements MediaDisplayListener {
|
||||
frameLabel.setText(("" + (currentFrame + 1)));
|
||||
totalFrameLabel.setText("" + totalFrames);
|
||||
if (frameRate != 0) {
|
||||
timeLabel.setText("(" + formatMs((currentFrame * 1000) / frameRate) + ")");
|
||||
totalTimeLabel.setText("(" + formatMs((totalFrames * 1000) / frameRate) + ")");
|
||||
timeLabel.setText("(" + formatMs((int) (currentFrame * 1000.0 / frameRate)) + ")");
|
||||
totalTimeLabel.setText("(" + formatMs((int) (totalFrames * 1000.0 / frameRate)) + ")");
|
||||
}
|
||||
if (totalFrames <= 1 && playbackControls.isVisible()) {
|
||||
playbackControls.setVisible(false);
|
||||
|
||||
Reference in New Issue
Block a user