Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <sys/types.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/time.h>
- #include <pthread.h>
- #include <math.h>
- #include <sys/param.h>
- //=========================================
- // BLOCK 0
- // INTERLEAVED 1
- //=========================================
- typedef struct {
- int colors;
- int width;
- int height;
- char ** structure;
- } Image;
- typedef struct {
- int size;
- double **structure;
- } Filter ;
- typedef struct {
- Image *image;
- Filter *filter;
- int thread_number;
- int type;
- int thread_amount;
- } Thread;
- int load_filter(Filter *filter,const char *path) {
- if (filter == NULL) {
- printf("Transform buffer is null");
- return 1;
- }
- long row = 0;
- long column = 0;
- FILE * file = fopen(path, "r");
- if(file == NULL){
- printf("error opening filter");
- return 1;
- }
- fseek(file, 0, SEEK_END);
- long filter_file_size = ftell(file);
- fseek(file, 0, SEEK_SET);
- char* buffer = calloc(sizeof(char), (size_t) filter_file_size);
- fread(buffer, sizeof(char), (size_t) filter_file_size, file);
- char *delim = "\r\n ";
- char *tok = strtok(buffer, delim);
- long filter_size = atoi(tok);
- filter->size = (int) filter_size;
- double **values = calloc((size_t) filter_size, sizeof(double *));
- for (long i = 0; i < filter_size; i++)
- values[i] = calloc((size_t) filter_size, sizeof(double));
- filter->structure = values;
- // rewrite filter_file into filter_structure
- char *token = strtok(NULL, delim);
- while (token != NULL) {
- if (column >= filter->size) {
- column = 0;
- row++;
- }
- if (row >= filter->size)
- break;
- double value = atof(token);
- values[row][column] = value;
- column++;
- token = strtok(NULL, delim);
- }
- fclose(file);
- return 0;
- }
- int load_image(Image *image, char *path){
- if(image == NULL){
- return 1;
- }
- long row = 0;
- long col = 0;
- FILE * file = fopen(path,"r");
- if(file == NULL){
- printf("Can't open image");
- }
- fseek(file, 0, SEEK_END);
- long file_size = ftell(file);
- fseek(file, 0, SEEK_SET);
- char *buff= calloc(sizeof(char), (size_t) file_size);
- fread(buff, sizeof(char), (size_t) file_size, file);
- char *delim1="\t\r\n";
- char *delim2="\t\r\n ";
- char *width= strtok(buff,delim1);
- width = strtok(NULL,delim1);
- width = strtok(NULL,delim2);
- image->width=atoi(width);
- char * height = strtok(NULL,delim1);
- image->height = atoi(height);
- char *colors=strtok(NULL,delim1);
- image->colors=atoi(colors);
- char **structure = calloc((size_t) image->height, sizeof(char *));
- for (long i = 0; i < image->height; i++)
- structure[i] = calloc((size_t) image->width, sizeof(char));
- image->structure = structure;
- char *token;
- while (1) {
- token = strtok(NULL, delim2);
- if (token == NULL)
- break;
- if (col >= image->width) {
- col = 0;
- row++;
- }
- if (row >= image->height)
- break;
- unsigned long grayscale = strtoul(token, NULL, 10);
- structure[row][col] = (unsigned char) grayscale;
- col++;
- }
- fclose(file);
- return 0;
- }
- __time_t get_time() {
- struct timeval time;
- gettimeofday(&time, NULL);
- return time.tv_sec * (int) 1e6 + time.tv_usec;
- }
- int change_pixel(Image *image,Filter *filter,long row,long col){
- double new_pixel=0;
- long size = filter->size;
- for (int i = 0; i < size; i++) {
- for (int j = 0; j < size; j++) {
- long img_col = MAX(0, col - (long) ceil(size / 2) + i);
- long img_row = MAX(0, row - (long) ceil(size / 2) + j);
- if (img_row < image->height && img_col < image->width)
- new_pixel += image->structure[img_row][img_col] * filter->structure[j][i];
- }
- }
- image->structure[row][col] = (unsigned char) round(new_pixel);
- return 0;
- }
- void *thread_function(void *arg){
- Thread *thread = (Thread *) arg;
- Image *image = thread->image;
- Filter * filter = thread ->filter;
- int thread_number = thread ->thread_number;
- __time_t start_time = get_time();
- if(thread->type == 0){
- long from = (long) (thread_number * ceil(image->width / thread->thread_amount));
- long to =0;
- if(thread_number == thread->thread_amount-1){
- to = image->width-1;
- } else{
- to = (long) ((thread_number + 1) * ceil(image->width / thread->thread_amount) - 1);
- }
- while(from<=to){
- for(long i =0; i<image->height;i++){
- change_pixel(image,filter,i,from);
- }
- from++;
- }
- }
- if(thread->type == 1){
- for(long from = thread_number; from<image->width; from += thread->thread_amount){
- for(int i=0;i<image->height;i++){
- change_pixel(image,filter,i,from);
- }
- }
- }
- free(thread);
- __time_t *time = malloc(sizeof(long));
- *time = get_time() - start_time;
- pthread_exit(time);
- }
- int save_image(Image *image,char *path) {
- if (image == NULL)
- return 1;
- FILE *file;
- if ((file = fopen(path, "w")) == NULL)
- return 1;
- fprintf(file,"P2\n%i %i\n%i\n", image->width, image->height, image->colors);
- int split_cnt = 0;
- for (int row = 0; row < image->height; row++) {
- for (int col = 0; col < image->width; col++) {
- if (split_cnt + 1 == image->width) {
- fprintf(file, " %3d\n", image->structure[row][col]);
- split_cnt = 0;
- } else {
- fprintf(file, " %3d", image->structure[row][col]);
- split_cnt += 1;
- }
- }
- }
- fclose(file);
- return 0;
- }
- int main(int argc, char **argv) {
- if (argc != 6){
- printf("Wrong arguments");
- return 1;
- }
- int mode =0;
- int thread_amount = atoi(argv[1]);
- if(strcmp(argv[2],"interleaved")==0){
- mode = 1;
- }
- char *input_image = argv[3];
- char *filter_path = argv[4];
- char *output_image = argv[5];
- pthread_t *threads;
- Filter *filter = malloc(sizeof(Filter));
- if (load_filter(filter, filter_path) != 0) {
- printf("Error while reading the filer file.\n");
- return 1;
- }
- Image *image = malloc(sizeof(Image));
- load_image(image,input_image);
- printf("IMAGE INFO\n");
- printf("Dimension: %ix%i\n", image->width, image->height);
- printf("Colors: %i\n", image->colors);
- printf("Filter size: %ix%i\n", filter->size, filter->size);
- printf("Split type: %s\n", argv[2]);
- __time_t start_time = get_time();
- printf("THREAD COUNT: %i\n", thread_amount);
- threads = calloc((size_t) thread_amount, sizeof(pthread_t));
- for (int i = 0; i < thread_amount; i++) {
- pthread_t tid;
- Thread *thread = malloc(sizeof(Thread));
- thread->image = image;
- thread->filter = filter;
- thread->thread_number = i;
- thread->type = mode;
- thread->thread_amount = thread_amount;
- pthread_create(&tid, NULL, thread_function, thread);
- threads[i] = tid;
- }
- for (int i = 0; i < thread_amount; i++) {
- void *ret;
- if (pthread_join(threads[i], &ret) != 0) {
- printf("Error while joining %d thread.\n", i);
- return 1;
- }
- unsigned long time = *((unsigned long *) ret);
- printf("Thread %d took %ldus.\n", i, time);
- free(ret);
- }
- printf("Overall time: %ldus.\n\n\n\n", get_time() - start_time);
- if (save_image(image, output_image) != 0) {
- printf("Error while saving output image to %s.\n", output_image);
- return 1;
- }
- for (int i = 0; i < filter->size; i++)
- free(filter->structure[i]);
- free(filter->structure);
- free(filter);
- for (int i = 0; i < image->height; i++)
- free(image->structure[i]);
- free(image->structure);
- free(image);
- free(threads);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement