using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Tools
{
internal enum OperationMode
{
Open,
Create
}
public class VinnoStreamReader
{
private readonly Stream _stream;
public VinnoStreamReader(Stream stream)
{
_stream = stream;
}
///
/// Read string from stream.
///
///
public string ReadString()
{
var dataLength = ReadInt();
var data = new byte[dataLength];
_stream.Read(data, 0, dataLength);
return Encoding.Unicode.GetString(data, 0, data.Length);
}
///
/// Read a int32 value from the stream.
///
///
public int ReadInt()
{
var data = new byte[sizeof(int)];
_stream.Read(data, 0, sizeof(int));
return BitConverter.ToInt32(data, 0);
}
///
/// Read a short value from the stream.
///
///
public short ReadShort()
{
var data = new byte[sizeof(short)];
_stream.Read(data, 0, sizeof(short));
return BitConverter.ToInt16(data, 0);
}
///
/// Read a Int64 value from the stream.
///
///
public long ReadLong()
{
var data = new byte[sizeof(long)];
_stream.Read(data, 0, sizeof(long));
return BitConverter.ToInt64(data, 0);
}
///
/// Read a float value from the stream.
///
///
public float ReadFloat()
{
var data = new byte[sizeof(float)];
_stream.Read(data, 0, sizeof(float));
return BitConverter.ToSingle(data, 0);
}
///
/// Read a double value from the stream.
///
///
public double ReadDouble()
{
var data = new byte[sizeof(double)];
_stream.Read(data, 0, sizeof(double));
return BitConverter.ToDouble(data, 0);
}
///
/// Read a bool value from the stream.
///
///
public bool ReadBool()
{
var data = new byte[sizeof(bool)];
_stream.Read(data, 0, sizeof(bool));
return BitConverter.ToBoolean(data, 0);
}
///
/// Read a byte value from the stream.
///
///
public byte ReadByte()
{
return (byte)(_stream.ReadByte());
}
///
/// Read a byte array from the stream.
///
///
public byte[] ReadBytes()
{
var size = ReadInt();
var data = new byte[size];
_stream.Read(data, 0, size);
return data;
}
public long[] ReadLongs()
{
var data = ReadBytes();
var result = new long[data.Length / sizeof(long)];
Buffer.BlockCopy(data, 0, result, 0, data.Length);
return result;
}
}
public class VinnoStreamWriter
{
private readonly Stream _stream;
public VinnoStreamWriter(Stream stream)
{
_stream = stream;
}
///
/// Write a string to stream.
///
///
public void WriteString(string value)
{
var data = Encoding.Unicode.GetBytes(value);
WriteInt(data.Length);
_stream.Write(data, 0, data.Length);
}
///
/// Write a int32 value to stream.
///
///
public void WriteInt(int value)
{
_stream.Write(BitConverter.GetBytes(value), 0, sizeof(int));
}
///
/// Write a short value to stream.
///
///
public void WriteShort(short value)
{
_stream.Write(BitConverter.GetBytes(value), 0, sizeof(short));
}
///
/// Write a int64 value to stream.
///
///
public void WriteLong(long value)
{
_stream.Write(BitConverter.GetBytes(value), 0, sizeof(long));
}
///
/// Write a float value to stream.
///
///
public void WriteFloat(float value)
{
_stream.Write(BitConverter.GetBytes(value), 0, sizeof(float));
}
///
/// Write a double value to stream.
///
///
public void WriteDouble(double value)
{
_stream.Write(BitConverter.GetBytes(value), 0, sizeof(double));
}
///
/// Write a bool value to stream.
///
///
public void WriteBool(bool value)
{
_stream.Write(BitConverter.GetBytes(value), 0, sizeof(bool));
}
///
/// Write a byte value to stream.
///
///
public void WriteByte(byte value)
{
_stream.WriteByte(value);
}
///
/// Write a array in to stream.
///
public void WriteBytes(byte[] value)
{
WriteInt(value.Length);
_stream.Write(value, 0, value.Length);
}
///
/// Write long array into stream.
///
///
public void WriteLongs(long[] value)
{
var data = new byte[value.Length * sizeof(long)];
Buffer.BlockCopy(value, 0, data, 0, data.Length);
WriteBytes(data);
}
}
public enum VinnoProbeType
{
Undefined,
Linear,
Convex,
Sector,
};
public class VinnoApplication
{
///
/// Gets the application's ID
///
public string ApplicationId { get; }
///
/// Gets the OriginalId of the applciation.
///
public string ApplicationOriginalId { get; }
///
/// Gets the application's name.
///
public string ApplicationName { get; }
///
/// Gets the applciation's category name.
///
public string ApplicationCategoryName { get; }
///
/// Gets if is user defined.
///
public bool IsUserDefined { get; }
public VinnoApplication(string applicationId, string applicationOriginalId, string applicationName, string applicationCategoryName, bool isUserDefined)
{
ApplicationId = applicationId;
ApplicationOriginalId = applicationOriginalId;
ApplicationName = applicationName;
ApplicationCategoryName = applicationCategoryName;
IsUserDefined = isUserDefined;
}
public byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteString(ApplicationId);
writer.WriteString(ApplicationOriginalId);
writer.WriteString(ApplicationName);
writer.WriteString(ApplicationCategoryName);
writer.WriteBool(IsUserDefined);
result = stream.ToArray();
}
return result;
}
public static VinnoApplication FromBytes(byte[] bytes)
{
VinnoApplication result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var applicationId = reader.ReadString();
var applicationOriginalId = reader.ReadString();
var applicationName = reader.ReadString();
var applicationCategoryName = reader.ReadString();
var isUserDefined = reader.ReadBool();
result = new VinnoApplication(applicationId, applicationOriginalId, applicationName, applicationCategoryName, isUserDefined);
}
return result;
}
}
public class VinnoProbe
{
public string Name { get; }
public VinnoProbeType Type { get; }
public VinnoApplication Application { get; }
public double FrameRate { get; }
public VinnoProbe(string name, VinnoProbeType type, VinnoApplication application, double frameRate)
{
Name = name; //探头的型号名
Type = type; //探头的类型
Application = application;
FrameRate = frameRate;
}
public byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteString(Name);
writer.WriteByte((byte)Type);
writer.WriteBytes(Application.ToBytes());
writer.WriteDouble(FrameRate);
result = stream.ToArray();
}
return result;
}
public static VinnoProbe FromBytes(byte[] bytes)
{
if (bytes == null)
{
return null;
}
VinnoProbe result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var name = reader.ReadString();
var type = (VinnoProbeType)reader.ReadByte();
var application = VinnoApplication.FromBytes(reader.ReadBytes());
var frameRate = reader.ReadDouble();
if (frameRate == 0)
{
frameRate = 15;
}
if (frameRate < 10 && frameRate >= 1)
{
frameRate = 10;
}
result = new VinnoProbe(name, type, application, frameRate);
}
return result;
}
}
internal enum VidImageFormat
{
Jpeg = 0,
Png = 1,
H264 = 2,
Zip = 3,
Diff = 4,
}
internal interface IImageDataContainer
{
byte[] ImageData { get; set; }
}
internal class VinnoImageUpdater
{
private readonly IImageDataContainer _imageDataContainer;
public VinnoImageUpdater(VinnoImage image)
{
_imageDataContainer = image;
}
///
/// Update VinnoImage's image data
///
/// The image data to be updated.
public void Update(byte[] imageData)
{
_imageDataContainer.ImageData = imageData;
}
}
public enum VinnoVisualType
{
V2D = 0,
V3D,
}
public enum VinnoVisualIndicator
{
A = 0,
B = 1,
C = 2,
D = 3
}
public enum VinnoDisplayMode
{
///
/// Normal B mode
///
Normal = 0,
///
/// Up/Down, B holds 1/3, Other hodes 2/3
///
UpDown13B = 1,
///
/// Up/Down, half, half
///
UpDownHalfHalf = 2,
///
/// Up/Down, B holds2/3, Other hodes1/3
///
UpDown23B = 3,
/////
///// Left/Right, B holds 1/3, other hodes 2/3
/////
//SideBySide13B = 3,
///
/// Left/Right, half, half
///
SideBySideHalfHalf = 4,
///
/// Left/Right, B holds2/3, Other hodes1/3
///
SideBySide14BOther = 5,
///
/// All Image area are Other image instead of B image
///
FullOther = 6,
FullTissue = 7,
}
public enum VinnoModeType
{
Undefined = 0,
Tissue,
Flow,
Doppler,
TissueTM,
Tissue3D,
FlowM,
};
public class VinnoMode
{
public string Name { get; }
public string DisplayName { get; }
public VinnoModeType Type { get; }
public VinnoMode(string name, string displayName, VinnoModeType type)
{
Name = name;
DisplayName = displayName;
Type = type;
}
public byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteString(Name);
writer.WriteString(DisplayName);
writer.WriteByte((byte)Type);
result = stream.ToArray();
}
return result;
}
public static VinnoMode FromBytes(byte[] bytes)
{
VinnoMode result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var name = reader.ReadString();
var displayName = reader.ReadString();
var type = (VinnoModeType)reader.ReadByte();
result = new VinnoMode(name, displayName, type);
}
return result;
}
}
internal enum VinnoVisualAreaType
{
Tissue = 0,
Flow,
TimeMotion,
Doppler,
TissueTimeMotion,
Trace,
Colorbar,
Tissue3D,
ZoomTissue,
ZoomFlow,
AssociateTissue,
AssociateFlow,
}
internal enum VinnoUnit
{
None = 0,
percent = 1,
cm = 10,
mm = 11,
inch = 12,
ft = 13,
s = 20,
minute = 21,
hour = 22,
day = 23,
week = 24,
week_day = 25,
Tick = 26,
msec = 27,
degree = 30,
radian = 31,
g = 40,
mg = 41,
ng = 42,
kg = 43,
oz = 44,
lb = 45,
cm2 = 50,
mm2 = 51,
m2 = 52,
cm3 = 60,
mm3 = 61,
ml = 62,
L = 63,
cms = 70,
mms = 71,
ms = 72,
cms2 = 80,
mms2 = 81,
cm3s = 90,
mls = 91,
mlmin = 92,
Lmin = 93,
gcm3 = 100,
gml = 101,
ngml = 102,
mmHg = 110,
mV = 120,
Hz = 130,
KHz = 131,
///
/// beats per minute
///
HR = 132,
//SI
cm3m2 = 140,
mlm2 = 141,
//CI
cm3sm2 = 150,
mlsm2 = 151,
cm3minm2 = 153,
mlminm2 = 154,
Lminm2 = 155,
///
/// MVCF:mean velocity of circumferential fiber shortening
///
circs = 160,
//CO
mlbeat = 170,
mm2pa = 180,
d1mpa = 181,
kpa = 182,
mmHgs = 190,
gm2 = 200,
/// AVA Index
cm2m2 = 210
}
internal class VinnoPoint
{
public double X { get; }
public double Y { get; }
public VinnoPoint(double x, double y)
{
X = x;
Y = y;
}
public override string ToString()
{
return $"X:{X},Y:{Y}";
}
protected bool Equals(VinnoPoint other)
{
return X.Equals(other.X) && Y.Equals(other.Y);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((VinnoPoint)obj);
}
public override int GetHashCode()
{
unchecked
{
return (X.GetHashCode() * 397) ^ Y.GetHashCode();
}
}
public static bool operator ==(VinnoPoint left, VinnoPoint right)
{
return Equals(left, right);
}
public static bool operator !=(VinnoPoint left, VinnoPoint right)
{
return !Equals(left, right);
}
}
internal class VinnoRect
{
public double Left { get; }
public double Right { get; }
public double Top { get; }
public double Bottom { get; }
public double Width => Math.Abs(Right - Left);
public double Height => Math.Abs(Bottom - Top);
public VinnoPoint TopLeft => new VinnoPoint(Left, Top);
public VinnoPoint TopRight => new VinnoPoint(Right, Top);
public VinnoPoint BottomLeft => new VinnoPoint(Left, Bottom);
public VinnoPoint BottomRight => new VinnoPoint(Right, Bottom);
public VinnoRect(double x, double y, double width, double height)
{
if ((width < 0.0) || (height < 0.0))
{
throw new ArgumentException("width and height can not less than 0.");
}
Left = x;
Top = y;
Right = Left + width;
Bottom = Top + height;
}
public VinnoRect(VinnoPoint topLeft, VinnoPoint bottomRight)
{
Left = topLeft.X;
Top = topLeft.Y;
Right = bottomRight.X;
Bottom = bottomRight.Y;
}
public static bool operator ==(VinnoRect rect1, VinnoRect rect2)
{
return ((((rect1.Left == rect2.Left) && (rect1.Right == rect2.Right)) && (rect1.Bottom == rect2.Bottom)) &&
(rect1.Top == rect2.Top));
}
public static bool operator !=(VinnoRect rect1, VinnoRect rect2)
{
return !(rect1 == rect2);
}
public static bool Equals(VinnoRect rect1, VinnoRect rect2)
{
return ((((rect1.Left == rect2.Left) && (rect1.Right == rect2.Right)) && (rect1.Bottom == rect2.Bottom)) &&
(rect1.Top == rect2.Top));
}
public override bool Equals(object o)
{
if ((o == null) || !(o is VinnoRect))
{
return false;
}
VinnoRect rect = (VinnoRect)o;
return Equals(this, rect);
}
public bool Equals(VinnoRect value)
{
return Equals(this, value);
}
public override int GetHashCode()
{
return (((Left.GetHashCode() ^ Right.GetHashCode()) ^ Top.GetHashCode()) ^ Bottom.GetHashCode());
}
public override string ToString()
{
return $"L:{Left},R:{Right},T:{Top},B:{Bottom}";
}
}
internal class VinnoLogicalCoordinate
{
public bool IsFlipHorizontal { get; }
public bool IsFlipVertical { get; }
public VinnoRect Region { get; }
public VinnoUnit XUnit { get; }
public VinnoUnit YUnit { get; }
public VinnoLogicalCoordinate(bool isFlipHorizontal, bool isFlipVertical, VinnoRect region, VinnoUnit xUnit, VinnoUnit yUnit)
{
YUnit = yUnit;
XUnit = xUnit;
Region = region;
IsFlipVertical = isFlipVertical;
IsFlipHorizontal = isFlipHorizontal;
}
public byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteBool(IsFlipHorizontal);
writer.WriteBool(IsFlipVertical);
writer.WriteByte((byte)XUnit);
writer.WriteByte((byte)YUnit);
writer.WriteDouble(Region.Left);
writer.WriteDouble(Region.Top);
writer.WriteDouble(Region.Right);
writer.WriteDouble(Region.Bottom);
result = stream.ToArray();
}
return result;
}
public static VinnoLogicalCoordinate FromBytes(byte[] bytes)
{
VinnoLogicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var isFlipHorizontal = reader.ReadBool();
var isFlipVertical = reader.ReadBool();
var xUnit = (VinnoUnit)reader.ReadByte();
var yUnit = (VinnoUnit)reader.ReadByte();
var left = reader.ReadDouble();
var top = reader.ReadDouble();
var right = reader.ReadDouble();
var bottom = reader.ReadDouble();
var region = new VinnoRect(new VinnoPoint(left, top), new VinnoPoint(right, bottom));
result = new VinnoLogicalCoordinate(isFlipHorizontal, isFlipVertical, region, xUnit, yUnit);
}
return result;
}
}
internal enum PhysicalCoordinateType
{
Tissue = 0,
TimeMotion,
ConvexTissue,
LinearTissue,
ConvexTVTissue,
LinearTVTissue,
Doppler,
TissueTimeMotion,
MAM,
PWV
}
internal abstract class VinnoPhysicalCoordinate
{
public PhysicalCoordinateType Type { get; protected set; }
public virtual byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteByte((byte)Type);
result = stream.ToArray();
}
return result;
}
public static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate physicalCoordinate = null;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
switch (type)
{
case PhysicalCoordinateType.ConvexTissue:
physicalCoordinate = VinnoConvexTissuePhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.LinearTissue:
physicalCoordinate = VinnoLinearTissuePhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.ConvexTVTissue:
physicalCoordinate = VinnoConvexTVTissuePhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.LinearTVTissue:
physicalCoordinate = VinnoLinearTVTissuePhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.Doppler:
physicalCoordinate = VinnoDopplerPhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.TissueTimeMotion:
physicalCoordinate = VinnoTissueTimeMotionPhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.MAM:
physicalCoordinate = VinnoMAMPhysicalCoordinate.FromBytes(bytes);
break;
case PhysicalCoordinateType.PWV:
physicalCoordinate = VinnoPWVPhysicalCoordinate.FromBytes(bytes);
break;
}
}
return physicalCoordinate;
}
}
internal abstract class VinnoTissuePhysicalCoordinate : VinnoPhysicalCoordinate
{
public double DepthEnd { get; }
public double DepthStart { get; }
public double Width { get; }
public double BeamPosition { get; }
protected VinnoTissuePhysicalCoordinate(double depthEnd, double depthStart, double width, double beamPosition)
{
Type = PhysicalCoordinateType.Tissue;
BeamPosition = beamPosition;
Width = width;
DepthStart = depthStart;
DepthEnd = depthEnd;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(DepthStart);
writer.WriteDouble(DepthEnd);
writer.WriteDouble(Width);
writer.WriteDouble(BeamPosition);
result = stream.ToArray();
}
return result;
}
}
internal abstract class VinnoTimeMotionPhysicalCoordinate : VinnoPhysicalCoordinate
{
public double SweepSpeed { get; }
public double Max { get; }
public double Min { get; }
protected VinnoTimeMotionPhysicalCoordinate(double sweepSpeed, double max, double min)
{
Type = PhysicalCoordinateType.TimeMotion;
Min = min;
Max = max;
SweepSpeed = sweepSpeed;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(Min);
writer.WriteDouble(Max);
writer.WriteDouble(SweepSpeed);
result = stream.ToArray();
}
return result;
}
}
internal class VinnoConvexTissuePhysicalCoordinate : VinnoTissuePhysicalCoordinate
{
public double ZeroRadius { get; private set; }
public VinnoConvexTissuePhysicalCoordinate(double depthEnd, double depthStart, double width, double beamPosition, double zeroRadius)
: base(depthEnd, depthStart, width, beamPosition)
{
Type = PhysicalCoordinateType.ConvexTissue;
ZeroRadius = zeroRadius;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(ZeroRadius);
result = stream.ToArray();
}
return result;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.ConvexTissue)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.ConvexTissue}, source type:{type}");
}
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
var width = reader.ReadDouble();
var beamPosition = reader.ReadDouble();
var zeroRadius = reader.ReadDouble();
result = new VinnoConvexTissuePhysicalCoordinate(depthEnd, depthStart, width, beamPosition, zeroRadius);
}
return result;
}
}
internal class VinnoLinearTissuePhysicalCoordinate : VinnoTissuePhysicalCoordinate
{
public double Steer { get; }
public VinnoLinearTissuePhysicalCoordinate(double depthEnd, double depthStart, double width, double beamPosition, double steer)
: base(depthEnd, depthStart, width, beamPosition)
{
Type = PhysicalCoordinateType.LinearTissue;
Steer = steer;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(Steer);
result = stream.ToArray();
}
return result;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.LinearTissue)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.LinearTissue}, source type:{type}");
}
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
var width = reader.ReadDouble();
var beamPosition = reader.ReadDouble();
var steer = reader.ReadDouble();
result = new VinnoLinearTissuePhysicalCoordinate(depthEnd, depthStart, width, beamPosition, steer);
}
return result;
}
}
internal class VinnoConvexTVTissuePhysicalCoordinate : VinnoConvexTissuePhysicalCoordinate
{
public double OriginalZeroRadius { get; private set; }
public double OriginalRocx { get; private set; }
public VinnoConvexTVTissuePhysicalCoordinate(double depthEnd, double depthStart, double width, double beamPosition, double zeroRadius, double originalZeroRadius, double originalRocx)
: base(depthEnd, depthStart, width, beamPosition, zeroRadius)
{
Type = PhysicalCoordinateType.ConvexTVTissue;
OriginalRocx = originalRocx;
OriginalZeroRadius = originalZeroRadius;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(OriginalZeroRadius);
writer.WriteDouble(OriginalRocx);
result = stream.ToArray();
}
return result;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.ConvexTVTissue)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.ConvexTVTissue}, source type:{type}");
}
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
var width = reader.ReadDouble();
var beamPosition = reader.ReadDouble();
var zeroRadius = reader.ReadDouble();
var originalZeroRadius = reader.ReadDouble();
var originalRocx = reader.ReadDouble();
result = new VinnoConvexTVTissuePhysicalCoordinate(depthEnd, depthStart, width, beamPosition, zeroRadius, originalZeroRadius, originalRocx);
}
return result;
}
}
internal class VinnoLinearTVTissuePhysicalCoordinate : VinnoConvexTissuePhysicalCoordinate
{
public VinnoLinearTVTissuePhysicalCoordinate(double depthEnd, double depthStart, double width, double beamPosition, double zeroRadius)
: base(depthEnd, depthStart, width, beamPosition, zeroRadius)
{
Type = PhysicalCoordinateType.LinearTVTissue;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.LinearTVTissue)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.LinearTVTissue}, source type:{type}");
}
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
var width = reader.ReadDouble();
var beamPosition = reader.ReadDouble();
var zeroRadius = reader.ReadDouble();
result = new VinnoLinearTVTissuePhysicalCoordinate(depthEnd, depthStart, width, beamPosition, zeroRadius);
}
return result;
}
}
internal class VinnoDopplerPhysicalCoordinate : VinnoTimeMotionPhysicalCoordinate
{
public double BaseLine { get; }
public VinnoDopplerPhysicalCoordinate(double sweepSpeed, double max, double min, double baseLine)
: base(sweepSpeed, max, min)
{
Type = PhysicalCoordinateType.Doppler;
BaseLine = baseLine;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(BaseLine);
result = stream.ToArray();
}
return result;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.Doppler)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.Doppler}, source type:{type}");
}
var min = reader.ReadDouble();
var max = reader.ReadDouble();
var sweepSpeed = reader.ReadDouble();
var baseLine = reader.ReadDouble();
result = new VinnoDopplerPhysicalCoordinate(sweepSpeed, max, min, baseLine);
}
return result;
}
}
internal class VinnoTissueTimeMotionPhysicalCoordinate : VinnoTimeMotionPhysicalCoordinate
{
public double DepthStart { get; }
public double DepthEnd { get; }
public VinnoTissueTimeMotionPhysicalCoordinate(double sweepSpeed, double max, double min, double depthStart, double depthEnd)
: base(sweepSpeed, max, min)
{
Type = PhysicalCoordinateType.TissueTimeMotion;
DepthEnd = depthEnd;
DepthStart = depthStart;
}
public override byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var baseData = base.ToBytes();
stream.Write(baseData, 0, baseData.Length);
stream.Position = stream.Length;
var writer = new VinnoStreamWriter(stream);
writer.WriteDouble(DepthStart);
writer.WriteDouble(DepthEnd);
result = stream.ToArray();
}
return result;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.TissueTimeMotion)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.TissueTimeMotion}, source type:{type}");
}
var min = reader.ReadDouble();
var max = reader.ReadDouble();
var sweepSpeed = reader.ReadDouble();
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
result = new VinnoTissueTimeMotionPhysicalCoordinate(sweepSpeed, max, min, depthStart, depthEnd);
}
return result;
}
}
internal class VinnoMAMPhysicalCoordinate : VinnoTissueTimeMotionPhysicalCoordinate
{
public VinnoMAMPhysicalCoordinate(double sweepSpeed, double max, double min, double depthStart, double depthEnd)
: base(sweepSpeed, max, min, depthStart, depthEnd)
{
Type = PhysicalCoordinateType.MAM;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.MAM)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.MAM}, source type:{type}");
}
var min = reader.ReadDouble();
var max = reader.ReadDouble();
var sweepSpeed = reader.ReadDouble();
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
result = new VinnoMAMPhysicalCoordinate(sweepSpeed, max, min, depthStart, depthEnd);
}
return result;
}
}
internal class VinnoPWVPhysicalCoordinate : VinnoTissueTimeMotionPhysicalCoordinate
{
public VinnoPWVPhysicalCoordinate(double sweepSpeed, double max, double min, double depthStart, double depthEnd)
: base(sweepSpeed, max, min, depthStart, depthEnd)
{
Type = PhysicalCoordinateType.PWV;
}
public new static VinnoPhysicalCoordinate FromBytes(byte[] bytes)
{
VinnoPhysicalCoordinate result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var type = (PhysicalCoordinateType)reader.ReadByte();
if (type != PhysicalCoordinateType.PWV)
{
throw new InvalidCastException($"Type not matched, target type:{PhysicalCoordinateType.PWV}, source type:{type}");
}
var min = reader.ReadDouble();
var max = reader.ReadDouble();
var sweepSpeed = reader.ReadDouble();
var depthStart = reader.ReadDouble();
var depthEnd = reader.ReadDouble();
result = new VinnoPWVPhysicalCoordinate(sweepSpeed, max, min, depthStart, depthEnd);
}
return result;
}
}
internal class Vinno2DVisual : VinnoVisual
{
///
/// Gets all LogicalCoordinates of this visual.
///
public Dictionary LogicalCoordinates { get; }
///
/// Gets all PhysicalCoordinates of this visual.
///
public Dictionary PhysicalCoordinates { get; }
public Vinno2DVisual()
{
VisualType = VinnoVisualType.V2D;
LogicalCoordinates = new Dictionary();
PhysicalCoordinates = new Dictionary();
}
public override byte[] ToBytes()
{
var baseData = base.ToBytes();
byte[] result;
using (var stream = new MemoryStream())
{
stream.Write(baseData, 0, baseData.Length);
var writer = new VinnoStreamWriter(stream);
writer.WriteByte((byte)PhysicalCoordinates.Count);
foreach (var key in PhysicalCoordinates.Keys)
{
writer.WriteByte((byte)key);
writer.WriteBytes(PhysicalCoordinates[key].ToBytes());
}
writer.WriteByte((byte)LogicalCoordinates.Count);
foreach (var key in LogicalCoordinates.Keys)
{
writer.WriteByte((byte)key);
writer.WriteBytes(LogicalCoordinates[key].ToBytes());
}
result = stream.ToArray();
}
return result;
}
public new static VinnoVisual FromBytes(byte[] bytes)
{
Vinno2DVisual result = null;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var visualType = (VinnoVisualType)reader.ReadByte();
var displayMode = (VinnoDisplayMode)reader.ReadByte();
if (visualType == VinnoVisualType.V2D)
{
var indicator = (VinnoVisualIndicator)reader.ReadByte();
var activeModeType = (VinnoModeType)reader.ReadByte();
var modeCount = reader.ReadByte();
var modes = new List();
for (var i = 0; i < modeCount; i++)
{
var mode = VinnoMode.FromBytes(reader.ReadBytes());
modes.Add(mode);
}
result = new Vinno2DVisual { Indicator = indicator };
foreach (var mode in modes)
{
result.Modes.Add(mode);
}
result.ActiveModeType = activeModeType;
var physicalCoordinateCount = reader.ReadByte();
var physicalCoordinates = new Dictionary();
for (var i = 0; i < physicalCoordinateCount; i++)
{
var visualAreaType = (VinnoVisualAreaType)reader.ReadByte();
var physicalCoordinate = VinnoPhysicalCoordinate.FromBytes(reader.ReadBytes());
physicalCoordinates.Add(visualAreaType, physicalCoordinate);
}
var logicalCoordinateCount = reader.ReadByte();
var logicalCoordinates = new Dictionary();
for (var i = 0; i < logicalCoordinateCount; i++)
{
var visualAreaType = (VinnoVisualAreaType)reader.ReadByte();
var logicalCoordinate = VinnoLogicalCoordinate.FromBytes(reader.ReadBytes());
logicalCoordinates.Add(visualAreaType, logicalCoordinate);
}
foreach (var key in physicalCoordinates.Keys)
{
result.PhysicalCoordinates.Add(key, physicalCoordinates[key]);
}
foreach (var key in logicalCoordinates.Keys)
{
result.LogicalCoordinates.Add(key, logicalCoordinates[key]);
}
result.DisplayMode = displayMode;
}
}
return result;
}
}
internal enum VinnoAreaIndicator
{
Global = 0,
A,
B,
C,
ThreeD
}
internal class VinnoTissue3DArea
{
public VinnoRect Bounds { get; }
public double CmPerPixel { get; }
public VinnoPoint GlobalOffset { get; }
public VinnoAreaIndicator Indicator { get; }
public VinnoTissue3DArea(VinnoRect bounds, double cmPerPixel, VinnoPoint globalOffset, VinnoAreaIndicator indicator)
{
Indicator = indicator;
GlobalOffset = globalOffset;
CmPerPixel = cmPerPixel;
Bounds = bounds;
}
public byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteByte((byte)Indicator);
writer.WriteDouble(CmPerPixel);
writer.WriteDouble(GlobalOffset.X);
writer.WriteDouble(GlobalOffset.Y);
writer.WriteDouble(Bounds.Left);
writer.WriteDouble(Bounds.Top);
writer.WriteDouble(Bounds.Right);
writer.WriteDouble(Bounds.Bottom);
result = stream.ToArray();
}
return result;
}
public static VinnoTissue3DArea FromBytes(byte[] tissue3DAreaData)
{
VinnoTissue3DArea result;
using (var stream = new MemoryStream(tissue3DAreaData))
{
var reader = new VinnoStreamReader(stream);
var indicator = (VinnoAreaIndicator)reader.ReadByte();
var cmPerPixel = reader.ReadDouble();
var x = reader.ReadDouble();
var y = reader.ReadDouble();
var globalOffset = new VinnoPoint(x, y);
var left = reader.ReadDouble();
var top = reader.ReadDouble();
var right = reader.ReadDouble();
var bottom = reader.ReadDouble();
var bounds = new VinnoRect(new VinnoPoint(left, top), new VinnoPoint(right, bottom));
result = new VinnoTissue3DArea(bounds, cmPerPixel, globalOffset, indicator);
}
return result;
}
}
internal class Vinno3DVisual : VinnoVisual
{
///
/// Gets the tissue 3d areas for this visual.
///
public IList Tissue3DAreas { get; }
public Vinno3DVisual()
{
VisualType = VinnoVisualType.V3D;
Tissue3DAreas = new List();
}
public override byte[] ToBytes()
{
var baseData = base.ToBytes();
byte[] result;
using (var stream = new MemoryStream())
{
stream.Write(baseData, 0, baseData.Length);
var writer = new VinnoStreamWriter(stream);
writer.WriteByte((byte)Tissue3DAreas.Count);
foreach (var tissue3DArea in Tissue3DAreas)
{
writer.WriteBytes(tissue3DArea.ToBytes());
}
result = stream.ToArray();
}
return result;
}
public new static VinnoVisual FromBytes(byte[] bytes)
{
Vinno3DVisual result = null;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var visualType = (VinnoVisualType)reader.ReadByte();
var displayMode = (VinnoDisplayMode)reader.ReadByte();
if (visualType == VinnoVisualType.V3D)
{
var indicator = (VinnoVisualIndicator)reader.ReadByte();
result = new Vinno3DVisual { Indicator = indicator };
var activeModeType = (VinnoModeType)reader.ReadByte();
var modeCount = reader.ReadByte();
var modes = new List();
for (int i = 0; i < modeCount; i++)
{
var mode = VinnoMode.FromBytes(reader.ReadBytes());
modes.Add(mode);
}
foreach (var mode in modes)
{
result.Modes.Add(mode);
}
result.ActiveModeType = activeModeType;
var tissue3DAreaCount = reader.ReadByte();
var tissue3DAreas = new List();
for (int i = 0; i < tissue3DAreaCount; i++)
{
var tissue3DArea = VinnoTissue3DArea.FromBytes(reader.ReadBytes());
tissue3DAreas.Add(tissue3DArea);
}
foreach (var tissue3DArea in tissue3DAreas)
{
result.Tissue3DAreas.Add(tissue3DArea);
}
result.DisplayMode = displayMode;
}
}
return result;
}
}
public class VinnoVisual
{
///
/// Gets or sets the Display mode of this image.
///
public VinnoDisplayMode DisplayMode { get; set; }
///
/// Gets the visual type of this Visual.
///
protected VinnoVisualType VisualType;
///
/// Gets or sets the Indicator of this Visual.
///
public VinnoVisualIndicator Indicator { get; set; }
///
/// Gets or set the active mode type of this visual.
///
public VinnoModeType ActiveModeType { get; set; }
///
/// Gets all modse of this visual.
///
public IList Modes { get; }
public VinnoVisual()
{
ActiveModeType = VinnoModeType.Undefined;
Modes = new List();
//Default is A
Indicator = VinnoVisualIndicator.A;
//Default is Normal
DisplayMode = VinnoDisplayMode.Normal;
}
public virtual byte[] ToBytes()
{
byte[] result;
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
writer.WriteByte((byte)VisualType);
writer.WriteByte((byte)DisplayMode);
writer.WriteByte((byte)Indicator);
writer.WriteByte((byte)ActiveModeType);
writer.WriteByte((byte)Modes.Count);
foreach (var mode in Modes)
{
writer.WriteBytes(mode.ToBytes());
}
result = stream.ToArray();
}
return result;
}
public static VinnoVisual FromBytes(byte[] bytes)
{
VinnoVisual result = null;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var visualType = (VinnoVisualType)reader.ReadByte();
if (visualType == VinnoVisualType.V2D)
{
result = Vinno2DVisual.FromBytes(bytes);
}
if (visualType == VinnoVisualType.V3D)
{
result = Vinno3DVisual.FromBytes(bytes);
}
}
return result;
}
}
internal class VinnoImage : IImageDataContainer
{
///
/// Gets the index of this image.
///
public int Index { get; }
///
/// Gets the width of this image data.
///
public int Width { get; }
///
/// Gets the height of this image data.
///
public int Height { get; }
///
/// Gets the image data of this image.
///
public byte[] ImageData { get; private set; }
///
/// Gets all visuals of this image.
///
public IList Visuals { get; }
///
/// Implement the interface for update the image data.
///
byte[] IImageDataContainer.ImageData
{
get => ImageData;
set => ImageData = value;
}
public VinnoImage(int index, int width, int height, byte[] imageData)
{
Visuals = new List();
Index = index;
Width = width;
Height = height;
ImageData = imageData;
}
///
/// Convert image to bytes.
///
/// The converted bytes.
public byte[] ToBytes()
{
byte[] result = new byte[0];
using (var stream = new MemoryStream())
{
var writer = new VinnoStreamWriter(stream);
if (writer != null)
{
writer.WriteInt(Index);
writer.WriteByte((byte)Visuals.Count);
foreach (var visual in Visuals)
{
var buffer = visual?.ToBytes();
if (buffer != null)
{
writer.WriteBytes(buffer);
}
}
writer.WriteShort((short)Width);
writer.WriteShort((short)Height);
writer.WriteBytes(ImageData);
result = stream.ToArray();
}
}
return result;
}
///
/// Convert bytes to a
///
/// The bytes to be converted.
/// The converted
public static VinnoImage FromBytes(byte[] bytes)
{
VinnoImage result;
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var index = reader.ReadInt();
var visualCount = reader.ReadByte();
var visuals = new List();
for (int i = 0; i < visualCount; i++)
{
var visual = VinnoVisual.FromBytes(reader.ReadBytes());
visuals.Add(visual);
}
var widht = reader.ReadShort();
var height = reader.ReadShort();
var imageData = reader.ReadBytes();
result = new VinnoImage(index, widht, height, imageData);
foreach (var visual in visuals)
{
result.Visuals.Add(visual);
}
}
return result;
}
}
internal class VinnoImageData : IDisposable
{
private readonly OperationMode _operationMode;
private readonly Stream _stream;
private readonly VinnoStreamReader _reader;
private readonly VinnoStreamWriter _writer;
private readonly string _filePath;
private readonly List _imagePositionList;
private bool _disposed;
private bool _closed;
private readonly object _addGetLocker = new object();
private const string Header = "VINNO IMAGE DATA";
private const string CacheHeader = "VINNOIMGCACHE";
///
/// Gets the version of this image data.
///
public int Version { get; }
///
/// Gets the image count of this image data.
///
public int ImageCount { get; private set; }
///
/// Gets the probe information.
///
public VinnoProbe Probe { get; private set; }
///
/// Gets the image format of this image data.
///
public VidImageFormat ImageFormat { get; }
///
/// Gets or sets the extended data.
///
public byte[] ExtendedData { get; set; }
///
/// Create a VINNO Image Data.
///
/// The file path to read or create.
/// The operation mode, create to create a vid file, open to open a vid file.
public VinnoImageData(string filePath, OperationMode mode)
{
try
{
ImageFormat = VidImageFormat.Jpeg;
_filePath = filePath;
_operationMode = mode;
ExtendedData = new byte[0];
if (mode == OperationMode.Create)
{
//Create temp file.
var tempFile = _filePath + ".tmp";
_stream = new FileStream(tempFile, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
_writer = new VinnoStreamWriter(_stream);
Version = 3;
Probe = null;
_imagePositionList = new List();
ImageCount = 0;
}
else
{
if (!File.Exists(_filePath) && File.Exists(_filePath + ".tmp"))
{
_filePath = _filePath + ".tmp";
}
_stream = new FileStream(_filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
_reader = new VinnoStreamReader(_stream);
var header = _reader.ReadString();
if (header != Header && header != CacheHeader)
{
_stream.Dispose();
throw new InvalidDataException("File is not a VID file.");
}
Version = _reader.ReadInt();
//Get probe info
var probeData = _reader.ReadBytes();
Probe = VinnoProbe.FromBytes(probeData);
ImageFormat = (VidImageFormat)_reader.ReadInt();
ExtendedData = _reader.ReadBytes();
//Get the index list.
_imagePositionList = new List(_reader.ReadLongs());
ImageCount = _imagePositionList.Count;
}
}
catch (Exception ex)
{
_stream?.Dispose();
}
}
///
/// Create a VINNO Image Data.
///
///
public VinnoImageData(Stream stream)
{
try
{
ImageFormat = VidImageFormat.Jpeg;
ExtendedData = new byte[0];
_stream = stream;
_reader = new VinnoStreamReader(_stream);
var header = _reader.ReadString();
if (header != Header)
{
_stream.Dispose();
throw new InvalidDataException("File is not a VID file.");
}
Version = _reader.ReadInt();
//Get probe info
var probeData = _reader.ReadBytes();
Probe = VinnoProbe.FromBytes(probeData);
ImageFormat = (VidImageFormat)_reader.ReadInt();
ExtendedData = _reader.ReadBytes();
//Get the index list.
_imagePositionList = new List(_reader.ReadLongs());
ImageCount = _imagePositionList.Count;
}
catch (Exception ex)
{
_stream?.Dispose();
}
}
///
/// Add probe info into vid.
///
///
public void AddProbe(VinnoProbe probe)
{
Probe = probe;
}
///
/// Add dicom info into vid
///
///
public void AddExtendedData(byte[] extendedData)
{
ExtendedData = extendedData;
}
///
/// Add one image into vid.
///
///
public void AddImage(VinnoImage image)
{
if (_closed)
{
throw new InvalidOperationException("ImageData closed.");
}
if (_operationMode != OperationMode.Create)
{
throw new InvalidOperationException("Can not add image under open mode.");
}
lock (_addGetLocker)
{
var postion = _stream.Position;
_writer.WriteBytes(image.ToBytes());
_imagePositionList.Add(postion);
ImageCount++;
}
}
///
/// Gets one image from the vid.
///
///
///
public VinnoImage GetImage(int index)
{
if (_closed)
{
throw new InvalidOperationException("ImageData closed.");
}
if (_operationMode != OperationMode.Open)
{
throw new InvalidOperationException("Can not open image under create mode.");
}
if (index >= ImageCount || index < 0)
{
throw new IndexOutOfRangeException("Can not find image Data");
}
lock (_addGetLocker)
{
//Jump to image.
_stream.Position = _imagePositionList[index];
var imageData = _reader.ReadBytes();
return VinnoImage.FromBytes(imageData);
}
}
public void Close()
{
if (!_closed)
{
lock (_addGetLocker)
{
if (_operationMode == OperationMode.Create && !string.IsNullOrWhiteSpace(_filePath) && ImageCount > 0)
{
using (var stream = File.Create(_filePath))
{
var writer = new VinnoStreamWriter(stream);
writer.WriteString(Header);
writer.WriteInt(Version);
writer.WriteBytes(Probe.ToBytes());
writer.WriteInt((int)ImageFormat);
writer.WriteBytes(ExtendedData);
//Position data length = imagecount(int 4bytes) + imagecount * positionSize(long 8bytes)
var positionsDataLength = _imagePositionList.Count * sizeof(long) + 4;
var offset = stream.Length + positionsDataLength;
for (var i = 0; i < _imagePositionList.Count; i++)
{
_imagePositionList[i] = _imagePositionList[i] + offset;
}
writer.WriteLongs(_imagePositionList.ToArray());
_stream.Position = 0;
_stream.CopyTo(stream);
}
}
_stream?.Dispose();
if (_operationMode == OperationMode.Create && !string.IsNullOrWhiteSpace(_filePath))
{
var tempFile = _filePath + ".tmp";
File.Delete(tempFile);
}
}
_closed = true;
}
}
protected void Dispose(bool disposing)
{
if (!_disposed)
{
Close();
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
///
/// 扫描方位 左侧或右侧
///
public enum ScanPosition
{
Left,
Right,
Fusion
}
public class Vinno3DPhysicalData
{
///
/// Get thyroid scan position.
///
public ScanPosition ScanPosition { get; }
///
/// Get vinno visual.
///
public IList VinnoVisuals { get; }
///
/// Get vinno visual.
///
public VinnoProbe VinnoProbe { get; }
public Vinno3DPhysicalData(ScanPosition scanPosition, VinnoProbe vinnoProbe, IList vinnoVisuals)
{
ScanPosition = scanPosition;
VinnoProbe = vinnoProbe;
VinnoVisuals = vinnoVisuals;
}
///
/// From bytes.
///
/// bytes.
/// Instance of vinno carotid 3d physical data.
public static Vinno3DPhysicalData FromBytes(byte[] bytes)
{
using (var stream = new MemoryStream(bytes))
{
stream.Position = 0;
var reader = new VinnoStreamReader(stream);
var thyroidType = (ScanPosition)reader.ReadByte();
var probe = VinnoProbe.FromBytes(reader.ReadBytes());
var visualCount = reader.ReadByte();
var visuals = new List();
for (int i = 0; i < visualCount; i++)
{
var visual = VinnoVisual.FromBytes(reader.ReadBytes()); // 全部为null
visuals.Add(visual);
}
return new Vinno3DPhysicalData(thyroidType, probe, visuals);
}
}
}
}