The unified diff between revisions [9dda360f..] and [56e5a93f..] is displayed below. It can also be downloaded as a raw diff.
#
#
# 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;
}