From 195a4af67458f921e64622b1d343e1b5256fa40a Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Wed, 25 Jan 2017 15:40:15 +1100 Subject: [PATCH] Multipal --- .../diskbrowser/applefile/HiResImage.java | 14 +++++ .../diskbrowser/applefile/SHRPictureFile.java | 61 +++++++++++++++++-- .../diskbrowser/utilities/HexFormatter.java | 4 +- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/com/bytezone/diskbrowser/applefile/HiResImage.java b/src/com/bytezone/diskbrowser/applefile/HiResImage.java index 070c566..f4c6745 100644 --- a/src/com/bytezone/diskbrowser/applefile/HiResImage.java +++ b/src/com/bytezone/diskbrowser/applefile/HiResImage.java @@ -193,6 +193,20 @@ public abstract class HiResImage extends AbstractFile } } + /* + * Unpack the Apple PackBytes format. + * + * Format is: + * ... + * + * Flag values (first 6 bits of flag byte): + * 00xxxxxx: (0-63) 1 to 64 bytes follow, all different + * 01xxxxxx: (0-63) 1 to 64 repeats of next byte + * 10xxxxxx: (0-63) 1 to 64 repeats of next 4 bytes + * 11xxxxxx: (0-63) 1 to 64 repeats of next byte taken as 4 bytes + * (as in 10xxxxxx case) + */ + // Super Hi-res IIGS protected byte[] unpackBytes (byte[] buffer) { diff --git a/src/com/bytezone/diskbrowser/applefile/SHRPictureFile.java b/src/com/bytezone/diskbrowser/applefile/SHRPictureFile.java index bb9e0bb..fd6c4e0 100644 --- a/src/com/bytezone/diskbrowser/applefile/SHRPictureFile.java +++ b/src/com/bytezone/diskbrowser/applefile/SHRPictureFile.java @@ -12,6 +12,7 @@ public class SHRPictureFile extends HiResImage { List blocks = new ArrayList (); Main mainBlock; + Multipal multipalBlock; public SHRPictureFile (String name, byte[] buffer, int fileType, int auxType) { @@ -31,6 +32,11 @@ public class SHRPictureFile extends HiResImage mainBlock = new Main (kind, data); blocks.add (mainBlock); } + else if ("MULTIPAL".equals (kind)) + { + multipalBlock = new Multipal (kind, data); + blocks.add (multipalBlock); + } else blocks.add (new Block (kind, data)); @@ -58,7 +64,9 @@ public class SHRPictureFile extends HiResImage DirEntry dirEntry = mainBlock.scanLineDirectory[row]; int hi = dirEntry.mode & 0xFF00; int lo = dirEntry.mode & 0x00FF; - ColorTable colorTable = mainBlock.colorTables[lo & 0x0F]; + + ColorTable colorTable = multipalBlock != null ? multipalBlock.colorTables[row] + : mainBlock.colorTables[lo & 0x0F]; boolean fillMode = (lo & 0x20) != 0; if (fillMode) @@ -68,8 +76,10 @@ public class SHRPictureFile extends HiResImage { int left = (unpackedBuffer[ptr] & 0xF0) >> 4; int right = unpackedBuffer[ptr] & 0x0F; + dataBuffer.setElem (element++, colorTable.entries[left].color.getRGB ()); dataBuffer.setElem (element++, colorTable.entries[right].color.getRGB ()); + ptr++; } } @@ -118,6 +128,31 @@ public class SHRPictureFile extends HiResImage } } + class Multipal extends Block + { + int numPalettes; + ColorTable[] colorTables; + + public Multipal (String kind, byte[] data) + { + super (kind, data); + + int ptr = 5 + kind.length (); + numPalettes = HexFormatter.unsignedShort (data, ptr); + + ptr += 2; + colorTables = new ColorTable[numPalettes]; + for (int i = 0; i < numPalettes; i++) + { + if (ptr < data.length - 32) + colorTables[i] = new ColorTable (i, data, ptr); + else + colorTables[i] = new ColorTable (); // default empty table + ptr += 32; + } + } + } + class Main extends Block { int masterMode; @@ -303,6 +338,16 @@ public class SHRPictureFile extends HiResImage int id; ColorEntry[] entries = new ColorEntry[16]; + public ColorTable () + { + // default empty table + id = -1; + for (int i = 0; i < 16; i++) + { + entries[i] = new ColorEntry (); + } + } + public ColorTable (int id, byte[] data, int offset) { this.id = id; @@ -346,12 +391,20 @@ public class SHRPictureFile extends HiResImage int value; // 0RGB Color color; + public ColorEntry () + { + // default empty entry + value = 0; + color = new Color (0, 0, 0); + } + public ColorEntry (byte[] data, int offset) { value = HexFormatter.unsignedShort (data, offset); - int red = (value & 0x0F00) >>> 8 | (value & 0x0F00) >>> 4; - int green = (value & 0x00F0) | (value & 0x00F0) >>> 4; - int blue = (value & 0x000F) | (value & 0x000F) << 4; + + int red = ((value >> 8) & 0x0f) * 17; + int green = ((value >> 4) & 0x0f) * 17; + int blue = (value & 0x0f) * 17; color = new Color (red, green, blue); } diff --git a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java index f8737ee..be5d19d 100755 --- a/src/com/bytezone/diskbrowser/utilities/HexFormatter.java +++ b/src/com/bytezone/diskbrowser/utilities/HexFormatter.java @@ -71,7 +71,9 @@ public class HexFormatter StringBuffer trans = new StringBuffer (); StringBuffer hexLine = new StringBuffer (); - for (int j = i; (j < i + 16) && (j < offset + length); j++) + int max = Math.min (i + 16, offset + length); + max = Math.min (max, buffer.length); + for (int j = i; j < max; j++) { int c = buffer[j] & 0xFF; freq[c]++;