Exemple #1
0
        internal CompressedVolume(VolumeMetadata metadata, VolumeCompressionOptions options, DirectionMap compressedData) : base(metadata)
        {
            if (compressedData[Direction.Z] == null)
            {
                throw new NotSupportedException(Resources.GetResource <Volume>("CompressedDataMissing_ErrorText"));
            }

            _CompressedData    = compressedData;
            CompressionOptions = options;
        }
        /// <summary>
        /// Compresses the volume with the specified compression options.
        /// </summary>
        /// <param name="options"></param>
        /// <param name="multiDirection"></param>
        /// <param name="progress">A progress indicator, which reports the current slice number.</param>
        /// <param name="ct"></param>
        /// <exception cref="VolumeException">Error during encoding</exception>
        public CompressedVolume Compress(VolumeCompressionOptions options, bool multiDirection = false, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken))
        {
            var directionMap = new DirectionMap {
                [Direction.Z] = CompressDirection(Direction.Z, options, progress, ct)
            };

            if (multiDirection)
            {
                directionMap[Direction.X] = CompressDirection(Direction.X, options, progress, ct);
                directionMap[Direction.Y] = CompressDirection(Direction.Y, options, progress, ct);
            }

            return(new CompressedVolume(Metadata, options, directionMap));
        }
        /// <summary>
        /// Compresses the volume with the specified compression options.
        /// </summary>
        /// <param name="progress">A progress indicator, which reports the current slice number.</param>
        /// <param name="ct"></param>
        /// <param name="direction"></param>
        /// <param name="options">Codec settings</param>
        /// <exception cref="VolumeException">Error during encoding</exception>
        /// <exception cref="NotSupportedException">The volume has no decompressed data</exception>
        private byte[] CompressDirection(Direction direction, VolumeCompressionOptions options, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken))
        {
            using (var outputStream = new MemoryStream())
            {
                GetEncodedSliceSize(Metadata, direction, out var encodingSizeX, out var encodingSizeY);

                var inputStreamWrapper  = new SliceReader(Metadata, Data, direction, progress, ct);
                var outputStreamWrapper = new StreamWrapper(outputStream);

                var error = ( VolumeError )CompressVolume(inputStreamWrapper.Interop, outputStreamWrapper.Interop, encodingSizeX, encodingSizeY, options.Encoder, options.PixelFormat, options.GetOptionsString(), options.Bitrate);

                if (error != VolumeError.Success)
                {
                    throw new VolumeException(error, Resources.FormatResource <Volume>("Compression_ErrorText", error));
                }

                return(outputStream.ToArray());
            }
        }
        internal static VolumeCompressionOptions Deserialize(Stream stream)
        {
            var settings = new XmlReaderSettings
            {
                IgnoreComments               = true,
                IgnoreWhitespace             = true,
                IgnoreProcessingInstructions = true,
                CloseInput = false,
                NameTable  = new NameTable()
            };

            using (var reader = XmlReader.Create(stream, settings))
            {
                var result = new VolumeCompressionOptions();
                reader.MoveToElement();
                while (reader.Read())
                {
                    switch (reader.Name)
                    {
                    case "Encoder":
                        result.Encoder = reader.ReadString();
                        break;

                    case "EncoderOptions":
                        result.EncoderOptions = OptionsFromString(reader.ReadString());
                        break;

                    case "PixelFormat":
                        result.PixelFormat = reader.ReadString();
                        break;

                    case "Bitrate":
                        result.Bitrate = int.Parse(reader.ReadString(), NumberStyles.Integer, CultureInfo.InvariantCulture);
                        break;
                    }
                }

                return(result);
            }
        }
Exemple #5
0
        /// <summary>
        /// Creates a new, decompressed volume from the specified data
        /// </summary>
        /// <param name="metadata">Describes the volumes size and resolution</param>
        /// <param name="data">The decompressed volume as 8-Bit grayscale values. The array dimensions must match the specified <paramref name="metadata"/> (byte[z][x*y]).</param>
        /// <param name="multiDirection"></param>
        /// <param name="progress">A progress indicator, which reports the current slice number.</param>
        /// <param name="options">Codec settings</param>
        /// <param name="ct"></param>
        /// <exception cref="IndexOutOfRangeException">The specified data did not match the dimensions of the specified <paramref name="metadata"/>.</exception>
        /// <exception cref="VolumeException">Error during encoding</exception>
        public static CompressedVolume CreateCompressed(VolumeMetadata metadata, byte[][] data, VolumeCompressionOptions options, bool multiDirection = false, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken))
        {
            var volume = new UncompressedVolume(metadata, data);

            return(volume.Compress(options, multiDirection, progress, ct));
        }
Exemple #6
0
        /// <summary>
        /// Loads volume data from the specified data stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <returns></returns>
        /// <exception cref="VolumeException">Error during decoding</exception>
        /// <exception cref="NotSupportedException">The volume has no compressed data</exception>
        /// <exception cref="InvalidOperationException">One or more entries are missing in the archive.</exception>
        public static CompressedVolume Load(Stream stream)
        {
            if (!stream.CanSeek)
            {
                stream = new MemoryStream(stream.StreamToArray());
            }

            VolumeMetadata           metaData;
            DirectionMap             directionMap = new DirectionMap();
            VolumeCompressionOptions compressionOptions;

            using (var archive = new ZipArchive(stream))
            {
                #region Metadata

                var metaDataEntry = archive.GetEntry("Metadata.xml");
                if (metaDataEntry == null)
                {
                    throw new InvalidOperationException(Resources.FormatResource <Volume>("InvalidFormatMissingFile_ErrorText", "Metadata.xml"));
                }

                using (var entryStream = metaDataEntry.Open())
                {
                    metaData = VolumeMetadata.Deserialize(entryStream);
                    if (metaData.FileVersion > FileVersion)
                    {
                        throw new InvalidOperationException(Resources.FormatResource <Volume>("FileVersionError_Text", metaData.FileVersion, FileVersion));
                    }
                }

                #endregion

                #region CompressionOptions

                var compressionOptionsEntry = archive.GetEntry("CompressionOptions.xml");

                if (compressionOptionsEntry != null)
                {
                    using (var entryStream = compressionOptionsEntry.Open())
                    {
                        compressionOptions = VolumeCompressionOptions.Deserialize(entryStream);
                    }
                }
                else
                {
                    compressionOptions = null;
                }

                #endregion

                #region Voxels

                var dataEntry = archive.GetEntry("Voxels.dat");
                if (dataEntry == null)
                {
                    dataEntry = archive.GetEntry("VoxelsZ.dat");
                    if (dataEntry == null)
                    {
                        throw new InvalidOperationException(Resources.FormatResource <Volume>("InvalidFormatMissingFile_ErrorText", "Voxels.dat"));
                    }

                    using (var entryStream = dataEntry.Open())
                    {
                        directionMap[Direction.Z] = entryStream.StreamToArray();
                    }

                    dataEntry = archive.GetEntry("VoxelsY.dat");
                    if (dataEntry != null)
                    {
                        using (var entryStream = dataEntry.Open())
                        {
                            directionMap[Direction.Y] = entryStream.StreamToArray();
                        }
                    }

                    dataEntry = archive.GetEntry("VoxelsX.dat");
                    if (dataEntry != null)
                    {
                        using (var entryStream = dataEntry.Open())
                        {
                            directionMap[Direction.X] = entryStream.StreamToArray();
                        }
                    }
                }
                else
                {
                    using (var entryStream = dataEntry.Open())
                    {
                        directionMap[Direction.Z] = entryStream.StreamToArray();
                    }
                }

                #endregion
            }

            return(new CompressedVolume(metaData, compressionOptions, directionMap));
        }
Exemple #7
0
        /// <summary>
        /// Creates a new, decompressed volume from the specified data
        /// </summary>
        /// <param name="metadata">Holds additional information about a volume</param>
        /// <param name="stream">A stream to the slice data</param>
        /// <param name="options">Codec settings</param>
        /// <param name="progress">A progress indicator, which reports the current slice number.</param>
        /// <param name="ct"></param>
        /// <exception cref="VolumeException">Error during encoding</exception>
        public static Volume CreateCompressed(VolumeMetadata metadata, Stream stream, VolumeCompressionOptions options, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken))
        {
            var compressedData = CompressStream(stream, Direction.Z, metadata, options, progress, ct);
            var dirctionMap    = new DirectionMap
            {
                [Direction.Z] = compressedData
            };

            return(new CompressedVolume(metadata, options, dirctionMap));
        }
        /// <summary>
        /// Compresses and saves the volume in the specified stream.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="options">The options.</param>
        /// <param name="multiDirection">if set to <c>true</c> [multi direction].</param>
        /// <param name="progress">The progress.</param>
        /// <param name="ct">The ct.</param>
        public void Save(Stream stream, VolumeCompressionOptions options, bool multiDirection = false, IProgress <VolumeSliceDefinition> progress = null, CancellationToken ct = default(CancellationToken))
        {
            var compressed = Compress(options, multiDirection, progress, ct);

            compressed.Save(stream);
        }