package ua.stu.scplib.structure;
import java.io.IOException;
import java.util.ArrayList;
import java.util.ListIterator;
import ua.stu.scplib.attribute.BinaryInputStream;
/**
* <p>A class to encapsulate the SCP-ECG Huffman Tables section.</p>
*
* @author stu
*/
public class Section2 extends Section {
/**
* <p>Get a string name for this section.</p>
*
* @return a string name for this section
*/
public String getSectionName() { return "Huffman Tables"; }
private int numberOfHuffmanTables;
private ArrayList huffmanTablesList; // of class HuffmanTable
public int getNumberOfHuffmanTables() { return numberOfHuffmanTables; }
static public boolean useDefaultTable(int numberOfHuffmanTables) { return numberOfHuffmanTables == 19999; }
public boolean useDefaultTable() { return useDefaultTable(numberOfHuffmanTables); }
public boolean useNoTable() { return numberOfHuffmanTables == 0; } // Hmmm ... should really be indicate by absence of this section
public int getNumberOfEncodedHuffmanTables() { return huffmanTablesList == null ? 0 : huffmanTablesList.size(); }
public ArrayList getHuffmanTables() { return huffmanTablesList; }
public Section2(SectionHeader header) {
super(header);
}
public long read(BinaryInputStream i) throws IOException {
numberOfHuffmanTables=i.readUnsigned16();
bytesRead+=2;
sectionBytesRemaining-=2;
// /Users/dclunie/Documents/Medical/stuff/ECG/OpenECG/Data/Files/101.scp has bytes after 19999
// /Users/dclunie/Documents/Medical/stuff/ECG/OpenECG/Data/Files/112.scp actually has a huffman table
if ((useDefaultTable() || useNoTable()) && sectionBytesRemaining != 0) {
System.err.println("Section 2 Number Of Huffman Tables ="+numberOfHuffmanTables+" dec, but "
+sectionBytesRemaining+" more bytes(code structures) in section are present - ignoring them");
skipToEndOfSectionIfNotAlreadyThere(i);
}
while (sectionBytesRemaining > 0) {
int numberOfCodeStructures = i.readUnsigned16();
bytesRead+=2;
sectionBytesRemaining-=2;
int[] numberOfBitsInPrefix = new int[numberOfCodeStructures];
int[] numberOfBitsInEntireCode = new int[numberOfCodeStructures];
int[] tableModeSwitch = new int[numberOfCodeStructures];
int[] baseValueRepresentedByBaseCode = new int[numberOfCodeStructures];
long[] baseCode = new long[numberOfCodeStructures];
for (int codeStructure=0; codeStructure<numberOfCodeStructures; ++codeStructure) {
numberOfBitsInPrefix[codeStructure] = i.readUnsigned8();
bytesRead++;
sectionBytesRemaining--;
numberOfBitsInEntireCode[codeStructure] = i.readUnsigned8();
bytesRead++;
sectionBytesRemaining--;
tableModeSwitch[codeStructure] = i.readUnsigned8();
bytesRead++;
sectionBytesRemaining--;
baseValueRepresentedByBaseCode[codeStructure] = i.readUnsigned16();
bytesRead+=2;
sectionBytesRemaining-=2;
baseCode[codeStructure] = i.readUnsigned32();
bytesRead+=4;
sectionBytesRemaining-=4;
}
if (huffmanTablesList == null) {
huffmanTablesList = new ArrayList();
}
huffmanTablesList.add(new HuffmanTable(numberOfCodeStructures,numberOfBitsInPrefix,numberOfBitsInEntireCode,
tableModeSwitch,baseValueRepresentedByBaseCode,baseCode));
}
if (!useDefaultTable() && numberOfHuffmanTables != getNumberOfEncodedHuffmanTables()) {
System.err.println("Section 2 Number Of Huffman Tables specified as "
+numberOfHuffmanTables+" but encountered "+getNumberOfEncodedHuffmanTables());
}
skipToEndOfSectionIfNotAlreadyThere(i);
return bytesRead;
}
public String toString() {
StringBuffer strbuf = new StringBuffer();
strbuf.append("Number of Huffman Tables = "+numberOfHuffmanTables+" dec (0x"+Integer.toHexString(numberOfHuffmanTables)+")");
strbuf.append((useDefaultTable() ? " DEFAULT" : "")+"\n");
if (huffmanTablesList != null) {
ListIterator i = huffmanTablesList.listIterator();
while (i.hasNext()) {
strbuf.append("Table Number = "+i.nextIndex()+"\n");
HuffmanTable t = (HuffmanTable)(i.next());
strbuf.append(t);
}
}
return strbuf.toString();
}
public String validate() {
return "";
}
}