The unified diff between revisions [45197df6..] and [0612e061..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "aca319/lab8q1.c"
# from [7a174ce6c938185e31421514b55073736fae82fe]
# to [f391acba5e0138fd0d949368633dcaef74671351]
#
============================================================
--- aca319/lab8q1.c 7a174ce6c938185e31421514b55073736fae82fe
+++ aca319/lab8q1.c f391acba5e0138fd0d949368633dcaef74671351
@@ -3,11 +3,12 @@
#include <stdlib.h>
#include <assert.h>
#include <string.h>
+#include <math.h>
-#define POINTER(img,x,y) (img+(3 * (((x)*width)+(y))) )
+#define POINTER(img,x,y) (img+(((x)*width)+(y)))
unsigned char *
-load_ppm(const unsigned char *filename, int *width, int *height)
+load_pgm(const unsigned char *filename, int *width, int *height)
{
FILE *f = fopen(filename, "r");
int v, mv;
@@ -17,7 +18,7 @@ load_ppm(const unsigned char *filename,
fprintf(stderr, "Unable to load input file: %s\n", filename);
return NULL;
}
- if ((fscanf(f, "P%d\n", &v) == EOF) || (v != 6)) {
+ if ((fscanf(f, "P%d\n", &v) == EOF) || (v != 5)) {
fprintf(stderr, "Wrong file version.\n");
return NULL;
}
@@ -34,12 +35,12 @@ load_ppm(const unsigned char *filename,
fprintf(stderr, "Unable to allocate image buffer\n");
return NULL;
}
- fread(rv, sizeof(unsigned char), *height * *width * 3, f);
+ fread(rv, sizeof(unsigned char), *height * *width, f);
return rv;
}
void
-write_ppm(const unsigned char *filename, int width, int height, const unsigned char *data)
+write_pgm(const unsigned char *filename, int width, int height, const unsigned char *data)
{
FILE *out;
@@ -48,49 +49,49 @@ write_ppm(const unsigned char *filename,
fprintf(stderr, "Unable to open output file.\n");
return;
}
- fprintf(out, "P6\n%d %d\n255\n", width, height);
- fwrite(data, sizeof(unsigned char), width*height*3, out);
+ fprintf(out, "P5\n%d %d\n255\n", width, height);
+ fwrite(data, sizeof(unsigned char), width*height, out);
fclose(out);
}
-void
-minimum(const unsigned char **pixels, int count, char *result)
+unsigned char
+minimum(const unsigned char **pixels, int count)
{
- int i, p;
- for (p=0;p<3;p++) {
- result[p] = *(pixels[0] + p);
- for (i=0;i<count;i++) {
- if (*(pixels[i] + p) < result[p])
- result[p] = *(pixels[i] + p);
- }
+ int i;
+ unsigned char rv;
+
+ rv = *(pixels[0]);
+ for (i=1;i<count;i++) {
+ if (*(pixels[i]) < rv)
+ rv = *(pixels[i]);
}
+ return rv;
}
-void
-maximum(const unsigned char **pixels, int count, char *result)
+unsigned char
+maximum(const unsigned char **pixels, int count)
{
- int i, p;
- for (p=0;p<3;p++) {
- result[p] = *(pixels[0] + p);
- for (i=0;i<count;i++) {
- if (*(pixels[i] + p) > result[p])
- result[p] = *(pixels[i] + p);
- }
+ int i;
+ unsigned char rv;
+
+ rv = *(pixels[0]);
+ for (i=1;i<count;i++) {
+ if (*(pixels[i]) > rv)
+ rv = *(pixels[i]);
}
+ return rv;
}
-void
-average(const unsigned char **pixels, int count, char *result)
+unsigned char
+average(const unsigned char **pixels, int count)
{
- int i, p;
+ int i;
+ int total = 0;
- for (p=0;p<3;p++) {
- int total = 0;
- for (i=0;i<count;i++) {
- total += *(pixels[i] + p);
- }
- result[p] = total / count;
+ for (i=0;i<count;i++) {
+ total += *(pixels[i]);
}
+ return total / count;
}
int
@@ -101,10 +102,10 @@ char_compare(const void *a, const void *
return c - d;
}
-void
-median(const unsigned char **pixels, int count, char *result)
+unsigned char
+median(const unsigned char **pixels, int count)
{
- int i, p;
+ int i;
int median;
unsigned char *s = calloc(count, sizeof(unsigned char));
@@ -112,47 +113,45 @@ median(const unsigned char **pixels, int
fprintf(stderr, "Out of memory in median()\n");
}
- for (p=0;p<3;p++) {
- for (i=0;i<count;i++) {
- s[i] = *(pixels[i] + p);
- }
- qsort(s, count, sizeof(unsigned char), char_compare);
- if (count % 2) {
- /* average the two middle values to get median */
- median = (s[count/2] + s[(count/2)+1]) / 2;
- } else {
- median = s[count/2];
- }
- result[p] = median;
+ for (i=0;i<count;i++) {
+ s[i] = *(pixels[i]);
}
+ qsort(s, count, sizeof(unsigned char), char_compare);
+ if (count % 2) {
+ /* average the two middle values to get median */
+ median = (s[count/2] + s[(count/2)+1]) / 2;
+ } else {
+ median = s[count/2];
+ }
free(s);
+ return median;
}
unsigned char *
run_filter(const unsigned char *clean_image, const unsigned char *dirty_image,
int width, int height,
- void (*filter_function)(const unsigned char **, int, char *),
+ unsigned char (*filter_function)(const unsigned char **, int),
double *error)
{
unsigned char *rv;
int i, j;
const unsigned char *cells[9];
+ unsigned long long error_count=0;
assert(clean_image != NULL);
assert(dirty_image != NULL);
assert(error != NULL);
- rv = calloc(sizeof(unsigned char), height * width * 3);
+ rv = calloc(sizeof(unsigned char), height * width);
if (!rv) {
fprintf(stderr, "Out of memory in run_filter\n");
return NULL;
}
- fprintf(stderr, "Applying filter to image of size %dx%d\n", width, height);
-
for (i=0;i<height;i++) {
for (j=0;j<width;j++) {
const unsigned char *clean, *unfiltered;
+ unsigned char filtered;
int count;
clean = POINTER(clean_image, i, j);
@@ -197,11 +196,14 @@ run_filter(const unsigned char *clean_im
cells[count] = POINTER(dirty_image, i+1, j+1);
count++;
}
-
- filter_function(cells, count, rv + (3 * ((i*width) + j)));
+ filtered = filter_function(cells, count);
+ *POINTER(rv, i, j) = filtered;
+ error_count += ((unsigned int)*clean - (unsigned int)filtered) * ((unsigned int)*clean - (unsigned int)filtered);
}
}
+ *error = error_count / (width * height);
+
return rv;
}
@@ -213,24 +215,28 @@ main(int argc, char *argv[])
unsigned char *clean, *noisy;
unsigned char *result;
- clean = load_ppm("ViGIR.ppm", &width, &height);
- noisy = load_ppm("ViGIRnoisy.ppm", &width, &height);
+ clean = load_pgm("ViGIR.pgm", &width, &height);
+ noisy = load_pgm("ViGIRnoisy.pgm", &width, &height);
-// write_ppm("bypass.ppm", width, height, noisy);
+// write_pgm("bypass.pgm", width, height, noisy);
result = run_filter(clean, noisy, width, height, minimum, &error);
- write_ppm("minimum.ppm", width, height, result);
+ printf("Minimum: error is %f\n", error);
+ write_pgm("minimum.pgm", width, height, result);
free(result);
result = run_filter(clean, noisy, width, height, maximum, &error);
- write_ppm("maximum.ppm", width, height, result);
+ printf("Maximum: error is %f\n", error);
+ write_pgm("maximum.pgm", width, height, result);
free(result);
result = run_filter(clean, noisy, width, height, average, &error);
- write_ppm("average.ppm", width, height, result);
+ printf("Average: error is %f\n", error);
+ write_pgm("average.pgm", width, height, result);
free(result);
result = run_filter(clean, noisy, width, height, median, &error);
- write_ppm("median.ppm", width, height, result);
+ printf("Median: error is %f\n", error);
+ write_pgm("median.pgm", width, height, result);
free(result);
free(clean);