示例#1
0
        private void CheckParameters(SerializerParameters parameters, out CompressAlgorithm algorithm)
        {
            if (!string.IsNullOrEmpty(parameters?.ContentEncoding))
            {
                switch (parameters.ContentEncoding)
                {
                case "identity":
                    algorithm = CompressAlgorithm.Identity;
                    return;

                case "deflate":
                    algorithm = CompressAlgorithm.Deflate;
                    return;

                case "gzip":
                    algorithm = CompressAlgorithm.GZip;
                    return;

                default:
                    throw new NotSupportedException("Compression algorithm not supported");
                }
            }

            algorithm = CompressAlgorithm.Identity;
        }
示例#2
0
        /// <summary>
        ///     Gets the correct arguments to pass to the compressor
        /// </summary>
        /// <param name="filePath">       The source file. </param>
        /// <param name="fileTempPath">  </param>
        /// <param name="algorithm">
        ///     Default is auto depend on file extension, others is force algorithm
        /// </param>
        /// <param name="qualityPercent"> Quality PercentSaving - Process </param>
        /// <returns> The <see cref="string" /> containing the correct command arguments. </returns>
        /// <exception cref="ArgumentException"> file path is invalid </exception>
        private static string GetArguments(string filePath, out string fileTempPath, CompressAlgorithm algorithm, int qualityPercent = 0)
        {
            fileTempPath = null;

            ImageCompressorHelper.CheckFilePath(filePath);

            qualityPercent = ImageCompressorHelper.GetQualityPercent(qualityPercent, algorithm);

            switch (algorithm)
            {
            case CompressAlgorithm.Gif:
            {
                return(GetGifCommand(filePath));
            }

            case CompressAlgorithm.Jpeg:
            {
                return(GetJpegCommand(filePath, out fileTempPath, qualityPercent));
            }

            case CompressAlgorithm.PngPrimary:
            {
                return(GetPngPrimaryCommand(filePath, qualityPercent));
            }
            }

            return(GetPngSecondaryCommand(filePath));
        }
示例#3
0
        public static byte[] Compress(byte[] data, CompressAlgorithm method = CompressAlgorithm.Deflate, CompressionLevel level = CompressionLevel.Optimal)
        {
            MemoryStream output = new MemoryStream();

            switch (method)
            {
            case CompressAlgorithm.Deflate:
            {
                using (DeflateStream dstream = new DeflateStream(output, level))
                {
                    dstream.Write(data, 0, data.Length);
                }
            }
            break;

            case CompressAlgorithm.Zstd:
            {
                var opt = new CompressionOptions(CompressionOptions.DefaultCompressionLevel);
                using (var compressor = new Compressor(opt))
                {
                    return(compressor.Wrap(data));
                }
            }
            }
            return(output.ToArray());
        }
示例#4
0
        public static byte[] Decompress(byte[] data, CompressAlgorithm method = CompressAlgorithm.Deflate)
        {
            MemoryStream input  = new MemoryStream(data);
            MemoryStream output = new MemoryStream();

            switch (method)
            {
            case CompressAlgorithm.Deflate:
            {
                using (DeflateStream dstream = new DeflateStream(input, CompressionMode.Decompress))
                {
                    dstream.CopyTo(output);
                }
            }
            break;

            case CompressAlgorithm.Zstd:
            {
                using (var decompressor = new Decompressor())
                {
                    return(decompressor.Unwrap(data));
                }
            }
            }
            return(output.ToArray());
        }
示例#5
0
        /// <summary>
        ///     Gets the correct arguments to pass to the compressor
        /// </summary>
        /// <param name="filePath">       The source file. </param>
        /// <param name="fileTempPath">  </param>
        /// <param name="algorithm">
        ///     Default is auto depend on file extension, others is force algorithm
        /// </param>
        /// <param name="qualityPercent"> Quality PercentSaving - Process </param>
        /// <returns> The <see cref="string" /> containing the correct command arguments. </returns>
        /// <exception cref="ArgumentException"> file path is invalid </exception>
        private static string GetArguments(string filePath, out string fileTempPath, CompressAlgorithm algorithm, int qualityPercent = 0)
        {
            fileTempPath = null;

            Helper.CheckFilePath(filePath);

            qualityPercent = Helper.GetQualityPercent(qualityPercent, algorithm);

            switch (algorithm)
            {
            case CompressAlgorithm.Png:
            {
                return(GetPngCommand(filePath, qualityPercent));
            }

            case CompressAlgorithm.Jpeg:
            {
                return(GetJpegCommand(filePath, out fileTempPath, qualityPercent));
            }

            case CompressAlgorithm.Gif:
            {
                return(GetGifCommand(filePath));
            }

            default:
                throw new NotSupportedException("The Compress Algorithm not support yet");
            }
        }
示例#6
0
        /// <summary>
        ///     Gets the correct arguments to pass to the compressor
        /// </summary>
        /// <param name="filePath">       The source file. </param>
        /// <param name="fileTempPaths">  </param>
        /// <param name="algorithm">
        ///     Default is auto depend on file extension, others is force algorithm
        /// </param>
        /// <param name="qualityPercent"> Quality PercentSaving - Process </param>
        /// <returns> The <see cref="string" /> containing the correct command arguments. </returns>
        /// <exception cref="ArgumentException"> file path is invalid </exception>
        private static string GetArguments(string filePath, CompressAlgorithm algorithm, out List <string> fileTempPaths, int qualityPercent = 0)
        {
            fileTempPaths = new List <string>();

            Helper.CheckFilePath(filePath);

            qualityPercent = Helper.GetQualityPercent(qualityPercent, algorithm);

            switch (algorithm)
            {
            case CompressAlgorithm.Jpeg:
            {
                var jpegCommand = GetJpegCommand(filePath, out var fileJpegTempPath, qualityPercent);
                fileTempPaths.Add(fileJpegTempPath);

                var jpegLosslessCommand = GetJpegLosslessCommand(filePath, out var fileJpegLossessTempPath);
                fileTempPaths.Add(fileJpegLossessTempPath);

                return($"{jpegCommand} && {jpegLosslessCommand}");
            }

            case CompressAlgorithm.Png:
            {
                return(GetPngCommand(filePath, qualityPercent));
            }

            case CompressAlgorithm.Gif:
            {
                return(GetGifCommand(filePath));
            }

            default:
                throw new NotSupportedException("The Compress Algorithm not support yet");
            }
        }
示例#7
0
        /// <summary>
        ///     Runs the process to optimize the image.
        /// </summary>
        /// <param name="stream">        </param>
        /// <param name="algorithm">
        ///     Default is auto depend on file extension, others is force algorithm
        /// </param>
        /// <param name="qualityPercent">
        ///     Quality of image after compress, 0 is default it mean auto quality by image type
        /// </param>
        /// <param name="timeout">        TimeoutMillisecond of process in millisecond </param>
        /// <returns> The Task containing processing information. </returns>
        /// <exception cref="ArgumentException"> stream is invalid image format </exception>
        private static ImageCompressResult Process(MemoryStream stream, CompressAlgorithm algorithm, int qualityPercent = 0, int timeout = 0)
        {
            bool isValidImage = ImageCompressorHelper.TryGetCompressImageType(stream, out var imageType);

            if (!isValidImage || imageType == CompressImageType.Invalid)
            {
                throw new ArgumentException($"{nameof(stream)} is invalid image format", nameof(stream));
            }

            // Create a source temporary file with the correct extension.
            var filePath = FileHelper.CreateTempFile(stream, imageType.AsString(EnumFormat.Description), out _);

            ImageCompressResult imageCompressResult = Process(filePath, algorithm, qualityPercent, timeout);

            if (imageCompressResult != null)
            {
                // update file type, because in process not update it
                imageCompressResult.FileType = imageType;
            }

            // Cleanup temp file
            FileHelper.SafeDelete(filePath);

            return(imageCompressResult);
        }
示例#8
0
        public CompressConnection(Connection connection, int maxReceiveCount, BufferManager bufferManager)
        {
            _connection      = connection;
            _maxReceiveCount = maxReceiveCount;
            _bufferManager   = bufferManager;

            _myCompressAlgorithm = CompressAlgorithm.Deflate;
        }
示例#9
0
 public CryptEncoder(CryptEncoderFactory encoderFactory, string key, string iv, CompressAlgorithm algorithm)
 {
     factory        = encoderFactory;
     this.key       = key;
     this.iv        = iv;
     innserEncoder  = factory.InnerMessageEncodingBindingElement.CreateMessageEncoderFactory().Encoder;
     this.algorithm = algorithm;
 }
        public CompressConnection(Connection connection, int maxReceiveCount, BufferManager bufferManager)
        {
            _connection = connection;
            _maxReceiveCount = maxReceiveCount;
            _bufferManager = bufferManager;

            _myCompressAlgorithm = CompressAlgorithm.Deflate;
        }
        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.  The Parameter
        /// property is typically used to configure the page.</param>

#if WINDOWS_PHONE_APP

        private void ShowFileOpen(CompressAlgorithm? Algorithm)
        {
            var picker = new FileOpenPicker();

            picker.FileTypeFilter.Add("*");

            picker.ContinuationData["Operation"] = "CompressFile";
            picker.ContinuationData["CompressAlgorithm"] = Algorithm.ToString(); 

            picker.PickSingleFileAndContinue();
        }
示例#12
0
        /// <summary>
        /// <see cref="Stream" />を圧縮/展開しながらコピーします。
        /// </summary>
        public static void CopyWithCompressionTo(this Stream stream,
                                                 Stream destination,
                                                 CompressionLevel compressionLevel,
                                                 CompressionMode compressionMode,
                                                 CompressAlgorithm compressAlgorithm = CompressAlgorithm.Deflate)
        {
            if (compressionLevel == CompressionLevel.NoCompression)
            {
                stream.CopyTo(destination);
            }
            else if (compressionMode == CompressionMode.Decompress)
            {
                switch (compressAlgorithm)
                {
                case CompressAlgorithm.Deflate:
                {
                    using var compressionStream = new DeflateStream(stream, CompressionMode.Decompress);
                    compressionStream.CopyTo(destination);
                    break;
                }

                case CompressAlgorithm.GZip:
                {
                    using var compressionStream = new GZipStream(stream, CompressionMode.Decompress);
                    compressionStream.CopyTo(destination);
                    break;
                }
                }
            }
            else
            {
                switch (compressAlgorithm)
                {
                case CompressAlgorithm.Deflate:
                {
                    using var compressionStream = new DeflateStream(destination, compressionLevel);
                    stream.CopyTo(compressionStream);
                    break;
                }

                case CompressAlgorithm.GZip:
                {
                    using var compressionStream = new GZipStream(destination, compressionLevel);
                    stream.CopyTo(compressionStream);
                    break;
                }
                }
            }
        }
 public CompressiveAesCryptor(string password,
                              int keySize                         = 256,
                              int iterationCount                  = 10000,
                              CipherMode cipherMode               = CipherMode.CBC,
                              CompressionLevel compressionLevel   = CompressionLevel.NoCompression,
                              CompressAlgorithm compressAlgorithm = CompressAlgorithm.Deflate)
 {
     _password      = Encoding.UTF8.GetBytes(password);
     KeySize        = keySize is 128 or 192 ? keySize : 256;
     IterationCount = iterationCount;
     Mode           = cipherMode;
     _aes           = new AesCng {
         Mode = Mode, Padding = PaddingMode.PKCS7
     };
     _blockSize        = _aes.BlockSize / 8;
     CompressionLevel  = compressionLevel;
     CompressAlgorithm = compressAlgorithm;
 }
示例#14
0
        public override void Connect(TimeSpan timeout, Information options)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }

            lock (this.ThisLock)
            {
                try
                {
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();

                    using (BufferStream stream = new BufferStream(_bufferManager))
                    {
                        byte[] buffer = NetworkConverter.GetBytes((uint)_myCompressAlgorithm);
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Flush();
                        stream.Seek(0, SeekOrigin.Begin);

                        _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout));
                    }

                    using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout)))
                    {
                        byte[] buffer = new byte[4];
                        stream.Read(buffer, 0, buffer.Length);

                        _otherCompressAlgorithm = (CompressAlgorithm)NetworkConverter.ToUInt32(buffer);
                    }
                }
                catch (ConnectionException ex)
                {
                    throw ex;
                }
                catch (Exception ex)
                {
                    throw new ConnectionException(ex.Message, ex);
                }

                _connect = true;
            }
        }
示例#15
0
        internal static CompressImageType GetCompressImageType(CompressAlgorithm compressAlgorithm)
        {
            var compressImageType = CompressImageType.Invalid;

            if (compressAlgorithm == CompressAlgorithm.Jpeg)
            {
                compressImageType = CompressImageType.Jpeg;
            }
            else if (compressAlgorithm == CompressAlgorithm.Png)
            {
                compressImageType = CompressImageType.Png;
            }
            else if (compressAlgorithm == CompressAlgorithm.Gif)
            {
                compressImageType = CompressImageType.Gif;
            }

            return(compressImageType);
        }
示例#16
0
        /// <summary>
        ///     Min 0 - max 99
        /// </summary>
        /// <param name="qualityPercent"></param>
        /// <param name="algorithm">     </param>
        /// <returns></returns>
        internal static int GetQualityPercent(int qualityPercent, CompressAlgorithm algorithm)
        {
            qualityPercent = qualityPercent < 0 ? 0 : (qualityPercent > 99 ? 99 : qualityPercent);

            if (qualityPercent <= 0)
            {
                switch (algorithm)
                {
                case CompressAlgorithm.PngPrimary:
                case CompressAlgorithm.PngSecondary:
                    qualityPercent = CompressConstants.DefaultPngQualityPercent;
                    break;

                case CompressAlgorithm.Jpeg:
                    qualityPercent = CompressConstants.DefaultJpegQualityPercent;
                    break;

                case CompressAlgorithm.Gif:
                    qualityPercent = CompressConstants.DefaultGifQualityPercent;
                    break;
                }
            }
            return(qualityPercent);
        }
        private void CheckParameters(SerializerParameters parameters, out CompressAlgorithm algorithm)
        {
            if (!string.IsNullOrEmpty(parameters?.ContentEncoding))
            {
                switch (parameters.ContentEncoding)
                {
                    case "identity":
                        algorithm = CompressAlgorithm.Identity;
                        return;
                    case "deflate":
                        algorithm = CompressAlgorithm.Deflate;
                        return;
                    case "gzip":
                        algorithm = CompressAlgorithm.GZip;
                        return;
                    default:
                        throw new NotSupportedException("Compression algorithm not supported");
                }
            }

            algorithm = CompressAlgorithm.Identity;
        }
示例#18
0
 public AlgorithmItem(CompressAlgorithm algorithm, String name)
 {
     this.algorithm = algorithm;
     this.name = name;
 }
