Add --labPBR flag to EBP encoder/decoder

This commit is contained in:
lax1dude 2024-06-17 20:40:01 -07:00
parent 4fc0a8d63f
commit 221229dc80
3 changed files with 104 additions and 16 deletions

View File

@ -10,6 +10,8 @@ import java.io.OutputStream;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import net.lax1dude.eaglercraft.bintools.utils.LabPBR2Eagler;
/** /**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved. * Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
* *
@ -38,30 +40,45 @@ public class EBPFileDecoder {
} }
public static void _main(String[] args) throws IOException { public static void _main(String[] args) throws IOException {
if(args.length > 1 && args.length < 4 && args[0].equals("-r")) { boolean labPBR = false;
if(args.length > 1 && args[0].equalsIgnoreCase("--labPBR")) {
labPBR = true;
String[] e = new String[args.length - 1];
System.arraycopy(args, 1, e, 0, e.length);
args = e;
}
if(args.length > 1 && args.length < 4 && args[0].equalsIgnoreCase("-r")) {
File input = new File(args[1]); File input = new File(args[1]);
if(!input.isDirectory()) { if(!input.isDirectory()) {
System.err.println("Error: Not a directory: " + input.getAbsolutePath()); System.err.println("Error: Not a directory: " + input.getAbsolutePath());
System.exit(-1); System.exit(-1);
return; return;
} }
convertDir(input, args.length == 3 ? new File(args[2]) : input); convertDir(input, args.length == 3 ? new File(args[2]) : input, labPBR);
}else if(args.length == 2) { }else if(args.length == 2) {
System.out.println("Reading input file..."); System.out.println("Reading input file...");
BufferedImage img; BufferedImage img;
try(InputStream is = new FileInputStream(new File(args[0]))) { try(InputStream is = new FileInputStream(new File(args[0]))) {
img = read(is); img = readEBP(is);
}
if(labPBR) {
System.out.println("Converting from Eagler to LabPBR...");
LabPBR2Eagler.convertEaglerToLabPBR(img, img);
} }
File output = new File(args[1]); File output = new File(args[1]);
System.out.println("Writing PNG: " + output.getAbsolutePath()); System.out.println("Writing PNG: " + output.getAbsolutePath());
ImageIO.write(img, "PNG", output); ImageIO.write(img, "PNG", output);
}else { }else {
System.out.println("Usage: ebp-decode <input file> <output file>"); System.out.println("Usage: ebp-decode [--labPBR] <input file> <output file>");
System.out.println(" ebp-decode -r <directory> [output directory]"); System.out.println(" ebp-decode [--labPBR] -r <directory> [output directory]");
} }
} }
public static void convertDir(File inputDir, File outputDir) throws IOException { public static void convertDir(File inputDir, File outputDir) throws IOException {
convertDir(inputDir, outputDir, false);
}
public static void convertDir(File inputDir, File outputDir, boolean labPBR) throws IOException {
if(!outputDir.isDirectory() && !outputDir.mkdirs()) { if(!outputDir.isDirectory() && !outputDir.mkdirs()) {
throw new IOException("Could not create directory: " + outputDir.getAbsolutePath()); throw new IOException("Could not create directory: " + outputDir.getAbsolutePath());
} }
@ -69,7 +86,7 @@ public class EBPFileDecoder {
for(int i = 0; i < f.length; ++i) { for(int i = 0; i < f.length; ++i) {
String name = f[i].getName(); String name = f[i].getName();
if(f[i].isDirectory()) { if(f[i].isDirectory()) {
convertDir(f[i], new File(outputDir, name)); convertDir(f[i], new File(outputDir, name), labPBR);
continue; continue;
} }
if(!name.toLowerCase().endsWith(".ebp")) { if(!name.toLowerCase().endsWith(".ebp")) {
@ -79,13 +96,16 @@ public class EBPFileDecoder {
System.out.println(f[i].getAbsolutePath()); System.out.println(f[i].getAbsolutePath());
BufferedImage img; BufferedImage img;
try(InputStream is = new FileInputStream(f[i])) { try(InputStream is = new FileInputStream(f[i])) {
img = read(is); img = readEBP(is);
}
if(labPBR) {
LabPBR2Eagler.convertEaglerToLabPBR(img, img);
} }
ImageIO.write(img, "PNG", ff); ImageIO.write(img, "PNG", ff);
} }
} }
public static BufferedImage read(InputStream is) throws IOException { public static BufferedImage readEBP(InputStream is) throws IOException {
if(is.read() != '%' || is.read() != 'E' || is.read() != 'B' || is.read() != 'P') { if(is.read() != '%' || is.read() != 'E' || is.read() != 'B' || is.read() != 'P') {
throw new IOException("Not an EBP file!"); throw new IOException("Not an EBP file!");
} }

View File

@ -13,6 +13,8 @@ import java.util.Set;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import net.lax1dude.eaglercraft.bintools.utils.LabPBR2Eagler;
/** /**
* Copyright (c) 2023-2024 lax1dude. All Rights Reserved. * Copyright (c) 2023-2024 lax1dude. All Rights Reserved.
* *
@ -40,29 +42,44 @@ public class EBPFileEncoder {
} }
public static void _main(String[] args) throws IOException { public static void _main(String[] args) throws IOException {
if(args.length > 1 && args.length < 4 && args[0].equals("-r")) { boolean labPBR = false;
if(args.length > 1 && args[0].equalsIgnoreCase("--labPBR")) {
labPBR = true;
String[] e = new String[args.length - 1];
System.arraycopy(args, 1, e, 0, e.length);
args = e;
}
if(args.length > 1 && args.length < 4 && args[0].equalsIgnoreCase("-r")) {
File input = new File(args[1]); File input = new File(args[1]);
if(!input.isDirectory()) { if(!input.isDirectory()) {
System.err.println("Error: Not a directory: " + input.getAbsolutePath()); System.err.println("Error: Not a directory: " + input.getAbsolutePath());
System.exit(-1); System.exit(-1);
return; return;
} }
convertDir(input, args.length == 3 ? new File(args[2]) : input); convertDir(input, args.length == 3 ? new File(args[2]) : input, labPBR);
}else if(args.length == 2) { }else if(args.length == 2) {
System.out.println("Reading input file..."); System.out.println("Reading input file...");
BufferedImage img = ImageIO.read(new File(args[0])); BufferedImage img = ImageIO.read(new File(args[0]));
File output = new File(args[1]); File output = new File(args[1]);
if(labPBR) {
System.out.println("Converting from LabPBR to Eagler...");
LabPBR2Eagler.convertLabPBRToEagler(img, img);
}
System.out.println("Encoding EBP: " + output.getAbsolutePath()); System.out.println("Encoding EBP: " + output.getAbsolutePath());
try(OutputStream os = new FileOutputStream(output)) { try(OutputStream os = new FileOutputStream(output)) {
write(img, os); writeEBP(img, os);
} }
}else { }else {
System.out.println("Usage: ebp-encode <input file> <output file>"); System.out.println("Usage: ebp-encode [--labPBR] <input file> <output file>");
System.out.println(" ebp-encode -r <directory> [output directory]"); System.out.println(" ebp-encode [--labPBR] -r <directory> [output directory]");
} }
} }
public static void convertDir(File inputDir, File outputDir) throws IOException { public static void convertDir(File inputDir, File outputDir) throws IOException {
convertDir(inputDir, outputDir, false);
}
public static void convertDir(File inputDir, File outputDir, boolean labPBR) throws IOException {
if(!outputDir.isDirectory() && !outputDir.mkdirs()) { if(!outputDir.isDirectory() && !outputDir.mkdirs()) {
throw new IOException("Could not create directory: " + outputDir.getAbsolutePath()); throw new IOException("Could not create directory: " + outputDir.getAbsolutePath());
} }
@ -70,7 +87,7 @@ public class EBPFileEncoder {
for(int i = 0; i < f.length; ++i) { for(int i = 0; i < f.length; ++i) {
String name = f[i].getName(); String name = f[i].getName();
if(f[i].isDirectory()) { if(f[i].isDirectory()) {
convertDir(f[i], new File(outputDir, name)); convertDir(f[i], new File(outputDir, name), labPBR);
continue; continue;
} }
if(!name.toLowerCase().endsWith(".png")) { if(!name.toLowerCase().endsWith(".png")) {
@ -78,13 +95,17 @@ public class EBPFileEncoder {
} }
File ff = new File(outputDir, name.substring(0, name.length() - 3) + "ebp"); File ff = new File(outputDir, name.substring(0, name.length() - 3) + "ebp");
System.out.println(f[i].getAbsolutePath()); System.out.println(f[i].getAbsolutePath());
BufferedImage img = ImageIO.read(f[i]);
if(labPBR) {
LabPBR2Eagler.convertLabPBRToEagler(img, img);
}
try(OutputStream os = new FileOutputStream(ff)) { try(OutputStream os = new FileOutputStream(ff)) {
write(ImageIO.read(f[i]), os); writeEBP(img, os);
} }
} }
} }
public static void write(BufferedImage img, OutputStream fos) throws IOException { public static void writeEBP(BufferedImage img, OutputStream fos) throws IOException {
fos.write(new byte[] { '%', 'E', 'B', 'P'}); fos.write(new byte[] { '%', 'E', 'B', 'P'});
fos.write(1); // v1 fos.write(1); // v1
fos.write(3); // 3 component fos.write(3); // 3 component

View File

@ -0,0 +1,47 @@
package net.lax1dude.eaglercraft.bintools.utils;
import java.awt.image.BufferedImage;
/**
* Copyright (c) 2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class LabPBR2Eagler {
/**
* See net.lax1dude.eaglercraft.v1_8.opengl.ext.deferred.texture.PBRTextureMapUtils
*/
public static void convertLabPBRToEagler(BufferedImage input, BufferedImage output) {
for(int w = input.getWidth(), x = 0; x < w; ++x) {
for(int h = input.getHeight(), y = 0; y < h; ++y) {
int pixel = input.getRGB(x, y);
int a = (pixel >>> 24) & 0xFF;
if(a == 0xFF) a = 0;
output.setRGB(x, y, (pixel & 0x00FFFF00) | Math.min(a << 2, 0xFF) | 0xFF000000);
}
}
}
public static void convertEaglerToLabPBR(BufferedImage input, BufferedImage output) {
for(int w = input.getWidth(), x = 0; x < w; ++x) {
for(int h = input.getHeight(), y = 0; y < h; ++y) {
int pixel = input.getRGB(x, y);
int a = (pixel >>> 2) & 0x3F;
if(a == 0) a = 0xFF;
output.setRGB(x, y, (pixel & 0x00FFFF00) | (a << 24));
}
}
}
}