#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAX_N = 512;
const int MAX_M = 512;
const int MAX_S = 1024;
const int MAX_CODE_LEN = 16;
// 定义节点结构体,用于哈夫曼编码
struct huffman_node {
int val;
int freq;
int left;
int right;
};
// 用于构建哈夫曼树的比较函数
struct cmp {
bool operator() (const huffman_node &a, const huffman_node &b) const {
return a.freq > b.freq;
}
};
// 将一个int转换为二进制字符串
string int_to_binary(int x, int len) {
string s = "";
for (int i = 0; i < len; i++) {
if (x & (1 << i)) {
s += "1";
} else {
s += "0";
}
}
reverse(s.begin(), s.end());
return s;
}
// 将一个二进制字符串转换为int
int binary_to_int(string s) {
int x = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '1') {
x |= (1 << (s.length() - i - 1));
}
}
return x;
}
// 对一个int数组进行差分编码
void diff_encode(int a[], int n) {
for (int i = n - 1; i > 0; i--) {
a[i] -= a[i - 1];
}
}
// 对一个经过差分编码的int数组进行解码
void diff_decode(int a[], int n) {
for (int i = 1; i < n; i++) {
a[i] += a[i - 1];
}
}
// 对一个int数组进行哈夫曼编码
void huffman_encode(int a[], int n, vector &code, vector<int> &freq) {
// 统计每个值的出现次数
int cnt[MAX_S];
memset(cnt, 0, sizeof(cnt));
for (int i = 0; i < n; i++) {
cnt[a[i] + 512]++;
}
// 构建哈夫曼树
priority_queue, cmp> pq;
for (int i = 0; i < MAX_S; i++) {
if (cnt[i] > 0) {
huffman_node node = {i - 512, cnt[i], -1, -1};
pq.push(node);
}
}
while (pq.size() > 1) {
huffman_node node1 = pq.top(); pq.pop();
huffman_node node2 = pq.top();
pq.pop();
huffman_node node = {0, node1.freq + node2.freq, -1, -1};
node.left = pq.size();
node.right = pq.size() + 1;
pq.push(node);
code.push_back("");
freq.push_back(node1.freq + node2.freq);
}
// 递归地生成哈夫曼编码
/*
std::function dfs = [&](int idx, string s) {
if (idx < 0) {
return;
}
if (idx < MAX_S) {
code[idx - 512] = s;
return;
}
dfs(pq[idx].left, s + "0");
dfs(pq[idx].right, s + "1");
};
*/
std::function<void(int, string)> dfs = [&](int idx, string s) {
if (idx < 0) {
return;
}
if (idx < MAX_S) {
code[idx - 512] = s;
return;
}
/*
dfs(pq[idx].left, s + "0");
dfs(pq[idx].right, s + "1");
*/
for (int i = 0; i < idx; i++) {
//huffman_node cur = pq.top();
pq.pop();
}
// 此时 pq.top() 就是第 idx 小的元素
huffman_node cur = pq.top();
//pq.pop();
dfs(cur.left, s + "0");
dfs(cur.right, s + "1");
};
dfs(pq.size() - 1, "");
// 输出哈夫曼编码
cout << "Huffman code: " << endl;
for (int i = 0; i < MAX_S; i++) {
if (cnt[i] > 0) {
cout << i - 512 << " " << code[i - 512] << endl;
}
}
// 将哈夫曼编码写入压缩文件
ofstream fout("lena512_compressed.bin", ios::binary);
int len[MAX_S];
memset(len, 0, sizeof(len));
for (int i = 0; i < n; i++) {
string s = code[a[i] + 512];
len[a[i] + 512] = max(len[a[i] + 512], (int)s.length());
fout << s;
}
fout.close();
// 输出压缩率
int uncompressed_size = n * sizeof(int);
int compressed_size = 0;
for (int i = 0; i < MAX_S; i++) {
compressed_size += len[i] * cnt[i];
}
cout << "Compression ratio: " << (double)compressed_size / uncompressed_size << endl;
}
// 对一个经过哈夫曼编码的二进制字符串进行解码
void huffman_decode(string s, int a[], int n) {
int len[MAX_S];
memset(len, 0, sizeof(len));
for (int i = 0; i < n; i++) {
len[a[i] + 512] = max(len[a[i] + 512], MAX_CODE_LEN);
}
for (int i = 0; i < s.length(); ) {
for (int j = MAX_S - 1; j >= 0; j--) {
if (len[j] > 0 && i + len[j] <= s.length()) {
a[n++] = j - 512;
i += len[j];
len[j] = 0;
break;
}
}
}
}
// 对一个int数组进行像素S型排列
void s_order(int a[][MAX_M], int n, int m, int b[]) {
for (int i = 0; i < n * m; i++) {
int x = i / m;
int y = (i % m) * (i % 2 == 0 ? 1 : -1) + (i / 2 % 2 == 0 ? 0 : 1) * (m - 1);
b[i] = a[x][y];
}
}
// 对一个经过像素S型排列的int数组进行解码
void s_order_decode(int b[], int n, int m, int a[][MAX_M]) {
for (int i = 0; i < n * m; i++) {
int x = i / m;
int y = (i % m) * (i % 2 == 0 ? 1 : -1) + (i / 2 % 2 == 0 ? 0 : 1) * (m - 1);
a[x][y] = b[i];
}
}
int main() {
// 读入灰度图像
int a[MAX_N][MAX_M];
FILE *fp = fopen("lena512.raw", "rb");
fread(a, sizeof(unsigned char), MAX_N * MAX_M, fp);
fclose(fp);
// 像素S型排列
int b[MAX_N * MAX_M];
s_order(a, MAX_N, MAX_M, b);
// 差分编码
int c[MAX_N * MAX_M];
c[0] = b[0];
for (int i = 1; i < MAX_N * MAX_M; i++) {
c[i] = b[i] - b[i - 1];
}
// 哈夫曼编码并写入压缩文件
//int c[MAX_N][MAX_M] = {...}; // 定义 c 数组
std::vector codes; // 创建空的 codes 容器
std::vector<int> freqs; // 创建空的 freqs 容器
//huffman_encode(&c[0][0], MAX_N * MAX_M, codes, freqs); // 调用函数并传递所有参数
huffman_encode(c, MAX_N * MAX_M,codes, freqs);
// 读入压缩文件并解码
ifstream fin("lena512_compressed.bin", ios::binary);
string s((istreambuf_iterator<char>(fin)), istreambuf_iterator<char>());
int d[MAX_N * MAX_M];
huffman_decode(s, d, 0);
s_order_decode(d, MAX_N, MAX_M, a);
// 差分解码
b[0] = a[0][0];
for (int i = 1; i < MAX_N * MAX_M; i++) {
b[i] = b[i - 1] + d[i];
}
// 写入解压后的raw文件
fp = fopen("lena512_decompressed.raw", "wb");
fwrite(a, sizeof(unsigned char), MAX_N * MAX_M, fp);
fclose(fp);
return 0;
}
图像压缩代码,不知道哪里出了问题,编译通过,最后运行失败,什么也没输出,结果是:Process exited after 5.541 seconds with return value 3221225725。
请帮我看看是哪里出了问题,应该怎么改
return value 3221225725
表示程序崩溃掉了,你加断点调试一下,看看执行到哪一步崩溃的