The unified diff between revisions [878a5382..] and [9dda360f..] 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 [5ff79d4a456314b39f4823189b9dd4dbd485aa7b]
#    to [0340b163efbfa59fc2fb6cc3362ba6eb71ce7bf5]
#
============================================================
--- aca319/lab8q1.c	5ff79d4a456314b39f4823189b9dd4dbd485aa7b
+++ aca319/lab8q1.c	0340b163efbfa59fc2fb6cc3362ba6eb71ce7bf5
@@ -4,12 +4,14 @@
 #include <assert.h>
 #include <string.h>

-char *
-load_pgm(const char *filename, int *width, int *height)
+#define POINTER(img,x,y)		( img + ( 3 * ((x*width)+y)) )
+
+unsigned char *
+load_ppm(const unsigned char *filename, int *width, int *height)
 {
 	FILE *f = fopen(filename, "r");
-	int v;
-	char *rv;
+	int v, mv;
+	unsigned char *rv;

 	if (!f) {
 		fprintf(stderr, "Unable to load input file: %s\n", filename);
@@ -23,47 +25,73 @@ load_pgm(const char *filename, int *widt
 		fprintf(stderr, "Unable to read height and width.\n");
 		return NULL;
 	}
-	rv = malloc(sizeof(char) * *height * *width);
+	if ((fscanf(f, "%d\n", &mv) == EOF)) {
+		fprintf(stderr, "Unable to max value.\n");
+		return NULL;
+	}
+	rv = malloc(sizeof(unsigned char) * *height * *width * 3);
 	if (!rv) {
 		fprintf(stderr, "Unable to allocate image buffer\n");
 		return NULL;
 	}
-	fread(rv, sizeof(char), *height * *width, f);
+	fread(rv, sizeof(unsigned char), *height * *width * 3, f);
 	return rv;
 }

-int
-minimum(const char *pixels, int count)
+void
+write_ppm(const unsigned char *filename, int width, int height, const unsigned char *data)
 {
-	int i, rv=pixels[0];
-	for (i=1;i<count;i++) {
-		if (pixels[i] < rv)
-			rv = pixels[i];
+	FILE *out;
+
+	out = fopen(filename, "w");
+	if (!out) {
+		fprintf(stderr, "Unable to open output file.\n");
+		return;
 	}
-	return rv;
+	fprintf(out, "P6\n%d %d\n255\n", width, height);
+	fwrite(data, sizeof(unsigned char), width*height*3, out);
+	fclose(out);
 }

-int
-maximum(const char *pixels, int count)
+void
+minimum(const unsigned char **pixels, int count, char *result)
 {
-	int i, rv=pixels[0];
-	for (i=1;i<count;i++) {
-		if (pixels[i] > rv)
-			rv = pixels[i];
+	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);
+		}
 	}
-	return rv;
 }

-int
-average(const char *pixels, int count)
+void
+maximum(const unsigned char **pixels, int count, char *result)
 {
-	int i, total;
-	for (i=0;i<count;i++) {
-		total += pixels[i];
+	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];
+		}
 	}
-	return total / count;
 }

+void
+average(const unsigned char **pixels, int count, char *result)
+{
+	int i, p;
+	for (p=0;p<3;p++) {
+		result[p] = 0;
+		for (i=0;i<count;i++) {
+			result[p] += pixels[i][p];
+		}
+		result[p] /= count;
+	}
+}
+
 int
 int_compare(const void *a, const void *b)
 {
@@ -71,53 +99,83 @@ int_compare(const void *a, const void *b
 	int d = *(int *)b;
 	return d - c;
 }
-int
-median(const char *pixels, int count)
+
+void
+median(const unsigned char **pixels, int count, char *result)
 {
-	char *s = malloc(sizeof(char) * count);
-	if (!s) {
-		fprintf(stderr, "Out of memory in median()\n");
-		return -1;
-	}
-	memcpy(s, pixels, sizeof(char) * count);
-	qsort(s, count, sizeof(char), int_compare);
-	if (count % 2) {
-		/* odd number of elements, average the middle two */
-		return (pixels[count/2] + pixels[(count/2)+1])  / 2;
-	} else {
-		return pixels[count/2];
-	}
+
 }

-char *
-run_filter(const char *clean_image, const char *dirty_image,
-		int height, int width,
-		int (*filter_function)(const char *, int),
+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 *),
 		double *error)
 {
-	char *rv, i, j;
-	char cells[9];
+	unsigned char *rv;
+	int i, j;
+	const unsigned char *cells[9];

 	assert(clean_image != NULL);
 	assert(dirty_image != NULL);
 	assert(error != NULL);

-	rv = malloc(sizeof(char) * height * width);
+	rv = malloc(sizeof(unsigned char) * height * width * 3);
 	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++) {
-			int clean, unfiltered, filtered;
-			int count=1;
+			const unsigned char *clean, *unfiltered;
+			int count;

-			cells[0] = unfiltered;
-			clean = clean_image[(i*width)+j];
-			unfiltered = dirty_image[(i*width)+j];
+			clean = POINTER(clean_image, i, j);
+			unfiltered = POINTER(dirty_image, i, j);

-			filtered = filter_function(cells, count);
+			count = 0;
+			/* the row above */
+			if ((i > 0) &  (j > 0)) {
+				cells[count] = POINTER(dirty_image, i-1, j-1);
+				count++;
+			}
+			if (i > 0) {
+				cells[count] = POINTER(dirty_image, i-1, j);
+				count++;
+			}
+			if ((i > 0) &  (j < width)) {
+				cells[count] = POINTER(dirty_image, i-1, j+1);
+				count++;
+			}
+			/* this row */
+			if (j>0) {
+				cells[count] = POINTER(dirty_image, i, j-1);
+				count++;
+			}
+			cells[count] = unfiltered;
+			count++;
+			if (j<height) {
+				cells[count] = POINTER(dirty_image, i, j+1);
+				count++;
+			}
+			/* the row below */
+			if ((i < height) &  (j > 0)) {
+				cells[count] = POINTER(dirty_image, i+1, j-1);
+				count++;
+			}
+			if (i < height) {
+				cells[count] = POINTER(dirty_image, i+1, j);
+				count++;
+			}
+			if ((i < height) &  (j < width)) {
+				cells[count] = POINTER(dirty_image, i+1, j+1);
+				count++;
+			}
+
+			filter_function(cells, count, rv + (3 * ((i*width) + j)));
 		}
 	}

@@ -129,16 +187,22 @@ main(int argc, char *argv[])
 {
 	int height, width;
 	double error;
-	char *clean, *noisy;
-	char *rv_minimum, *rv_maximum, *rv_average, *rv_median;
+	unsigned char *clean, *noisy;
+	unsigned char *rv_minimum, *rv_maximum, *rv_average, *rv_median;

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

-	rv_minimum = run_filter(clean, noisy, height, width, minimum, &error);
-	rv_maximum = run_filter(clean, noisy, height, width, maximum, &error);
-	rv_average = run_filter(clean, noisy, height, width, average, &error);
-	rv_median = run_filter(clean, noisy, height, width, median, &error);
+//	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);

 	return 0;
 }