The unified diff between revisions [9dda360f..] and [56e5a93f..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'aca319/lab8q1.c'

#
#
# patch "aca319/lab8q1.c"
#  from [0340b163efbfa59fc2fb6cc3362ba6eb71ce7bf5]
#    to [8ff5f24b4a00f634973be72edd4ab692d98bb232]
#
============================================================
--- aca319/lab8q1.c	0340b163efbfa59fc2fb6cc3362ba6eb71ce7bf5
+++ aca319/lab8q1.c	8ff5f24b4a00f634973be72edd4ab692d98bb232
@@ -4,7 +4,7 @@
 #include <assert.h>
 #include <string.h>

-#define POINTER(img,x,y)		( img + ( 3 * ((x*width)+y)) )
+#define POINTER(img,x,y)		(img+(3 * (((x)*width)+(y))) )

 unsigned char *
 load_ppm(const unsigned char *filename, int *width, int *height)
@@ -59,7 +59,7 @@ minimum(const unsigned char **pixels, in
 	int i, p;
 	for (p=0;p<3;p++) {
 		result[p] = *(pixels[0] + p);
-		for (i=1;i<count;i++) {
+		for (i=0;i<count;i++) {
 			if (*(pixels[i] + p) < result[p])
 				result[p] = *(pixels[i] + p);
 		}
@@ -71,10 +71,10 @@ maximum(const unsigned char **pixels, in
 {
 	int i, p;
 	for (p=0;p<3;p++) {
-		result[p] = pixels[0][p];
-		for (i=1;i<count;i++) {
-			if (pixels[i][p] > result[p])
-				result[p] = pixels[i][p];
+		result[p] = *(pixels[0] + p);
+		for (i=0;i<count;i++) {
+			if (*(pixels[i] + p) > result[p])
+				result[p] = *(pixels[i] + p);
 		}
 	}
 }
@@ -83,12 +83,13 @@ average(const unsigned char **pixels, in
 average(const unsigned char **pixels, int count, char *result)
 {
 	int i, p;
+
 	for (p=0;p<3;p++) {
-		result[p] = 0;
+		int total = 0;
 		for (i=0;i<count;i++) {
-			result[p] += pixels[i][p];
+			total += *(pixels[i] + p);
 		}
-		result[p] /= count;
+		result[p] = total / count;
 	}
 }

@@ -103,7 +104,28 @@ median(const unsigned char **pixels, int
 void
 median(const unsigned char **pixels, int count, char *result)
 {
+	int i, p;
+	int median;

+	unsigned char *s = calloc(count, sizeof(unsigned char));
+	if (!s) {
+		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), int_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;
+	}
+	free(s);
 }

 unsigned char *
@@ -120,7 +142,7 @@ run_filter(const unsigned char *clean_im
 	assert(dirty_image != NULL);
 	assert(error != NULL);

-	rv = malloc(sizeof(unsigned char) * height * width * 3);
+	rv = calloc(sizeof(unsigned char), height * width * 3);
 	if (!rv) {
 		fprintf(stderr, "Out of memory in run_filter\n");
 		return NULL;
@@ -137,8 +159,11 @@ run_filter(const unsigned char *clean_im
 			unfiltered = POINTER(dirty_image, i, j);

 			count = 0;
-			/* the row above */
-			if ((i > 0) &  (j > 0)) {
+			/* this cell; always should be added */
+			cells[count] = unfiltered;
+			count++;
+			/* the row below */
+			if ((i > 0) && (j > 0)) {
 				cells[count] = POINTER(dirty_image, i-1, j-1);
 				count++;
 			}
@@ -146,7 +171,7 @@ run_filter(const unsigned char *clean_im
 				cells[count] = POINTER(dirty_image, i-1, j);
 				count++;
 			}
-			if ((i > 0) &  (j < width)) {
+			if ((i > 0) && (j < (width - 1))) {
 				cells[count] = POINTER(dirty_image, i-1, j+1);
 				count++;
 			}
@@ -155,22 +180,20 @@ run_filter(const unsigned char *clean_im
 				cells[count] = POINTER(dirty_image, i, j-1);
 				count++;
 			}
-			cells[count] = unfiltered;
-			count++;
-			if (j<height) {
+			if (j<width-1) {
 				cells[count] = POINTER(dirty_image, i, j+1);
 				count++;
 			}
-			/* the row below */
-			if ((i < height) &  (j > 0)) {
+			/* the row above */
+			if ((i < height - 1) && (j > 0)) {
 				cells[count] = POINTER(dirty_image, i+1, j-1);
 				count++;
 			}
-			if (i < height) {
+			if (i < height - 1) {
 				cells[count] = POINTER(dirty_image, i+1, j);
 				count++;
 			}
-			if ((i < height) &  (j < width)) {
+			if ((i < height - 1) && (j < (width - 1))) {
 				cells[count] = POINTER(dirty_image, i+1, j+1);
 				count++;
 			}
@@ -188,22 +211,31 @@ main(int argc, char *argv[])
 	int height, width;
 	double error;
 	unsigned char *clean, *noisy;
-	unsigned char *rv_minimum, *rv_maximum, *rv_average, *rv_median;
+	unsigned char *result;

 	clean = load_ppm("ViGIR.ppm", &width, &height);
 	noisy = load_ppm("ViGIRnoisy.ppm", &width, &height);

 //	write_ppm("bypass.ppm", width, height, noisy);
-	rv_minimum = run_filter(clean, noisy, width, height, minimum, &error);
-	write_ppm("minimum.ppm", width, height, rv_minimum);
-	return 0 ;
-	rv_maximum = run_filter(clean, noisy, width, height, maximum, &error);
-	write_ppm("maximum.ppm", width, height, rv_maximum);
-	rv_average = run_filter(clean, noisy, width, height, average, &error);
-	write_ppm("average.ppm", width, height, rv_average);
-	rv_median = run_filter(clean, noisy, width, height, median, &error);
-	write_ppm("median.ppm", width, height, rv_median);
+	result = run_filter(clean, noisy, width, height, minimum, &error);
+	write_ppm("minimum.ppm", width, height, result);
+	free(result);

+	result = run_filter(clean, noisy, width, height, maximum, &error);
+	write_ppm("maximum.ppm", width, height, result);
+	free(result);
+
+	result = run_filter(clean, noisy, width, height, average, &error);
+	write_ppm("average.ppm", width, height, result);
+	free(result);
+
+	result = run_filter(clean, noisy, width, height, median, &error);
+	write_ppm("median.ppm", width, height, result);
+	free(result);
+
+	free(clean);
+	free(noisy);
+
 	return 0;
 }