using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace fis.Vid { public class VinnoCameraExtendedData:IDisposable { private readonly OperationMode _operationMode; private readonly Stream _stream; private readonly VinnoStreamReader _reader; private readonly VinnoStreamWriter _writer; private readonly string _filePath; private bool _disposed; private bool _closed; private readonly List _imagePositionList; private readonly object _addGetLocker = new object(); private const string Header = "VINNO Camera Extended Data"; public int ImageCount { get; private set; } /// /// Create Mode /// /// public VinnoCameraExtendedData(string path) { _filePath = path + ".ced"; _operationMode = OperationMode.Create; _stream = new FileStream(_filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite); _writer = new VinnoStreamWriter(_stream); _imagePositionList = new List(); } /// /// Open Mode /// /// /// internal VinnoCameraExtendedData(string path,List positionList) { _filePath = path + ".ced"; _operationMode = OperationMode.Open; _stream = new FileStream(_filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite); _reader = new VinnoStreamReader(_stream); _imagePositionList = positionList; ImageCount = _imagePositionList.Count; } public void AddImage(VinnoImage image) { 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++; } } public VinnoImage GetImage(int index) { 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) { _stream.Dispose(); File.Delete(_filePath); } _closed = true; } } public void Dispose() { if (!_disposed) { Close(); GC.SuppressFinalize(this); _disposed = true; } } public byte[] ToBytes() { lock (_addGetLocker) { if (!_imagePositionList.Any()) { return new byte[0]; } using (var stream = new MemoryStream()) { var writer = new VinnoStreamWriter(stream); writer.WriteString(Header); writer.WriteLongs(_imagePositionList.ToArray()); _stream.Position = 0; _stream.CopyTo(stream); return stream.ToArray(); } } } public static VinnoCameraExtendedData FromBytes(byte[] bytes,string path) { using (var stream = new MemoryStream(bytes)) { stream.Position = 0; var reader = new VinnoStreamReader(stream); var header = reader.ReadString(); if (!string.Equals(header,Header)) { return null; } var imagePositions = reader.ReadLongs(); using (var fileStream = new FileStream(path + ".ced", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)) { var writer = new VinnoStreamWriter(fileStream); for (int i = 0; i < imagePositions.Length; i++) { writer.WriteBytes(reader.ReadBytes()); } } return new VinnoCameraExtendedData(path, imagePositions.ToList()); } } } }