Fetch the repository succeeded.
This action will force synchronization from pppsh/GZip文件压缩, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include "HuffmanCompress.hpp"
#include "huffman.hpp"
#include "UseForLZ.hpp"
HuffmanCompress::HuffmanCompress() {
_status.resize(256);
for (int i = 0; i < 256; ++i) {
_status[i]._ch = i;
}
}
void HuffmanCompress::CompressFile(const string& filePath, string outPath) {
FILE* fIn = fopen(filePath.c_str(), "rb");
if (nullptr == fIn) {
std::cout << "无法打开文件" << std::endl;
return;
}
unsigned char readBuf[1024];
while (1) {
size_t size = fread(readBuf, 1, 1024, fIn);
if (0 == size) {
break;
}
for (size_t i = 0; i < size; ++i) {
_status[readBuf[i]]._appareCount++;
}
}
FreqInfo vaild;
HuffmanTree<FreqInfo> ht(_status, vaild);
//获取huffman编码
GetHuffmanCode(ht.GetRoot());
fseek(fIn, 0, SEEK_SET);
if (outPath == "") {
outPath += GetFileName(filePath);
outPath += ".huffman";
}
//打开压缩文件
FILE* fOut = fopen(outPath.c_str(), "wb");
unsigned char tmp = 0;
int tmpCnt = 0;
//压缩文件头部
//文件类型
//频次信息总行数
//文件频次信息
PutsHead(filePath, fOut);
while (1) {
size_t readSize = fread(readBuf, 1, 1024, fIn);
if (0 == readSize) break;
for (size_t i = 0; i < readSize; ++i) {
string& s = _status[readBuf[i]]._enCode;
for (size_t k = 0; k < s.size(); ++k) {
tmp <<= 1;
if ('1' == s[k]) tmp |= 1;
tmpCnt++;
if (8 == tmpCnt) {
fputc(tmp, fOut);
tmp = 0;
tmpCnt = 0;
}
}
}
}
if (tmpCnt > 0 && tmpCnt < 8) {
tmp <<= (8 - tmpCnt);
fputc(tmp, fOut);
}
fclose(fIn);
fclose(fOut);
}
void HuffmanCompress::GetHuffmanCode(HuffmanTreeNode<FreqInfo>* root) {
if (nullptr == root) {
std::cout << "编码出错" << std::endl;
return;
}
enCode(root);
}
void HuffmanCompress::enCode(HuffmanTreeNode<FreqInfo>* root) {
if (nullptr == root->_left && nullptr == root->_right) {
string& code = _status[root->_weight._ch]._enCode;
code = root->_weight._enCode;
}
if (nullptr != root->_left) {
root->_left->_weight._enCode += root->_weight._enCode + '0';
enCode(root->_left);
}
if (nullptr != root->_right) {
root->_right->_weight._enCode += root->_weight._enCode + '1';
enCode(root->_right);
}
}
void HuffmanCompress::PutsHead(const string& filePath, FILE* fOut) {
string headInfo;
//文件后缀
//headInfo += filePath;
headInfo += GetsFileTail(filePath);
headInfo += '\n';
size_t lineCnt = 0;
string tmp;
//频次信息
for (auto& i : _status) {
if (0 == i._appareCount)
continue;
tmp += i._ch;
tmp += ':';
tmp += std::to_string(i._appareCount);
tmp += '\n';
lineCnt++;
}
headInfo += std::to_string(lineCnt);
headInfo += '\n';
fwrite(headInfo.c_str(), 1, headInfo.size(), fOut);
fwrite(tmp.c_str(), 1, tmp.size(), fOut);
}
string HuffmanCompress::GetsFileTail(const string& filePath) {
return filePath.substr(filePath.find_last_of('.') + 1);
}
void HuffmanCompress::DeCmpressFile(const string& filePath, string name) {
string postfix = GetsFileTail(filePath);
if (postfix != "huffman") {
std::cout << "文件格式错误" << std::endl;
return;
}
FILE* fIn = fopen(filePath.c_str(), "rb");
if (nullptr == fIn) {
std::cout << "解压缩文件路径错误" << std::endl;
return;
}
string tmp;
GetLine(fIn, tmp);
if (name.size() == 0) {
name += GetFileName(filePath);
name += "_hfm";
name += '.';
name += tmp;
}
FILE* fOut = fopen(name.c_str(), "wb");
tmp = "";
GetLine(fIn, tmp);
size_t lineCnt = atoi(tmp.c_str());
for (int i = 0; i < lineCnt; ++i) {
tmp = "";
GetLine(fIn, tmp);
if ("" == tmp) {
tmp += '\n';
GetLine(fIn, tmp);
}
unsigned char t = tmp[0];
//放到对应位置
_status[t]._ch = t;
_status[t]._appareCount = atoi(tmp.c_str() + 2);
}
FreqInfo vaild;
HuffmanTree<FreqInfo> ht(_status, vaild);
unsigned char readBuf[1024];
HuffmanTreeNode<FreqInfo>* cur = ht.GetRoot();
size_t cnt = cur->_weight._appareCount;
while (1) {
size_t size = fread(readBuf, 1, 1024, fIn);
if (0 == size) {
break;
}
//std::cout << size << std::endl;
for (size_t i = 0; i < size; ++i) {
char ch = readBuf[i];
for (int k = 0; k < 8; ++k) {
if (ch & 0x80) cur = cur->_right;
else cur = cur->_left;
ch <<= 1;
if (nullptr == cur->_left && nullptr == cur->_right) {
fputc(cur->_weight._ch, fOut);
cur = ht.GetRoot();
--cnt;
if (!cnt) break;
}
}
}
}
fclose(fIn);
fclose(fOut);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。