Code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "iplib2New.c"
#define FILTER_SIZE 3
//Function prototypes
image_ptr read_pnm(char *filename, int *rows, int *cols, int *type);
int getnum(FILE *fp);
void write_pnm(image_ptr ptr, char *filename, int rows, int cols, int type);
int apply_horizontal_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_h[FILTER_SIZE][FILTER_SIZE]);
int apply_vertical_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_v[FILTER_SIZE][FILTER_SIZE]);
int main(int argc, char **argv)
{
int f_des[2]; //Two ends of our pipe
static int message[5]; //message container for our image results to send into the pipe
int pid, childpid;
int rows, cols, type, row_pos, col_pos, pixelID; //Basic image info
image_ptr imagePtr, imagePtr2; //image pointer types
//image_ptr imageNegPtr;
int sobel_h[FILTER_SIZE][FILTER_SIZE] = {-1, -2, -1, 0, 0, 0, 1, 2, 1}; //Horizontal Sobel filter
int sobel_v[FILTER_SIZE][FILTER_SIZE] = {-1, 0, 1, -2, 0, 2, -1, 0, 1}; //Vertical Sobel filter
unsigned char small_block[FILTER_SIZE][FILTER_SIZE]; //sub block for image
int i=0, j=0, x=0, y=0, p=0, k=0, l=0, m=0; //Loop variables...big image, small block, # of processes, process management
int value_h = 0, value_v = 0, value_both = 0, binarized_pixel_value; //pixel values for 3 x 3 small_block horizontally, vertically, and both
double edge_mean, edge_std_dev, edge_threshold; //Creating the threshold to binarize the image
int tp; //File type
double ave=0; //??
char aveStr[10], *aveStrEnd;
//Create the pipe and check if it fails - gives both ends of the pipe to the child since it's created before the fork()
if (pipe(f_des) == -1)
{
printf("Pipe failed.");
}
//Check inputs
if (argc != 6)
{
printf("wrong inputs: use %s infile out1 out2 out3 p \n", argv[0]); //p is the # of processes
}
//Reading the image in
printf("\nReading input image... \n");
//Pointer to access the whole image
imagePtr = read_pnm(argv[1], &rows, &cols, &type); //Returns ptr from read_pnm - why &type?
//Notifying the user
printf("\nYour image was read successfully!\n");
printf("Info about your image: rows = %d, cols = %d, type = %d\n", rows, cols, type);
//Has to be created here after the image has been read in by read_pnm so rows and cols have correct values
unsigned char horizontal_edge_image[rows][cols];
unsigned char vertical_edge_image[rows][cols];
unsigned char both_edges_image[rows][cols];
unsigned char binarized_edge_image[rows][cols];
//Convert p from string to int atoi()
p = 4;
//Outer loop for determining the level of process we're at aka which process we're on
for(k=0; k<p; k++) //Creating all of our children
{
if((childpid = fork()) <= 0) {} //Create only a child...Note: no braces
}
pixelID = 0; //Our initial image position
//If child do these 4 for loops to analyse each sub block of the image
if(childpid == 0)
{
//Going over the whole image
for(i=0; i<rows; i++) //The height of the image
{
for(j=0; j<cols; j++) //The width of the image
{
pixelID++;
if(pixelID%p == k)
{
//Making sure the right process is doing the correct region of the image
//Picking up our sub block of the image
for(y=0; y<FILTER_SIZE; y++) //Width of the sub block - cols
{
for(x=0; x<FILTER_SIZE; x++) //Height of the sub block - rows
{
small_block[x][y]=imagePtr[(i+x)*cols+(j+y)];
}
}
}
//Analyze sub blocks horizontally and vertically here
value_h = apply_horizontal_filter(small_block, sobel_h);
value_v = apply_vertical_filter(small_block, sobel_v);
//Both edges together - E(x,y)
value_both = value_h + value_v;
//Will need to send the above^ 3 values to the pipe aka write this to the pipe
//array of pipe will be...pixelID, hE, vE, hvE
//Instead of pixelID, sending i,j pos in image
row_pos = i;
col_pos = j;
//Putting the values in the message container for the pipe
row_pos = message[0];
col_pos = message[1];
value_h = message[2];
value_v = message[3];
value_both = message[4];
//Writing to the pipe
//before writing, make sure other end is closed
close(f_des[0]);
if(write(f_des[1], message, sizeof(message)) != -1)
{
printf("Writing to pipe.\n");
fflush(stdout);
}
else
{
perror("Write:");
}
}
}
}
else
{
//Else if parent do these 2 for loops to update the output image
//The parent will have to read from the pipe to know where and what to update in the output image
for(i=0; i<rows; i++)
{
for(j=0; j<cols; j++)
{
//Also close the other end of the pipe?
//Read from the pipe here - will I need to flush the pipe every time it reads?
//Organize new image
close(f_des[1]);
if(read(f_des[0], message, sizeof(message)) != -1)
{
printf("Reading pipe.\n");
fflush(stdout);
}
else
{
perror("Read:");
}
//Update output images - The parent will do this now
//Should be i,j or vars from pipe?
horizontal_edge_image[message[0]][message[1]] = (unsigned char)abs(message[2]);
vertical_edge_image[i][j] = (unsigned char)abs(value_v);
both_edges_image[i][j] = (unsigned char)abs(value_both);
}
}
//Now begin writing the image file
tp = 5; //Setting the file type to be read/write as PGM
imagePtr2 = (image_ptr)horizontal_edge_image; //Assign pointer to write image
printf("\nNow writing Horizontal edge image...\n");
write_pnm(imagePtr2, argv[2], rows, cols, tp); //Creating the horizontal edge
imagePtr2 = (image_ptr)vertical_edge_image; //Reassigning our ptr for next img
printf("\nNow writing Vertical edge image...\n");
write_pnm(imagePtr2, argv[3], rows, cols, tp); //Creating the vertical edge
imagePtr2 = (image_ptr)both_edges_image; //Reassign the pointer
printf("\nNow writing Both edges image...\n");
write_pnm(imagePtr2, argv[4], rows, cols, tp); //Creating the image of both edges
}
/* image negatives */
// imageNegPtr=(image_ptr)malloc(rows*cols*(sizeof(unsigned char)) );
// ... codes for image negative here
// printf("\nNow writing negative image file ... \n");
// printf("rows=%d, cols=%d, type=%d \n", rows, cols, type);
// write_pnm(imageNegPtr, argv[3], rows, cols, type); //Creating the out2.pgm
return 0;
}
int apply_horizontal_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_h[3][3])
{
int x = 0;
int y = 0;
int pixel_value_h = 0;
for(x = 0; x<3; x++)
{
for(y=0; y<3; y++)
{
pixel_value_h += sobel_h[x][y]*small_block[x][y];
}
}
return pixel_value_h;
}
int apply_vertical_filter(unsigned char small_block[FILTER_SIZE][FILTER_SIZE], int sobel_v[3][3])
{
int x = 0;
int y = 0;
int pixel_value_v = 0;
for(x = 0; x<3; x++)
{
for(y=0; y<3; y++)
{
pixel_value_v += sobel_v[x][y]*small_block[x][y];
}
}
return pixel_value_v;
}