/// <inheritdoc /> /// <exception cref="NotSupportedException">The volume has no compressed data</exception> public override VolumeSliceCollection GetSliceRanges(IReadOnlyCollection <VolumeSliceRangeDefinition> ranges, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken)) { if (ranges == null) { throw new ArgumentNullException(nameof(ranges)); } if (ranges.Count == 0) { return(new VolumeSliceCollection()); } var combinedRanges = ranges.Merge().ToArray(); //Partial scan in directed compressed volumes if (combinedRanges.All(r => _CompressedData[r.Direction] != null) && combinedRanges.Length <= Constants.RangeNumberLimitForEfficientScan && combinedRanges.Sum(r => r.Last - r.First + 1) < Constants.SliceNumberLimitForEfficientScan) { return(new VolumeSliceCollection(ranges.Select(range => GetSliceRange(range)))); } var direction = combinedRanges.First().Direction; //Full scan in directed volume in case all ranges have this direction. Scan performance is the same, but copy is more efficient if (_CompressedData[direction] == null || combinedRanges.Any(r => r.Direction != direction)) { direction = Direction.Z; } if (_CompressedData[direction] == null) { throw new NotSupportedException(Resources.GetResource <Volume>("CompressedDataMissing_ErrorText")); } using (var input = new MemoryStream(_CompressedData[direction], false)) { var inputWrapper = new StreamWrapper(input); var rangeReader = new VolumeSliceRangeCollector(Metadata, direction, combinedRanges, progress, ct); var error = ( VolumeError )DecompressVolume(inputWrapper.Interop, rangeReader.Interop); if (error != VolumeError.Success) { throw new VolumeException(error, Resources.FormatResource <Volume>("Decompression_ErrorText", error)); } return(rangeReader.GetSliceRangeCollection()); } }
/// <inheritdoc /> /// <exception cref="NotSupportedException">The volume has no compressed data</exception> public override VolumeSlice GetSlice(VolumeSliceDefinition slice, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken)) { //Videos with a very small number of frames appearantly have issues with av_seek, so we do a full scan instead if (_CompressedData[slice.Direction] != null) { using (var input = new MemoryStream(_CompressedData[slice.Direction])) { var inputWrapper = new StreamWrapper(input); var outputWrapper = new VolumeSliceRangeCollector(Metadata, slice.Direction, new[] { new VolumeSliceRangeDefinition(slice.Direction, slice.Index, slice.Index) }, progress, ct); var error = ( VolumeError )DecompressSlices(inputWrapper.Interop, outputWrapper.Interop, slice.Index, 1); if (error != VolumeError.Success) { throw new VolumeException(error, Resources.FormatResource <Volume>("Decompression_ErrorText", error)); } return(outputWrapper.GetSlice(slice.Direction, slice.Index)); } } if (_CompressedData[Direction.Z] == null) { throw new NotSupportedException(Resources.GetResource <Volume>("CompressedDataMissing_ErrorText")); } using (var input = new MemoryStream(_CompressedData[Direction.Z])) { var inputWrapper = new StreamWrapper(input); var rangeReader = new VolumeSliceRangeCollector(Metadata, Direction.Z, new[] { new VolumeSliceRangeDefinition(slice.Direction, slice.Index, slice.Index) }, progress, ct); var error = ( VolumeError )DecompressVolume(inputWrapper.Interop, rangeReader.Interop); if (error != VolumeError.Success) { throw new VolumeException(error, Resources.FormatResource <Volume>("Decompression_ErrorText", error)); } return(rangeReader.GetSlice(slice.Direction, slice.Index)); } }
/// <inheritdoc /> /// <exception cref="NotSupportedException">The volume has no compressed data</exception> public override VolumeSliceRange GetSliceRange(VolumeSliceRangeDefinition range, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken)) { if (_CompressedData[range.Direction] != null) { using (var input = new MemoryStream(_CompressedData[range.Direction], false)) { var inputWrapper = new StreamWrapper(input); var rangeReader = new VolumeSliceRangeCollector(Metadata, range.Direction, new[] { range }, progress, ct); var error = ( VolumeError )DecompressSlices(inputWrapper.Interop, rangeReader.Interop, range.First, ( ushort )(range.Last - range.First + 1)); if (error != VolumeError.Success) { throw new VolumeException(error, Resources.FormatResource <Volume>("Decompression_ErrorText", error)); } return(rangeReader.GetSliceRange(range)); } } if (_CompressedData[Direction.Z] == null) { throw new NotSupportedException(Resources.GetResource <Volume>("CompressedDataMissing_ErrorText")); } using (var input = new MemoryStream(_CompressedData[Direction.Z], false)) { var inputWrapper = new StreamWrapper(input); var rangeReader = new VolumeSliceRangeCollector(Metadata, Direction.Z, new[] { range }, progress, ct); var error = ( VolumeError )DecompressVolume(inputWrapper.Interop, rangeReader.Interop); if (error != VolumeError.Success) { throw new VolumeException(error, Resources.FormatResource <Volume>("Decompression_ErrorText", error)); } return(rangeReader.GetSliceRange(range)); } }