export fixes

This commit is contained in:
honfika@gmail.com
2015-01-22 10:08:26 +01:00
parent 6eefb19f9e
commit 7ebe345c4d
14 changed files with 213 additions and 222 deletions

View File

@@ -58,29 +58,13 @@ import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.dumpview.DumpInfoSwfNode;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.exporters.BinaryDataExporter;
import com.jpexs.decompiler.flash.exporters.FontExporter;
import com.jpexs.decompiler.flash.exporters.ImageExporter;
import com.jpexs.decompiler.flash.exporters.MorphShapeExporter;
import com.jpexs.decompiler.flash.exporters.MovieExporter;
import com.jpexs.decompiler.flash.exporters.ShapeExporter;
import com.jpexs.decompiler.flash.exporters.SoundExporter;
import com.jpexs.decompiler.flash.exporters.TextExporter;
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.exporters.script.AS2ScriptExporter;
import com.jpexs.decompiler.flash.exporters.settings.BinaryDataExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.FramesExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.ImageExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.MorphShapeExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.MovieExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.ShapeExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.SoundExportSettings;
import com.jpexs.decompiler.flash.exporters.settings.TextExportSettings;
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
import com.jpexs.decompiler.flash.helpers.BMPFile;
import com.jpexs.decompiler.flash.helpers.HighlightedText;
@@ -110,6 +94,7 @@ import com.jpexs.decompiler.flash.tags.base.ButtonTag;
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.Exportable;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.MorphShapeTag;
@@ -120,10 +105,13 @@ import com.jpexs.decompiler.flash.tags.base.TextTag;
import com.jpexs.decompiler.flash.timeline.Clip;
import com.jpexs.decompiler.flash.timeline.DepthState;
import com.jpexs.decompiler.flash.timeline.Frame;
import com.jpexs.decompiler.flash.timeline.FrameScript;
import com.jpexs.decompiler.flash.timeline.SvgClip;
import com.jpexs.decompiler.flash.timeline.TagScript;
import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.flash.treeitems.SWFList;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.RECT;
@@ -1105,13 +1093,13 @@ public final class SWF implements SWFContainerItem, Timelined {
private List<File> exportActionScript2(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel, EventListener evl) throws IOException {
List<File> ret = new ArrayList<>();
Map<String, ASMSource> asms = getASMs();
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
}
outdir += "scripts" + File.separator;
ret.addAll(new AS2ScriptExporter().exportAS2ScriptsTimeout(handler, outdir, asms.values(), exportMode, evl));
ret.addAll(new AS2ScriptExporter().exportAS2ScriptsTimeout(handler, outdir, getASMs(true), exportMode, evl));
return ret;
}
@@ -1171,9 +1159,8 @@ public final class SWF implements SWFContainerItem, Timelined {
return ret;
}
public List<File> exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel) throws Exception {
List<File> ret = new ArrayList<>();
final EventListener evl = new EventListener() {
public EventListener getExportEventListener() {
EventListener evl = new EventListener() {
@Override
public void handleEvent(String event, Object data) {
if (event.equals("exporting") || event.equals("exported")) {
@@ -1182,6 +1169,13 @@ public final class SWF implements SWFContainerItem, Timelined {
}
};
return evl;
}
public List<File> exportActionScript(AbortRetryIgnoreHandler handler, String outdir, ScriptExportMode exportMode, boolean parallel) throws IOException {
List<File> ret = new ArrayList<>();
final EventListener evl = getExportEventListener();
if (isAS3()) {
ret.addAll(exportActionScript3(handler, outdir, exportMode, parallel));
} else {
@@ -1190,37 +1184,130 @@ public final class SWF implements SWFContainerItem, Timelined {
return ret;
}
public Map<String, ASMSource> getASMs() {
Map<String, ASMSource> asms = new HashMap<>();
getASMs("", tags, asms);
return asms;
public Map<String, ASMSource> getASMs(boolean exportFileNames) {
return getASMs(exportFileNames, new ArrayList<TreeItem>(), true);
}
private static void getASMs(String path, List<Tag> items, Map<String, ASMSource> asms) {
for (Tag t : items) {
String subPath = path + "/" + t.toString();
if (t instanceof ASMSource) {
addASM(asms, (ASMSource) t, subPath);
public Map<String, ASMSource> getASMs(boolean exportFileNames, List<TreeItem> nodesToExport, boolean exportAll) {
Map<String, ASMSource> asmsToExport = new HashMap<>();
for (TreeItem treeItem : getFirstLevelASMNodes(null)) {
getASMs(exportFileNames, treeItem, nodesToExport, exportAll, asmsToExport, File.separator + getASMPath(exportFileNames, treeItem));
}
return asmsToExport;
}
private void getASMs(boolean exportFileNames, TreeItem treeItem, List<TreeItem> nodesToExport, boolean exportAll, Map<String, ASMSource> asmsToExport, String path) {
boolean exportNode = nodesToExport.contains(treeItem);
TreeItem realItem = treeItem instanceof TagScript ? ((TagScript) treeItem).getTag() : treeItem;
if (realItem instanceof ASMSource && (exportAll || exportNode)) {
String npath = path;
int ppos = 1;
while (asmsToExport.containsKey(npath)) {
ppos++;
npath = path + (exportFileNames ? "[" + ppos + "]" : "_" + ppos);
}
if (t instanceof ASMSourceContainer) {
for (ASMSource asm : ((ASMSourceContainer) t).getSubItems()) {
addASM(asms, asm, subPath + "/" + asm.toString());
asmsToExport.put(npath, (ASMSource) realItem);
}
if (treeItem instanceof TagScript) {
TagScript tagScript = (TagScript) treeItem;
for (TreeItem subItem : tagScript.getFrames()) {
getASMs(exportFileNames, subItem, nodesToExport, exportAll, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem));
}
} else if (treeItem instanceof FrameScript) {
FrameScript frameScript = (FrameScript) treeItem;
Frame parentFrame = frameScript.getFrame();
for (TreeItem subItem : parentFrame.actionContainers) {
getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem));
}
for (TreeItem subItem : parentFrame.actions) {
getASMs(exportFileNames, getASMWrapToTagScript(subItem), nodesToExport, exportAll || exportNode, asmsToExport, path + File.separator + getASMPath(exportFileNames, subItem));
}
}
}
private String getASMPath(boolean exportFileName, TreeItem treeItem) {
if (!exportFileName) {
return treeItem.toString();
}
String result;
if (treeItem instanceof Exportable) {
result = ((Exportable) treeItem).getExportFileName();
} else {
result = treeItem.toString();
}
return Helper.makeFileName(result);
}
private TreeItem getASMWrapToTagScript(TreeItem treeItem) {
if (treeItem instanceof Tag) {
Tag resultTag = (Tag) treeItem;
List<TreeItem> subNodes = new ArrayList<>();
if (treeItem instanceof ASMSourceContainer) {
for (ASMSource item : ((ASMSourceContainer) treeItem).getSubItems()) {
subNodes.add(item);
}
}
if (t instanceof DefineSpriteTag) {
getASMs(subPath, ((DefineSpriteTag) t).getSubTags(), asms);
}
TagScript tagScript = new TagScript(treeItem.getSwf(), resultTag, subNodes);
return tagScript;
}
return treeItem;
}
private static void addASM(Map<String, ASMSource> asms, ASMSource asm, String path) {
String npath = path;
int ppos = 1;
while (asms.containsKey(npath)) {
ppos++;
npath = path + "[" + ppos + "]";
public List<TreeItem> getFirstLevelASMNodes(Map<Tag, TagScript> tagScriptCache) {
Timeline timeline = getTimeline();
List<TreeItem> subNodes = new ArrayList<>();
List<TreeItem> subFrames = new ArrayList<>();
subNodes.addAll(timeline.getAS2RootPackage().subPackages.values());
subNodes.addAll(timeline.getAS2RootPackage().scripts.values());
for (Tag tag : timeline.otherTags) {
boolean hasInnerFrames = false;
List<TreeItem> tagSubNodes = new ArrayList<>();
if (tag instanceof Timelined) {
Timeline timeline2 = ((Timelined) tag).getTimeline();
for (Frame frame : timeline2.getFrames()) {
if (!frame.actions.isEmpty() || !frame.actionContainers.isEmpty()) {
FrameScript frameScript = new FrameScript(this, frame);
tagSubNodes.add(frameScript);
hasInnerFrames = true;
}
}
}
if (tag instanceof ASMSourceContainer) {
for (ASMSource asm : ((ASMSourceContainer) tag).getSubItems()) {
tagSubNodes.add(asm);
}
}
if (!tagSubNodes.isEmpty()) {
TagScript ts = new TagScript(this, tag, tagSubNodes);
if (tagScriptCache != null) {
tagScriptCache.put(tag, ts);
}
if (hasInnerFrames) {
subFrames.add(ts);
} else {
subNodes.add(ts);
}
}
}
asms.put(npath, asm);
subNodes.addAll(subFrames);
for (Frame frame : timeline.getFrames()) {
if (!frame.actions.isEmpty() || !frame.actionContainers.isEmpty()) {
FrameScript frameScript = new FrameScript(this, frame);
subNodes.add(frameScript);
}
}
return subNodes;
}
private final HashSet<EventListener> listeners = new HashSet<>();
@@ -1274,18 +1361,6 @@ public final class SWF implements SWFContainerItem, Timelined {
}
}
public void exportMovies(AbortRetryIgnoreHandler handler, String outdir, MovieExportSettings settings) throws IOException {
new MovieExporter().exportMovies(handler, outdir, tags, settings);
}
public void exportSounds(AbortRetryIgnoreHandler handler, String outdir, SoundExportSettings settings) throws IOException {
new SoundExporter().exportSounds(handler, outdir, tags, settings);
}
public void exportFonts(AbortRetryIgnoreHandler handler, String outdir, FontExportSettings settings) throws IOException {
new FontExporter().exportFonts(handler, outdir, tags, settings);
}
private static void writeLE(OutputStream os, long val, int size) throws IOException {
for (int i = 0; i < size; i++) {
os.write((int) (val & 0xff));
@@ -1701,26 +1776,6 @@ public final class SWF implements SWFContainerItem, Timelined {
return ret;
}
public void exportTexts(AbortRetryIgnoreHandler handler, String outdir, TextExportSettings settings) throws IOException {
new TextExporter().exportTexts(handler, outdir, tags, settings);
}
public void exportImages(AbortRetryIgnoreHandler handler, String outdir, ImageExportSettings settings) throws IOException {
new ImageExporter().exportImages(handler, outdir, tags, settings);
}
public void exportShapes(AbortRetryIgnoreHandler handler, String outdir, ShapeExportSettings settings) throws IOException {
new ShapeExporter().exportShapes(handler, outdir, tags, settings);
}
public void exportMorphShapes(AbortRetryIgnoreHandler handler, String outdir, MorphShapeExportSettings settings) throws IOException {
new MorphShapeExporter().exportMorphShapes(handler, outdir, tags, settings);
}
public void exportBinaryData(AbortRetryIgnoreHandler handler, String outdir, BinaryDataExportSettings settings) throws IOException {
new BinaryDataExporter().exportBinaryData(handler, outdir, tags, settings);
}
private static void getVariables(ConstantPool constantPool, BaseLocalData localData, TranslateStack stack, List<GraphTargetItem> output, ActionGraphSource code, int ip, List<MyEntry<DirectValueActionItem, ConstantPool>> variables, List<GraphSourceItem> functions, HashMap<DirectValueActionItem, ConstantPool> strings, List<Integer> visited, HashMap<DirectValueActionItem, String> usageTypes, String path) throws InterruptedException {
boolean debugMode = false;
while ((ip > -1) && ip < code.size()) {

View File

@@ -22,11 +22,7 @@ import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.FileTextWriter;
import com.jpexs.decompiler.flash.tags.DoInitActionTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.timeline.Timeline;
import com.jpexs.decompiler.flash.timeline.Timelined;
import com.jpexs.decompiler.graph.TranslateException;
import com.jpexs.helpers.CancellableWorker;
import com.jpexs.helpers.Helper;
@@ -34,11 +30,9 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@@ -53,7 +47,7 @@ import java.util.logging.Logger;
*/
public class AS2ScriptExporter {
public List<File> exportAS2ScriptsTimeout(final AbortRetryIgnoreHandler handler, final String outdir, final Collection<ASMSource> asms, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
public List<File> exportAS2ScriptsTimeout(final AbortRetryIgnoreHandler handler, final String outdir, final Map<String, ASMSource> asms, final ScriptExportMode exportMode, final EventListener ev) throws IOException {
try {
List<File> result = CancellableWorker.call(new Callable<List<File>>() {
@@ -68,7 +62,7 @@ public class AS2ScriptExporter {
return new ArrayList<>();
}
private List<File> exportAS2Scripts(AbortRetryIgnoreHandler handler, String outdir, Collection<ASMSource> asms, ScriptExportMode exportMode, EventListener ev) throws IOException {
private List<File> exportAS2Scripts(AbortRetryIgnoreHandler handler, String outdir, Map<String, ASMSource> asms, ScriptExportMode exportMode, EventListener ev) throws IOException {
List<File> ret = new ArrayList<>();
if (!outdir.endsWith(File.separator)) {
outdir += File.separator;
@@ -76,8 +70,9 @@ public class AS2ScriptExporter {
Map<String, List<String>> existingNamesMap = new HashMap<>();
AtomicInteger cnt = new AtomicInteger(1);
for (ASMSource asm : asms) {
String currentOutDir = outdir + getFilePath(asm) + File.separator;
for (String key : asms.keySet()) {
ASMSource asm = asms.get(key);
String currentOutDir = outdir + key + File.separator;
currentOutDir = new File(currentOutDir).getParentFile().toString() + File.separator;
List<String> existingNames = existingNamesMap.get(currentOutDir);
@@ -173,44 +168,4 @@ public class AS2ScriptExporter {
return null;
}
// todo: honfika: get the path from the tree
private String getFilePath(ASMSource asm) {
if (asm instanceof DoInitActionTag) {
String exportName = ((DoInitActionTag) asm).getExportName();
if (exportName != null) {
String path = "";
StringTokenizer st = new StringTokenizer(exportName, ".");
while (st.hasMoreTokens()) {
String pathElement = st.nextToken();
if (path.length() > 0) {
path += File.separator;
}
path += Helper.makeFileName(pathElement);
}
return path;
}
}
if (!(asm instanceof Tag)) {
return Helper.makeFileName(asm.getSourceTag().getExportFileName()) + File.separator + Helper.makeFileName(asm.getExportFileName());
} else {
String result = "";
Timelined timelined = asm.getSourceTag().getTimelined();
if (timelined instanceof Tag) {
result += Helper.makeFileName(((Tag) timelined).getExportFileName()) + File.separator;
}
Timeline timeline = timelined.getTimeline();
int frame = timeline.getFrameForAction(asm);
if (frame != -1) {
result += "frame_" + (frame + 1) + File.separator;
}
return result + Helper.makeFileName(asm.getExportFileName());
}
}
}

View File

@@ -1,5 +1,6 @@
The quick brown fox jumps over the lazy dog.
Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich
Voix ambiguë d'un coeur qui au zéphyr préfère les jattes de kiwis. 1234567890
Nechť již hříšné saxofony ďáblů rozzvučí síň úděsnými tóny waltzu, tanga a quickstepu.
Egy hűtlen vejét fülöncsípő, dühös mexikói úr ázik Quitóban.
Mężny bądź, chroń pułk twój i sześć flag

View File

@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.tags.DoActionTag;
import com.jpexs.decompiler.flash.tags.ShowFrameTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSourceContainer;
import com.jpexs.decompiler.flash.tags.base.Exportable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.RGBA;
@@ -32,7 +33,7 @@ import java.util.TreeMap;
*
* @author JPEXS
*/
public class Frame implements TreeItem {
public class Frame implements TreeItem, Exportable {
public final int frame;
@@ -81,4 +82,9 @@ public class Frame implements TreeItem {
public String toString() {
return "frame " + (frame + 1);
}
@Override
public String getExportFileName() {
return "frame_" + (frame + 1);
}
}

View File

@@ -17,13 +17,14 @@
package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.base.Exportable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
/**
*
* @author JPEXS
*/
public class FrameScript implements TreeItem {
public class FrameScript implements TreeItem, Exportable {
private final SWF swf;
@@ -47,4 +48,9 @@ public class FrameScript implements TreeItem {
public String toString() {
return frame.toString();
}
@Override
public String getExportFileName() {
return frame.getExportFileName();
}
}

View File

@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.timeline;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.Exportable;
import com.jpexs.decompiler.flash.treeitems.TreeItem;
import java.util.List;
@@ -25,7 +26,7 @@ import java.util.List;
*
* @author JPEXS
*/
public class TagScript implements TreeItem {
public class TagScript implements TreeItem, Exportable {
private final SWF swf;
@@ -56,4 +57,23 @@ public class TagScript implements TreeItem {
public String toString() {
return tag.toString();
}
@Override
public String getExportFileName() {
return tag.getExportFileName();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TagScript) {
return tag.equals(((TagScript) obj).getTag());
}
return false;
}
@Override
public int hashCode() {
return tag.hashCode();
}
}

View File

@@ -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.treeitems;
import com.jpexs.decompiler.flash.SWF;

View File

@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.tags.base.Exportable;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
@@ -44,7 +43,7 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
public class BUTTONCONDACTION implements ASMSource, Exportable, Serializable {
public class BUTTONCONDACTION implements ASMSource, Serializable {
private final SWF swf;

View File

@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.tags.base.ASMSource;
import com.jpexs.decompiler.flash.tags.base.Exportable;
import com.jpexs.decompiler.flash.types.annotations.Conditional;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.helpers.ByteArrayRange;
@@ -43,7 +42,7 @@ import java.util.logging.Logger;
*
* @author JPEXS
*/
public class CLIPACTIONRECORD implements ASMSource, Exportable, Serializable {
public class CLIPACTIONRECORD implements ASMSource, Serializable {
public static String keyToString(int key) {
if ((key < CLIPACTIONRECORD.KEYNAMES.length) && (key > 0) && (CLIPACTIONRECORD.KEYNAMES[key] != null)) {