Skip to content

Commit d81c21e

Browse files
authored
Merge pull request #12 from ErickOF/compresion
Compresion
2 parents d449211 + 576f657 commit d81c21e

12 files changed

+1587
-0
lines changed
Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
#include <systemc.h>
2+
3+
/**
4+
* @brief jpg_output module. Federico Cruz
5+
* It takes the image and compresses it into jpeg format
6+
* It is done in 4 parts:
7+
* 1. Divides the image in 8x8 pixel blocks; for 8-bit grayscale images the a level shift is done by substracting 128 from each pixel.
8+
* 2. Discrete Cosine Transform (DCT) of the 8x8 image.
9+
* 3. Each transformed 8x8 block is divided by a quantization value for each block entry.
10+
* 4. Each quantized 8x8 block is reordered by a Zig-Zag sequence into a array of size 64.
11+
* *5. Entropy compression by variable length encoding (huffman). Used to maximize compression. Not implemented here.
12+
*/
13+
#define PI 3.1415926535897932384626433832795
14+
#define Block_rows 8
15+
#define Block_cols 8
16+
17+
SC_MODULE (jpg_output) {
18+
19+
//input signals
20+
sc_in<sc_int<32> > PixelValue_signal;
21+
sc_in<sc_int<32> > row_signal;
22+
sc_in<sc_int<32> > col_signal;
23+
24+
//output signals
25+
sc_out<sc_int<8> > Element_signal;
26+
sc_in<sc_int<32> > index_signal;
27+
28+
//compression signals
29+
sc_out<sc_int<32> > output_size_signal;
30+
31+
//-----------Internal variables-------------------
32+
//const int Block_rows = 8;
33+
//const int Block_cols = 8;
34+
double* image;
35+
int image_rows = 480;
36+
int image_cols = 640;
37+
signed char EOB = 127; // end of block
38+
39+
int quantificator[8][8] = { // quantization table
40+
{16,11,10,16,24,40,51,61},
41+
{12,12,14,19,26,58,60,55},
42+
{14,13,16,24,40,57,69,56},
43+
{14,17,22,29,51,87,80,62},
44+
{18,22,37,56,68,109,103,77},
45+
{24,35,55,64,81,104,113,92},
46+
{49,64,78,87,103,121,120,101},
47+
{72,92,95,98,112,100,103,99}};
48+
49+
int zigzag_index[64]={ // zigzag table
50+
0,1,5,6,14,15,27,28,
51+
2,4,7,13,16,26,29,42,
52+
3,8,12,17,25,30,41,43,
53+
9,11,18,24,31,40,44,53,
54+
10,19,23,32,39,45,52,54,
55+
20,22,33,38,46,51,55,60,
56+
21,34,37,47,50,56,59,61,
57+
35,36,48,49,57,58,62,63};
58+
59+
sc_event starter_event;
60+
sc_event input_event;
61+
sc_event output_event;
62+
sc_event compression_event;
63+
64+
// Constructor for compressor
65+
SC_HAS_PROCESS(jpg_output);
66+
jpg_output(sc_module_name jpg_compressor): sc_module(jpg_compressor){
67+
image = new double[image_rows*image_cols];
68+
//initialize the image matrix to avoid nan
69+
for(int i=0; i<(image_rows*image_cols);i++){
70+
image[i]=0;
71+
}
72+
SC_THREAD(starter_operation);
73+
SC_THREAD(input_operation);
74+
SC_THREAD(output_operation);
75+
SC_THREAD(compression_operation);
76+
} // End of Constructor
77+
78+
//------------Code Starts Here-------------------------
79+
void Starter() {
80+
starter_event.notify(4, SC_NS);
81+
}
82+
83+
void starter_operation(){
84+
while(true) {
85+
wait(starter_event);
86+
int im_rows = row_signal.read();
87+
if(im_rows%Block_rows==0) {image_rows=im_rows;}
88+
else {image_rows=(im_rows/Block_rows+1)*Block_rows;}
89+
wait(4, SC_NS);
90+
int im_cols = col_signal.read();
91+
if(im_cols%Block_cols==0) {image_cols=im_cols;}
92+
else {image_cols=(im_cols/Block_cols+1)*Block_cols;}
93+
}
94+
}
95+
96+
void InputPixel() {
97+
input_event.notify(8, SC_NS);
98+
}
99+
100+
void input_operation(){
101+
while(true) {
102+
wait(input_event);
103+
double* i_row = &image[row_signal.read() * image_cols];
104+
i_row[col_signal.read()] = double(PixelValue_signal.read());
105+
}
106+
}
107+
108+
//void OutputPixel(int *Pixel, int row, int col) {
109+
// double* i_row = &image[row * image_cols];
110+
// *Pixel = int(i_row[col]);
111+
//}
112+
113+
void OutputByte() {
114+
output_event.notify(8, SC_NS);
115+
}
116+
117+
void output_operation(){
118+
while(true) {
119+
wait(output_event);
120+
Element_signal = image[index_signal.read()];
121+
}
122+
}
123+
124+
void JPEG_compression() {
125+
compression_event.notify(100, SC_NS);
126+
}
127+
128+
void compression_operation() {
129+
while(true) {
130+
wait(compression_event);
131+
int output_size = 0;
132+
//Level shift
133+
for(int i=0; i<(image_rows*image_cols);i++){
134+
image[i]=image[i]-128;
135+
}
136+
wait(100, SC_NS);
137+
int Number_of_blocks = image_rows*image_cols/(Block_rows*Block_cols);
138+
int block_output[Number_of_blocks][Block_rows*Block_cols] = {0};
139+
int block_output_size[Number_of_blocks] = {0};
140+
int block_counter = 0;
141+
output_size = 0;
142+
for(int row=0; row<image_rows; row+=Block_rows) {
143+
double* i_row = &image[row * image_cols];
144+
for(int col=0; col<image_cols; col+=Block_cols) { //Divided the image in 8×8 blocks
145+
DCT(row,col);
146+
Quantization(row,col);
147+
ZigZag(row,col,&block_output_size[block_counter],block_output[block_counter]);
148+
output_size += block_output_size[block_counter]+1;
149+
block_counter++;
150+
}
151+
}
152+
int output_counter = 0;
153+
for(int block_index=0;block_index<Number_of_blocks;block_index++){
154+
for(int out_index=0; out_index<block_output_size[block_index];out_index++){
155+
image[output_counter]=block_output[block_index][out_index];
156+
output_counter++;
157+
}
158+
image[output_counter]=EOB;
159+
output_counter++;
160+
}
161+
output_size_signal = output_size;
162+
}
163+
}
164+
165+
void DCT(int row_offset, int col_offset) {
166+
wait(400, SC_NS);
167+
double cos_table[Block_rows][Block_cols];
168+
for (int row = 0; row < Block_rows; row++) //make the cosine table
169+
{
170+
for (int col = 0; col < Block_cols; col++) {
171+
cos_table[row][col] = cos((((2*row)+1)*col*PI)/16);
172+
}
173+
}
174+
double temp;
175+
for(int row=row_offset; row<row_offset+Block_rows; row++)
176+
{
177+
double* i_row = &image[row * image_cols];
178+
for(int col=col_offset; col<col_offset+Block_cols; col++) {
179+
//i_row[col] = cos_table[row-row_offset][col-col_offset];
180+
temp = 0.0;
181+
for (int x = 0; x < 8; x++){
182+
double* x_row = &image[(x+row_offset) * image_cols];
183+
for (int y = 0; y < 8; y++) {
184+
temp += x_row[y+col_offset] * cos_table[x][row-row_offset] * cos_table[y][col-col_offset];
185+
}
186+
}
187+
if ((row-row_offset == 0) && (col-col_offset == 0)) {
188+
temp /= 8.0;
189+
}
190+
else if (((row-row_offset == 0) && (col-col_offset != 0)) || ((row-row_offset != 0) && (col-col_offset == 0))){
191+
temp /= (4.0*sqrt(2.0));
192+
}
193+
else {
194+
temp /= 4.0;
195+
}
196+
i_row[col] = temp;
197+
}
198+
}
199+
}
200+
201+
void Quantization(int row_offset, int col_offset) {
202+
wait(100, SC_NS);
203+
for(int row=row_offset; row<row_offset+Block_rows; row++)
204+
{
205+
double* i_row = &image[row * image_cols];
206+
for(int col=col_offset; col<col_offset+Block_cols; col++) {
207+
i_row[col] = round(i_row[col]/quantificator[row-row_offset][col-col_offset]);
208+
}
209+
}
210+
}
211+
212+
void ZigZag(int row_offset, int col_offset, int *block_output_size, int *block_output) {
213+
wait(200, SC_NS);
214+
int index_last_non_zero_value = 0; // index to last non-zero in a block zigzag array
215+
for(int row=row_offset; row<row_offset+Block_rows; row++)
216+
{
217+
double* i_row = &image[row * image_cols];
218+
for(int col=col_offset; col<col_offset+Block_cols; col++) {
219+
int temp_index = zigzag_index[(row-row_offset)*8+(col-col_offset)];
220+
block_output[temp_index]=i_row[col];
221+
if(i_row[col] !=0 && temp_index>index_last_non_zero_value) {index_last_non_zero_value = temp_index+1;}
222+
}
223+
}
224+
*block_output_size = index_last_non_zero_value;
225+
}
226+
};

0 commit comments

Comments
 (0)