-
Notifications
You must be signed in to change notification settings - Fork 0
/
rgbComponentConversions.c
153 lines (127 loc) · 4.93 KB
/
rgbComponentConversions.c
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
// TODO: pass in methods to files
#include "rgbComponentConversions.h"
#include <string.h> // TODO: remove
#define A2 A2Methods_Array2
// TODO: Change argument(s) to A2, denominator, w, h
extern A2 scaledIntToFloat(Pnm_ppm img)
{
assert(img);
int h = img->height;
assert(h > 0);
int w = img->width;
assert(w > 0);
float denom = (float) img->denominator;
assert(denom > 0.0 && denom < 65536.0);
A2 pixmap = img->pixels;
assert(pixmap); // TODO: check this out later
A2Methods_T methods = array2_methods_plain;
A2 floatMap = methods->new(methods->width(pixmap),
methods->height(pixmap),
sizeof(struct rgb_float));
if(h % 2 == 1)
h = h - 1;
if(w % 2 == 1)
w = w - 1;
// int testWidth = Array2_width(floatMap);
// printf("TESTWIDTH: %i\n", testWidth);
/* Get Pnm_rgb from original A2
* Get rgb_float struct from output A2
* Create values and stick them in output struct
* */
for(int row = 0; row < h; row++)
{
for(int col = 0; col < w; col++)
{
Pnm_rgb intTemp = (Pnm_rgb) methods->at(pixmap, col, row);
rgb_float floatTemp = (rgb_float) methods->at(floatMap, col, row);
floatTemp->r = ((float) intTemp->red) / denom;
floatTemp->g = ((float) intTemp->green) / denom;
floatTemp->b = ((float) intTemp->blue) / denom;
}
}
return floatMap;
}
// TODO: Restructure/Clean up function
extern A2 rgbFloatToYbrFloat(A2 rgbFloatArray, int h, int w)
{
assert(rgbFloatArray);
assert(h > 0);
assert(w > 0);
A2Methods_T methods = array2_methods_plain;
A2 ybrMap = methods->new(methods->width(rgbFloatArray),
methods->height(rgbFloatArray),
sizeof(struct ybr_float));
for(int row = 0; row < h; row++)
{
for(int col = 0; col < w; col++)
{
rgb_float rgbFloatTemp = (rgb_float) methods->at(rgbFloatArray, col, row);
ybr_float ybrFloatTemp = (ybr_float) methods->at(ybrMap, col, row);
float red = rgbFloatTemp->r;
float green = rgbFloatTemp->g;
float blue = rgbFloatTemp->b;
ybrFloatTemp->y = 0.299 * red + 0.587 * green + 0.114 * blue;
ybrFloatTemp->Pb = -0.168736 * red - 0.331264 * green + 0.5 * blue;
ybrFloatTemp->Pr = 0.5 * red - 0.418688 * green - 0.081312 * blue;
//printf("YBR VALUES: Y: %f, B: %f, R: %f\n", ybrFloatTemp->y, ybrFloatTemp->Pb, ybrFloatTemp->Pr);
}
}
return ybrMap;
}
extern A2 ybrFloatToRgbFloat(A2 ybrFloatMap)
{
assert(ybrFloatMap);
int w = Array2_width(ybrFloatMap);
assert(w > 0);
int h = Array2_height(ybrFloatMap);
assert(h > 0);
A2Methods_T methods = array2_methods_plain;
A2 rgbFloatMap = methods->new(methods->width(ybrFloatMap),
methods->height(ybrFloatMap),
sizeof(struct rgb_float));
for(int row = 0; row < h; row++)
{
for(int col = 0; col < w; col++)
{
ybr_float ybrFloatTemp = (ybr_float) methods->at(ybrFloatMap, col, row);
rgb_float rgbFloatTemp = (rgb_float) methods->at(rgbFloatMap, col, row);
float y = ybrFloatTemp->y;
float Pb = ybrFloatTemp->Pb;
float Pr = ybrFloatTemp->Pr;
rgbFloatTemp->r = 1.0 * y + 0.0 * Pb + 1.402 * Pr;
rgbFloatTemp->g = 1.0 * y - 0.344136 * Pb - 0.714136 * Pr;
rgbFloatTemp->b = 1.0 * y + 1.772 * Pb + 0.0 * Pr;
//printf("RGB FLOAT VALUES: R: %f, G: %f, B: %f\n", rgbFloatTemp->r, rgbFloatTemp->g, rgbFloatTemp->b);
}
}
return rgbFloatMap;
}
extern A2 rgbFloatToScaledInt(A2 rgbFloatMap)
{
assert(rgbFloatMap);
int h = Array2_height(rgbFloatMap);
assert(h > 0);
int w = Array2_width(rgbFloatMap);
assert(w > 0);
//TODO: denom will be 255
float denom = 255.0;
//assert(pixmap); // TODO: check this out later
A2Methods_T methods = array2_methods_plain;
A2 rgbIntMap = methods->new(methods->width(rgbFloatMap),
methods->height(rgbFloatMap),
sizeof(struct rgb_int));
for(int row = 0; row < h; row++)
{
for(int col = 0; col < w; col++)
{
rgb_float floatTemp = (rgb_float) methods->at(rgbFloatMap, col, row);
rgb_int intTemp = (rgb_int) methods->at(rgbIntMap, col, row);
intTemp->r = (int) roundf(((floatTemp->r) * denom));
intTemp->g = (int) roundf(((floatTemp->g) * denom));
intTemp->b = (int) roundf(((floatTemp->b) * denom));
//printf("RGB SCALED INT VALUES: R: %i, G: %i, B: %i\n", intTemp->r, intTemp->g, intTemp->b);
}
}
return rgbIntMap;
}
#undef A2