16 if (node ==
nullptr)
return;
27 if (!(nodeType ==
'1' || nodeType ==
'0')) {
28 throw std::runtime_error(
"Compressed file is corrupted.");
31 if (nodeType ==
'1') {
48 uint16_t fileCount = 0;
49 infile.read(
reinterpret_cast<char*
>(&fileCount),
sizeof(fileCount));
52 std::filesystem::path p(infileName);
53 if (!std::filesystem::exists(p))
54 throw std::runtime_error(
"ERROR: Compressed file couldn't be found");
55 p = p.parent_path() / p.stem().concat(
" (decompressed)");
58 unsigned int chars = 0;
60 for (
int i = 0; i < fileCount; i++) {
61 infile.read(
reinterpret_cast<char*
>(&chars),
sizeof(chars));
68 auto path = p / fileData;
69 if (!std::filesystem::exists(path.parent_path())) {
70 if (!std::filesystem::create_directories(path.parent_path())) {
71 throw std::runtime_error(
"ERROR : Couldn't create output directories");
84 fs::path outfilePath =
files.getFront().filePath;
85 std::ofstream outfile(outfilePath, std::ios::out | std::ios::binary | std::ios::trunc);
87 throw std::runtime_error(
"Output Error : \'" + outfilePath.string() +
"\' couldn't be created");
88 std::cout <<
"Writing into : " << outfilePath.filename() << std::endl;
91 unsigned int fileChars = 0;
93 while (
infile.read(
reinterpret_cast<char*
>(&ch),
sizeof(ch)) && !
files.isEmpty()) {
94 for (
auto&& binCode : std::bitset<8>(ch).to_string()) {
97 else if (binCode ==
'1')
100 throw std::logic_error(
"Assertion error: Invalid binary code");
107 if (fileChars ==
files.getFront().fileSize) {
114 if (
files.isEmpty())
break;
116 outfilePath =
files.getFront().filePath;
117 outfile.open(outfilePath, std::ios::out | std::ios::binary | std::ios::trunc);
119 throw std::runtime_error(
"Output Error : \'" + outfilePath.string() +
"\' couldn't be created");
120 std::cout <<
"Writing into : " << outfilePath.filename() << std::endl;
130 if (!fileChars && !
files.isEmpty())
131 throw std::runtime_error(
"ERROR: Compressed file is corrupted");
135 if (fs::path(infileName).extension().
string() !=
".huf") {
136 throw std::runtime_error(
"Enter compressed (.huf) file");
139 std::cout <<
"Huffman Decompression\n";
140 std::cout << std::string(22,
char(205));
142 std::cout <<
"\nDecompressing ..." << std::endl;
143 auto start = std::chrono::steady_clock::now();
145 infile.open(infileName, std::ios::in | std::ios::binary);
147 throw std::runtime_error(
"Input Error : \'" + infileName +
"\' couldn't be opened");
149 std::cout <<
"Reading File Header ..." << std::endl;
150 std::cout <<
"Building decoding Tree ..." << std::endl;
152 std::cout <<
files.size() <<
" file(s) to be obtained after decompression" << std::endl;
154 std::cout <<
"Decoding Characters ..." << std::endl;
157 std::cout <<
"Cleaning Up ..." << std::endl;
160 std::cout <<
"Success : Decompression Completed.\n" << std::endl;
161 std::cout <<
"Decompressed Folder : " << fs::path(infileName).parent_path().string() << std::endl;
163 auto stop = std::chrono::steady_clock::now();
164 auto duration = std::chrono::duration_cast<std::chrono::duration<double>>(stop - start);
165 std::cout <<
"Decompression Time : " << duration.count() <<
" seconds\n" << std::endl;
constexpr auto INTERNAL_NODE_CHARACTER
Constants for Huffman Tree.
constexpr auto FILE_NAME_SEPARATOR
Constants for file Header.
This class models a node structure used for building Huffman Binary Tree.
BinNode * getRightChild() const
void setRightChild(BinNode *)
sets parameter node as left child of the caller node instance.
void setLeftChild(BinNode *)
sets parameter node as left child of the caller node instance.
BinNode * getLeftChild() const
char getCharacter() const
void clear()
Resets all the attributes for next decompression operation.
std::ifstream infile
Instance of ifstream class for reading encoded characters from compressed file.
Queue< fileInfo > files
Queue of input file(s) to be decompressed.
void readHeader(const std::string &infileName, std::ifstream &infile)
Reads the header section from compressed file.
void deleteTree(BinNode *node)
Frees all heap storage associated with the Huffman Tree.
void decompressFile(const std::string &infileName)
Decompresses the compressed(.huf) file to its original form.
BinNode * rootNode
Root node for Huffman tree.
void writeIntoFile(const std::string &infileName)
Decodes encoded characters using the tree obtained from header section.
BinNode * readTree(std::ifstream &reader)
Reads the entire Huffman tree in to the file header section using a pre-order traversal algorithm.
Structure to hold file metadata.