⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 form1.cs

📁 LZ77 - compresor and uncompresor in C#
💻 CS
字号:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using BinaryRW;
using System.Threading;

namespace CC1
{
    public partial class Form1 : Form
    {
        delegate void UpdateDelegate(int ct);
        event UpdateDelegate UpdateEvent;
        delegate void FinishedDelegate();
        event FinishedDelegate FinishedEvent;

        string source, destination;
        int sourcesize, destinationsize;
        BinaryRW.BinaryRW reader, writer;

        bool compress;

        int L, P, B;

        public Form1()
        {
            InitializeComponent();
            UpdateEvent = UpdatePB;
        }

        //--------------------------BUTTONS-----------------------------------//
        private void btnSelFile_Click(object sender, EventArgs e)
        {
            btnCompress.Enabled = btnDecompress.Enabled = false;

            OpenFileDialog odlg = new OpenFileDialog();
            odlg.CheckFileExists = true;
            if (odlg.ShowDialog() == DialogResult.OK)
            {
                source = odlg.FileName;
                string extension = Path.GetExtension(source);
                if (extension == ".lz77")
                {
                    compress = false;
                    btnDecompress.Enabled = true;
                    nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = false;
                    destination = Path.GetFileNameWithoutExtension(source);
                    destination = Path.GetFileNameWithoutExtension(destination) + "_dcd" + Path.GetExtension(destination);
                }
                else
                {
                    compress = true;
                    btnCompress.Enabled = true;
                    nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = true;
                    destination = source + ".lz77";
                }
                sourcesize = (int)(new System.IO.FileInfo(source).Length);
                lblOutput.Text = "";
            }
        }
        private void btnCompress_Click(object sender, EventArgs e)
        {
            InitForCompress();
            //Compress();
            Thread t = new Thread(Compress);
            t.Start();
        }
        private void btnDecompress_Click(object sender, EventArgs e)
        {
            InitForDecompress();
            //Decompress();
            Thread t = new Thread(Decompress);
            t.Start();
        }
        private void InitForCompress()
        {
            btnCompress.Enabled = false;
            nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = false;
            btnSelFile.Enabled = false;
            L = (int)nudLen.Value;
            P = (int)nudPos.Value;
            B = (int)nudBuffer.Value;
            pbProgress.Maximum = sourcesize;
            FinishedEvent = FinishedCompress;
        }
        private void InitForDecompress()
        {
            btnDecompress.Enabled = false;
            btnSelFile.Enabled = false;
            pbProgress.Maximum = sourcesize * 8;
            FinishedEvent = FinishedDecompress;
        }
        //-------------------------THREADS------------------------//
        private void Compress()
        {
            BinaryReader br = new BinaryReader(File.Open(source, FileMode.Open));
            writer = new BinaryRW.BinaryRW(destination, false);
            //header
            writer.WriteByte((byte)P);
            writer.WriteByte((byte)L);
            
            List<byte> buffer = new List<byte>();
            bool lastread = false;
            int MaxL = 1<<L;
            int MaxP = 1<<P;
            int BR;
            int pos;

            buffer.AddRange(br.ReadBytes(B * 1024));
            BR = buffer.Count;
            if (BR < B * 1024) lastread = true;

            pos = 0;
            while (pos<BR)
            {
                //start looking for sequence
                int l = 0;
                //max left to go
                int SBL = Math.Min(MaxP, pos);
                //list of positions of sequences
                List<int> p = new List<int>();
                //init with first appearences
                for (int i = 0; i < SBL; i++)
                {
                    if (buffer[pos - (i + 1)] == buffer[pos])
                        p.Add(i);
                }
                if (p.Count == 0)
                {
                    //new character
                    //write to file
                    //flag
                    writer.WriteBit(1);
                    //character
                    writer.WriteBits(buffer[pos], 8);

                    //step forward
                    pos++;
                    if (UpdateEvent != null) UpdateEvent(1);
                }
                else
                {
                    l=1;
                    while (pos+l<BR && l<MaxL-1)
                    {
                        //tempp stores sequences of length l+1
                        List<int> tempp = new List<int>();
                        foreach (int i in p)
                        {
                            if (buffer[pos - (i + 1) + l] == buffer[pos + l])
                                tempp.Add(i);
                        }
                        if (tempp.Count == 0) break;//didnt find sequences of l+1 length
                        else
                        {
                            //select only the sequences of length l+1
                            p.Clear();
                            p.AddRange(tempp);
                            //go on
                            l++;
                        }
                    }
                    //found a l length sequence
                    //write to file
                    //flag
                    writer.WriteBit(0);
                    //pos
                    writer.WriteBits(p[0], P);
                    //lenght
                    writer.WriteBits(l, L);

                    //step forward
                    pos += l;
                    if (UpdateEvent != null) UpdateEvent(l);
                }
                //check if we're too close to the end of buffer
                if (pos >= BR-MaxP && !lastread)
                {
                    //try and read more
                    byte[] tempbuffer = br.ReadBytes(B * 1024);
                    //if no more signal it
                    if (tempbuffer.Length == 0)
                        lastread = true;
                    else
                    {
                        //add bytes read
                        List<byte> tempbuffer2 = new List<byte>();
                        for (int i = pos - SBL; i < BR; i++)
                            tempbuffer2.Add(buffer[i]);
                        buffer = tempbuffer2;
                        buffer.AddRange(tempbuffer);
                        BR = buffer.Count;
                        pos = SBL;
                    }
                }                
            }
            //end sequence
            //flag
            writer.WriteBit(1);
            //character
            writer.WriteBits(buffer[pos - 1], 8);

            writer.Close();
            br.Close();
            if (FinishedEvent != null) FinishedEvent();
        }
        private void Decompress()
        {
            reader = new BinaryRW.BinaryRW(source, true);
            BinaryWriter bw = new BinaryWriter(File.Create(destination));
            P = (int)reader.ReadByte();
            L = (int)reader.ReadByte();

            List<byte> buffer = new List<byte>();

            int MaxL = 1 << L;
            int MaxP = 1 << P;
            int BR = 0;
            int pos = 0;

            while (true)
            {
                int flag = reader.ReadBit();
                if (flag == 1)
                {
                    //new character
                    byte character = (byte)reader.ReadBits(8);
                    //end of stream
                    if(buffer.Count!=0)
                        if (character == buffer[pos]) 
                            break;
                    buffer.Add(character);
                    bw.Write(character);
                    if (UpdateEvent != null) UpdateEvent(9);
                }
                else
                {
                    //sequence
                    int position = reader.ReadBits(P);
                    int length = reader.ReadBits(L);
                    for (int i = 0; i < length; i++)
                    {
                        bw.Write(buffer[pos - position + i]);
                        buffer.Add(buffer[pos - position + i]);
                    }
                    if (UpdateEvent != null) UpdateEvent(P + L + 1);
                }
                BR = buffer.Count - 1;
                if (BR > MaxP)
                {
                    for (int i = MaxP; i < BR; i++)
                        buffer.RemoveAt(0);
                }
                BR = buffer.Count - 1;
                pos = BR;
            }

            reader.Close();
            bw.Close();
            if (FinishedEvent != null) FinishedEvent();
        }
        //-------------------------EVENTS-----------------------//
        private void UpdatePB(int ct)
        {
            pbProgress.Value += ct;
        }
        private void FinishedCompress()
        {
            btnCompress.Enabled = true;
            nudBuffer.Enabled = nudLen.Enabled = nudPos.Enabled = true;
            btnSelFile.Enabled = true;
            pbProgress.Value = 0;
            destinationsize = (int)(new System.IO.FileInfo(destination).Length);
            lblOutput.Text = sourcesize + " >> " + destinationsize;
        }
        private void FinishedDecompress()
        {
            btnDecompress.Enabled = true;
            btnSelFile.Enabled = true;
            pbProgress.Value = 0;
            destinationsize = (int)(new System.IO.FileInfo(destination).Length);
            lblOutput.Text = sourcesize + " >> " + destinationsize;
        }
        //-------------------------EXTRA---------------------------//
        
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -