Capture RCO image data (PNG) for the renderer

RCO IMG entries hold PNG images (magic 89 50 4E 47), decodable directly
by ImageIO/JavaFX. RcoFile now reads pImgData and stores raw image
bytes in ImageObject; the CLI reports the first image's magic.
This commit is contained in:
2026-09-15 22:56:13 -04:00
parent b18e8447dc
commit fd41390642
2 changed files with 29 additions and 5 deletions
@@ -409,6 +409,14 @@ public final class Main {
System.out.printf("%s: valid=%b compression=%d objects=%d images=%d%n",
rcoPath, rco.isValid(), rco.compression(), rco.objects().size(), rco.images().size());
for (Map.Entry<Integer, dev.quoije.umd.rco.object.ImageObject> img : rco.images().entrySet()) {
byte[] imgData = img.getValue().getData();
System.out.printf(" image 0x%X: %d bytes, magic=%s%n",
img.getKey(), imgData == null ? 0 : imgData.length,
imgData == null ? "null" : hexPrefix(imgData, 8));
break;
}
System.out.printf("events (%d):%n", rco.events().size());
for (Map.Entry<Integer, String> event : rco.events().entrySet()) {
System.out.printf(" [%3d] %s%n", event.getKey(), event.getValue());
@@ -80,6 +80,8 @@ public final class RcoFile {
private int lTextData;
private int pLabelData;
private int lLabelData;
private int pImgData;
private int lImgData;
private int pMainTable;
private int pEventData;
private int lEventData;
@@ -186,8 +188,12 @@ public final class RcoFile {
pEventData = read32();
lEventData = read32();
// Remaining pointer/data tables (18 ints) plus 3 trailing 0xFFFFFFFF.
skip(21 * 4);
// Remaining pointer/data tables: 12 pointer ints, then image data,
// sound data, model data, and 3 trailing 0xFFFFFFFF.
skip(4 * 12);
pImgData = read32();
lImgData = read32();
skip(4 * 7);
}
private void readEvents() {
@@ -245,12 +251,13 @@ public final class RcoFile {
if (entry.type == 1) {
skip(2); // format
int comp = read16();
skip(4); // sizePacked
skip(4); // offset
int sizePacked = read32();
int imgOffset = read32();
if (comp != COMPRESSION_NONE) {
skip(4); // sizeUnpacked
}
images.put(entryOffset, new ImageObject(null));
byte[] imgData = readImageData(imgOffset, sizePacked);
images.put(entryOffset, new ImageObject(imgData));
}
}
case TABLE_MODEL -> {
@@ -327,6 +334,15 @@ public final class RcoFile {
return entry;
}
private byte[] readImageData(int imgOffset, int length) {
if (imgOffset == RCO_NULL_PTR || length <= 0 || pImgData + imgOffset + length > buffer.length) {
return null;
}
byte[] data = new byte[length];
System.arraycopy(buffer, pImgData + imgOffset, data, 0, length);
return data;
}
private String readLabel(int labelOffset) {
int current = tell();
seek(pLabelData + labelOffset);