mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-11-25 01:32:26 +00:00
Added Squeeze format (BQY)
This commit is contained in:
parent
898587b23b
commit
921c946ab5
@ -148,7 +148,7 @@ public class DiskFactory
|
||||
|
||||
if ("sdk".equals (suffix) // NuFX disk
|
||||
|| "shk".equals (suffix) // NuFX files or disk
|
||||
|| "bxy".equals (suffix)) // NuFX in Binary2
|
||||
|| "bxy".equals (suffix)) // NuFX in Bin2
|
||||
{
|
||||
if (debug)
|
||||
System.out.println (" ** sdk/shk/bxy **");
|
||||
@ -156,7 +156,11 @@ public class DiskFactory
|
||||
{
|
||||
nuFX = new NuFX (file.toPath ());
|
||||
if (nuFX.getTotalDisks () == 0 && nuFX.getTotalFiles () == 0)
|
||||
{
|
||||
if (debug)
|
||||
System.out.println ("Empty NuFX file");
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] diskBuffer = nuFX.getDiskBuffer ();
|
||||
if (diskBuffer == null)
|
||||
@ -183,10 +187,10 @@ public class DiskFactory
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else if ("bny".equals (suffix)) // Binary2 uncompressed files
|
||||
else if ("bny".equals (suffix) || "bqy".equals (suffix)) // Binary2 uncompressed files
|
||||
{
|
||||
if (debug)
|
||||
System.out.println (" ** bny **");
|
||||
System.out.println (" ** bny/bqy **");
|
||||
try
|
||||
{
|
||||
binary2 = new Binary2 (file.toPath ());
|
||||
|
@ -36,6 +36,7 @@ public class FontAction extends DefaultAction implements QuitListener
|
||||
{
|
||||
super ("Set Font...", "Set display to a different font or font size",
|
||||
"/com/bytezone/loadlister/");
|
||||
|
||||
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_F, mask));
|
||||
}
|
||||
@ -146,8 +147,7 @@ public class FontAction extends DefaultAction implements QuitListener
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
FontChangeEvent fontChangeEvent = new FontChangeEvent (font);
|
||||
FontChangeListener[] listeners =
|
||||
(listenerList.getListeners (FontChangeListener.class));
|
||||
FontChangeListener[] listeners = (listenerList.getListeners (FontChangeListener.class));
|
||||
for (FontChangeListener listener : listeners)
|
||||
listener.changeFont (fontChangeEvent);
|
||||
}
|
||||
|
@ -1,11 +1,15 @@
|
||||
package com.bytezone.diskbrowser.gui;
|
||||
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.File;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import com.bytezone.diskbrowser.applefile.AppleFileSource;
|
||||
|
||||
@ -23,6 +27,8 @@ class SaveFileAction extends AbstractSaveAction implements FileSelectionListener
|
||||
super ("Save file...", "Save currently selected file", "Save File");
|
||||
|
||||
fileChooser.setAccessory (formatted);
|
||||
int mask = Toolkit.getDefaultToolkit ().getMenuShortcutKeyMaskEx ();
|
||||
putValue (Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke (KeyEvent.VK_S, mask));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -36,6 +42,11 @@ class SaveFileAction extends AbstractSaveAction implements FileSelectionListener
|
||||
return;
|
||||
}
|
||||
|
||||
if (formatted.isSelected ())
|
||||
setSelectedFile (new File (appleFileSource.getUniqueName () + ".txt"));
|
||||
else
|
||||
setSelectedFile (new File (appleFileSource.getUniqueName () + ".bin"));
|
||||
|
||||
if (fileChooser.showSaveDialog (null) != JFileChooser.APPROVE_OPTION)
|
||||
return;
|
||||
|
||||
@ -51,7 +62,6 @@ class SaveFileAction extends AbstractSaveAction implements FileSelectionListener
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
this.appleFileSource = event.appleFileSource;
|
||||
setSelectedFile (new File (appleFileSource.getUniqueName () + ".bin"));
|
||||
|
||||
setEnabled (appleFileSource != null && appleFileSource.getDataSource () != null
|
||||
&& appleFileSource.getDataSource ().getBuffer () != null);
|
||||
|
@ -10,14 +10,14 @@ import com.bytezone.diskbrowser.prodos.write.DiskFullException;
|
||||
import com.bytezone.diskbrowser.prodos.write.FileAlreadyExistsException;
|
||||
import com.bytezone.diskbrowser.prodos.write.ProdosDisk;
|
||||
import com.bytezone.diskbrowser.prodos.write.VolumeCatalogFullException;
|
||||
import com.bytezone.diskbrowser.utilities.Utility;
|
||||
|
||||
// -----------------------------------------------------------------------------------//
|
||||
public class Binary2
|
||||
// -----------------------------------------------------------------------------------//
|
||||
{
|
||||
private static final String UNDERLINE =
|
||||
"------------------------------------------------------"
|
||||
+ "-----------------------";
|
||||
"------------------------------------------------------" + "-----------------------";
|
||||
|
||||
Binary2Header binary2Header;
|
||||
byte[] buffer;
|
||||
@ -43,7 +43,6 @@ public class Binary2
|
||||
do
|
||||
{
|
||||
binary2Header = new Binary2Header (buffer, ptr);
|
||||
System.out.println (binary2Header);
|
||||
headers.add (binary2Header);
|
||||
|
||||
totalBlocks += binary2Header.totalBlocks;
|
||||
@ -53,19 +52,33 @@ public class Binary2
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
public byte[] getDiskBuffer () throws DiskFullException, VolumeCatalogFullException,
|
||||
FileAlreadyExistsException, IOException
|
||||
public byte[] getDiskBuffer ()
|
||||
throws DiskFullException, VolumeCatalogFullException, FileAlreadyExistsException, IOException
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
ProdosDisk disk = new ProdosDisk (800, "DiskBrowser");
|
||||
|
||||
for (Binary2Header header : headers)
|
||||
{
|
||||
byte[] dataBuffer = new byte[header.eof]; // this sux
|
||||
System.arraycopy (buffer, header.ptr + 128, dataBuffer, 0, dataBuffer.length);
|
||||
if (header.compressed && buffer[header.ptr + 128] == 0x76
|
||||
&& buffer[header.ptr + 129] == (byte) 0xFF)
|
||||
{
|
||||
byte[] tmp = new byte[header.eof]; // this sux
|
||||
System.arraycopy (buffer, header.ptr + 128, tmp, 0, tmp.length);
|
||||
String name = Utility.getCString (tmp, 4);
|
||||
|
||||
disk.addFile (header.fileName, header.fileType, header.auxType, header.created,
|
||||
header.modified, dataBuffer, header.eof);
|
||||
Squeeze squeeze = new Squeeze ();
|
||||
byte[] dataBuffer = squeeze.unSqueeze (tmp);
|
||||
disk.addFile (name, header.fileType, header.auxType, header.created, header.modified,
|
||||
dataBuffer, header.eof);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] dataBuffer = new byte[header.eof]; // this sux
|
||||
System.arraycopy (buffer, header.ptr + 128, dataBuffer, 0, dataBuffer.length);
|
||||
disk.addFile (header.fileName, header.fileType, header.auxType, header.created,
|
||||
header.modified, dataBuffer, header.eof);
|
||||
}
|
||||
|
||||
}
|
||||
disk.close ();
|
||||
@ -80,12 +93,12 @@ public class Binary2
|
||||
{
|
||||
StringBuilder text = new StringBuilder ();
|
||||
|
||||
text.append (String.format (
|
||||
" %-15.15s Files:%5d%n%n",
|
||||
fileName, headers.size ()));
|
||||
text.append (
|
||||
String.format (" %-15.15s Files:%5d%n%n",
|
||||
fileName, headers.size ()));
|
||||
|
||||
text.append (" Name Type Auxtyp Modified"
|
||||
+ " Fmat Length\n");
|
||||
text.append (
|
||||
" Name Type Auxtyp Modified" + " Fmat Length\n");
|
||||
|
||||
text.append (String.format ("%s%n", UNDERLINE));
|
||||
|
||||
|
@ -14,10 +14,9 @@ public class Binary2Header
|
||||
// -----------------------------------------------------------------------------------//
|
||||
{
|
||||
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern ("dd-LLL-yy HH:mm");
|
||||
static String[] osTypes =
|
||||
{ "Prodos", "DOS 3.3", "Reserved", "DOS 3.2 or 3.1", "Pascal", "Macintosh MFS",
|
||||
"Macintosh HFS", "Lisa", "CPM", "Reserved", "MS-DOS", "High Sierra (CD-ROM)",
|
||||
"ISO 9660 (CD-ROM)", "AppleShare" };
|
||||
static String[] osTypes = { "Prodos", "DOS 3.3", "Reserved", "DOS 3.2 or 3.1", "Pascal",
|
||||
"Macintosh MFS", "Macintosh HFS", "Lisa", "CPM", "Reserved", "MS-DOS", "High Sierra (CD-ROM)",
|
||||
"ISO 9660 (CD-ROM)", "AppleShare" };
|
||||
|
||||
int ptr;
|
||||
byte[] buffer;
|
||||
@ -89,8 +88,8 @@ public class Binary2Header
|
||||
public String getLine ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
return String.format (" %-33s %3s $%04X %s unc %7d", fileName,
|
||||
fileTypes[fileType], auxType, modified.format (formatter), eof);
|
||||
return String.format (" %-33s %3s $%04X %s unc %7d", fileName, fileTypes[fileType],
|
||||
auxType, modified.format (formatter), eof);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
@ -117,12 +116,13 @@ public class Binary2Header
|
||||
text.append (String.format ("Prodos storage type ... %02X%n", prodos16storageType));
|
||||
text.append (String.format ("Prodos total blocks ... %02X%n", prodos16totalBlocks));
|
||||
text.append (String.format ("Prodos eof ............ %06X %<,d%n", prodos16eof));
|
||||
text.append (
|
||||
String.format ("Disk space needed ..... %08X %<,d%n", diskSpaceRequired));
|
||||
text.append (
|
||||
String.format ("OS type ............... %02X %s%n", osType, osTypes[osType]));
|
||||
text.append (String.format ("Disk space needed ..... %08X %<,d%n", diskSpaceRequired));
|
||||
text.append (String.format ("OS type ............... %02X %s%n", osType, osTypes[osType]));
|
||||
text.append (String.format ("Native file type ...... %02X%n", nativeFileType));
|
||||
text.append (String.format ("Data flags ............ %02X%n", dataFlags));
|
||||
text.append (String.format (" compressed .......... %s%n", compressed));
|
||||
text.append (String.format (" encrypted ........... %s%n", encrypted));
|
||||
text.append (String.format (" sparse .............. %s%n", sparsePacked));
|
||||
text.append (String.format ("Version ............... %02X%n", version));
|
||||
text.append (String.format ("Following files ....... %02X%n", filesToFollow));
|
||||
|
||||
|
125
src/com/bytezone/diskbrowser/nufx/Squeeze.java
Normal file
125
src/com/bytezone/diskbrowser/nufx/Squeeze.java
Normal file
@ -0,0 +1,125 @@
|
||||
package com.bytezone.diskbrowser.nufx;
|
||||
|
||||
import com.bytezone.diskbrowser.utilities.FileFormatException;
|
||||
import com.bytezone.diskbrowser.utilities.Utility;
|
||||
|
||||
// see http://fileformats.archiveteam.org/wiki/Squeeze
|
||||
// see http://fileformats.archiveteam.org/wiki/RLE90
|
||||
// -----------------------------------------------------------------------------------//
|
||||
public class Squeeze
|
||||
// -----------------------------------------------------------------------------------//
|
||||
{
|
||||
private static final byte[] Squeeze = { 0x76, (byte) 0xFF };
|
||||
private static int RLE_DELIMITER = 0x90;
|
||||
private static int EOF_TOKEN = 0x100;
|
||||
|
||||
private int bits;
|
||||
private int bitPos = 7; // trigger the first read
|
||||
private int ptr;
|
||||
private byte[] buffer;
|
||||
private Node[] nodes;
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
public byte[] unSqueeze (byte[] buffer)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
if (!Utility.isMagic (buffer, 0, Squeeze))
|
||||
throw new FileFormatException ("Not Squeeze format");
|
||||
|
||||
byte[] uncompressed = new byte[buffer.length * 3];
|
||||
int uncPtr = 0;
|
||||
|
||||
int fileChecksum = Utility.getShort (buffer, 2);
|
||||
String fileName = Utility.getCString (buffer, 4);
|
||||
|
||||
ptr = fileName.length () + 5;
|
||||
int nodeCount = Utility.getShort (buffer, ptr);
|
||||
ptr += 2;
|
||||
|
||||
nodes = new Node[nodeCount];
|
||||
this.buffer = buffer;
|
||||
|
||||
for (int i = 0; i < nodes.length; i++)
|
||||
{
|
||||
int left = Utility.getSignedShort (buffer, ptr);
|
||||
int right = Utility.getSignedShort (buffer, ptr + 2);
|
||||
nodes[i] = new Node (left, right);
|
||||
ptr += 4;
|
||||
}
|
||||
|
||||
boolean repeating = false;
|
||||
int lastVal = 0;
|
||||
int sum = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
int val = decodeSymbol ();
|
||||
if (val == EOF_TOKEN)
|
||||
break;
|
||||
|
||||
if (repeating)
|
||||
{
|
||||
repeating = false;
|
||||
|
||||
if (val == 0) // flag indicating a single RLE_DELIMITER
|
||||
{
|
||||
lastVal = RLE_DELIMITER;
|
||||
val = 2;
|
||||
}
|
||||
|
||||
while (--val != 0)
|
||||
{
|
||||
sum += lastVal;
|
||||
uncompressed[uncPtr++] = (byte) lastVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val == RLE_DELIMITER)
|
||||
repeating = true;
|
||||
else
|
||||
{
|
||||
lastVal = val;
|
||||
sum += lastVal;
|
||||
uncompressed[uncPtr++] = (byte) lastVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((sum & 0xFFFF) != fileChecksum)
|
||||
System.out.printf ("Checksum mismatch : %04X %04X%n", fileChecksum, sum & 0xFFFF);
|
||||
|
||||
byte[] uncompressedBuffer = new byte[uncPtr];
|
||||
System.arraycopy (uncompressed, 0, uncompressedBuffer, 0, uncompressedBuffer.length);
|
||||
|
||||
return uncompressedBuffer;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private int decodeSymbol ()
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (++bitPos > 7)
|
||||
{
|
||||
bits = buffer[ptr++];
|
||||
bitPos = 0;
|
||||
}
|
||||
|
||||
val = (bits & 1) == 0 ? nodes[val].left : nodes[val].right;
|
||||
bits >>>= 1;
|
||||
|
||||
if (val < 0)
|
||||
return -++val; // increment and make positive
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
record Node (int left, int right)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
};
|
||||
}
|
@ -17,6 +17,7 @@ public abstract class DefaultAction extends AbstractAction
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
super (text);
|
||||
|
||||
this.baseURL = null;
|
||||
putValue (Action.SHORT_DESCRIPTION, tip);
|
||||
}
|
||||
@ -26,6 +27,7 @@ public abstract class DefaultAction extends AbstractAction
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
super (text);
|
||||
|
||||
this.baseURL = baseURL;
|
||||
putValue (Action.SHORT_DESCRIPTION, tip);
|
||||
}
|
||||
@ -39,6 +41,7 @@ public abstract class DefaultAction extends AbstractAction
|
||||
System.out.println ("Base URL not set");
|
||||
return;
|
||||
}
|
||||
|
||||
URL url = this.getClass ().getResource (baseURL + iconName);
|
||||
if (url != null)
|
||||
putValue (iconType, new ImageIcon (url));
|
||||
|
@ -41,7 +41,7 @@ public final class Utility
|
||||
private static MathContext mathContext8 = new MathContext (15);
|
||||
|
||||
private static final List<String> suffixes = Arrays.asList ("po", "dsk", "do", "hdv", "2mg",
|
||||
"d13", "sdk", "shk", "bxy", "bny", "woz", "img", "dimg");
|
||||
"d13", "sdk", "shk", "bxy", "bny", "bqy", "woz", "img", "dimg");
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
private Utility ()
|
||||
@ -454,6 +454,19 @@ public final class Utility
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
public static String getCString (byte[] buffer, int offset)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
{
|
||||
int length = 0;
|
||||
int ptr = offset;
|
||||
|
||||
while (buffer[ptr++] != 0)
|
||||
++length;
|
||||
|
||||
return new String (buffer, offset, length);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
public static int getWizLong (byte[] buffer, int offset)
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
Loading…
Reference in New Issue
Block a user