//кодирование символа public string Encode(Byte?SymbolToEncode) { string Code = ""; char a = Convert.ToChar(SymbolToEncode); HuffmanTree KeyLeave; if (SymbolToEncode == null) { KeyLeave = Find("EoF"); } else { KeyLeave = Find(SymbolToEncode); if (KeyLeave == null) { Code = HuffmanTree.ToBinaryString(SymbolToEncode); KeyLeave = Find("Esc"); } } HuffmanTree 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); }
static void Main(string[] args) { string fileName = "bigLog.txt"; var charsInFile = HuffmanTree.MakeFreqList(fileName); var tree = CodeMatch.MakeTree(charsInFile); // тест дерева var codeStruct = CodeMatch.getCode(tree[0]); makeLog(codeStruct); WriteFile(fileName, codeStruct); if (charsInFile.Count > 1) { Console.WriteLine($"В {tree.ToString()} {tree.Count} записей"); } WriteFreqList(charsInFile, "Leafs.txt"); }
private int srav(HuffmanTree a, HuffmanTree b) { return(a.freq.CompareTo(b.freq)); }
private const int MAX_BUFFER_SIZE = 4096; // 4KiB public static void SetReader(string pathIn) { readerIn = new BinaryReader(File.OpenRead(pathIn)); huffmanTree = new HuffmanTree(pathIn); }
public int CompareTo(HuffmanTree <T> other) { return(RootNode.Weight < other.Weight ? -1 : (RootNode.Weight == other.Weight ? 0 : 1)); }
private uint DecodeBytes(byte[] input, uint inputBitSize, uint pointer, out uint unDecodedBitSize, byte[] output, HuffmanTree tree, bool ignore32) { uint counter = 0; byte character; int reserved = ignore32 ? 0 : 32; while (pointer < inputBitSize - reserved) { character = DecodeByte(input, pointer, tree, out bool isNew, out uint bitLength); pointer += bitLength; if (isNew) { character = GetByte(input, pointer); pointer += 8; } output[counter] = character; tree.Add(character); counter++; } unDecodedBitSize = inputBitSize - pointer; return(counter); }
public async Task DecodeFile(StorageFile readFile, StorageFile writeFile) { byte[] output = new byte[8192]; ulong readFileSize = (await readFile.GetBasicPropertiesAsync()).Size; ulong readSize = 0; HuffmanTree tree = new HuffmanTree(); using (IInputStream fin = await readFile.OpenSequentialReadAsync()) { using (DataReader dataReader = new DataReader(fin)) { using (IRandomAccessStream fout = await writeFile.OpenAsync(FileAccessMode.ReadWrite)) { using (IOutputStream outputStream = fout.GetOutputStreamAt(0)) { using (DataWriter dataWriter = new DataWriter(outputStream)) { uint unDecodedBitSize = 0; await dataReader.LoadAsync(sizeof(ulong)); ulong fileSize = dataReader.ReadUInt64(); byte[] lastNotDecoded = new byte[4]; while (true) { uint loadSize = await dataReader.LoadAsync(1024); readSize += loadSize; double percent = (double)readSize * 100 / readFileSize; ApplicationView.GetForCurrentView().Title = percent.ToString("0.0") + "%已完成"; byte[] input = new byte[loadSize]; dataReader.ReadBytes(input); uint resultSize; if (loadSize < 1024) { resultSize = DecodeBytes(lastNotDecoded.Concat(input).ToArray(), loadSize * 8 + 32, 32 - unDecodedBitSize, out unDecodedBitSize, output, tree, true); dataWriter.WriteBytes(output.Take((int)fileSize).ToArray()); break; } else { resultSize = DecodeBytes(lastNotDecoded.Concat(input).ToArray(), loadSize * 8 + 32, 32 - unDecodedBitSize, out unDecodedBitSize, output, tree, false); fileSize -= resultSize; lastNotDecoded[0] = input[loadSize - 4]; lastNotDecoded[1] = input[loadSize - 3]; lastNotDecoded[2] = input[loadSize - 2]; lastNotDecoded[3] = input[loadSize - 1]; dataWriter.WriteBytes(output.Take((int)resultSize).ToArray()); } } await dataWriter.StoreAsync(); await outputStream.FlushAsync(); } } } } } }
//перестроение дерева private void Rebuild(Byte?SymbolToEncode) { HuffmanTree CurrentVertex = Find(SymbolToEncode); //создание нового листа if (CurrentVertex == null) { HuffmanTree NewVertex = new HuffmanTree(); HuffmanTree LastVertex = Find(1); HuffmanTree LastVertexParent = FindParent(LastVertex); HuffmanTree VertexWithSymbol = new HuffmanTree(); 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) { HuffmanTree VertexForChange; VertexForChange = Find(Number); //перестановка узлов-родителей if (FindParent(VertexForChange) != FindParent(CurrentVertex)) { HuffmanTree Parent1 = FindParent(VertexForChange); HuffmanTree 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 { HuffmanTree 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(); } }
private int EncodeBytes(byte[] input, uint inputSize, byte[] output, int outputInitializedOffset, HuffmanTree tree) { int resultSize = outputInitializedOffset, code; for (int i = 0; i < inputSize; i++) { if (tree.Exists(input[i])) { code = tree.GetCode(input[i], out int bitsCount); for (int j = 0; j < bitsCount; j++) { SetBit(output, resultSize + j, GetBit(code, j)); } resultSize += bitsCount; } else { code = tree.GetCode(tree.newNode, out int bitsCount); for (int j = 0; j < bitsCount; j++) { SetBit(output, resultSize + j, GetBit(code, j)); } resultSize += bitsCount; code = input[i]; bitsCount = 8; for (int j = 0; j < bitsCount; j++) { SetBit(output, resultSize + j, GetBit(code, j)); } resultSize += bitsCount; } tree.Add(input[i]); } return(resultSize); }
public async Task EncodeFile(StorageFile readFile, StorageFile writeFile) { byte[] output = new byte[4096]; ulong readFileSize = (await readFile.GetBasicPropertiesAsync()).Size; ulong readSize = 0; HuffmanTree tree = new HuffmanTree(); using (IInputStream fin = await readFile.OpenSequentialReadAsync()) { using (DataReader dataReader = new DataReader(fin)) { using (IRandomAccessStream fout = await writeFile.OpenAsync(FileAccessMode.ReadWrite)) { using (IOutputStream outputStream = fout.GetOutputStreamAt(0)) { using (DataWriter dataWriter = new DataWriter(outputStream)) { int outputInitializedOffset = 0; dataWriter.WriteUInt64((await readFile.GetBasicPropertiesAsync()).Size); while (true) { uint loadSize = await dataReader.LoadAsync(2048); readSize += loadSize; double percent = (double)readSize * 100 / readFileSize; ApplicationView.GetForCurrentView().Title = percent.ToString("0.0") + "%已完成"; byte[] input = new byte[loadSize]; dataReader.ReadBytes(input); int resultBitSize = EncodeBytes(input, loadSize, output, outputInitializedOffset, tree); dataWriter.WriteBytes(output.Take(resultBitSize / 8).ToArray()); if (loadSize < 2048) { if (resultBitSize % 8 != 0) { dataWriter.WriteByte(output[resultBitSize / 8]); } break; } else { if (resultBitSize % 8 != 0) { output[0] = output[resultBitSize / 8]; outputInitializedOffset = resultBitSize % 8; } else { outputInitializedOffset = 0; } } } await dataWriter.StoreAsync(); await outputStream.FlushAsync(); } } } } } }
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) { HuffmanTree EncodingModel = new HuffmanTree(); 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(HuffmanTree.ToByte(Code.Substring(0, 8))); Code = Code.Remove(0, 8); } if (EndOfFile) { while (Buffer.Length != 8) { Buffer += "0"; } OutputFile.Write(HuffmanTree.ToByte(Buffer)); } } SourceFile.Close(); OutputFile.Close(); } return(OpenSuccessfully); }
private static void OnNotEnoughCodeEvent(ref string Code) { Code += HuffmanTree.ToBinaryString(SourceFile.ReadByte()); ProgressEvent(); }