Advertisement
Guest User

MPI Project

a guest
Apr 8th, 2020
695
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.24 KB | None | 0 0
  1. /*
  2. Convert an image to grayscale.
  3.  
  4. The code is written for a mini-project of ITCS 5145 Parallel Programming at UNCC.(Q.C.)
  5.  
  6. To compile the code, we use
  7.         gcc -g -Wall -o color2grapy stb_image/stb_image.h stb_image/stb_image_write.h color2gray.c -lm
  8.  
  9. To run the code, type
  10.         ./color2gray ${input color image} ${output grayscale image} ${image type}
  11.  
  12.         The format of images depends on its types.
  13.         To specify image type, we have ${image type} as follows:
  14.             1 is for .png file
  15.             2 is for .jpg file
  16.        
  17.         For example,
  18.         ./color2grapy lena1.png lena2.png 1
  19.         ./color2grapy lizard1.jpg lizard2.jpg 2
  20. */
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <math.h>
  24. #include <mpi.h>
  25.  
  26. #define STB_IMAGE_IMPLEMENTATION
  27. #include "stb_image/stb_image.h"
  28. #define STB_IMAGE_WRITE_IMPLEMENTATION
  29. #include "stb_image/stb_image_write.h"
  30.  
  31. void colorToGrayscale(unsigned char *gray_img, unsigned char * color_img, int width, int height, int my_rank);
  32.  
  33. const int IS_PNG = 1;
  34. const int IS_JPG = 2;
  35. const int DESIRED_CHANNELS = 3;
  36. const int MAX_NAME_LENGTH = 500;
  37. int main(int argc, char *argv[]) {
  38.     if (argc < 4){
  39.         printf("Usage: color2Grayscale ${input color image file} ${output grayscale image file} ${image type}\n Image Types:\n\t1: PGN\n\t2: JPG");
  40.     exit(-1);
  41.     }
  42.  
  43.     int width, height, channels, type, csize, rank, gray_channels, c_size, g_size;
  44.     char  in_name[MAX_NAME_LENGTH], out_name[MAX_NAME_LENGTH];
  45.     unsigned char *color_img;
  46.     unsigned char *gray_img;
  47.     strcpy(in_name, argv[1]);
  48.     strcpy(out_name, argv[2]);
  49.     type = atoi(argv[3]);
  50.     MPI_Init(NULL, NULL);
  51.     MPI_Comm_size(MPI_COMM_WORLD, &csize);
  52.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  53.     if(rank==0){
  54.         color_img = stbi_load(in_name, &width, &height, &channels, 0); // load and conver the image to 3 channels (ignore the transparancy channel)
  55.         if(color_img == NULL) {
  56.             printf("Error in loading the image\n");
  57.             exit(-1);
  58.         }
  59.         printf("Loaded image %s with a width of %dpx, a height of %dpx and %d channels\n", in_name, width, height, channels);
  60.  
  61.         // Convert the input image to gray
  62.         gray_channels = channels == 4 ? 2 : 1;
  63.         size_t gray_img_size = width * height * gray_channels;
  64.    
  65.         gray_img = (unsigned char *)malloc(gray_img_size);
  66.         if(gray_img == NULL) {
  67.             printf("Unable to allocate memory for the gray image.\n");
  68.             exit(1);
  69.         }
  70.         printf("Create a image array with a width of %dpx, a height of %dpx and %d channels\n", width, height, gray_channels);
  71.         c_size=(width*height*channels)/csize;
  72.         g_size=(width*height*gray_channels)/csize;
  73.     }
  74.     MPI_Bcast(&c_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
  75.     MPI_Bcast(&g_size, 1, MPI_INT, 0, MPI_COMM_WORLD);
  76.     unsigned char *local_carr=(unsigned char*)malloc(c_size);
  77.     unsigned char *local_garr=(unsigned char*)malloc(g_size);
  78.     MPI_Scatter(color_img,c_size,MPI_UNSIGNED_CHAR,local_carr,c_size,MPI_UNSIGNED_CHAR,0,MPI_COMM_WORLD);
  79.     unsigned char pixel[DESIRED_CHANNELS];
  80.     MPI_Barrier(MPI_COMM_WORLD);
  81.     for (int row = 0; row < height/2; ++row)
  82.     {  
  83.  
  84.         if(rank==1){
  85.             printf("Hi");
  86.         }
  87.         for (int col = 0; col < width/2; ++col)
  88.         {
  89.            //If the input image has a transparency channel this will be simply copied to the second channel of the gray image, while the first channel of the gray image will contain the gray pixel values. If the input image has three channels, the output image will have only one channel with the gray data.
  90.             int greyOffset = row * (width/2) + col;
  91.             int rgbOffset = greyOffset * DESIRED_CHANNELS;
  92.             pixel[0] = local_carr[rgbOffset];
  93.             pixel[1] = local_carr[rgbOffset + 1];
  94.             pixel[2] = local_carr[rgbOffset + 2];
  95.  
  96.             local_garr[greyOffset] = pixel[0] * 0.3 + pixel[1] * 0.58 + pixel[2] * 0.11;
  97.         }
  98.     }
  99.     MPI_Gather(local_garr,g_size,MPI_UNSIGNED_CHAR,gray_img,g_size,MPI_UNSIGNED_CHAR,0,MPI_COMM_WORLD);
  100.     MPI_Barrier(MPI_COMM_WORLD);
  101.     if(rank==0){
  102.         if (type == IS_PNG)
  103.             stbi_write_png(out_name, width, height, gray_channels, gray_img, width * gray_channels);
  104.         else
  105.             if (type == IS_JPG)
  106.                 stbi_write_jpg(out_name, width, height, gray_channels, gray_img, 100); //The last parameter of the stbi_write_jpg function is a quality parameter that goes from 1 to 100. Since JPG is a lossy image format, you can chose how much data is dropped at save time. Lower quality means smaller image size on disk and lower visual image quality.
  107.         printf("Wrote image %s with a width of %dpx, a height of %dpx and %d channels\n", out_name, width, height, channels);
  108.  
  109.         stbi_image_free(gray_img);
  110.     }
  111.     MPI_Finalize();
  112. }
  113.  
  114. void colorToGrayscale(unsigned char *gray_img, unsigned char * color_img, int width, int height, int my_rank){
  115.  
  116.     int counter=0;
  117.     MPI_Barrier(MPI_COMM_WORLD); //The arrays were properly scattered, however none of the threads outside of the main process are accessing the for loop so the first one is the only one with data by the time it gets to MPI_Gather.
  118.  
  119.  
  120.     MPI_Barrier(MPI_COMM_WORLD);
  121. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement