/* 1999 08 20; 1999 09 06; 1999 11 09 */
package pl.edu.fuw.MP.Core;
import java.io.*;
class FormatComponent {
public static final int TEXT_INFO=1,DATE_INFO=2;
public static final int SIGNAL_INFO=3,DECOMP_INFO=4;
public int type;
public void Read(DataArrayInputStream stream)
throws IOException {
;
}
public void Read(DataArrayInputStream stream,int size)
throws IOException {
;
}
}
class DecompositionInfo extends FormatComponent {
public float energy_percent;
public int max_number_of_iterations;
public int dictionary_size;
public char dictionary_type;
public void Read(DataArrayInputStream stream) throws IOException {
energy_percent=stream.readFloat();
max_number_of_iterations=stream.readInt();
dictionary_size=stream.readInt();
dictionary_type=(char)stream.readByte();
stream.skipBytes(3L);
}
}
class SignalInfo extends FormatComponent {
public float sampling_freq;
public float points_per_microvolt;
public int number_of_chanels_in_file;
public void Read(DataArrayInputStream stream) throws IOException {
sampling_freq=stream.readFloat();
points_per_microvolt=stream.readFloat();
number_of_chanels_in_file=stream.readInt();
}
}
class TextInfo extends FormatComponent {
public String text;
public void Read(DataArrayInputStream stream,int size) throws IOException {
text="";
for (int i=0 ; i<size ; i++) {
char c=(char)stream.readByte();
if (c!='\0')
text+=c;
}
}
}
class DateInfo extends FormatComponent {
public String date;
public void Read(DataArrayInputStream stream,int size) throws IOException {
date="";
for (int i=0 ; i<size ; i++) {
char c=(char)stream.readByte();
if (c!='\0')
date+=c;
}
}
}
class SegmentHeader {
public int channel;
public int file_offset;
public int book_size;
public int signal_size;
public float signal_energy;
public float book_energy;
public void Read(RandomAccessFile stream) throws IOException {
channel=stream.readInt();
file_offset=stream.readInt();
book_size=stream.readInt();
signal_size=stream.readInt();
signal_energy=stream.readFloat();
book_energy=stream.readFloat();
}
}
public class NewBookLibrary {
public static final int VERSION_NONE=-1,VERSION_III=1,VERSION_IV=2,VERSION_V=3;
private FormatComponent fields[];
private int fieldsCount;
private SegmentHeader segment=new SegmentHeader();
private NewAtom atoms[]=null;
private RandomAccessFile streamClass=null;
//private int BookCount;
private int MaxBookNumber;
private int version=VERSION_NONE;
public final NewAtom getAtom(int k) {
return atoms[k];
}
public final int getMaxBookNumber() {
return MaxBookNumber;
}
public void export(BookHeader head) {
head.file_offset=(short)segment.file_offset;
head.book_size=(short)segment.book_size;
head.signal_size=getDimBase();
head.points_per_micro_V=getConvFactor();
head.FREQUENCY=getSamplingFreq();
head.signal_energy=segment.signal_energy;
head.book_energy=segment.book_energy;
}
public final void export(BookAtom atom,int k) {
atoms[k].export(atom);
}
public NewBookLibrary() {
fields=new FormatComponent[256];
fieldsCount=0;
for (int i=0 ; i<256 ; i++)
fields[i]=null;
}
private void Close() {
try {
if (streamClass!=null) {
streamClass.close();
streamClass=null;
}
} catch (IOException e) {
}
}
private static int checkFormat(RandomAccessFile stream)
throws IOException {
byte s[]=new byte[4];
stream.read(s,0,4);
String string=new String(s);
if (string.equals("MPv3")) {
return VERSION_III;
} else if (string.equals("MPv4")) {
return VERSION_IV;
} else if (string.equals("MPv5")) {
return VERSION_V;
}
return VERSION_NONE;
}
public static int checkFormat(String filename) {
try {
RandomAccessFile stream=new RandomAccessFile(filename, "r");
int ok=checkFormat(stream);
stream.close();
return ok;
} catch (IOException e) {
Utils.log(e.toString());
return VERSION_NONE;
}
}
private boolean setOffset(RandomAccessFile stream,int offset) {
try {
SegmentHeader segHead=new SegmentHeader();
for (int i=0 ; i<offset ; i++) {
segHead.Read(stream);
stream.skipBytes(segHead.book_size*NewAtom.sizeOf());
}
} catch (IOException e) {
return false;
}
return true;
}
public boolean SetOffset(String filename,int Offset) {
try {
Close();
streamClass=new RandomAccessFile(filename, "r");
return setOffset(streamClass,Offset);
} catch (IOException e) {
return false;
}
}
private void readBook(RandomAccessFile stream) throws IOException {
segment.Read(stream);
atoms=new NewAtom[segment.book_size];
byte buffor[]=new byte[segment.book_size*NewAtom.sizeOf()];
DataArrayInputStream block=new DataArrayInputStream(stream,buffor);
for (int i=0 ; i<segment.book_size ; i++) {
(atoms[i]=new NewAtom(version)).Read(block);
atoms[i].index=i;
}
}
private int countBook(RandomAccessFile stream) throws IOException {
int code;
if ((code=checkFormat(stream))==VERSION_NONE)
return 0;
version=code;
int headSize=stream.readUnsignedShort()-6;
stream.skipBytes(headSize);
int k=0;
try {
SegmentHeader segHead=new SegmentHeader();
for (k=0 ; ; k++) {
segHead.Read(stream);
stream.skipBytes(segHead.book_size*NewAtom.sizeOf());
}
} catch (IOException e) {
return k;
}
}
private boolean loadBook(RandomAccessFile stream,int offset)
throws IOException {
int code;
if ((code=checkFormat(stream))==VERSION_NONE) {
return false;
}
version=code;
int headSize=stream.readUnsignedShort()-6;
stream.skipBytes(headSize);
if (!setOffset(stream,offset)) {
return false;
}
readBook(stream);
return true;
}
public boolean readNextBook() {
try {
readBook(streamClass);
} catch (IOException e) {
return false;
}
return true;
}
public int countBook(String filename) {
try {
RandomAccessFile streamClass=new RandomAccessFile(filename, "r");
int count=countBook(streamClass);
streamClass.close();
return count;
} catch (IOException e) {
return 0;
}
}
public boolean loadBook(String filename,int offset) {
MaxBookNumber=countBook(filename);
try {
Close();
streamClass=new RandomAccessFile(filename, "r");
return loadBook(streamClass,offset);
} catch (IOException e) {
return false;
}
}
public void importBook(Book book) {
Close();
int size;
MaxBookNumber=1;
segment.channel=0;
segment.file_offset=0;
segment.book_size=book.atoms.length;
segment.signal_size=book.param.DimBase;
segment.signal_energy=1.0F;
segment.book_energy=1.0F;
atoms=new NewAtom[size=book.atoms.length];
for (int i=0 ; i<size ; i++) {
NewAtom stmp=book.atoms[i];
atoms[i]=new NewAtom();
atoms[i].scale=stmp.scale;
atoms[i].frequency=stmp.frequency;
atoms[i].position=stmp.position;
atoms[i].modulus=stmp.modulus;
atoms[i].amplitude=stmp.amplitude;
atoms[i].phase=stmp.phase;
atoms[i].index=i;
}
fieldsCount=0;
}
private boolean readFileHeader(RandomAccessFile stream) throws IOException {
int code;
if ((code=checkFormat(stream))==VERSION_NONE) {
return false;
}
version=code;
int MaxSize=stream.readUnsignedShort(),size=6;
byte buff[]=new byte[MaxSize];
DataArrayInputStream block=new DataArrayInputStream(stream,buff);
fieldsCount=0;
while (size<MaxSize) {
code= block.readUnsignedByte();
int fieldSize=block.readUnsignedByte();
switch (code) {
case FormatComponent.TEXT_INFO:
(fields[fieldsCount]=new TextInfo()).Read(block,fieldSize);
fields[fieldsCount++].type=FormatComponent.TEXT_INFO;
break;
case FormatComponent.DATE_INFO:
(fields[fieldsCount]=new DateInfo()).Read(block,fieldSize);
fields[fieldsCount++].type=FormatComponent.DATE_INFO;
break;
case FormatComponent.SIGNAL_INFO:
(fields[fieldsCount]=new SignalInfo()).Read(block);
fields[fieldsCount++].type=FormatComponent.SIGNAL_INFO;
break;
case FormatComponent.DECOMP_INFO:
(fields[fieldsCount]=new DecompositionInfo()).Read(block);
fields[fieldsCount++].type=FormatComponent.DECOMP_INFO;
break;
default:
block.skipBytes(fieldSize);
break;
}
size+=fieldSize+2;
}
return true;
}
public final int getDimBase() {
return segment.signal_size;
}
public final int getNumOfAtoms() {
return segment.book_size;
}
public final String getDate() {
for (int i=0 ; i<fieldsCount ; i++)
if (fields[i].type==FormatComponent.DATE_INFO)
return ((DateInfo)fields[i]).date;
return null;
}
public final String getText() {
for (int i=0 ; i<fieldsCount ; i++)
if (fields[i].type==FormatComponent.TEXT_INFO)
return ((TextInfo)fields[i]).text;
return null;
}
public final float getEnergyPercent() {
for (int i=0 ; i<fieldsCount ; i++)
if (fields[i].type==FormatComponent.DECOMP_INFO)
return ((DecompositionInfo)fields[i]).energy_percent;
return -1.0F;
}
public final int getMaxNumberOfIteration() {
for (int i=0 ; i<fieldsCount ; i++)
if (fields[i].type==FormatComponent.DECOMP_INFO)
return ((DecompositionInfo)fields[i]).max_number_of_iterations;
return -1;
}
public final int getDictionarySize() {
for (int i=0 ; i<fieldsCount ; i++)
if (fields[i].type==FormatComponent.DECOMP_INFO)
return ((DecompositionInfo)fields[i]).dictionary_size;
return -1;
}
public final int getMaxChannel() {
for (int i=0 ; i<fieldsCount ; i++)
if (fields[i].type==FormatComponent.SIGNAL_INFO)
return ((SignalInfo)fields[i]).number_of_chanels_in_file;
return -1;
}
public final char getDictionaryType() {
for (int i=0 ; i<fieldsCount ; i++) {
if (fields[i].type==FormatComponent.DECOMP_INFO) {
return ((DecompositionInfo)fields[i]).dictionary_type;
}
}
return '0';
}
public final float getConvFactor() {
for (int i=0 ; i<fieldsCount ; i++) {
if (fields[i].type==FormatComponent.SIGNAL_INFO) {
return ((SignalInfo)fields[i]).points_per_microvolt;
}
}
return 1.0F;
}
public final float getSamplingFreq() {
for (int i=0 ; i<fieldsCount ; i++) {
if (fields[i].type==FormatComponent.SIGNAL_INFO) {
return ((SignalInfo)fields[i]).sampling_freq;
}
}
return 1.0F;
}
public final String getVersion() {
switch (version) {
case VERSION_III:
return "III";
case VERSION_IV:
return "IV";
case VERSION_V:
return "V";
}
return "UNKNOWN";
}
public String getString() {
String mydate=getDate(),mytext=getText();
if (mydate==null)
mydate="(null)";
if (mytext==null)
mytext="(null)";
return ("\nSampling frequency: "+getSamplingFreq()+" Hz\n"+
"Version : "+getVersion()+"\n"+
"Conversion : "+getConvFactor()+" points/uV\n"+
"Dictionary Type : "+getDictionaryType()+"\n"+
"Dictionary Size : "+getDictionarySize()+"\n"+
"Energy Percent : "+getEnergyPercent()+" %\n"+
"File offset : "+segment.file_offset+"\n"+
"Book size : "+segment.book_size+"\n"+
"Signal size : "+segment.signal_size+"\n"+
"Signal energy : "+segment.signal_energy+"\n"+
"Channel : "+segment.channel+"\n"+
"Number of channels: "+getMaxChannel()+"\n"+
"Book energy : "+segment.book_energy+"\n"+
"Book number : "+getMaxBookNumber()+"\n"+
"Text : "+mytext+"\n"+
"Date : "+mydate+"\n"
);
}
public boolean Open(String filename,int Offset) {
try {
Close();
RandomAccessFile stream=new RandomAccessFile(filename, "r");
boolean ok=readFileHeader(stream);
stream.close();
if (!ok) return false;
return loadBook(filename,Offset);
} catch (IOException e) {
return false;
}
}
}