/* this file is the modified version of cementinit.c...includes ability to apply filters */ #include #include #include #include #include #include #include #include #include #include #include #include #include "cement.h" #include "pnmutils.h" #include "file.h" #include "powLookup.h" #include struct ImageParameters { int width, height; int max_val; int type; float bert, ernie; double *red, *green, *blue; }; int get_image_parameters(FILE *source, struct ImageParameters *parameters) { int c, dimsScanned; float dims[5]; if ((source == NULL) || (parameters == NULL)) { fprintf(stderr, "getImageParameters: invalid arguments\n"); return -1; } if (fgetc(source) != 'P') { fprintf(stderr, "getImageParameters: invalid image format\n"); return -1; } c = fgetc(source); if (c != 'A') { printf("Image file does not begin with PA.\n"); return -1; } parameters->type = c; dimsScanned = 0; do { char line[80]; fgets(line, sizeof(line), source); if (line[0] == '#') { /* line is a comment */ /* make sure that the entire line is read */ while (strchr(line, '\n') == NULL) fgets(line, sizeof(line), source); continue; } else if (*line != '#') { char *p = strtok(line, " \n"); while (p && (*p != '#')) { sscanf(p, "%f", &dims[dimsScanned]); dimsScanned++; p = strtok(NULL, " \n"); } if ((p != NULL) && (*p == '#')) { /* make sure that the entire line is read */ while (strchr(line, '\n') == NULL) { fgets(line, sizeof(line), source); } } } } while (dimsScanned < 5); parameters->width = (int) dims[0]; parameters->height = (int) dims[1]; parameters->max_val = (int) dims[2]; parameters->bert = dims[3]; parameters->ernie = dims[4]; if (parameters->max_val != 255) { fprintf(stderr, "getImageParameters: max value must be 255.\n"); return -1; } return 0; } /* Global Variables */ extern int errno; extern char **environ; /* Functions need in the library and the executable */ static inline double createValue(unsigned char a,double weight); static int verbose=0; #ifndef OBJECT_COMPILE /* Functions only needed in the executable */ void usage(char *string); void parse_commandline(int argc, char ** argv, char ** input_filename, double *R, double *G, double *B, char ** output_filename); void mystatus(char *action, char *filename, double R,double G, double B, double complete); #endif static int my_system (char *command) { int pid, status; if (command == 0) return 1; pid = fork(); if (pid == -1) return -1; if (pid == 0) { char *argv[4]; argv[0] = "sh"; argv[1] = "-c"; argv[2] = command; argv[3] = 0; execve("/bin/sh", argv, environ); exit(127); } do { if (waitpid(pid, &status, 0) == -1) { if (errno != EINTR) return -1; } else return status; } while(1); } int grey(char *filename) { int counter = 0, no_pixels; int bytes_per_pixel; double temp_red, temp_green, temp_blue, *red, *green, *blue; FILE *source_fd; FILE *dest_fd; char string[MAX_STRING_LENGTH]; struct ImageParameters source_header = {0, 0, 0, 0, 0.0, 0.0, NULL, NULL, NULL}; source_fd = fopen(filename, "r"); if (source_fd == NULL) { fprintf(stderr, "grey: unable to open %s\n", filename); return -1; } sprintf(string, "greyed.%s", filename); dest_fd = fopen(string, "w"); if (dest_fd == NULL) { fprintf(stderr, "grey: unable to create %s\n", string); return -1; } get_image_parameters(source_fd, &source_header); if (source_header.type == 'A') { bytes_per_pixel = 3; sprintf(string, "P%c\n%d %d\n%d\n%f\n%f\n", source_header.type, source_header.width, source_header.height, source_header.max_val, source_header.bert, source_header.ernie); fwrite(string, sizeof(unsigned char), strlen(string), dest_fd); } printf("grey: reading in source pixels..."); no_pixels = source_header.width * source_header.height; red = (double *) malloc(sizeof(double) * no_pixels); green = (double *) malloc(sizeof(double) * no_pixels); blue = (double *) malloc(sizeof(double) * no_pixels); counter = 0; while (counter < no_pixels) { fread(&(red[counter]), sizeof(double), 1, source_fd); fread(&(green[counter]), sizeof(double), 1, source_fd); fread(&(blue[counter]), sizeof(double), 1, source_fd); counter++; } printf("done\n"); /* loop to grey the image data */ counter = 0; while (counter < no_pixels) { temp_red = 0.299 * red[counter] + 0.587 * green[counter] + 0.114 * blue[counter]; temp_green = temp_red; temp_blue = temp_red; fwrite(&temp_red, sizeof(double), 1, dest_fd); fwrite(&temp_green, sizeof(double), 1, dest_fd); fwrite(&temp_blue, sizeof(double), 1, dest_fd); counter++; } fclose(source_fd); fclose(dest_fd); /* moving the temporary image file to the destination file */ sprintf(string, "rm %s; mv greyed.%s %s", filename, filename, filename); if (my_system(string) == -1) { printf("Error calling %s\n", string); exit(EXIT_FAILURE); } return 0; } int blur(char *filename, int power) { int counter = 0, no_pixels; int bytes_per_pixel, no_colours = 0; int x, y, dx, dy; double temp_red, temp_green, temp_blue, *red, *green, *blue; FILE *source_fd; FILE *dest_fd; char string[MAX_STRING_LENGTH]; struct ImageParameters source_header = {0, 0, 0, 0, 0.0, 0.0, NULL, NULL, NULL}; source_fd = fopen(filename, "r"); if (source_fd == NULL) { fprintf(stderr, "blur: unable to open %s\n", filename); return -1; } sprintf(string, "blurred.%s", filename); dest_fd = fopen(string, "w"); if (dest_fd == NULL) { fprintf(stderr, "blur: unable to create %s\n", string); return -1; } get_image_parameters(source_fd, &source_header); if (source_header.type == 'A') { bytes_per_pixel = 3; sprintf(string, "P%c\n%d %d\n%d\n%f\n%f\n", source_header.type, source_header.width, source_header.height, source_header.max_val, source_header.bert, source_header.ernie); fwrite(string, sizeof(unsigned char), strlen(string), dest_fd); } printf("blur: reading in source pixels..."); no_pixels = source_header.width * source_header.height; red = (double *) malloc(sizeof(double) * no_pixels); green = (double *) malloc(sizeof(double) * no_pixels); blue = (double *) malloc(sizeof(double) * no_pixels); counter = 0; while (counter < no_pixels) { fread(&(red[counter]), sizeof(double), 1, source_fd); fread(&(green[counter]), sizeof(double), 1, source_fd); fread(&(blue[counter]), sizeof(double), 1, source_fd); counter++; } printf("done\n"); /* loop to blur the image data */ for (y = 0; y < source_header.height; y++) { for (x = 0; x < source_header.width; x++) { temp_red = 0; temp_green = 0; temp_blue = 0; no_colours = 0; for (dy = -power + y; dy <= power + y; dy++) { for (dx = -power + x; dx <= power + x; dx++) { if ((dx >= 0) && (dx < source_header.width) && (dy >= 0) && (dy < source_header.height)) { temp_red = temp_red + red[dx + dy * source_header.width]; temp_green = temp_green + green[dx + dy * source_header.width]; temp_blue = temp_blue + blue[dx + dy * source_header.width]; no_colours++; } } } temp_red = temp_red / no_colours; temp_green = temp_green / no_colours; temp_blue = temp_blue / no_colours; fwrite(&temp_red, sizeof(double), 1, dest_fd); fwrite(&temp_green, sizeof(double), 1, dest_fd); fwrite(&temp_blue, sizeof(double), 1, dest_fd); } } fclose(source_fd); fclose(dest_fd); /* moving the temporary image file to the destination file */ sprintf(string, "rm %s; mv blurred.%s %s", filename, filename, filename); if (my_system(string) == -1) { printf("Error calling %s\n", string); exit(EXIT_FAILURE); } return 0; } int cementinit(char *input_filename, char *dest_filename, double R, double G, double B, char* command, void (*status)(char *action, char *filename, double R,double G, double B, double complete), int argc, char **argv ) { struct image_params a_params={NULL,0,0,0,0}; File * a, * dest; double p=EXPONENT; /* exponent for pow */ unsigned char a_pixel[ARRAY_SIZE]; double out_pixel[ARRAY_SIZE]; int i,j; int channels_per_pixel; int counter = 0, position = 1; /* Timing measurments */ struct timeval timeValStart; struct timeval timeValEnd; struct timezone timeZone; int minutes; double seconds=0.0; #ifdef GET_TIME_MEASUREMENTS struct timeval runTimeStart; struct timeval runTimeStop; double fileReadTime=0.0; double fileWriteTime=0.0; double computeTime=0.0; #endif unsigned int numberOfPixels; char string[MAX_STRING_LENGTH]; unsigned int image_ptr=0; a_params.filename=input_filename; if ((a=fileopen(a_params.filename, "r"))==NULL) { fprintf(stderr, "Unable to open %s.\n", a_params.filename); exit(EXIT_FAILURE); } if (dest_filename==NULL) { fprintf(stderr, "ERROR: There is no destination file.\n"); exit(EXIT_FAILURE); } if ((dest=fileopen(dest_filename, "w"))==NULL) { fprintf(stderr, "Unable to open %s.\n", dest_filename); exit(EXIT_FAILURE); } if(p!=powLookupExponent) { printf("Exonents must match\n"); exit(EXIT_FAILURE); } if(isJpegFile(a)==0) { get_image_params(a, &a_params); if (a_params.type=='6') channels_per_pixel=3; else { fprintf(stderr, "Input image must be type P6 and it is of type P%c\n",a_params.type); exit(EXIT_FAILURE); } } else { a_params.type='6'; a_params.max_val=255; channels_per_pixel=3; if(read_JPEG_file (a_params.filename)==0) { printf("ERROR: File %s does not exist\n",a_params.filename); exit(0); } image_ptr=0; a_params.width=image_width; a_params.height=image_height; } sprintf(string, "P%c\n", 'A'); filewrite(string,sizeof(unsigned char),strlen(string),dest); // fileclose(dest); // exit(0); sprintf(string, "# %s %s %f %f %f -o %s\n",command,input_filename,R,G, B,dest_filename); filewrite(string,sizeof(unsigned char),strlen(string),dest); sprintf(string, "%d %d\n%d\n%d\n%f\n",a_params.width, a_params.height, a_params.max_val,1,(float)EXPONENT); filewrite(string,sizeof(unsigned char),strlen(string),dest); #ifdef SILENT_RUN // printf("Init %s %d %d %d\r",a_params.filename,(int)R,(int)G,(int)B); #else printf("Initilizing Lightspace from file: \"%s\",",a_params.filename); printf(" P%c, %dx%d, Channels_per_pixel: %d, ",a_params.type,a_params.width,a_params.height,channels_per_pixel); printf("R=%7.3f ",R); printf("G=%7.3f ",G); printf("B=%7.3f\n",B); #endif /* Start Timer */ if(gettimeofday(&timeValStart,&timeZone)==-1) { fprintf(stderr,"Error getting the time\n"); exit(0); } numberOfPixels=a_params.width*a_params.height; if(((float)numberOfPixels/NUMBER_PIXELS_PER_READ)!=(int)((float)numberOfPixels/NUMBER_PIXELS_PER_READ)) { if(verbose) printf("\nERROR: The number of pixels %d is not evenly divisible by %d. ",numberOfPixels,NUMBER_PIXELS_PER_READ); numberOfPixels=(int)((float)numberOfPixels/NUMBER_PIXELS_PER_READ)*NUMBER_PIXELS_PER_READ; if(verbose) printf("We will go up to %d pixels.\n",numberOfPixels); } for(i=0;i 0) { if (strcmp(argv[6 + position], "b") == 0) { printf("applying the blur filter...\n"); blur(dest_filename, atoi(argv[7 + position])); position = position + 2; counter = counter - 2; } else if (strcmp(argv[6 + position], "g") == 0) { printf("applying the grey filter...\n"); grey(dest_filename); position++; counter--; } } seconds=(double)timeValEnd.tv_sec+(double)timeValEnd.tv_usec/1000000; seconds-=(double)timeValStart.tv_sec+(double)timeValStart.tv_usec/1000000; #ifdef GET_TIME_MEASUREMENTS printf("%f s doing File Read %f%%\n",fileReadTime,100*fileReadTime/seconds); printf("%f s doing File Writes %f%%\n",fileWriteTime,100*fileWriteTime/seconds); printf("%f s doing Computation %f%%\n",computeTime,100*computeTime/seconds); printf("%f s doing Timing and looping\n",seconds-fileReadTime-fileWriteTime-computeTime); #endif if(seconds>60) { minutes=seconds/60; seconds=seconds-minutes*60; } else minutes=0; if(verbose || GET_RUN_TIME) { #ifndef SILENT_RUN if(minutes==1) printf("Run Time is about %d minute %f seconds.\n",minutes,seconds); else printf("Run Time is about %d minutes %f seconds.\n",minutes,seconds); #else if(status!=NULL) status("Init",a_params.filename,R,G,B,(double)100); // printf("Init %s %d %d %d %4.2f(s)\n",a_params.filename,(int)R,(int)G,(int)B,minutes*60+seconds); #endif } if(isJpegFile(a)==1) free(image_buffer); return(EXIT_SUCCESS); } static inline double createValue(unsigned char a,double weight) { return(weight*powLookupTable[a]); } #ifndef OBJECT_COMPILE int main(int argc, char ** argv) { char * dest_filename=NULL; char * input_filename=NULL; double R,G,B; parse_commandline(argc, argv, &input_filename, &R,&G,&B,&dest_filename); return(cementinit(input_filename,dest_filename,R,G,B,argv[0],mystatus, argc, argv)); } void mystatus(char *action, char *filename, double R,double G, double B, double complete) { printf("%s %s %d %d %d %d%%\r",action,filename,(int)R,(int)G,(int)B,(int)complete); fflush(stdout); if((int)complete==100) printf("\n"); } void usage(char *string) { fprintf(stderr, "Use: %s [Imagespace file] -o [Lightspace file]\n",string); fprintf(stderr, " [Imagespace file] is a ppm file that will start a lightspace.\n"); fprintf(stderr, " =Float for Red weight.\n"); fprintf(stderr, " =Float for Green weight.\n"); fprintf(stderr, " =Float for Blue weight.\n"); fprintf(stderr, " [LightSpaceFile] is a Portable Lightspace Map (plm) that will be created.\n"); exit(EXIT_SUCCESS); } void parse_commandline(int argc, char ** argv, char ** input_filename, double *R, double *G, double *B, char ** output_filename) { if (argc<7) { fprintf(stderr,"number of input arguments was only %d\n",argc); usage(argv[0]); } *input_filename=(char*)strdup(argv[1]); sscanf(argv[2],"%lf",R); /* sscanf does not recognize %g, must be %lf */ sscanf(argv[3],"%lf",G); /* sscanf does not recognize %g, must be %lf */ sscanf(argv[4],"%lf",B); /* sscanf does not recognize %g, must be %lf */ if(argv[5][0]!='-' || argv[5][1] !='o') usage(argv[0]); *output_filename=(char *)strdup(argv[6]); } #endif