-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFilterMain.cpp
126 lines (103 loc) · 2.98 KB
/
FilterMain.cpp
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
#include <stdio.h>
#include "cs1300bmp.h"
#include <iostream>
#include <fstream>
#include "Filter.h"
using namespace std;
#include "rtdsc.h"
//
// Forward declare the functions
//
Filter * readFilter(string filename);
double applyFilter(Filter *filter, cs1300bmp *input, cs1300bmp *output);
int
main(int argc, char **argv)
{
if ( argc < 2) {
fprintf(stderr,"Usage: %s filter inputfile1 inputfile2 .... \n", argv[0]);
}
//
// Convert to C++ strings to simplify manipulation
//
string filtername = argv[1];
//
// remove any ".filter" in the filtername
//
string filterOutputName = filtername;
string::size_type loc = filterOutputName.find(".filter");
if (loc != string::npos) {
//
// Remove the ".filter" name, which should occur on all the provided filters
//
filterOutputName = filtername.substr(0, loc);
}
Filter *filter = readFilter(filtername);
double sum = 0.0;
int samples = 0;
for (int inNum = 2; inNum < argc; inNum++) {
string inputFilename = argv[inNum];
string outputFilename = "filtered-" + filterOutputName + "-" + inputFilename;
struct cs1300bmp *input = new struct cs1300bmp;
struct cs1300bmp *output = new struct cs1300bmp;
int ok = cs1300bmp_readfile( (char *) inputFilename.c_str(), input);
if ( ok ) {
double sample = applyFilter(filter, input, output);
sum += sample;
samples++;
cs1300bmp_writefile((char *) outputFilename.c_str(), output);
}
}
fprintf(stdout, "Average cycles per sample is %f\n", sum / samples);
}
struct Filter *
readFilter(string filename)
{
ifstream input(filename.c_str());
if ( ! input.bad() ) {
int size = 0;
input >> size;
Filter *filter = new Filter(size);
int div;
input >> div;
filter -> setDivisor(div);
for (int i=0; i < size; i++) {
for (int j=0; j < size; j++) {
int value;
input >> value;
filter -> set(i,j,value);
}
}
return filter;
}
}
double
applyFilter(struct Filter *filter, cs1300bmp *input, cs1300bmp *output)
{
long long cycStart, cycStop;
cycStart = rdtscll();
output -> width = input -> width;
output -> height = input -> height;
for(int row = 1; row < (input -> height) - 1 ; row = row + 1) {
for(int col = 1; col < (input -> width) - 1; col = col + 1) {
for(int plane = 0; plane < 3; plane++) {
int value = 0;
for (int j = 0; j < filter -> getSize(); j++) {
for (int i = 0; i < filter -> getSize(); i++) {
value = value + input -> color[col + j - 1][plane][row + i - 1]
* filter -> get(i, j);
}
}
value = value / filter -> getDivisor();
if ( value < 0 ) { value = 0; }
if ( value > 255 ) { value = 255; }
output -> color[col][plane][row] = value;
}
}
}
cycStop = rdtscll();
double diff = cycStop - cycStart;
double diffPerPixel = diff / (output -> width * output -> height);
fprintf(stderr, "Took %f cycles to process, or %f cycles per pixel\n",
diff, diff / (output -> width * output -> height));
return diffPerPixel;
}