diff --git a/src/main/java/com/shade/decima/model/rtti/types/ds/DSDataSource.java b/src/main/java/com/shade/decima/model/rtti/types/ds/DSDataSource.java index 4cfd02d5..395aa123 100644 --- a/src/main/java/com/shade/decima/model/rtti/types/ds/DSDataSource.java +++ b/src/main/java/com/shade/decima/model/rtti/types/ds/DSDataSource.java @@ -12,6 +12,7 @@ import com.shade.util.NotNull; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; @@ -58,12 +59,30 @@ public int getSize() { @NotNull @Override public byte[] getData(@NotNull PackfileManager manager) throws IOException { + return getData(manager, getOffset(), getLength()); + } + + @NotNull + @Override + public byte[] getData(@NotNull PackfileManager manager, int offset, int length) throws IOException { final String path = "%s.core.stream".formatted(location); final Packfile packfile = manager.findFirst(path); + if (packfile == null) { throw new IOException("Can't find packfile that contains " + path); } - return packfile.extract(path); + + try (InputStream is = packfile.newInputStream(path)) { + if (offset > 0) { + is.skipNBytes(offset); + } + + if (length > 0) { + return is.readNBytes(length); + } else { + return is.readAllBytes(); + } + } } @NotNull diff --git a/src/main/java/com/shade/decima/model/rtti/types/hzd/HZDDataSource.java b/src/main/java/com/shade/decima/model/rtti/types/hzd/HZDDataSource.java index 952ebeea..8d3504d5 100644 --- a/src/main/java/com/shade/decima/model/rtti/types/hzd/HZDDataSource.java +++ b/src/main/java/com/shade/decima/model/rtti/types/hzd/HZDDataSource.java @@ -11,6 +11,7 @@ import com.shade.util.NotNull; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; @@ -49,16 +50,35 @@ public int getSize() { @NotNull @Override public byte[] getData(@NotNull PackfileManager manager) throws IOException { + return getData(manager, getOffset(), getLength()); + } + + @NotNull + @Override + public byte[] getData(@NotNull PackfileManager manager, int offset, int length) throws IOException { if (!location.startsWith("cache:")) { throw new IOException("Data source points to a resource outside cache: " + location); } + // TODO: Should prefix removal be handled by the manager itself? final String path = location.substring(6); final Packfile packfile = manager.findFirst(path); + if (packfile == null) { throw new IOException("Can't find packfile that contains " + path); } - return packfile.extract(path); + + try (InputStream is = packfile.newInputStream(path)) { + if (offset > 0) { + is.skipNBytes(offset); + } + + if (length > 0) { + return is.readNBytes(length); + } else { + return is.readAllBytes(); + } + } } @NotNull diff --git a/src/main/java/com/shade/decima/model/rtti/types/java/HwDataSource.java b/src/main/java/com/shade/decima/model/rtti/types/java/HwDataSource.java index d29bb76f..68a85b6d 100644 --- a/src/main/java/com/shade/decima/model/rtti/types/java/HwDataSource.java +++ b/src/main/java/com/shade/decima/model/rtti/types/java/HwDataSource.java @@ -9,6 +9,9 @@ public interface HwDataSource extends HwType { @NotNull byte[] getData(@NotNull PackfileManager manager) throws IOException; + @NotNull + byte[] getData(@NotNull PackfileManager manager, int offset, int length) throws IOException; + @NotNull String getLocation(); diff --git a/src/main/java/com/shade/decima/ui/data/viewer/texture/TextureViewer.java b/src/main/java/com/shade/decima/ui/data/viewer/texture/TextureViewer.java index 53109f1d..bf67e5cd 100644 --- a/src/main/java/com/shade/decima/ui/data/viewer/texture/TextureViewer.java +++ b/src/main/java/com/shade/decima/ui/data/viewer/texture/TextureViewer.java @@ -121,7 +121,7 @@ private ImageData getImageData(int mip, int slice) { throw new UncheckedIOException(e); } - mipBuffer = ByteBuffer.wrap(stream).slice(dataSource.getOffset(), dataSource.getLength()); + mipBuffer = ByteBuffer.wrap(stream); mipOffset = IntStream.range(0, mip + 1) .map(x -> getTextureSize(reader, dimension, x) * (x == mip ? slice : getSliceCount(x))) .sum();