//декодирование одного символа
        public Byte?Decode(ref string Code)
        {
            AdaptiveHuffmanTree TargetLeaf = this;
            Byte?  DecodedSymbol           = null;
            string Destination             = "";

            do
            {
                if (Code.Length == 0)
                {
                    NotEnoughCodeEvent(ref Code);
                }
                Destination = Code.Substring(0, 1);
                Code        = Code.Substring(1, Code.Length - 1);
                if (Destination == "0")
                {
                    TargetLeaf = TargetLeaf.Left;
                }
                if (Destination == "1")
                {
                    TargetLeaf = TargetLeaf.Right;
                }
            }while (TargetLeaf.Symbol == null && TargetLeaf.SpecialSymbol == null);

            if (TargetLeaf.Symbol != null)
            {
                DecodedSymbol = TargetLeaf.Symbol;
            }
            if (TargetLeaf.SpecialSymbol == "Esc")
            {
                if (Code.Length < 8)
                {
                    NotEnoughCodeEvent(ref Code);
                }
                DecodedSymbol = ToByte(Code.Substring(0, 8));
                if (Code.Length != 8)
                {
                    Code = Code.Substring(8, Code.Length - 8);
                }
                else
                {
                    Code = "";
                }
            }
            if (TargetLeaf.SpecialSymbol == "Eof")
            {
                return(null);
            }

            Rebuild(DecodedSymbol);
            char a = Convert.ToChar(DecodedSymbol);

            return(DecodedSymbol);
        }
 public void CreateModel()
 {
     Number              = 3;
     Weight              = 2;
     Left                = new AdaptiveHuffmanTree();
     Left.SpecialSymbol  = "Esc";
     Left.Number         = 1;
     Left.Weight         = 1;
     Right               = new AdaptiveHuffmanTree();
     Right.SpecialSymbol = "EoF";
     Right.Number        = 2;
     Right.Weight        = 1;
 }
Пример #3
0
        public static bool DecodeFile(string InputPath, string OutputPath)
        {
            bool         OpenSuccessfully = true;
            BinaryWriter OutputFile       = null;

            try
            {
                SourceFile = new BinaryReader(File.OpenRead(InputPath));
                OutputFile = new BinaryWriter(File.Create(OutputPath));
            }
            catch
            {
                OpenSuccessfully = false;
            }

            if (OpenSuccessfully)
            {
                AdaptiveHuffmanTree DecodingModel = new AdaptiveHuffmanTree();
                DecodingModel.CreateModel();
                DecodingModel.NotEnoughCodeEvent += new AdaptiveHuffmanTree.NotEnoughCodeEventDelegate(OnNotEnoughCodeEvent);
                bool   FinishFlag = false;
                Byte?  Symbol     = 0;
                string Code       = "";

                //убираем расширение
                do
                {
                    ProgressEvent();
                }while (SourceFile.ReadChar() != '.');

                ProgressEvent();
                Code = AdaptiveHuffmanTree.ToBinaryString(SourceFile.ReadByte());

                while (!FinishFlag)
                {
                    Symbol = DecodingModel.Decode(ref Code);
                    if (Symbol == null)
                    {
                        FinishFlag = true;
                    }
                    if (!FinishFlag)
                    {
                        OutputFile.Write((Byte)Symbol);
                    }
                }
            }
            SourceFile.Close();
            OutputFile.Close();
            return(OpenSuccessfully);
        }
        private AdaptiveHuffmanTree Find(int NumberToFind)
        {
            if (Number == NumberToFind)
            {
                return(this);
            }
            AdaptiveHuffmanTree Result = null;

            if (Right != null)
            {
                Result = Right.Find(NumberToFind);
            }
            if (Result == null && Left != null)
            {
                Result = Left.Find(NumberToFind);
            }
            return(Result);
        }
        private AdaptiveHuffmanTree Find(string SpecialSymbolToFind)
        {
            if (SpecialSymbol == SpecialSymbolToFind)
            {
                return(this);
            }
            AdaptiveHuffmanTree Result = null;

            if (Right != null)
            {
                Result = Right.Find(SpecialSymbolToFind);
            }
            if (Result == null && Left != null)
            {
                Result = Left.Find(SpecialSymbolToFind);
            }
            return(Result);
        }
        private AdaptiveHuffmanTree FindParent(AdaptiveHuffmanTree Child)
        {
            if (Left == Child || Right == Child || this == Child)
            {
                return(this);
            }
            AdaptiveHuffmanTree Result = null;

            if (Right != null)
            {
                Result = Right.FindParent(Child);
            }
            if (Result == null && Left != null)
            {
                Result = Left.FindParent(Child);
            }
            return(Result);
        }
        //кодирование символа
        public string Encode(Byte?SymbolToEncode)
        {
            string Code = "";
            char   a    = Convert.ToChar(SymbolToEncode);
            AdaptiveHuffmanTree KeyLeave;

            if (SymbolToEncode == null)
            {
                KeyLeave = Find("EoF");
            }
            else
            {
                KeyLeave = Find(SymbolToEncode);
                if (KeyLeave == null)
                {
                    Code     = AdaptiveHuffmanTree.ToBinaryString(SymbolToEncode);
                    KeyLeave = Find("Esc");
                }
            }
            AdaptiveHuffmanTree Parent = this.FindParent(KeyLeave);

            do
            {
                if (Parent.Left == KeyLeave)
                {
                    Code = "0" + Code;
                }
                if (Parent.Right == KeyLeave)
                {
                    Code = "1" + Code;
                }
                KeyLeave = Parent;
                Parent   = this.FindParent(KeyLeave);
            }while (Parent != KeyLeave);

            Rebuild(SymbolToEncode);

            return(Code);
        }
Пример #8
0
        public static bool EncodeFile(string InputPath, string OutputPath)
        {
            bool         OpenSuccessfully = true;
            BinaryWriter OutputFile       = null;

            try
            {
                SourceFile = new BinaryReader(File.OpenRead(InputPath));
                OutputFile = new BinaryWriter(File.Create(OutputPath));
            }
            catch
            {
                OpenSuccessfully = false;
            }

            if (OpenSuccessfully)
            {
                AdaptiveHuffmanTree EncodingModel = new AdaptiveHuffmanTree();
                EncodingModel.CreateModel();
                bool   EndOfFile = false;
                Byte   Symbol    = 0;
                string Code;
                string Buffer = "";

                //запись расширения исходного файла
                char[]   CharTypeBuffer;
                FileInfo Finfo = new FileInfo(InputPath);
                CharTypeBuffer = (Finfo.Extension.Substring(1, Finfo.Extension.Length - 1) + ".").ToCharArray();
                OutputFile.Write(CharTypeBuffer);

                while (!EndOfFile)
                {
                    ProgressEvent();

                    try
                    {
                        Symbol = SourceFile.ReadByte();
                    }
                    catch
                    {
                        EndOfFile = true;
                    }

                    if (!EndOfFile)
                    {
                        Code = EncodingModel.Encode(Symbol);
                    }
                    else
                    {
                        Code = EncodingModel.Encode(null);
                    }
                    Code   = Buffer + Code;
                    Buffer = Code.Substring(Code.Length - (Code.Length % 8), (Code.Length) - (Code.Length - (Code.Length % 8)));
                    Code   = Code.Remove(Code.Length - (Code.Length % 8), (Code.Length) - (Code.Length - (Code.Length % 8)));
                    while (Code != "")
                    {
                        OutputFile.Write(AdaptiveHuffmanTree.ToByte(Code.Substring(0, 8)));
                        Code = Code.Remove(0, 8);
                    }

                    if (EndOfFile)
                    {
                        while (Buffer.Length != 8)
                        {
                            Buffer += "0";
                        }
                        OutputFile.Write(AdaptiveHuffmanTree.ToByte(Buffer));
                    }
                }
                SourceFile.Close();
                OutputFile.Close();
            }
            return(OpenSuccessfully);
        }
Пример #9
0
 private static void OnNotEnoughCodeEvent(ref string Code)
 {
     Code += AdaptiveHuffmanTree.ToBinaryString(SourceFile.ReadByte());
     ProgressEvent();
 }
        //перестроение дерева
        private void Rebuild(Byte?SymbolToEncode)
        {
            AdaptiveHuffmanTree CurrentVertex = Find(SymbolToEncode);

            //создание нового листа
            if (CurrentVertex == null)
            {
                AdaptiveHuffmanTree NewVertex        = new AdaptiveHuffmanTree();
                AdaptiveHuffmanTree LastVertex       = Find(1);
                AdaptiveHuffmanTree LastVertexParent = FindParent(LastVertex);
                AdaptiveHuffmanTree VertexWithSymbol = new AdaptiveHuffmanTree();
                VertexWithSymbol.Symbol = SymbolToEncode;
                VertexWithSymbol.Weight = 1;
                NewVertex.Weight        = LastVertex.Weight + VertexWithSymbol.Weight;
                LastVertexParent.Left   = NewVertex;
                NewVertex.Left          = VertexWithSymbol;
                NewVertex.Right         = LastVertex;
                CurrentVertex           = NewVertex;
                ReNumber();
            }
            else
            {
                CurrentVertex.Weight++;
            }

            while (CurrentVertex != this)
            {
                //проверяем нужна ли перестановка
                int Number = CurrentVertex.Number;
                while (CurrentVertex.Weight == Find(Number + 1).Weight + 1)
                {
                    Number++;
                }

                //если нужна:
                if (Number != CurrentVertex.Number)
                {
                    AdaptiveHuffmanTree VertexForChange;
                    VertexForChange = Find(Number);

                    //перестановка узлов-родителей
                    if (FindParent(VertexForChange) != FindParent(CurrentVertex))
                    {
                        AdaptiveHuffmanTree Parent1 = FindParent(VertexForChange);
                        AdaptiveHuffmanTree Parent2 = FindParent(CurrentVertex);
                        if (Parent1.Left == VertexForChange)
                        {
                            Parent1.Left = CurrentVertex;
                        }
                        if (Parent1.Right == VertexForChange)
                        {
                            Parent1.Right = CurrentVertex;
                        }
                        if (Parent2.Left == CurrentVertex)
                        {
                            Parent2.Left = VertexForChange;
                        }
                        if (Parent2.Right == CurrentVertex)
                        {
                            Parent2.Right = VertexForChange;
                        }
                    }
                    else
                    {
                        AdaptiveHuffmanTree Parent = FindParent(VertexForChange);
                        if (Parent.Left == VertexForChange)
                        {
                            Parent.Left  = CurrentVertex;
                            Parent.Right = VertexForChange;
                        }
                        if (Parent.Left == CurrentVertex)
                        {
                            Parent.Left  = VertexForChange;
                            Parent.Right = CurrentVertex;
                        }
                    }
                }
                CurrentVertex = FindParent(CurrentVertex);
                CurrentVertex.Weight++;
                ReNumber();
            }
        }