scpsection2.cs
来自「ecg tool kit for medical image retrieval」· CS 代码 · 共 1,006 行 · 第 1/2 页
CS
1,006 行
int currentBit = 0;
// Make buffer for worst case.
byte[] buffer = new byte[((time * 26) >> 3) + 1];
// For each sample do encode.
for (int currentTime=0;currentTime < time;currentTime++)
{
short code = 0;
// Encode Differences.
switch (difference)
{
case 0:
code = data[currentTime];
break;
case 1:
code = (short) ((currentTime < 1) ? data[currentTime] : data[currentTime] - data[currentTime - 1]);
break;
case 2:
code = (short) ((currentTime < 2) ? data[currentTime] : data[currentTime] - (data[currentTime - 1] << 1) + data[currentTime - 2]);
break;
default:
// Undefined difference used exit empty.
return null;
}
// Do inhouse encode
//System.Diagnostics.Debug.WriteLine("Begin inhouse!"+code.ToString());
if ( code == -32768) code = 32767;
if (Math.Abs(code) <= 8)
{
// System.Diagnostics.Debug.WriteLine("Begin !");
// if code 0 then add one 0 bit.
if (code == 0)
{
buffer[currentBit >> 3] <<= 1;
currentBit++;
}
else
{
// add absolute number of 1 bits.
int codeAbs = Math.Abs(code);
for (int loper=0;loper < codeAbs;loper++)
{
buffer[currentBit >> 3] <<= 1;
buffer[currentBit >> 3] |= 1;
currentBit++;
}
// add one 0 bit.
buffer[currentBit >> 3] <<= 1;
currentBit++;
// add one more bit for positive of negative
buffer[currentBit >> 3] <<= 1;
if (code < 0)
{
buffer[currentBit >> 3] |= 1;
}
currentBit++;
}
}
else
{
//System.Diagnostics.Debug.WriteLine("esle!");
// Code doesn't fit in normal table do special.
// First add nine 1 bits.
for (int loper=0;loper < 9;loper++)
{
buffer[currentBit >> 3] <<= 1;
buffer[currentBit >> 3] |= 1;
currentBit++;
}
// Add one more bit depending on size of code
buffer[currentBit >> 3] <<= 1;
int extraLength = 8;
if (!((code <= 127) && (code >= -128)))
{
buffer[currentBit >> 3] |= 1;
extraLength = 16;
}
currentBit++;
// Add bits for extra code.
for (extraLength--;extraLength >= 0;extraLength--)
{
buffer[currentBit >> 3] <<= 1;
buffer[currentBit >> 3] |= (byte)((code >> extraLength) & 0x1);
currentBit++;
int currentBitShift = currentBit >> 3;
}
}
}
// Shift end to right position.
if ((currentBit & 0x7) != 0x0)
{
buffer[(currentBit >> 3)] <<= (0x8 - (currentBit & 0x7));
currentBit += (0x8 - (currentBit & 0x7));
}
// Allocate a fitting buffer
ret = new byte[(currentBit >> 3)];
// Copy worst case buffer in fitting buffer.
for (int loper = 0;loper < ret.Length;loper++)
{
ret[loper] = buffer[loper];
}
}
return ret;
}
/// <summary>
/// Function to encode signal using the huffman table.
/// </summary>
/// <param name="data">signal to read from</param>
/// <param name="time">number of samples to use</param>
/// <param name="quanta">sample distance in signal</param>
/// <param name="usedTable">table to use for encoding</param>
/// <param name="difference">difference to use durring decoding</param>
/// <returns>byte array containing encoded data</returns>
private byte[] HuffmanTableEncode(short[] data, int time, short usedTable, byte difference)
{
byte[] ret = null;
// Check if input makes sense
if ((data != null)
&& (time <= data.Length))
{
// Initialize some handy variables
int currentBit = 0;
// Make buffer for worst case.
byte[] buffer = null;
if ((usedTable >= 0)
&& (usedTable < _Tables.Length)
&& (usedTable != _Selected))
{
uint code = 0;
int len = 0;
// get TableSwap position in HuffmanTable.
int p = getTableSwap(usedTable);
// Check if table swap is possible in this table.
if (p >= 0)
{
// Store needed data from swap HuffmanStruct.
code = _Tables[_Selected][p].code;
len = _Tables[_Selected][p].entire;
// set currently selected table.
_Selected = usedTable;
}
// allocate buffer for worstcase.
buffer = new byte[((len + (time * getWorstCase())) >> 3) + 1];
// add table swap.
for (len--;len >= 0;len--)
{
buffer[currentBit >> 3] <<= 1;
buffer[currentBit >> 3] |= (byte)((code >> len) & 0x1);
currentBit++;
}
}
else
{
// No tables swap, so only space needed for worst case.
buffer = new byte[((time * getWorstCase()) >> 3) + 1];
}
// For each sample do encode.
for (int currentTime=0;currentTime < time;currentTime++)
{
short code = 0;
// Encode Differences.
switch (difference)
{
case 0:
code = data[currentTime];
break;
case 1:
code = (short) ((currentTime < 1) ? data[currentTime] : data[currentTime] - data[currentTime - 1]);
break;
case 2:
code = (short) ((currentTime < 2) ? data[currentTime] : data[currentTime] - (data[currentTime - 1] << 1) + data[currentTime - 2]);
break;
default:
// Undefined difference used exit empty.
return null;
}
// Call Interpetting data to get an hit.
SCPHuffmanStruct h = InterpettingData(code);
if (h == null)
{
// not hit table or data must be wrong.
return null;
}
// Push in the code.
for (int loper=(h.prefix-1);loper >= 0;loper--)
{
buffer[currentBit >> 3] <<= 1;
buffer[currentBit >> 3] |= (byte)((h.code >> loper) & 0x1);
currentBit++;
}
// Push in the extra code, for special case.
uint now = (uint) (code - h.value);
for (int loper=(h.entire - h.prefix - 1);loper >= 0;loper--)
{
buffer[currentBit >> 3] <<= 1;
buffer[currentBit >> 3] |= (byte)((code >> loper) & 0x1);
currentBit++;
}
}
// Shift end to right position.
if ((currentBit & 0x7) != 0x0)
{
buffer[(currentBit >> 3)] <<= (0x8 - (currentBit & 0x7));
currentBit += (0x8 - (currentBit & 0x7));
}
// Allocate a fitting buffer
ret = new byte[(currentBit >> 3)];
// Copy worst case buffer in fitting buffer.
for (int loper = 0;loper < ret.Length;loper++)
{
ret[loper] = buffer[loper];
}
}
return ret;
}
/// <summary>
/// Function to find corresponding HuffmanStruct with value.
/// </summary>
/// <param name="value">value to search</param>
/// <returns>corresponding HuffmanStruct</returns>
private SCPHuffmanStruct InterpettingData(short value)
{
// Check if selected Table exists
if ((_Tables != null)
&& (_Tables[_Selected] != null))
{
// Search in structs of table.
for (int loper=0;loper < _Tables[_Selected].Length;loper++)
{
SCPHuffmanStruct h = _Tables[_Selected][loper];
// -1, because it can be positive and negative
int extra = (h.entire - h.prefix - 1);
// Check if value is equal to struct.
if ((h.value == value)
&& (h.tablemode != 0))
{
return h;
}
// Check if value fits in special case.
else if ((extra > 0)
&& ((value - h.value) < (0x1 << extra))
&& ((value - h.value) >= -(0x1 << extra))
&& (h.tablemode != 0))
{
return h;
}
}
}
return null;
}
/// <summary>
/// Function to store signal using no compression.
/// </summary>
/// <param name="data">signal to read from</param>
/// <param name="time">number of samples to use</param>
/// <param name="quanta">sample distance in signal</param>
/// <param name="difference">difference to use durring decoding</param>
/// <returns>byte array containing encoded data</returns>
public static byte[] NoEncode(short[] data, int time, byte difference)
{
// Check if input data makes sense.
if ((data != null)
&& (time <= data.Length))
{
// Initializing some handy variables
int offset = 0;
int sizeOfSample = Marshal.SizeOf(typeof(short));
// Make buffer to contain samples
byte[] ret = new byte[time * sizeOfSample];
// For each sample do encode.
for (int currentTime=0;currentTime < time;currentTime++)
{
short code = 0;
// Encode Differences.
switch (difference)
{
case 0:
code = data[currentTime];
break;
case 1:
code = (short) ((currentTime < 1) ? data[currentTime] : data[currentTime] - data[currentTime - 1]);
break;
case 2:
code = (short) ((currentTime < 2) ? data[currentTime] : data[currentTime] - (data[currentTime - 1] << 1) + data[currentTime - 2]);
break;
default:
// Undefined difference used exit empty.
return null;
}
// Write data in buffer.
BytesTool.writeBytes(code, ret, offset, sizeOfSample, true);
offset += sizeOfSample;
}
return ret;
}
return null;
}
/// <summary>
/// Resets the current selected HuffmanTable
/// </summary>
public void ResetSelect()
{
if (Works())
{
_Selected = 0;
}
}
/// <summary>
/// Function to get position of table swap.
/// </summary>
/// <param name="table">prefered table</param>
/// <returns>position in current table</returns>
private int getTableSwap(int table)
{
if (Works()
&& (table < _Tables.Length)
&& (_Selected < _Tables.Length))
{
for (int loper=0;loper < _Tables[_Selected].Length;loper++)
{
if (_Tables[_Selected][loper].tablemode == 0
&& _Tables[_Selected][loper].value == (table + 1))
{
return loper;
}
}
}
return -1;
}
/// <summary>
/// Function to get binary length of worst case of selected table.
/// </summary>
/// <returns>length of worst case</returns>
private int getWorstCase()
{
int worst = -1;
if (Works())
{
if (this._NrTables == _DefaultTable)
{
worst = 26;
}
else if (_NrTables == 0)
{
worst = 16;
}
else
{
for (int loper=0;loper < _Tables[_Selected].Length;loper++)
{
if (_Tables[_Selected][loper].entire > worst)
{
worst = _Tables[_Selected][loper].entire;
}
}
}
}
return worst;
}
/// <summary>
/// Function to set standard huffman table.
/// </summary>
public void UseStandard()
{
_NrTables = _DefaultTable;
}
/// <summary>
/// Function to set no huffman encoding.
/// </summary>
public void UseNoHuffman()
{
_NrTables = 0;
}
/// <summary>
/// Class that contains a SCP Huffman struct
/// </summary>
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet=CharSet.Ansi)]
public class SCPHuffmanStruct
{
public byte prefix;
public byte entire;
public byte tablemode;
public short value;
public uint code;
public SCPHuffmanStruct()
{}
public SCPHuffmanStruct(byte prefix, byte entire, byte tablemode, short value, uint code)
{
this.prefix = prefix;
this.entire = entire;
this.tablemode = tablemode;
this.value = value;
this.code = code;
}
/// <summary>
/// Function to read an SCP huffman struct.
/// </summary>
/// <param name="buffer">byte array to read from</param>
/// <param name="offset">position to start reading</param>
/// <returns>0 on success</returns>
public int Read(byte[] buffer, int offset)
{
if ((offset + Marshal.SizeOf(this)) > buffer.Length)
{
return 0x1;
}
prefix = (byte) BytesTool.readBytes(buffer, offset, Marshal.SizeOf(prefix), true);
offset += Marshal.SizeOf(prefix);
entire = (byte) BytesTool.readBytes(buffer, offset, Marshal.SizeOf(entire), true);
offset += Marshal.SizeOf(entire);
tablemode = (byte) BytesTool.readBytes(buffer, offset, Marshal.SizeOf(tablemode), true);
offset += Marshal.SizeOf(tablemode);
value = (short) BytesTool.readBytes(buffer, offset, Marshal.SizeOf(value), true);
offset += Marshal.SizeOf(value);
uint tempCode = (byte) BytesTool.readBytes(buffer, offset, Marshal.SizeOf(code), true);
offset += Marshal.SizeOf(code);
// Have to reverse the code, because SCP stores it that way.
code = 0;
for (int loper=prefix;loper > 0;loper--)
{
code <<= 1;
code |= (tempCode & 0x1);
tempCode >>= 1;
}
return 0x0;
}
/// <summary>
/// Function to write SCP huffman struct.
/// </summary>
/// <param name="buffer">byte array to write into</param>
/// <param name="offset">position to start writing</param>
/// <returns>0 on success</returns>
public int Write(byte[] buffer, int offset)
{
if ((offset + Marshal.SizeOf(this)) > buffer.Length)
{
return 0x1;
}
BytesTool.writeBytes(prefix, buffer, offset, Marshal.SizeOf(prefix), true);
offset += Marshal.SizeOf(prefix);
BytesTool.writeBytes(entire, buffer, offset, Marshal.SizeOf(entire), true);
offset += Marshal.SizeOf(entire);
BytesTool.writeBytes(tablemode, buffer, offset, Marshal.SizeOf(tablemode), true);
offset += Marshal.SizeOf(tablemode);
BytesTool.writeBytes(value, buffer, offset, Marshal.SizeOf(value), true);
offset += Marshal.SizeOf(value);
// Have to reverse the code, becaus SCP stores it that way.
uint tempCode1 = code;
uint tempCode2 = 0;
for (int loper=prefix;loper > 0;loper--)
{
tempCode2 <<= 1;
tempCode2 |= (tempCode1 & 0x1);
tempCode1 >>= 1;
}
BytesTool.writeBytes((int)tempCode2, buffer, offset, Marshal.SizeOf(code), true);
offset += Marshal.SizeOf(code);
return 0x0;
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?