lzw2 crc bug fixed

This commit is contained in:
Denis Molony 2021-04-17 14:41:36 +10:00
parent 2cb40b84e4
commit 1c9cbc4942
10 changed files with 30 additions and 20 deletions

View File

@ -59,23 +59,23 @@ public interface ProdosConstants
"FOT", "BA3", "DA3", "WPF", "SOS", "$0D", "$0E", "DIR", // "FOT", "BA3", "DA3", "WPF", "SOS", "$0D", "$0E", "DIR", //
"RPD", "RPI", "AFD", "AFM", "AFR", "SCL", "PFS", "$17", // "RPD", "RPI", "AFD", "AFM", "AFR", "SCL", "PFS", "$17", //
"$18", "ADB", "AWP", "ASP", "$1C", "$1D", "$1E", "$1F", // "$18", "ADB", "AWP", "ASP", "$1C", "$1D", "$1E", "$1F", //
"TDM", "$21", "$22", "$23", "$24", "$25", "$26", "$27", // "TDM", "IPS", "UPV", "$23", "$24", "$25", "$26", "$27", //
"$28", "$29", "8SC", "8OB", "8IC", "8LD", "P8C", "$2F", // "$28", "3SD", "8SC", "8OB", "8IC", "8LD", "P8C", "$2F", //
"$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", // "$30", "$31", "$32", "$33", "$34", "$35", "$36", "$37", //
"$38", "$39", "$3A", "$3B", "$3C", "$3D", "$3E", "$3F", // "$38", "$39", "$3A", "$3B", "$3C", "$3D", "$3E", "$3F", //
"DIC", "OCR", "FTD", "$43", "$44", "$45", "$46", "$47", // "DIC", "OCR", "FTD", "$43", "$44", "$45", "$46", "$47", //
"$48", "$49", "$4A", "$4B", "$4C", "$4D", "$4E", "$4F", // "$48", "$49", "$4A", "$4B", "$4C", "$4D", "$4E", "$4F", //
"GWP", "GSS", "GDB", "DRW", "GDP", "HMD", "EDU", "STN", // "GWP", "GSS", "GDB", "DRW", "GDP", "HMD", "EDU", "STN", //
"HLP", "COM", "CFG", "ANM", "MUM", "ENT", "DVU", "FIN", // "HLP", "COM", "CFG", "ANM", "MUM", "ENT", "DVU", "FIN", //
"$60", "$61", "$62", "$63", "$64", "$65", "NCF", "$67", // "PRE", "$61", "$62", "$63", "$64", "$65", "NCF", "$67", //
"$68", "$69", "$6A", "BIO", "$6C", "TDR", "PRE", "HDV", // "$68", "$69", "$6A", "BIO", "$6C", "TDR", "PRE", "HDV", //
"$70", "$71", "$72", "$73", "$74", "$75", "$76", "$77", // "SN2", "KMT", "DSR", "BAN", "CG7", "TNJ", "SA7", "KES", //
"$78", "$79", "$7A", "$7B", "$7C", "$7D", "$7E", "$7F", // "JAP", "CSL", "TME", "TLB", "MR7", "MLR", "MMM", "JCP", //
"GES", "GEA", "GEO", "GED", "GEF", "GEP", "GEI", "GEX", // "GES", "GEA", "GEO", "GED", "GEF", "GEP", "GEI", "GEX", //
"$88", "GEV", "$8A", "GEC", "GEK", "GEW", "$8E", "$8F", // "$88", "GEV", "$8A", "GEC", "GEK", "GEW", "$8E", "$8F", //
"$90", "$91", "$92", "$93", "$94", "$95", "$96", "$97", // "$90", "$91", "$92", "$93", "$94", "$95", "$96", "$97", //
"$98", "$99", "$9A", "$9B", "$9C", "$9D", "$9E", "$9F", // "$98", "$99", "$9A", "$9B", "$9C", "$9D", "$9E", "$9F", //
"WP ", "$A1", "$A2", "$A3", "$A4", "$A5", "$A6", "$A7", // "WPJ", "$A1", "$A2", "$A3", "$A4", "$A5", "$A6", "$A7", //
"$A8", "$A9", "$AA", "GSB", "TDF", "BDF", "$AE", "$AF", // "$A8", "$A9", "$AA", "GSB", "TDF", "BDF", "$AE", "$AF", //
"SRC", "OBJ", "LIB", "S16", "RTL", "EXE", "PIF", "TIF", // "SRC", "OBJ", "LIB", "S16", "RTL", "EXE", "PIF", "TIF", //
"NDA", "CDA", "TOL", "DVR", "LDF", "FST", "$BE", "DOC", // "NDA", "CDA", "TOL", "DVR", "LDF", "FST", "$BE", "DOC", //

View File

@ -46,6 +46,8 @@ class DateTime
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
int adjustedYear = year + (year > 70 ? 1900 : 2000); int adjustedYear = year + (year > 70 ? 1900 : 2000);
if (day < 1 || day > 31)
return null;
return LocalDateTime.of (adjustedYear, month + 1, day, hour, minute); return LocalDateTime.of (adjustedYear, month + 1, day, hour, minute);
} }

View File

@ -15,6 +15,7 @@ class LZW
protected byte runLengthChar; protected byte runLengthChar;
protected int crc; protected int crc;
protected int crcBase; protected int crcBase;
int v3eof;
private int buffer; // one character buffer private int buffer; // one character buffer
private int bitsLeft; // unused bits left in buffer private int bitsLeft; // unused bits left in buffer
@ -119,14 +120,17 @@ class LZW
public byte[] getData () public byte[] getData ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
byte[] buffer = new byte[chunks.size () * TRACK_LENGTH]; byte[] buffer = new byte[getSize ()];
int trackNumber = 0; int trackNumber = 0;
for (byte[] track : chunks) for (byte[] track : chunks)
System.arraycopy (track, 0, buffer, trackNumber++ * TRACK_LENGTH, TRACK_LENGTH); System.arraycopy (track, 0, buffer, trackNumber++ * TRACK_LENGTH, TRACK_LENGTH);
if (crc != Utility.getCRC (buffer, crcBase)) int length = v3eof != 0 ? v3eof : buffer.length;
System.out.println ("\n*** LZW CRC mismatch ***");
int calculatedCrc = Utility.getCRC (buffer, length, crcBase);
if (crc != calculatedCrc)
System.out.printf ("%n*** LZW CRC mismatch *** %04X %04X%n", crc, calculatedCrc);
return buffer; return buffer;
} }

View File

@ -75,6 +75,7 @@ class LZW1 extends LZW
prev = s; prev = s;
} }
return lzwBuffer; return lzwBuffer;
} }

View File

@ -11,7 +11,7 @@ class LZW2 extends LZW
private int codeWord; private int codeWord;
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public LZW2 (byte[] buffer, int crc) public LZW2 (byte[] buffer, int crc, int eof)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
bytes = Objects.requireNonNull (buffer); bytes = Objects.requireNonNull (buffer);
@ -19,6 +19,7 @@ class LZW2 extends LZW
this.crc = crc; this.crc = crc;
crcBase = 0xFFFF; crcBase = 0xFFFF;
codeWord = 0; codeWord = 0;
v3eof = eof;
volume = buffer[0] & 0xFF; volume = buffer[0] & 0xFF;
runLengthChar = (byte) (buffer[1] & 0xFF); runLengthChar = (byte) (buffer[1] & 0xFF);

View File

