Skip to content

Commit 1facc48

Browse files
committed
huffman for image
1 parent de024b5 commit 1facc48

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

huffman_image.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include <bits/stdc++.h>
2+
using namespace std;
3+
#define STB_IMAGE_IMPLEMENTATION
4+
#include "stb_image.h"
5+
6+
struct pixel{
7+
float freq;
8+
int label;
9+
pixel* left, *right;
10+
11+
pixel(int x, float y): label(x), freq(y){
12+
left = NULL;
13+
right = NULL;
14+
}
15+
16+
void print(){
17+
cout << label << " " << freq << endl;
18+
}
19+
};
20+
21+
struct compare{
22+
bool operator() (pixel* a, pixel* b){
23+
return a->freq > b->freq;
24+
}
25+
};
26+
27+
string code[256];
28+
29+
void preoder(pixel* root, string s){
30+
31+
if(root->label != -1){
32+
cout << setfill(' ') << setw(3) << root->label
33+
<< " -> " << setw(15) << s << setw(20) << fixed << setprecision(8) << root->freq << endl;
34+
code[root->label] = s;
35+
return;
36+
}
37+
38+
preoder(root->left, s + '0');
39+
preoder(root->right, s + '1');
40+
41+
return;
42+
}
43+
44+
45+
int main()
46+
{
47+
int width, height, bpp;
48+
49+
uint8_t* rgb_image = stbi_load("/home/sundesh/Downloads/colombia.jpg", &width, &height, &bpp, 1);
50+
51+
int image[height][width];
52+
int itr = 0;
53+
for (int i = 0; i < height; ++i)
54+
for (int j = 0; j < width; ++j)
55+
image[i][j] = rgb_image[itr++];
56+
57+
stbi_image_free(rgb_image);
58+
59+
int hist[256] = {0};
60+
61+
for (int i = 0; i < height; i++)
62+
for (int j = 0; j < width; j++)
63+
hist[image[i][j]] += 1;
64+
65+
int totpix = height*width;
66+
67+
float freq[256] = {0};
68+
69+
for (int i = 0; i < 256; ++i)
70+
freq[i] = ((float)hist[i])/totpix;
71+
72+
73+
74+
priority_queue<pixel*, vector<pixel*>, compare> pq;
75+
76+
for(int i = 0; i < 256; i++){
77+
if (freq[i] > 0){
78+
pixel* tmp = new pixel(i, freq[i]);
79+
pq.push(tmp);
80+
}
81+
}
82+
83+
while(pq.size() > 1){
84+
pixel* first = pq.top();
85+
pq.pop();
86+
pixel* second = pq.top();
87+
pq.pop();
88+
pixel* tmp = new pixel(-1, first->freq + second->freq);
89+
tmp->left = first;
90+
tmp->right = second;
91+
pq.push(tmp);
92+
}
93+
94+
pixel* root = pq.top();
95+
96+
preoder(root, "");
97+
98+
int compression_size = 0;
99+
100+
for (int i = 0;i < height; ++i)
101+
{
102+
for (int j = 0; j < width; ++j)
103+
{
104+
compression_size += code[image[i][j]].size();
105+
}
106+
}
107+
108+
cout << compression_size << " " << 256*256*8 << endl;
109+
110+
111+
return 0;
112+
}
113+

0 commit comments

Comments
 (0)