Advertisement
Guest User

Untitled

a guest
May 20th, 2019
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.24 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/time.h>
  6. #include <pthread.h>
  7. #include <math.h>
  8. #include <sys/param.h>
  9.  
  10. //=========================================
  11. //                BLOCK 0
  12. //              INTERLEAVED 1
  13. //=========================================
  14.  
  15. typedef struct {
  16.     int colors;
  17.     int width;
  18.     int height;
  19.     char ** structure;
  20. } Image;
  21.  
  22. typedef struct {
  23.     int size;
  24.     double **structure;
  25. } Filter ;
  26.  
  27. typedef struct {
  28.     Image *image;
  29.     Filter *filter;
  30.     int thread_number;
  31.     int type;
  32.     int thread_amount;
  33. } Thread;
  34.  
  35.  
  36. int load_filter(Filter *filter,const char *path) {
  37.  
  38.    if (filter == NULL) {
  39.         printf("Transform buffer is null");
  40.         return 1;
  41.     }
  42.  
  43.     long row = 0;
  44.     long column = 0;
  45.     FILE * file = fopen(path, "r");
  46.     if(file == NULL){
  47.         printf("error opening filter");
  48.         return 1;
  49.     }
  50.  
  51.     fseek(file, 0, SEEK_END);
  52.     long filter_file_size = ftell(file);
  53.     fseek(file, 0, SEEK_SET);
  54.  
  55.     char* buffer = calloc(sizeof(char), (size_t) filter_file_size);
  56.     fread(buffer, sizeof(char), (size_t) filter_file_size, file);
  57.  
  58.  
  59.     char *delim = "\r\n ";
  60.     char *tok = strtok(buffer, delim);
  61.     long filter_size = atoi(tok);
  62.     filter->size = (int) filter_size;
  63.  
  64.     double **values = calloc((size_t) filter_size, sizeof(double *));
  65.     for (long i = 0; i < filter_size; i++)
  66.         values[i] = calloc((size_t) filter_size, sizeof(double));
  67.     filter->structure = values;
  68.  
  69.     // rewrite filter_file into filter_structure
  70.  
  71.     char *token = strtok(NULL, delim);
  72.     while (token != NULL) {
  73.         if (column >= filter->size) {
  74.             column = 0;
  75.             row++;
  76.         }
  77.         if (row >= filter->size)
  78.             break;
  79.  
  80.         double value = atof(token);
  81.         values[row][column] = value;
  82.         column++;
  83.         token = strtok(NULL, delim);
  84.     }
  85.  
  86.     fclose(file);
  87.     return 0;
  88. }
  89.  
  90. int load_image(Image *image, char *path){
  91.     if(image == NULL){
  92.         return 1;
  93.     }
  94.  
  95.     long row = 0;
  96.     long col = 0;
  97.     FILE * file = fopen(path,"r");
  98.     if(file == NULL){
  99.         printf("Can't open image");
  100.     }
  101.     fseek(file, 0, SEEK_END);
  102.     long file_size = ftell(file);
  103.     fseek(file, 0, SEEK_SET);
  104.     char *buff= calloc(sizeof(char), (size_t) file_size);
  105.     fread(buff, sizeof(char), (size_t) file_size, file);
  106.  
  107.     char *delim1="\t\r\n";
  108.     char *delim2="\t\r\n ";
  109.  
  110.     char *width= strtok(buff,delim1);
  111.     width = strtok(NULL,delim1);
  112.     width = strtok(NULL,delim2);
  113.     image->width=atoi(width);
  114.     char * height = strtok(NULL,delim1);
  115.     image->height = atoi(height);
  116.     char *colors=strtok(NULL,delim1);
  117.     image->colors=atoi(colors);
  118.  
  119.     char **structure = calloc((size_t) image->height, sizeof(char *));
  120.     for (long i = 0; i < image->height; i++)
  121.         structure[i] = calloc((size_t) image->width, sizeof(char));
  122.     image->structure = structure;
  123.  
  124.     char *token;
  125.     while (1) {
  126.         token = strtok(NULL, delim2);
  127.         if (token == NULL)
  128.             break;
  129.         if (col >= image->width) {
  130.             col = 0;
  131.             row++;
  132.         }
  133.         if (row >= image->height)
  134.             break;
  135.  
  136.         unsigned long grayscale = strtoul(token, NULL, 10);
  137.         structure[row][col] = (unsigned char) grayscale;
  138.         col++;
  139.     }
  140.     fclose(file);
  141.     return 0;
  142. }
  143. __time_t get_time() {
  144.     struct timeval time;
  145.     gettimeofday(&time, NULL);
  146.     return time.tv_sec * (int) 1e6 + time.tv_usec;
  147. }
  148. int change_pixel(Image *image,Filter *filter,long row,long col){
  149.     double new_pixel=0;
  150.     long size = filter->size;
  151.     for (int i = 0; i < size; i++) {
  152.         for (int j = 0; j < size; j++) {
  153.             long img_col = MAX(0, col - (long) ceil(size / 2) + i);
  154.             long img_row = MAX(0, row - (long) ceil(size / 2) + j);
  155.             if (img_row < image->height && img_col < image->width)
  156.                 new_pixel += image->structure[img_row][img_col] * filter->structure[j][i];
  157.         }
  158.     }
  159.     image->structure[row][col] = (unsigned char) round(new_pixel);
  160.     return 0;
  161. }
  162. void *thread_function(void *arg){
  163.     Thread *thread = (Thread *) arg;
  164.     Image *image = thread->image;
  165.     Filter * filter = thread ->filter;
  166.     int thread_number = thread ->thread_number;
  167.     __time_t start_time = get_time();
  168.  
  169.     if(thread->type == 0){
  170.         long from = (long) (thread_number * ceil(image->width / thread->thread_amount));
  171.         long to =0;
  172.         if(thread_number == thread->thread_amount-1){
  173.             to = image->width-1;
  174.         } else{
  175.             to = (long) ((thread_number + 1) * ceil(image->width / thread->thread_amount) - 1);
  176.         }
  177.         while(from<=to){
  178.             for(long i =0; i<image->height;i++){
  179.                 change_pixel(image,filter,i,from);
  180.             }
  181.             from++;
  182.         }
  183.     }
  184.     if(thread->type == 1){
  185.         for(long from = thread_number; from<image->width; from += thread->thread_amount){
  186.             for(int i=0;i<image->height;i++){
  187.                 change_pixel(image,filter,i,from);
  188.             }
  189.         }
  190.     }
  191.     free(thread);
  192.     __time_t *time = malloc(sizeof(long));
  193.     *time = get_time() - start_time;
  194.     pthread_exit(time);
  195. }
  196. int save_image(Image *image,char *path) {
  197.     if (image == NULL)
  198.         return 1;
  199.  
  200.     FILE *file;
  201.     if ((file = fopen(path, "w")) == NULL)
  202.         return 1;
  203.  
  204.     fprintf(file,"P2\n%i %i\n%i\n", image->width, image->height, image->colors);
  205.  
  206.     int split_cnt = 0;
  207.     for (int row = 0; row < image->height; row++) {
  208.         for (int col = 0; col < image->width; col++) {
  209.             if (split_cnt + 1 == image->width) {
  210.                 fprintf(file, " %3d\n", image->structure[row][col]);
  211.                 split_cnt = 0;
  212.             } else {
  213.                 fprintf(file, " %3d", image->structure[row][col]);
  214.                 split_cnt += 1;
  215.             }
  216.         }
  217.     }
  218.  
  219.     fclose(file);
  220.     return 0;
  221. }
  222.  
  223. int main(int argc, char **argv) {
  224.     if (argc != 6){
  225.         printf("Wrong arguments");
  226.         return 1;
  227.     }
  228.     int mode =0;
  229.  
  230.     int thread_amount = atoi(argv[1]);
  231.     if(strcmp(argv[2],"interleaved")==0){
  232.         mode = 1;
  233.     }
  234.  
  235.     char *input_image = argv[3];
  236.     char *filter_path = argv[4];
  237.     char *output_image = argv[5];
  238.  
  239.     pthread_t *threads;
  240.     Filter *filter = malloc(sizeof(Filter));
  241.     if (load_filter(filter, filter_path) != 0) {
  242.         printf("Error while reading the filer file.\n");
  243.         return 1;
  244.     }
  245.     Image *image = malloc(sizeof(Image));
  246.     load_image(image,input_image);
  247.  
  248.     printf("IMAGE INFO\n");
  249.     printf("Dimension: %ix%i\n", image->width, image->height);
  250.     printf("Colors: %i\n", image->colors);
  251.     printf("Filter size: %ix%i\n", filter->size, filter->size);
  252.     printf("Split type: %s\n", argv[2]);
  253.  
  254.     __time_t start_time = get_time();
  255.     printf("THREAD COUNT: %i\n", thread_amount);
  256.     threads = calloc((size_t) thread_amount, sizeof(pthread_t));
  257.  
  258.     for (int i = 0; i < thread_amount; i++) {
  259.         pthread_t tid;
  260.         Thread *thread = malloc(sizeof(Thread));
  261.         thread->image = image;
  262.         thread->filter = filter;
  263.         thread->thread_number = i;
  264.         thread->type = mode;
  265.         thread->thread_amount = thread_amount;
  266.  
  267.         pthread_create(&tid, NULL, thread_function, thread);
  268.         threads[i] = tid;
  269.     }
  270.     for (int i = 0; i < thread_amount; i++) {
  271.         void *ret;
  272.         if (pthread_join(threads[i], &ret) != 0) {
  273.             printf("Error while joining %d thread.\n", i);
  274.             return 1;
  275.         }
  276.  
  277.         unsigned long time = *((unsigned long *) ret);
  278.         printf("Thread %d took %ldus.\n", i, time);
  279.         free(ret);
  280.     }
  281.  
  282.     printf("Overall time: %ldus.\n\n\n\n", get_time() - start_time);
  283.  
  284.     if (save_image(image, output_image) != 0) {
  285.         printf("Error while saving output image to %s.\n", output_image);
  286.         return 1;
  287.     }
  288.  
  289.     for (int i = 0; i < filter->size; i++)
  290.         free(filter->structure[i]);
  291.     free(filter->structure);
  292.     free(filter);
  293.  
  294.     for (int i = 0; i < image->height; i++)
  295.         free(image->structure[i]);
  296.     free(image->structure);
  297.     free(image);
  298.     free(threads);
  299.  
  300.     return 0;
  301.  
  302. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement