//декодирование одного символа 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; }
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); }
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); }
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(); } }