示例#19
0
        /// <summary>
        ///     Runs the process to optimize the image.
        /// </summary>
        /// <param name="filePath">       The source file. </param>
        /// <param name="algorithm">
        ///     Default is auto depend on file extension, others is force algorithm
        /// </param>
        /// <param name="qualityPercent">
        ///     Quality of image after compress, 0 is default it mean auto quality by image type
        /// </param>
        /// <param name="timeout">        TimeoutMillisecond of process in millisecond </param>
        /// <returns> The Task containing processing information. </returns>
        /// <exception cref="ArgumentException">
        ///     file path is invalid, argument of command is invalid
        /// </exception>
        /// <exception cref="NotSupportedException">
        ///     Some security policies don't allow execution of programs in this way
        /// </exception>
        private static ImageCompressedModel Process(string filePath, CompressAlgorithm algorithm, int qualityPercent = 0, int timeout = 0)
        {
            Helper.CheckFilePath(filePath);

            long fileSizeBeforeCompress = new FileInfo(filePath).Length;

            ImageCompressedModel imageCompressedModel = null;

            var processInfo = new ProcessStartInfo
            {
                Arguments = GetArguments(filePath, out var fileTempPath, algorithm, qualityPercent),

                WorkingDirectory = Bootstrapper.Instance.WorkingFolder,

                UseShellExecute = false,

                CreateNoWindow = true,

                WindowStyle = ProcessWindowStyle.Hidden,

                RedirectStandardOutput = true,

                RedirectStandardError = true
            };

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                processInfo.FileName = "cmd";

                // "/c" to allow " char in arguments
                processInfo.Arguments = $"/c {processInfo.Arguments}";
            }
            else
            {
                processInfo.FileName = "/bin/bash";

                var compressorFileName = processInfo.Arguments.Split(" ").FirstOrDefault();

                var compressorFileAbsolutePath = Path.Combine(processInfo.WorkingDirectory, compressorFileName);

                // Change the file name in arguments to absolute path
                processInfo.Arguments = "-c " + processInfo.Arguments.Replace(compressorFileName, compressorFileAbsolutePath);
            }

            if (string.IsNullOrWhiteSpace(processInfo.Arguments))
            {
                throw new ArgumentException($"Command {nameof(processInfo.Arguments)} is empty",
                                            $"{nameof(processInfo.Arguments)}");
            }

            int elapsedTime = 0;

            bool eventHandled = false;

            try
            {
                var process = new Process
                {
                    StartInfo           = processInfo,
                    EnableRaisingEvents = true
                };

                process.Exited += (sender, args) =>
                {
#if DEBUG
                    string standardOutput = process.StandardOutput.ReadLine();
                    Console.WriteLine("-------------------------");
                    Console.WriteLine("Process Standard Output: ");
                    Console.WriteLine(standardOutput);
                    Console.WriteLine("-------------------------");

                    string standardError = process.StandardError.ReadLine();
                    Console.WriteLine("------------------------");
                    Console.WriteLine("Process Standard Error: ");
                    Console.WriteLine(standardError);
                    Console.WriteLine("-------------------------");
#endif
                    // Done compress
                    imageCompressedModel = new ImageCompressedModel(filePath, fileSizeBeforeCompress);
                    process.Dispose();
                    eventHandled = true;

                    // Remove temp file if have
                    FileHelper.SafeDelete(fileTempPath);
                };

                process.Start();
            }
            catch (System.ComponentModel.Win32Exception ex)
            {
                throw new NotSupportedException("Some security policies don't allow execution of programs in this way", ex);
            }

            // Wait for Exited event, but not more than config timeout time.
            const int sleepAmount = 100;

            while (!eventHandled)
            {
                elapsedTime += sleepAmount;

                if (elapsedTime > timeout && timeout > 0)
                {
                    break;
                }

                Thread.Sleep(sleepAmount);
            }

            // update compress result stream
            if (imageCompressedModel != null)
            {
                FileHelper.WriteToStream(filePath, imageCompressedModel.ResultFileStream);
            }

            return(imageCompressedModel);
        }
        public override void Connect(TimeSpan timeout, Information options)
        {
            if (_disposed) throw new ObjectDisposedException(this.GetType().FullName);

            lock (this.ThisLock)
            {
                try
                {
                    var stopwatch = new Stopwatch();
                    stopwatch.Start();

                    using (BufferStream stream = new BufferStream(_bufferManager))
                    {
                        byte[] buffer = NetworkConverter.GetBytes((uint)_myCompressAlgorithm);
                        stream.Write(buffer, 0, buffer.Length);
                        stream.Flush();
                        stream.Seek(0, SeekOrigin.Begin);

                        _connection.Send(stream, CheckTimeout(stopwatch.Elapsed, timeout));
                    }

                    using (Stream stream = _connection.Receive(CheckTimeout(stopwatch.Elapsed, timeout)))
                    {
                        byte[] buffer = new byte[4];
                        stream.Read(buffer, 0, buffer.Length);

                        _otherCompressAlgorithm = (CompressAlgorithm)NetworkConverter.ToUInt32(buffer);
                    }
                }
                catch (ConnectionException ex)
                {
                    throw ex;
                }
                catch (Exception ex)
                {
                    throw new ConnectionException(ex.Message, ex);
                }

                _connect = true;
            }
        }
示例#21
0
 public Compressor(CompressAlgorithm algorithm)
 {
     this.algorithm = algorithm;
 }
示例#22
0
        /// <summary>
        ///     Runs the process to optimize the image.
        /// </summary>
        /// <param name="filePath">       The source file. </param>
        /// <param name="algorithm">
        ///     Default is auto depend on file extension, others is force algorithm
        /// </param>
        /// <param name="qualityPercent">
        ///     Quality of image after compress, 0 is default it mean auto quality by image type
        /// </param>
        /// <param name="timeout">        TimeoutMillisecond of process in millisecond </param>
        /// <returns> The Task containing processing information. </returns>
        /// <exception cref="ArgumentException">
        ///     file path is invalid, argument of command is invalid
        /// </exception>
        /// <exception cref="NotSupportedException">
        ///     Some security policies don't allow execution of programs in this way
        /// </exception>
        private static ImageCompressResult Process(string filePath, CompressAlgorithm algorithm, int qualityPercent = 0, int timeout = 0)
        {
            ImageCompressorHelper.CheckFilePath(filePath);

            long fileSizeBeforeCompress = new FileInfo(filePath).Length;

            ImageCompressResult imageCompressResult = null;

            var processInfo = new ProcessStartInfo("cmd")
            {
                WorkingDirectory       = ImageCompressorBootstrapper.Instance.WorkingPath,
                Arguments              = GetArguments(filePath, out var fileTempPath, algorithm, qualityPercent),
                UseShellExecute        = false,
                CreateNoWindow         = true,
                WindowStyle            = ProcessWindowStyle.Hidden,
                RedirectStandardOutput = false,
                RedirectStandardError  = false,
            };

            if (IsProcessRunAsUser)
            {
                System.Security.SecureString runAsPassword = new System.Security.SecureString();

                foreach (char c in ProcessRunAsPassword)
                {
                    runAsPassword.AppendChar(c);
                }

                processInfo.UserName = ProcessRunAsUserName;

                processInfo.Password = runAsPassword;
            }

            if (string.IsNullOrWhiteSpace(processInfo.Arguments))
            {
                throw new ArgumentException($"Command {nameof(processInfo.Arguments)} is empty", $"{nameof(processInfo.Arguments)}");
            }

            int elapsedTime = 0;

            bool eventHandled = false;

            try
            {
                Process process = new Process
                {
                    StartInfo           = processInfo,
                    EnableRaisingEvents = true
                };

                process.Exited += (sender, args) =>
                {
                    // Done compress
                    imageCompressResult = new ImageCompressResult(filePath, fileSizeBeforeCompress);
                    process.Dispose();
                    eventHandled = true;

                    // Remove temp file if have
                    FileHelper.SafeDelete(fileTempPath);
                };

                process.Start();
            }
            catch (System.ComponentModel.Win32Exception ex)
            {
                throw new NotSupportedException("Some security policies don't allow execution of programs in this way", ex);
            }

            // Wait for Exited event, but not more than config timeout time.
            const int sleepAmount = 100;

            while (!eventHandled)
            {
                elapsedTime += sleepAmount;

                if (elapsedTime > timeout && timeout > 0)
                {
                    break;
                }

                Thread.Sleep(sleepAmount);
            }

            // update compress result stream
            if (imageCompressResult != null)
            {
                FileHelper.WriteToStream(filePath, imageCompressResult.ResultFileStream);
            }
            return(imageCompressResult);
        }
        private async void CompressFile(CompressAlgorithm? Algorithm, StorageFile originalFile)
        {
            Progress.Text = "";
            
            try
            {
                Progress.Text += String.Format("\"{0}\" has been picked\n", originalFile.Name);

                var compressedFilename = originalFile.Name + ".compressed";
                var compressedFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(compressedFilename, CreationCollisionOption.GenerateUniqueName);
                Progress.Text += String.Format("\"{0}\" has been created to store compressed data\n", compressedFile.Path);

                // ** DO COMPRESSION **
                // Following code actually performs compression from original file to the newly created
                // compressed file. In order to do so it:
                // 1. Opens input for the original file.
                // 2. Opens output stream on the file to be compressed and wraps it into Compressor object.
                // 3. Copies original stream into Compressor wrapper.
                // 4. Finalizes compressor - it puts termination mark into stream and flushes all intermediate
                //    buffers.
                using (var originalInput = await originalFile.OpenReadAsync())
                using (var compressedOutput = await compressedFile.OpenAsync(FileAccessMode.ReadWrite))
                using (var compressor = !Algorithm.HasValue ?
                    new Compressor(compressedOutput.GetOutputStreamAt(0)) :
                    new Compressor(compressedOutput.GetOutputStreamAt(0), Algorithm.Value, 0))
                {
                    Progress.Text += "All streams wired for compression\n";
                    var bytesCompressed = await RandomAccessStream.CopyAsync(originalInput, compressor);
                    var finished = await compressor.FinishAsync();
                    Progress.Text += String.Format("Compressed {0} bytes into {1}\n", bytesCompressed, compressedOutput.Size);
                }

                var decompressedFilename = originalFile.Name + ".decompressed";
                var decompressedFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync(decompressedFilename, CreationCollisionOption.GenerateUniqueName);
                Progress.Text += String.Format("\"{0}\" has been created to store decompressed data\n", decompressedFile.Path);

                // ** DO DECOMPRESSION **
                // Following code performs decompression from the just compressed file to the
                // decompressed file. In order to do so it:
                // 1. Opens input stream on compressed file and wraps it into Decompressor object.
                // 2. Opens output stream from the file that will store decompressed data.
                // 3. Copies data from Decompressor stream into decompressed file stream.
                using (var compressedInput = await compressedFile.OpenSequentialReadAsync())
                using (var decompressor = new Decompressor(compressedInput))
                using (var decompressedOutput = await decompressedFile.OpenAsync(FileAccessMode.ReadWrite))
                {
                    Progress.Text += "All streams wired for decompression\n";
                    var bytesDecompressed = await RandomAccessStream.CopyAsync(decompressor, decompressedOutput);
                    Progress.Text += String.Format("Decompressed {0} bytes of data\n", bytesDecompressed);
                }

                rootPage.NotifyUser("All done", NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser(ex.Message, NotifyType.ErrorMessage);
            }
        }
        /// <summary>
        /// This is the main scenario worker.
        /// </summary>
        /// <param name="Algorithm">
        /// Comression algorithm to use. If no value is provided compressor will be created using
        /// Compressor(IInputStream) constructor, otherwise extended version will be used:
        /// Compressor(IInputStream, CompressAlgorithm, uint)
        /// </param>
#if WINDOWS_PHONE_APP
        private void DoScenario(CompressAlgorithm? Algorithm)
        private async void DoScenario(CompressAlgorithm? Algorithm)
#endif
        {
            try
            {
                rootPage.NotifyUser("Working...", NotifyType.StatusMessage);

#if WINDOWS_PHONE_APP
                ShowFileOpen(Algorithm);
#else
                StorageFile originalFile;

                var picker = new FileOpenPicker();

                picker.FileTypeFilter.Add("*");

                originalFile = await picker.PickSingleFileAsync();
                if (originalFile == null)
                {
                    throw new OperationCanceledException("No file has been selected");
                }

                CompressFile(Algorithm, originalFile);
#endif
            }
            catch (Exception ex)
            {
                rootPage.NotifyUser(ex.Message, NotifyType.ErrorMessage);
            }
        }