int write_image(const char *filename, int width, int height, unsigned char *rgb) { FILE *outfile; char *extension = strrchr(filename, '.'); char *lowercase; char *ptr; int success = 0; lowercase = malloc(strlen(extension) + 1); strcpy(lowercase, extension); ptr = lowercase; while (*ptr != '\0') *ptr++ = tolower(*extension++); outfile = fopen(filename, "wb"); if (outfile == NULL) return(0); if (strcmp(lowercase, ".bmp" ) == 0) { success = write_bmp(filename, width, height, rgb); } else if (strcmp(lowercase, ".gif" ) == 0) { #ifdef HAVE_LIBGIF success = write_gif(filename, width, height, rgb); #else fprintf(stderr, "Sorry, this program was not compiled with GIF support\n"); success = 0; #endif /* HAVE_LIBPNG */ } else if (( strcmp(lowercase, ".jpg" ) == 0) || (strcmp(lowercase, ".jpeg") == 0)) { #ifdef HAVE_LIBJPEG success = write_jpeg(outfile, width, height, rgb, Q); #else fprintf(stderr, "Sorry, this program was not compiled with JPEG support\n"); success = 0; #endif /* HAVE_LIBJPEG */ } else if (strcmp(lowercase, ".png" ) == 0) { #ifdef HAVE_LIBPNG success = write_png(outfile, width, height, rgb, alpha); #else fprintf(stderr, "Sorry, this program was not compiled with PNG support\n"); success = 0; #endif /* HAVE_LIBPNG */ } else if (( strcmp(lowercase, ".pbm") == 0) || (strcmp(lowercase, ".pgm") == 0) || (strcmp(lowercase, ".ppm") == 0)) { #ifdef HAVE_LIBPNM if (strcmp(lowercase, ".pbm") == 0) success = write_pnm(outfile, width, height, rgb, 1, PBM_TYPE, 0); else if (strcmp(lowercase, ".pgm") == 0) success = write_pnm(outfile, width, height, rgb, 255, PGM_TYPE, 0); else if (strcmp(lowercase, ".ppm") == 0) success = write_pnm(outfile, width, height, rgb, 255, PPM_TYPE, 0); #else fprintf(stderr, "Sorry, this program was not compiled with PNM support\n"); success = 0; #endif /* HAVE_LIBPNM */ } else if ((strcmp(lowercase, ".tif" ) == 0) || (strcmp(lowercase, ".tiff" ) == 0)) { #ifdef HAVE_LIBTIFF success = write_tiff(filename, width, height, rgb); #else fprintf(stderr, "Sorry, this program was not compiled with TIFF support\n"); success = 0; #endif /* HAVE_LIBTIFF */ } else { fprintf(stderr, "Unknown image format\n"); success = 0; } free(lowercase); fclose(outfile); return(success); }
int main(int argc, char *argv[]) { printf("\n"); printf("%15c########################################\n", ' '); printf("%15c# Image Manipulation Program for CS350 #\n", ' '); printf("%15c# NOW WITH MORE THREADS!!!! #\n", ' '); printf("%15c########################################\n\n", ' '); if (argc != 5) { printf ("Wrong inputs: Run as: %s inFile outFile scaleFactor threads\n\n", argv[0]); printf("bye bye....\n"); return 0; } image_ptr imagePtr; /* Image Read In */ int rows, cols, type, s = atoi(argv[3]); imagePtr = read_pnm(argv[1], &rows, &cols, &type); int requestedThreads = atoi(argv[4]); /* Something about having an array representation of this image data * rather than a linear representation seems much more intuitive */ int nonlin[rows][cols]; int i, j; for (i = 0; i < rows; i++) { for (j = 0; j <= cols; j++) { nonlin[i][j] = imagePtr[i * cols + j]; } } /* Allocate space for the image we're going to write OUT */ unsigned char outputImage[rows / s][cols / s]; /* Welcome to McDonalds.. bla bla bla */ printf("Input File: %s\n", argv[1]); printf("Output File: %s\n", argv[2]); printf("Scale Factor: %d\n", s); printf("Input image has: \n %d rows\n %d cols\n", rows, cols); printf("Resulting image will have: \n %d rows\n %d cols\n", rows / s, cols / s); printf ("Process will try to run using %d thread server(s) at a time\n\n", requestedThreads); pthread_t threads[cols / s]; /* Map of all the threads */ int rc, workingCols = 0, threadsCreated = 0, remainingChunks = rows / s, threadJoining; long int status; /* passed to pthread_join as an address so we can check on their finishing status */ struct imgArgs threadStructs[cols / s]; /* here's the process..... * make batches of threads up to requestedThreads * keep doing that and making sure they all finish executing (join each) UNTIL... * remaining chunks <= requestedThreads * move to the "catch all run" of thread building. * this last thread initialization will create <= requestedThreads. * we only ever had alive UP TO 'requestedThreads' at once because we can only run with * 'requestedThreads' server threads (read from argv[4]) * .... * along the way we keep track of how many have been created to date with 'threadsCreated' * each batch uses workingRows to keep track of how many its made in that batch * workingCols shall never exceed requestedThreads but MAY be equal to requestedThreads */ printf("Initializing threads...\n"); int startPoint; while (remainingChunks > requestedThreads) { /* "until remainingChunks <= requested Threads" */ for (workingCols = 0; workingCols < requestedThreads; workingCols++) { threadStructs[threadsCreated].initColumn = threadsCreated * s; threadStructs[threadsCreated].scale = &s; threadStructs[threadsCreated].rows = &rows; threadStructs[threadsCreated].columns = &cols; threadStructs[threadsCreated].nonlin = &nonlin; threadStructs[threadsCreated].tid = threadsCreated; threadStructs[threadsCreated].newImage = &outputImage; rc = pthread_create(&threads[threadsCreated], NULL, resize, (void *) &threadStructs[threadsCreated]); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } remainingChunks--; threadsCreated++; } /* End batch thread creation process */ /* Join the last spawned threads and wait for them all to finish processing before continuing */ threadJoining = threadsCreated - requestedThreads; /* Join from where we last started spawning threads */ for (; threadJoining < threadsCreated; threadJoining++) { rc = pthread_join(threads[threadJoining], &status); if (rc) { printf("error joining thread %d\n", threadJoining); exit(-1); } } /* End thread joining process */ } /* End while: remainingChunks > requestedThreads */ /* Details at this point: either you requested <= the number of threads required to process the image * or we've calculated all the thread batches up to the point where we have (remainingChunks <= requestedThreads) */ for (; threadsCreated < cols / s; threadsCreated++) { threadStructs[threadsCreated].initColumn = threadsCreated * s; threadStructs[threadsCreated].scale = &s; threadStructs[threadsCreated].rows = &rows; threadStructs[threadsCreated].columns = &cols; threadStructs[threadsCreated].nonlin = &nonlin; threadStructs[threadsCreated].tid = threadsCreated; threadStructs[threadsCreated].newImage = &outputImage; rc = pthread_create(&threads[threadsCreated], NULL, resize, (void *) &threadStructs[threadsCreated]); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } /* Join the last spawned threads and wait for them all to finish processing before continuing */ threadJoining = threadsCreated - remainingChunks; /* Join from where we last started spawning threads */ for (; threadJoining < threadsCreated; threadJoining++) { rc = pthread_join(threads[threadJoining], &status); if (rc) { printf("error joining thread %d\n", threadJoining); exit(-1); } } printf("Calculations complete! Writing to file...\n"); /* Hard work's done, write it to file */ write_pnm((image_ptr) outputImage, argv[2], rows / s, cols / s, type); printf("Wrote: %s to file!\n", argv[2]); pthread_exit(NULL); }
int main(int argc, char** argv){ int i, j, num_frames; char buf[MAX_PATH_LEN]; char input_path[MAX_PATH_LEN]; char output_path[MAX_PATH_LEN]; struct image input[NUM_STREAMS]; struct image scaled[NUM_STREAMS]; struct image big_image; struct timeval t1, t2, t3, t4; double scale_time = 0, total_time = 0; if (argc != 4){ printf("Usage: ./serial input_path output_path num_frames\n"); exit(1); } gettimeofday(&t3, NULL); strncpy(input_path, argv[1], MAX_PATH_LEN - 1); strncpy(output_path, argv[2], MAX_PATH_LEN - 1); num_frames = atoi(argv[3]); if (num_frames > MAX_FRAMES) num_frames = MAX_FRAMES; for (i = 0; i < num_frames; i++){ printf("Processing Frame %d\n", i + 1); //read the input images for (j = 0; j < NUM_STREAMS; j++){ sprintf(buf, "%s/stream%02d/image%d.pnm", input_path, j + 1, i + 1); read_pnm(buf, &input[j]); } gettimeofday(&t1, NULL); //scale the input images for (j = 0; j < NUM_STREAMS; j++){ scaled[j].height = input[j].height / SCALE_FACTOR; scaled[j].width = input[j].width / SCALE_FACTOR; alloc_image(&scaled[j]); scale_area_avg(&input[j], &scaled[j]); } //create the big image out of the scaled images big_image.height = scaled[0].height * NUM_IMAGES_HEIGHT; big_image.width = scaled[0].width * NUM_IMAGES_WIDTH; alloc_image(&big_image); create_big_image(scaled, &big_image); gettimeofday(&t2, NULL); scale_time += GET_TIME_DELTA(t1, t2); //write the big image sprintf(buf, "%s/result%d.pnm", output_path, i + 1); write_pnm(buf, &big_image); //free the image data for (j = 0; j < NUM_STREAMS; j++){ free_image(&input[j]); free_image(&scaled[j]); } free_image(&big_image); } gettimeofday(&t4, NULL); total_time += GET_TIME_DELTA(t3, t4); printf("Scale time: %lf\n", scale_time); printf("Total time: %lf\n", total_time); return 0; }