@ -51,7 +51,7 @@ class MasterHeader
byte[] crcBuffer = new byte[40]; byte[] crcBuffer = new byte[40];
System.arraycopy (buffer, ptr + 8, crcBuffer, 0, crcBuffer.length); System.arraycopy (buffer, ptr + 8, crcBuffer, 0, crcBuffer.length);
if (crc != Utility.getCRC (crcBuffer, 0)) if (crc != Utility.getCRC (crcBuffer, crcBuffer.length, 0))
{ {
System.out.println ("***** Master CRC mismatch *****"); System.out.println ("***** Master CRC mismatch *****");
throw new FileFormatException ("Master CRC failed"); throw new FileFormatException ("Master CRC failed");

View File

@ -72,7 +72,7 @@ class Record
byte[] crcBuffer = new byte[len + totThreads * 16]; byte[] crcBuffer = new byte[len + totThreads * 16];
System.arraycopy (buffer, dataPtr + 6, crcBuffer, 0, crcBuffer.length); System.arraycopy (buffer, dataPtr + 6, crcBuffer, 0, crcBuffer.length);
if (crc != Utility.getCRC (crcBuffer, 0)) if (crc != Utility.getCRC (crcBuffer, crcBuffer.length, 0))
{ {
System.out.println ("***** Header CRC mismatch *****"); System.out.println ("***** Header CRC mismatch *****");
throw new FileFormatException ("Header CRC failed"); throw new FileFormatException ("Header CRC failed");
@ -255,9 +255,9 @@ class Record
text.append (String.format ("Access ......... %s %s%n", bits, decode)); text.append (String.format ("Access ......... %s %s%n", bits, decode));
if (storType < 16) if (storType < 16)
{ {
text.append (String.format ("File type ...... %,d %s%n", fileType, text.append (String.format ("File type ...... %02X %s%n", fileType,
ProdosConstants.fileTypes[fileType])); ProdosConstants.fileTypes[fileType]));
text.append (String.format ("Aux type ....... %,d%n", auxType)); text.append (String.format ("Aux type ....... %,d $%<04X%n", auxType));
text.append ( text.append (
String.format ("Stor type ...... %,d %s%n", storType, storage[storType])); String.format ("Stor type ...... %,d %s%n", storType, storage[storType]));
} }

View File

@ -37,7 +37,7 @@ class Thread
lzw = switch (header.threadFormat) lzw = switch (header.threadFormat)
{ {
case 2 -> new LZW1 (data); case 2 -> new LZW1 (data);
case 3 -> new LZW2 (data, header.threadCrc); case 3 -> new LZW2 (data, header.threadCrc, header.uncompressedEOF);
default -> null; // 1 = Huffman Squeeze default -> null; // 1 = Huffman Squeeze
}; };

View File

@ -17,6 +17,7 @@ class ThreadHeader
final int threadClass; final int threadClass;
final int threadFormat; final int threadFormat;
final int threadKind; final int threadKind;
final int threadCrc; final int threadCrc;
final int uncompressedEOF; final int uncompressedEOF;
final int compressedEOF; final int compressedEOF;
@ -28,6 +29,7 @@ class ThreadHeader
threadClass = Utility.getWord (buffer, offset); threadClass = Utility.getWord (buffer, offset);
threadFormat = Utility.getWord (buffer, offset + 2); threadFormat = Utility.getWord (buffer, offset + 2);
threadKind = Utility.getWord (buffer, offset + 4); threadKind = Utility.getWord (buffer, offset + 4);
threadCrc = Utility.getWord (buffer, offset + 6); threadCrc = Utility.getWord (buffer, offset + 6);
uncompressedEOF = Utility.getLong (buffer, offset + 8); uncompressedEOF = Utility.getLong (buffer, offset + 8);
compressedEOF = Utility.getLong (buffer, offset + 12); compressedEOF = Utility.getLong (buffer, offset + 12);
@ -42,11 +44,11 @@ class ThreadHeader
text.append (String.format (" threadClass ....... %d %s%n", threadClass, text.append (String.format (" threadClass ....... %d %s%n", threadClass,
threadClassText[threadClass])); threadClassText[threadClass]));
text.append ( text.append (String.format (" format ............ %d %s%n", threadFormat,
String.format (" format ............ %d %s%n", threadFormat, formatText[threadFormat])); formatText[threadFormat]));
text.append (String.format (" kind .............. %d %s%n", threadKind, text.append (String.format (" kind .............. %d %s%n", threadKind,
threadKindText[threadClass][threadKind])); threadKindText[threadClass][threadKind]));
text.append (String.format (" crc ............... %,d%n", threadCrc)); text.append (String.format (" crc ............... %,d (%<04X)%n", threadCrc));
text.append (String.format (" uncompressedEOF ... %,d%n", uncompressedEOF)); text.append (String.format (" uncompressedEOF ... %,d%n", uncompressedEOF));
text.append (String.format (" compressedEOF ..... %,d (%08X)", compressedEOF, text.append (String.format (" compressedEOF ..... %,d (%08X)", compressedEOF,
compressedEOF)); compressedEOF));

View File

@ -496,11 +496,11 @@ public class Utility
} }
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
protected static int getCRC (final byte[] buffer, int initialValue) protected static int getCRC (final byte[] buffer, int length, int initialValue)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
int crc = initialValue; int crc = initialValue;
for (int j = 0; j < buffer.length; j++) for (int j = 0; j < length; j++)
{ {
crc = ((crc >>> 8) | (crc << 8)) & 0xFFFF; crc = ((crc >>> 8) | (crc << 8)) & 0xFFFF;
crc ^= (buffer[j] & 0xFF); crc ^= (buffer[j] & 0xFF);