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;
}