mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-25 12:21:04 +00:00
Added: #2556 CLI subsprite animation export (-sublength <length> option for export)
Added: #2556 Option to select arbitrary frames of sprites export via `-select`. Check `--help -select` for details.
This commit is contained in:
@@ -517,6 +517,7 @@ public class CommandLineArgumentParser {
|
||||
List<String> selectionClasses = null;
|
||||
String nextParam = null;
|
||||
String nextParamOriginal = null;
|
||||
int subLength = 1;
|
||||
OUTER:
|
||||
while (true) {
|
||||
nextParamOriginal = args.pop();
|
||||
@@ -534,14 +535,17 @@ public class CommandLineArgumentParser {
|
||||
cliMode = true;
|
||||
break;
|
||||
case "-selectid":
|
||||
selectionIds = parseSelect(args);
|
||||
selectionIds = parseSelect(args, false, "selectid");
|
||||
break;
|
||||
case "-select":
|
||||
selection = parseSelect(args);
|
||||
selection = parseSelect(args, true, "select");
|
||||
break;
|
||||
case "-selectclass":
|
||||
selectionClasses = parseSelectClass(args);
|
||||
break;
|
||||
case "-sublength":
|
||||
subLength = parseSubLength(args);
|
||||
break;
|
||||
case "-exportembed":
|
||||
exportEmbed = true;
|
||||
break;
|
||||
@@ -677,7 +681,7 @@ public class CommandLineArgumentParser {
|
||||
} else if (command.equals("proxy")) {
|
||||
parseProxy(args);
|
||||
} else if (command.equals("export")) {
|
||||
parseExport(selectionClasses, selection, selectionIds, args, handler, traceLevel, format, zoom, charset, exportEmbed, resampleWav, transparentBackground, urlResolver);
|
||||
parseExport(selectionClasses, selection, selectionIds, args, handler, traceLevel, format, zoom, charset, exportEmbed, resampleWav, transparentBackground, urlResolver, subLength);
|
||||
System.exit(0);
|
||||
} else if (command.equals("compress")) {
|
||||
parseCompress(args);
|
||||
@@ -1584,16 +1588,29 @@ public class CommandLineArgumentParser {
|
||||
|
||||
private static class Range {
|
||||
|
||||
public Integer prefix;
|
||||
|
||||
public Integer min;
|
||||
|
||||
public Integer max;
|
||||
|
||||
public Range(Integer min, Integer max) {
|
||||
public Range(Integer prefix, Integer min, Integer max) {
|
||||
this.prefix = prefix;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public boolean contains(int index) {
|
||||
return contains(0, index);
|
||||
}
|
||||
|
||||
public boolean contains(int prefix, int index) {
|
||||
if (this.prefix == null && prefix == 0) {
|
||||
return false;
|
||||
}
|
||||
if (this.prefix != null && this.prefix != prefix) {
|
||||
return false;
|
||||
}
|
||||
int minimum = min == null ? Integer.MIN_VALUE : min;
|
||||
int maximum = max == null ? Integer.MAX_VALUE : max;
|
||||
|
||||
@@ -1607,7 +1624,7 @@ public class CommandLineArgumentParser {
|
||||
|
||||
public Selection() {
|
||||
this.ranges = new ArrayList<>();
|
||||
this.ranges.add(new Range(null, null));
|
||||
this.ranges.add(new Range(0, null, null));
|
||||
}
|
||||
|
||||
public Selection(List<Range> ranges) {
|
||||
@@ -1615,36 +1632,76 @@ public class CommandLineArgumentParser {
|
||||
}
|
||||
|
||||
public boolean contains(int index) {
|
||||
return contains(0, index);
|
||||
}
|
||||
|
||||
public boolean contains(int prefix, int index) {
|
||||
boolean prefixFound = false;
|
||||
for (Range r : ranges) {
|
||||
if (r.contains(index)) {
|
||||
if (r.prefix == prefix || (prefix != 0 && r.prefix == null)) {
|
||||
prefixFound = true;
|
||||
}
|
||||
if (r.contains(prefix, index)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!prefixFound) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static Selection parseSelect(Stack<String> args) {
|
||||
private static Selection parseSelect(Stack<String> args, boolean allowPrefix, String command) {
|
||||
List<Range> ret = new ArrayList<>();
|
||||
if (args.isEmpty()) {
|
||||
System.err.println("range parameter expected");
|
||||
badArguments("select");
|
||||
badArguments(command);
|
||||
}
|
||||
String range = args.pop();
|
||||
String[] ranges;
|
||||
if (range.contains(",")) {
|
||||
ranges = range.split(",");
|
||||
ranges = range.split(",", -1);
|
||||
} else {
|
||||
ranges = new String[]{range};
|
||||
}
|
||||
|
||||
Integer prefix = 0;
|
||||
|
||||
for (String r : ranges) {
|
||||
Integer min = null;
|
||||
Integer max = null;
|
||||
if (r.contains("-")) {
|
||||
String[] ps = r.split("\\-");
|
||||
if (r.contains(":")) {
|
||||
if (!allowPrefix) {
|
||||
System.err.println("invalid range");
|
||||
badArguments(command);
|
||||
}
|
||||
String[] ps = r.split(":", -1);
|
||||
if (ps.length != 2) {
|
||||
System.err.println("invalid range");
|
||||
badArguments("select");
|
||||
badArguments(command);
|
||||
}
|
||||
if ("all".equals(ps[0])) {
|
||||
prefix = null;
|
||||
} else {
|
||||
try {
|
||||
prefix = Integer.parseInt(ps[0]);
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.err.println("invalid range");
|
||||
badArguments(command);
|
||||
}
|
||||
if (prefix < 0) {
|
||||
System.err.println("invalid range");
|
||||
badArguments(command);
|
||||
}
|
||||
}
|
||||
r = ps[1];
|
||||
}
|
||||
if (r.contains("-")) {
|
||||
String[] ps = r.split("\\-", -1);
|
||||
if (ps.length != 2) {
|
||||
System.err.println("invalid range");
|
||||
badArguments(command);
|
||||
}
|
||||
try {
|
||||
if (!"".equals(ps[0])) {
|
||||
@@ -1655,7 +1712,7 @@ public class CommandLineArgumentParser {
|
||||
}
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.err.println("invalid range");
|
||||
badArguments("select");
|
||||
badArguments(command);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
@@ -1663,13 +1720,33 @@ public class CommandLineArgumentParser {
|
||||
max = min;
|
||||
} catch (NumberFormatException nfe) {
|
||||
System.err.println("invalid range");
|
||||
badArguments("select");
|
||||
badArguments(command);
|
||||
}
|
||||
}
|
||||
ret.add(new Range(min, max));
|
||||
ret.add(new Range(prefix, min, max));
|
||||
}
|
||||
return new Selection(ret);
|
||||
}
|
||||
|
||||
private static int parseSubLength(Stack<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
System.err.println("sub length parameter expected");
|
||||
badArguments("sublength");
|
||||
}
|
||||
try {
|
||||
int subLen = Integer.parseInt(args.pop());
|
||||
if (subLen < 1) {
|
||||
System.err.println("Minimum for sub length is 1");
|
||||
badArguments("sublength");
|
||||
subLen = 1;
|
||||
}
|
||||
return subLen;
|
||||
} catch (NumberFormatException nre) {
|
||||
System.err.println("Invalid sub length");
|
||||
badArguments("sublength");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static double parseZoom(Stack<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
@@ -2033,7 +2110,21 @@ public class CommandLineArgumentParser {
|
||||
|
||||
}
|
||||
|
||||
private static void parseExport(List<String> selectionClasses, Selection selection, Selection selectionIds, Stack<String> args, AbortRetryIgnoreHandler handler, Level traceLevel, Map<String, String> formats, double zoom, String charset, boolean exportEmbed, boolean resampleWav, boolean transparentBackground, UrlResolver urlResolver) {
|
||||
private static void parseExport(
|
||||
List<String> selectionClasses,
|
||||
Selection selection,
|
||||
Selection selectionIds,
|
||||
Stack<String> args,
|
||||
AbortRetryIgnoreHandler handler,
|
||||
Level traceLevel,
|
||||
Map<String, String> formats,
|
||||
double zoom,
|
||||
String charset,
|
||||
boolean exportEmbed,
|
||||
boolean resampleWav,
|
||||
boolean transparentBackground,
|
||||
UrlResolver urlResolver,
|
||||
int subFrameLength) {
|
||||
if (args.size() < 3) {
|
||||
badArguments("export");
|
||||
}
|
||||
@@ -2258,20 +2349,27 @@ public class CommandLineArgumentParser {
|
||||
System.out.println("Exporting frames...");
|
||||
List<Integer> frames = new ArrayList<>();
|
||||
for (int i = 0; i < swf.frameCount; i++) {
|
||||
if (selection.contains(i + 1)) {
|
||||
if (selection.contains(0, i + 1)) {
|
||||
frames.add(i);
|
||||
}
|
||||
}
|
||||
FrameExportSettings fes = new FrameExportSettings(enumFromStr(formats.get("frame"), FrameExportMode.class), zoom, transparentBackground);
|
||||
frameExporter.exportFrames(handler, outDir + (multipleExportTypes ? File.separator + FrameExportSettings.EXPORT_FOLDER_NAME : ""), swf, 0, frames, 1, fes, evl);
|
||||
frameExporter.exportFrames(handler, outDir + (multipleExportTypes ? File.separator + FrameExportSettings.EXPORT_FOLDER_NAME : ""), swf, 0, frames, subFrameLength, fes, evl);
|
||||
}
|
||||
|
||||
if (exportAll || exportFormats.contains("sprite")) {
|
||||
System.out.println("Exporting sprite...");
|
||||
SpriteExportSettings ses = new SpriteExportSettings(enumFromStr(formats.get("sprite"), SpriteExportMode.class), zoom);
|
||||
for (Tag t : extags) {
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
frameExporter.exportSpriteFrames(handler, outDir + (multipleExportTypes ? File.separator + SpriteExportSettings.EXPORT_FOLDER_NAME : ""), swf, ((DefineSpriteTag) t).getCharacterId(), null, 1, ses, evl);
|
||||
if (t instanceof DefineSpriteTag) {
|
||||
List<Integer> frames = new ArrayList<>();
|
||||
int spriteId = ((DefineSpriteTag) t).getCharacterId();
|
||||
for (int i = 0; i < ((DefineSpriteTag) t).getFrameCount(); i++) {
|
||||
if (selection.contains(spriteId, i + 1)) {
|
||||
frames.add(i);
|
||||
}
|
||||
}
|
||||
frameExporter.exportSpriteFrames(handler, outDir + (multipleExportTypes ? File.separator + SpriteExportSettings.EXPORT_FOLDER_NAME : ""), swf, spriteId, frames, subFrameLength, ses, evl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,15 +378,30 @@ Pre-options:
|
||||
-select <ranges>
|
||||
Applies to: -export
|
||||
Select frames/pages for export.
|
||||
Comma separated ranges in format <min>-<max> (<max> is optional) or <num>.
|
||||
If it has prefix "<characterId>:" then all following ranges apply
|
||||
to the character with specific id.
|
||||
Use "all" as characterId to apply for every character.
|
||||
Use "0" (default) as characterId to apply for main timeline.
|
||||
Example <ranges> formats:
|
||||
1-5
|
||||
2,3
|
||||
2-5,7,9-
|
||||
DO NOT PUT space between comma (,) and next ramge.
|
||||
1-5 ... exports frames 1,2,3,4,5
|
||||
2,3 ... exports frames 2 and 3
|
||||
2-5,7,9- ... exports frames 2,3,4,5,7,9 and all after
|
||||
57:5-10,12,62:5 ... exports frames 5,6,7,8,9,10,12
|
||||
of character 57 and frame 5 of character 62
|
||||
all:12-29 ... exports frames 12 to 29 of all characters
|
||||
12:3,4,0:1-12 ... exports frames 3 and 4 of character 12
|
||||
and first 12 frames of main timeline
|
||||
DO NOT PUT space between comma (,) and next range.
|
||||
|
||||
-selectid <ranges>
|
||||
-selectid <charRanges>
|
||||
Applies to: -export
|
||||
Select characters for export by character id.
|
||||
<ranges> format is same as in -select
|
||||
Comma separated ranges in format <min>-<max> (<max> is optional) or <characterId>.
|
||||
Example <charRanges> formats:
|
||||
1-5 ... exports characters 1,2,3,4,5
|
||||
2,3 ... exports characters 2 and 3
|
||||
2-5,7,9- ... exports characters 2,3,4,5,7,9 and all ids after
|
||||
|
||||
-selectclass <classnames>
|
||||
Applies to: -export
|
||||
@@ -398,6 +413,11 @@ Pre-options:
|
||||
subpackages, class net.company.MyClass)
|
||||
DO NOT PUT space between comma (,) and next class.
|
||||
|
||||
-sublength <length>
|
||||
Applies to: -export
|
||||
Export subsprite animation of length <length>.
|
||||
<length> is measured in number of subframes. Must be >= 1.
|
||||
|
||||
-exportembed
|
||||
Applies to: -export
|
||||
Allow exporting embedded assets via [Embed tag].
|
||||
|
||||
Reference in New Issue
Block a user