-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdecompression.c
More file actions
195 lines (171 loc) · 8.4 KB
/
decompression.c
File metadata and controls
195 lines (171 loc) · 8.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
* decompression.c
* by Ahmed Aly & Ryan Vasios, 2/28/14
* Assignment 4
*
* Functions used to decompress an image in the comp40 image
* format back into pnm format.
*/
#include <decompression.h>
/*
* unpack takes in 8bit characters and combines them using
* bitpack into one 64bit unsigned int. Then it unpacks the
* a,b,c,d,Pravg, and Pbavg from it and it stores this information
* in a struct and returns a pointer to it.
*/
void unpack(int c1, int c2, int c3, int c4, abcd currentabcd)
{
uint64_t word = 0;
word = Bitpack_newu(word, 8, 0, (uint64_t)c4);
word = Bitpack_newu(word, 8, 8, (uint64_t)c3);
word = Bitpack_newu(word, 8, 16, (uint64_t)c2);
word = Bitpack_newu(word, 8, 24, (uint64_t)c1);
currentabcd-> a = Bitpack_getu(word, 6, 26);
currentabcd-> b = Bitpack_gets(word, 6, 20);
currentabcd-> c = Bitpack_gets(word, 6, 14);
currentabcd-> d = Bitpack_gets(word, 6, 8);
currentabcd-> Pbavg = Bitpack_getu(word, 4, 4);
currentabcd-> Pravg = Bitpack_getu(word, 4, 0);
}
/* ABCD_to_XYZ converts a,b,c,d, Pbavg, and Pravg values back to
* Y, Pb, and Pr values for each pixel.
*/
A2Methods_UArray2 ABCD_to_XYZ(UArray_T abcds, unsigned width, unsigned height)
{
A2Methods_T methods = uarray2_methods_plain;
A2Methods_UArray2 decomp_image = methods -> new (width, height,
sizeof(struct XYZvals));
int index = 0;
abcd currentABCD;
XYZvals currentXYZ1, currentXYZ2, currentXYZ3, currentXYZ4;
for (unsigned row = 0; row < height; row = row + 2)
for (unsigned col = 0 ; col < width; col = col + 2)
{
{
currentXYZ1 = (XYZvals)
(methods->at(decomp_image, col, row));
currentXYZ2 = (XYZvals)
(methods->at(decomp_image, col+1, row));
currentXYZ3 = (XYZvals)
(methods->at(decomp_image, col, row+1));
currentXYZ4 = (XYZvals)
(methods->at(decomp_image, col+1, row+1));
currentABCD = (abcd)UArray_at(abcds, index);
float a = (float)currentABCD->a/63;
a = clip(a, 0, 1);
float b = sint_to_float( currentABCD->b, 0.3, 31);
b = clip(b, -.5, .5);
float c = sint_to_float( currentABCD->c, 0.3, 31);
c = clip(c, -.5, .5);
float d = sint_to_float( currentABCD->d, 0.3, 31);
d = clip(d, -.5, .5);
currentXYZ1->Y = a - b - c + d;
currentXYZ1->Y = clip(currentXYZ1->Y, 0, 1);
currentXYZ2->Y = a - b + c - d;
currentXYZ2->Y = clip(currentXYZ2->Y, 0, 1);
currentXYZ3->Y = a + b - c - d;
currentXYZ3->Y = clip(currentXYZ3->Y, 0, 1);
currentXYZ4->Y = a + b + c + d;
currentXYZ4->Y = clip(currentXYZ4->Y, 0, 1);
currentXYZ1->Pb = Arith40_chroma_of_index(currentABCD->Pbavg);
currentXYZ1->Pb = clip(currentXYZ1->Pb, -.5, .5);
currentXYZ2->Pb = Arith40_chroma_of_index(currentABCD->Pbavg);
currentXYZ2->Pb = clip(currentXYZ2->Pb, -.5, .5);
currentXYZ3->Pb = Arith40_chroma_of_index(currentABCD->Pbavg);
currentXYZ3->Pb = clip(currentXYZ3->Pb, -.5, .5);
currentXYZ4->Pb = Arith40_chroma_of_index(currentABCD->Pbavg);
currentXYZ4->Pb = clip(currentXYZ4->Pb, -.5, .5);
currentXYZ1->Pr = Arith40_chroma_of_index(currentABCD->Pravg);
currentXYZ1->Pb = clip(currentXYZ1->Pb, -.5, .5);
currentXYZ2->Pr = Arith40_chroma_of_index(currentABCD->Pravg);
currentXYZ2->Pb = clip(currentXYZ2->Pb, -.5, .5);
currentXYZ3->Pr = Arith40_chroma_of_index(currentABCD->Pravg);
currentXYZ3->Pb = clip(currentXYZ3->Pb, -.5, .5);
currentXYZ4->Pr = Arith40_chroma_of_index(currentABCD->Pravg);
currentXYZ4->Pb = clip(currentXYZ4->Pb, -.5, .5);
index++;
}
}
return decomp_image;
}
/*
* XYZ_to_RGB converts Y, Pb, and Pr values for each pixel into pnm format.The
* function returns a pnm_ppm sturct pointer. It takes in an A2Methods_Uarray2
* of Y, Pb, and Pr values.
*/
Pnm_ppm XYZ_to_RGB(A2Methods_UArray2 decompXYZs)
{
A2Methods_T methods = uarray2_methods_plain;
Pnm_ppm decompressedPNM = malloc( sizeof(struct Pnm_ppm) );
decompressedPNM->width = methods->width(decompXYZs);
decompressedPNM->height = methods->height(decompXYZs);
decompressedPNM->denominator = 255;
decompressedPNM->pixels = methods->new(decompressedPNM->width,
decompressedPNM->height, sizeof(struct Pnm_rgb) );
Pnm_rgb pixelPointer= NULL;
XYZvals currentXYZ = NULL;
for (unsigned row = 0; row < decompressedPNM->height; row++)
for (unsigned col = 0 ; col < decompressedPNM->width; col++)
{
{
pixelPointer = methods->at
(decompressedPNM->pixels, col, row);
currentXYZ = methods->at(decompXYZs, col, row);
float r = ( ( 1 * currentXYZ->Y ) + ( 0.0 *
currentXYZ->Pb ) + (1.402 * currentXYZ->Pr) );
r = clip(r, 0, 1);
float g= ( ( 1 * currentXYZ->Y ) + ( -0.344136 *
currentXYZ->Pb )+ (-0.714136 * currentXYZ->Pr));
g = clip(g, 0, 1);
float b = ( ( 1 * currentXYZ->Y ) + ( 1.772 *
currentXYZ->Pb )+ (0 * currentXYZ->Pr));
b = clip(b, 0, 1);
pixelPointer-> red = (unsigned)(r * decompressedPNM
->denominator);
pixelPointer->red = clip_unsigned( pixelPointer->
red, 0, 255);
pixelPointer-> green = (unsigned)(g * decompressedPNM
->denominator);
pixelPointer->green = clip_unsigned( pixelPointer
->green, 0, 255);
pixelPointer-> blue = (unsigned)(b * decompressedPNM
->denominator);
pixelPointer->blue = clip_unsigned( pixelPointer
->blue, 0, 255);
}
}
return decompressedPNM;
}
/* Function sint_to_float converts a quantized signed integer back to
* to an unquantized float. It take the quantized integer, it's quantized
* upper bound and the unquantized upper bound.
*/
float sint_to_float(int integer, float fl_upbound, unsigned int_upbound)
{
float fl =(float)integer*(fl_upbound/int_upbound);
return fl;
}
/* decompression_caller takes in the a, b, c, d, Pbavg, and Pravg
* values and calls all the functions necessary to decompress back
* into pnm format.
*/
void decompression_caller(UArray_T abcds, unsigned width, unsigned height)
{
A2Methods_UArray2 XYZarray= ABCD_to_XYZ(abcds, width, height);
Pnm_ppm decomp_pixmap = XYZ_to_RGB(XYZarray);
A2Methods_T methods = uarray2_methods_plain;
printf("P6\n%u %u\n%u\n", width, height, 255);
for (unsigned row=0 ; row < height; row++)
{
for( unsigned col = 0; col < width; col++)
{
Pnm_rgb currentRGB = methods->at(decomp_pixmap->pixels,
col, row);
printf("%c%c%c", currentRGB->red, currentRGB->green,
currentRGB->blue);
}
}
methods->free(&decomp_pixmap->pixels);
free(decomp_pixmap);
methods->free(&XYZarray);
}