private CompressionStats Compress( IGrid grid, ICompressor compressor, double[] errors, string outName, ProgressViewModel progressBar ) { double[] leftBorders = new double[grid.ColumnCount]; double[] rightBorders = new double[grid.ColumnCount]; var qs = new IQuantization[grid.ColumnCount]; var distrs = new IDistribution[grid.ColumnCount]; progressBar.Status = "Quantizing columns..."; Parallel.For( 0, grid.ColumnCount, column => { var distr = new EmpiricalDistribution( grid, column ); leftBorders[column] = double.MaxValue; rightBorders[column] = double.MinValue; for ( int row = 0; row < grid.RowCount; ++row ) { double value = grid.GetValue( row, column ); leftBorders[column] = leftBorders[column] < value ? leftBorders[column] : value; rightBorders[column] = rightBorders[column] > value ? rightBorders[column] : value; } var quantizer = new Quantizer( leftBorders[column], rightBorders[column] ); var quantization = quantizer.Quantize( errors[column], distr ); lock ( _lockGuard ) { progressBar.Progress += 1.0 / ( grid.ColumnCount + 1 ); distrs[column] = distr; qs[column] = quantization; } } ); var quantizations = new List<IQuantization>( qs ); var distributions = new List<IDistribution>( distrs ); progressBar.Status = "Writing archive..."; progressBar.Progress = ( double )grid.ColumnCount / ( grid.ColumnCount + 1 ); ICompressionResult result; using ( var stream = new FileOutputStream( outName ) ) { result = compressor.Compress( grid, quantizations, stream ); } progressBar.Progress = 1.0; progressBar.TryClose( ); return new CompressionStats { CompressionResult = result, Distributions = distributions, LeftBorders = leftBorders, RightBorders = rightBorders, Quantizations = quantizations }; }
public async void Compress( ) { ICompressor compressor; string extension; var grid = await OpenGrid( ); if ( grid == null ) return; ChooseCompressor( out compressor, out extension ); if ( compressor == null || extension == null ) { MessageBox.Show( "Unknown compression scheme!", "Error", MessageBoxButton.OK, MessageBoxImage.Error ); } var columnNames = new List<string>( ); for ( var i = 0; i < grid.ColumnCount; ++i ) { columnNames.Add( $"Column #{i}" ); } dynamic paramsSettings = new ExpandoObject( ); paramsSettings.Height = 200; paramsSettings.Width = 420; paramsSettings.SizeToContent = SizeToContent.Manual; paramsSettings.Title = "Compression parameters"; var compParams = new CompressionParamsViewModel( columnNames ); bool? result = _manager.ShowDialog( compParams, null, paramsSettings ); if ( result == null || !result.Value ) { return; } var dialog = new SaveFileDialog { DefaultExt = extension, Filter = $"Quantized and compressed grid|*.{extension}", AddExtension = true }; if ( dialog.ShowDialog( ) != true ) return; var errors = ( from desc in compParams.Errors select desc.Error ).ToArray( ); string outName = dialog.FileName; var progressBar = new ProgressViewModel( ); dynamic settings = new ExpandoObject( ); settings.Height = 130; settings.Width = 500; settings.SizeToContent = SizeToContent.Manual; _manager.ShowWindow( progressBar, null, settings ); var stats = await Task<CompressionStats>.Factory.StartNew( ( ) => Compress( grid, compressor, errors, outName, progressBar ) ); dynamic resultSettings = new ExpandoObject( ); resultSettings.Height = 450; resultSettings.MinHeight = 180; resultSettings.Width = 800; resultSettings.MinWidth = 320; resultSettings.Title = "Report"; resultSettings.SizeToContent = SizeToContent.Manual; _manager.ShowWindow( new CompressionResultViewModel( stats ), null, resultSettings ); }