Click here to Skip to main content
15,895,011 members
Articles / Programming Languages / Visual Basic

Better Than Zip Algorithm For Compressing In-Memory Data

Rate me:
Please Sign up or sign in to vote.
4.07/5 (41 votes)
23 May 2006CPOL6 min read 177.9K   5.2K   75  
An article on the in-memory data compression engine for .NET
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.IO;
using Aced.IMC;

namespace IMCompressor_Demo
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form
	{
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.ComboBox ratioCombo;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.Label label8;
		private System.Windows.Forms.Label label9;
		private System.Windows.Forms.Label originalSizeLabel;
		private System.Windows.Forms.Label originalSumLabel;
		private System.Windows.Forms.Label compTimeLabel;
		private System.Windows.Forms.Label compSizeLabel;
		private System.Windows.Forms.Label decompTimeLabel;
		private System.Windows.Forms.Label decompSizeLabel;
		private System.Windows.Forms.Label decompSumLabel;
		private System.Windows.Forms.Label fileNameLabel;
		private System.Windows.Forms.OpenFileDialog openFileDialog1;
		private System.Windows.Forms.Button loadFileButton;
		private System.Windows.Forms.Button compDataButton;
		private System.Windows.Forms.Button decompDataButton;
		private System.Windows.Forms.Label compStatusLabel;
		private System.Windows.Forms.Label decompStatusLabel;
		private System.Windows.Forms.Label percentLabel;
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			//
			// TODO: Add any constructor code after InitializeComponent call
			//
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			this.loadFileButton = new System.Windows.Forms.Button();
			this.label1 = new System.Windows.Forms.Label();
			this.label2 = new System.Windows.Forms.Label();
			this.compDataButton = new System.Windows.Forms.Button();
			this.ratioCombo = new System.Windows.Forms.ComboBox();
			this.label3 = new System.Windows.Forms.Label();
			this.decompDataButton = new System.Windows.Forms.Button();
			this.label4 = new System.Windows.Forms.Label();
			this.label5 = new System.Windows.Forms.Label();
			this.label6 = new System.Windows.Forms.Label();
			this.label7 = new System.Windows.Forms.Label();
			this.label8 = new System.Windows.Forms.Label();
			this.label9 = new System.Windows.Forms.Label();
			this.originalSizeLabel = new System.Windows.Forms.Label();
			this.originalSumLabel = new System.Windows.Forms.Label();
			this.compTimeLabel = new System.Windows.Forms.Label();
			this.compSizeLabel = new System.Windows.Forms.Label();
			this.decompTimeLabel = new System.Windows.Forms.Label();
			this.decompSizeLabel = new System.Windows.Forms.Label();
			this.decompSumLabel = new System.Windows.Forms.Label();
			this.fileNameLabel = new System.Windows.Forms.Label();
			this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
			this.compStatusLabel = new System.Windows.Forms.Label();
			this.decompStatusLabel = new System.Windows.Forms.Label();
			this.percentLabel = new System.Windows.Forms.Label();
			this.SuspendLayout();
			// 
			// loadFileButton
			// 
			this.loadFileButton.Location = new System.Drawing.Point(28, 40);
			this.loadFileButton.Name = "loadFileButton";
			this.loadFileButton.Size = new System.Drawing.Size(152, 23);
			this.loadFileButton.TabIndex = 2;
			this.loadFileButton.Text = "Load File In Memory...";
			this.loadFileButton.Click += new System.EventHandler(this.loadFileButton_Click);
			// 
			// label1
			// 
			this.label1.Location = new System.Drawing.Point(28, 12);
			this.label1.Name = "label1";
			this.label1.Size = new System.Drawing.Size(60, 16);
			this.label1.TabIndex = 0;
			this.label1.Text = "File Name:";
			// 
			// label2
			// 
			this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label2.Location = new System.Drawing.Point(368, 168);
			this.label2.Name = "label2";
			this.label2.Size = new System.Drawing.Size(148, 16);
			this.label2.TabIndex = 15;
			this.label2.Text = "Original Adler32 Checksum:";
			// 
			// compDataButton
			// 
			this.compDataButton.Location = new System.Drawing.Point(28, 92);
			this.compDataButton.Name = "compDataButton";
			this.compDataButton.Size = new System.Drawing.Size(152, 23);
			this.compDataButton.TabIndex = 7;
			this.compDataButton.Text = "Compress Data";
			this.compDataButton.Click += new System.EventHandler(this.compDataButton_Click);
			// 
			// ratioCombo
			// 
			this.ratioCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
			this.ratioCombo.Items.AddRange(new object[] {
															"Store",
															"Fastest",
															"Fast",
															"Normal",
															"Maximum"});
			this.ratioCombo.Location = new System.Drawing.Point(372, 68);
			this.ratioCombo.Name = "ratioCombo";
			this.ratioCombo.Size = new System.Drawing.Size(136, 21);
			this.ratioCombo.TabIndex = 6;
			// 
			// label3
			// 
			this.label3.Location = new System.Drawing.Point(320, 72);
			this.label3.Name = "label3";
			this.label3.Size = new System.Drawing.Size(52, 16);
			this.label3.TabIndex = 5;
			this.label3.Text = "Method:";
			// 
			// decompDataButton
			// 
			this.decompDataButton.Location = new System.Drawing.Point(28, 176);
			this.decompDataButton.Name = "decompDataButton";
			this.decompDataButton.Size = new System.Drawing.Size(152, 23);
			this.decompDataButton.TabIndex = 13;
			this.decompDataButton.Text = "Decompress Data";
			this.decompDataButton.Click += new System.EventHandler(this.decompDataButton_Click);
			// 
			// label4
			// 
			this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label4.Location = new System.Drawing.Point(368, 212);
			this.label4.Name = "label4";
			this.label4.Size = new System.Drawing.Size(148, 16);
			this.label4.TabIndex = 21;
			this.label4.Text = "Decompressed Checksum:";
			// 
			// label5
			// 
			this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label5.Location = new System.Drawing.Point(208, 36);
			this.label5.Name = "label5";
			this.label5.Size = new System.Drawing.Size(144, 16);
			this.label5.TabIndex = 3;
			this.label5.Text = "Original File Size, bytes:";
			// 
			// label6
			// 
			this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label6.Location = new System.Drawing.Point(208, 128);
			this.label6.Name = "label6";
			this.label6.Size = new System.Drawing.Size(160, 16);
			this.label6.TabIndex = 11;
			this.label6.Text = "Compressed Data Size, bytes:";
			// 
			// label7
			// 
			this.label7.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label7.Location = new System.Drawing.Point(208, 212);
			this.label7.Name = "label7";
			this.label7.Size = new System.Drawing.Size(152, 16);
			this.label7.TabIndex = 19;
			this.label7.Text = "Decompressed Data Size:";
			// 
			// label8
			// 
			this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label8.Location = new System.Drawing.Point(28, 128);
			this.label8.Name = "label8";
			this.label8.Size = new System.Drawing.Size(152, 16);
			this.label8.TabIndex = 9;
			this.label8.Text = "Compression Time, ms:";
			// 
			// label9
			// 
			this.label9.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.label9.Location = new System.Drawing.Point(28, 212);
			this.label9.Name = "label9";
			this.label9.Size = new System.Drawing.Size(152, 16);
			this.label9.TabIndex = 17;
			this.label9.Text = "Decompression Time, ms:";
			// 
			// originalSizeLabel
			// 
			this.originalSizeLabel.Location = new System.Drawing.Point(208, 56);
			this.originalSizeLabel.Name = "originalSizeLabel";
			this.originalSizeLabel.Size = new System.Drawing.Size(144, 16);
			this.originalSizeLabel.TabIndex = 4;
			this.originalSizeLabel.Text = "<size>";
			// 
			// originalSumLabel
			// 
			this.originalSumLabel.Location = new System.Drawing.Point(372, 188);
			this.originalSumLabel.Name = "originalSumLabel";
			this.originalSumLabel.Size = new System.Drawing.Size(124, 16);
			this.originalSumLabel.TabIndex = 16;
			this.originalSumLabel.Text = "<checksum>";
			this.originalSumLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// compTimeLabel
			// 
			this.compTimeLabel.Location = new System.Drawing.Point(32, 148);
			this.compTimeLabel.Name = "compTimeLabel";
			this.compTimeLabel.Size = new System.Drawing.Size(132, 16);
			this.compTimeLabel.TabIndex = 10;
			this.compTimeLabel.Text = "<duration>";
			// 
			// compSizeLabel
			// 
			this.compSizeLabel.Location = new System.Drawing.Point(212, 148);
			this.compSizeLabel.Name = "compSizeLabel";
			this.compSizeLabel.Size = new System.Drawing.Size(152, 16);
			this.compSizeLabel.TabIndex = 12;
			this.compSizeLabel.Text = "<size>";
			// 
			// decompTimeLabel
			// 
			this.decompTimeLabel.Location = new System.Drawing.Point(32, 232);
			this.decompTimeLabel.Name = "decompTimeLabel";
			this.decompTimeLabel.Size = new System.Drawing.Size(132, 16);
			this.decompTimeLabel.TabIndex = 18;
			this.decompTimeLabel.Text = "<duration>";
			// 
			// decompSizeLabel
			// 
			this.decompSizeLabel.Location = new System.Drawing.Point(212, 232);
			this.decompSizeLabel.Name = "decompSizeLabel";
			this.decompSizeLabel.Size = new System.Drawing.Size(148, 16);
			this.decompSizeLabel.TabIndex = 20;
			this.decompSizeLabel.Text = "<size>";
			// 
			// decompSumLabel
			// 
			this.decompSumLabel.Location = new System.Drawing.Point(372, 232);
			this.decompSumLabel.Name = "decompSumLabel";
			this.decompSumLabel.Size = new System.Drawing.Size(124, 16);
			this.decompSumLabel.TabIndex = 22;
			this.decompSumLabel.Text = "<checksum>";
			this.decompSumLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// fileNameLabel
			// 
			this.fileNameLabel.Location = new System.Drawing.Point(92, 12);
			this.fileNameLabel.Name = "fileNameLabel";
			this.fileNameLabel.Size = new System.Drawing.Size(412, 16);
			this.fileNameLabel.TabIndex = 1;
			this.fileNameLabel.Text = "<file name>";
			// 
			// openFileDialog1
			// 
			this.openFileDialog1.Filter = "All files|*.*";
			this.openFileDialog1.Title = "Choose the File";
			// 
			// compStatusLabel
			// 
			this.compStatusLabel.Location = new System.Drawing.Point(208, 96);
			this.compStatusLabel.Name = "compStatusLabel";
			this.compStatusLabel.Size = new System.Drawing.Size(112, 16);
			this.compStatusLabel.TabIndex = 8;
			this.compStatusLabel.Text = "<status>";
			// 
			// decompStatusLabel
			// 
			this.decompStatusLabel.Location = new System.Drawing.Point(208, 180);
			this.decompStatusLabel.Name = "decompStatusLabel";
			this.decompStatusLabel.Size = new System.Drawing.Size(124, 16);
			this.decompStatusLabel.TabIndex = 14;
			this.decompStatusLabel.Text = "<status>";
			// 
			// percentLabel
			// 
			this.percentLabel.Location = new System.Drawing.Point(372, 128);
			this.percentLabel.Name = "percentLabel";
			this.percentLabel.Size = new System.Drawing.Size(124, 16);
			this.percentLabel.TabIndex = 23;
			this.percentLabel.Text = "<percent>";
			this.percentLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
			// 
			// Form1
			// 
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 14);
			this.ClientSize = new System.Drawing.Size(528, 261);
			this.Controls.Add(this.percentLabel);
			this.Controls.Add(this.label3);
			this.Controls.Add(this.decompStatusLabel);
			this.Controls.Add(this.compStatusLabel);
			this.Controls.Add(this.fileNameLabel);
			this.Controls.Add(this.decompSumLabel);
			this.Controls.Add(this.decompSizeLabel);
			this.Controls.Add(this.decompTimeLabel);
			this.Controls.Add(this.compSizeLabel);
			this.Controls.Add(this.compTimeLabel);
			this.Controls.Add(this.originalSumLabel);
			this.Controls.Add(this.originalSizeLabel);
			this.Controls.Add(this.label9);
			this.Controls.Add(this.label8);
			this.Controls.Add(this.label7);
			this.Controls.Add(this.label6);
			this.Controls.Add(this.label5);
			this.Controls.Add(this.label4);
			this.Controls.Add(this.decompDataButton);
			this.Controls.Add(this.ratioCombo);
			this.Controls.Add(this.compDataButton);
			this.Controls.Add(this.label2);
			this.Controls.Add(this.label1);
			this.Controls.Add(this.loadFileButton);
			this.Font = new System.Drawing.Font("Tahoma", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((System.Byte)(204)));
			this.MaximizeBox = false;
			this.Name = "Form1";
			this.Text = "IMCompressor Test Application";
			this.Load += new System.EventHandler(this.Form1_Load);
			this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run(new Form1());
		}

		private string _fileName;
		private int _originalSize;
		private byte[] _originalData;
		private int _originalSum;

		private byte[] _compData;
		private int _compTime;
		private int _compSize;

		private byte[] _decompData;
		private int _decompTime;
		private int _decompSize;
		private int _decompSum;

		private void LoadFile()
		{
			_fileName = openFileDialog1.FileName;
			FileStream fs = new FileStream(_fileName, FileMode.Open);
			_originalSize = (int)fs.Length;
			_originalData = new byte[_originalSize];
			fs.Read(_originalData, 0, _originalSize);
			fs.Close();
			_originalSum = AcedBinary.Adler32(_originalData, 0, _originalSize);

			fileNameLabel.Text = _fileName;
			originalSizeLabel.Text = _originalSize.ToString("#,##0");
			originalSumLabel.Text = _originalSum.ToString("X");
		}

		private void CompressData()
		{
			compStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			AcedCompressionLevel level = AcedCompressionLevel.Fast;
			switch (ratioCombo.SelectedIndex)
			{
				case 0:
					level = AcedCompressionLevel.Store;
					break;
				case 1:
					level = AcedCompressionLevel.Fastest;
					break;
				case 2:
					level = AcedCompressionLevel.Fast;
					break;
				case 3:
					level = AcedCompressionLevel.Normal;
					break;
				case 4:
					level = AcedCompressionLevel.Maximum;
					break;
			}
			long L = DateTime.Now.Ticks;


			//-- Uncomment this block to try the standard DeflateStream compression --

			//MemoryStream ms = new MemoryStream();
			//System.IO.Compression.DeflateStream ds =
			//    new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Compress);
			//ds.Write(_originalData, 0, _originalSize);
			//ds.Close();
			//_compData = ms.ToArray();

			//-- End of the block -- (see also the DecompressData method) ------------


			//-- Comment out this block to try the DeflateStream compression ---------

			_compData = AcedDeflator.Instance.Compress(_originalData, 0, _originalSize, level, 0, 0);

			//-- End of the block -- (see also the DecompressData method) ------------


			_compTime = (int)((DateTime.Now.Ticks - L) / 10000);
			_compSize = _compData.Length;

			compTimeLabel.Text = _compTime.ToString();
			compSizeLabel.Text = _compSize.ToString("#,##0");
			percentLabel.Text = ((double)_compSize / _originalSize * 100.00).ToString("G5") + " %";
			compStatusLabel.Text = "< OK >";
		}

		private void DecompressData()
		{
			decompStatusLabel.Text = "Please wait...";
			Application.DoEvents();

			long L = DateTime.Now.Ticks;


			//-- Uncomment this block to try the standard DeflateStream compression --

			//MemoryStream ms = new MemoryStream(_compData);
			//System.IO.Compression.DeflateStream ds =
			//    new System.IO.Compression.DeflateStream(ms, System.IO.Compression.CompressionMode.Decompress);
			//_decompData = new byte[_originalSize];
			//int offset = 0;
			//int count = _originalSize;
			//while (count > 0)
			//{
			//    int delta = ds.Read(_decompData, offset, count);
			//    offset += delta;
			//    count -= delta;
			//}
			//ds.Close();

			//-- End of the block -- (see also the CompressData method) --------------


			//-- Comment out this block to try the DeflateStream compression ---------

			_decompData = AcedInflator.Instance.Decompress(_compData, 0, 0, 0);

			//-- End of the block -- (see also the CompressData method) --------------


			_decompTime = (int)((DateTime.Now.Ticks - L) / 10000);
			_decompSize = _decompData.Length;
			_decompSum = AcedBinary.Adler32(_decompData, 0, _decompSize);

			decompTimeLabel.Text = _decompTime.ToString();
			decompSizeLabel.Text = _decompSize.ToString("#,##0");
			decompSumLabel.Text = _decompSum.ToString("X");
			decompStatusLabel.Text = "< OK >";
		}

		private void Form1_Load(object sender, System.EventArgs e)
		{
			ratioCombo.SelectedIndex = 2;
		}

		private void loadFileButton_Click(object sender, System.EventArgs e)
		{
			if (openFileDialog1.ShowDialog() == DialogResult.OK)
				LoadFile();
		}

		private void compDataButton_Click(object sender, System.EventArgs e)
		{
			if (_originalData != null)
				CompressData();
		}

		private void decompDataButton_Click(object sender, System.EventArgs e)
		{
			if (_compData != null)
				DecompressData();
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Russian Federation Russian Federation
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions