#include #include typedef struct bitmap { int x; int y; unsigned char* pixels; } BITMAP; int mpi_self; /* process number */ int mpi_npes; /* number of process */ BITMAP picture; /* loaded picture */ int count; /* size of one part of work */ int read_bitmap(char* filename) { FILE* file; int readcount = 0; int size = 0; int i = 0; if ((file = fopen(filename, "rb")) == NULL) { printf("File %s not found!\n", filename); return 0; } fscanf(file, "%d %d", &picture.x, &picture.y); size = picture.x * picture.y; if (size == 0) { printf("File %s is not correct!\n", filename); fclose(file); return 0; } if ((size % mpi_npes) != 0) { count = ((size / mpi_npes) + 1) * mpi_npes; } else { count = size; } picture.pixels = (unsigned char*) malloc(count); readcount = fread(picture.pixels, 1, size, file); if (readcount != size) { printf("File %s is not correct!\n", filename); free((void*) picture.pixels); fclose(file); return 0; } for (i = 0; i < count - size; i++) { picture.pixels[size+i] = picture.pixels[0]; } count = count / mpi_npes; fclose(file); return 1; } void write_bitmap(char* filename) { FILE* file; int size = 0; int i = 0; if ((file = fopen(filename, "wb")) == NULL) { printf("File %s can not be created!\n", filename); } else { fprintf(file, "%d %d", picture.x, picture.y); size = picture.x * picture.y; fwrite(picture.pixels, 1, size, file); free((void*) picture.pixels); printf("Successfully done.\n"); fclose(file); } } void stretch_color(void) { int i; unsigned char min = 0; unsigned char max = 0; unsigned char lmin = 255; unsigned char lmax = 0; double konst = 0; unsigned char* work = NULL; /* everyone have to know how much to do*/ MPI_Bcast(&count, 1, MPI_INT, 0, MPI_COMM_WORLD); work = (unsigned char*) malloc(count); /* send part of work */ MPI_Scatter(picture.pixels, count, MPI_UNSIGNED_CHAR, work, count, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD); /* compute local extrems */ for (i = 0; i < count; i++) { if (work[i] < lmin) { lmin = work[i]; } if (work[i] > lmax) { lmax = work[i]; } } /* find out global extrems */ MPI_Allreduce(&lmin, &min, 1, MPI_UNSIGNED_CHAR, MPI_MIN, MPI_COMM_WORLD); MPI_Allreduce(&lmax, &max, 1, MPI_UNSIGNED_CHAR, MPI_MAX, MPI_COMM_WORLD); /* stretch colors */ konst = (255.0 / (max - min)); for (i = 0; i < count; i++) { work[i] = (unsigned char) (((work[i] - min) * konst) + 0.5); } /* get whole picture */ MPI_Gather(work, count, MPI_UNSIGNED_CHAR, picture.pixels, count, MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD); free((void*) work); } int main (int argc, char *argv[]) { int ok = 0; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_self); MPI_Comm_size(MPI_COMM_WORLD, &mpi_npes); if (mpi_self == 0) { if (argc == 3) { ok = read_bitmap(argv[1]); } else { printf("Incorrect number of arguments!\n"); printf("Arguments are source file and destination file.\n"); } } /* waiting for root to read picture */ MPI_Bcast(&ok, 1, MPI_INT, 0, MPI_COMM_WORLD); if (ok) { stretch_color(); if (mpi_self == 0) { write_bitmap(argv[2]); } } MPI_Finalize(); return 0; }