#include #include #include #include #include #include #include #include #include #include #include #include #include "pic.h" #if 1 #define HOST "151.217.40.82" #define PORT 1234 #else #define HOST "127.0.0.1" #define PORT 1337 #endif #define MAX_Y_THREADS 2 #define MAX_X_THREADS 5 #define Y_RES (gimp_image.height) #define X_RES (gimp_image.width) #define ROW_WISE 0 #define COL_WISE 1 #define PARTIAL_WISE 2 #define RENDERALG PARTIAL_WISE uint8_t image[1920][1080][3]; unsigned int offset_x = 1000, offset_y = 500; pthread_mutex_t get_lock; size_t thcnt = 0; int perform_px(int y_segment, int x_segment); int write_px_to_fd(int fd, uint16_t x, uint16_t y, uint8_t r, uint8_t g, uint8_t b){ char intm[100]; snprintf(intm, sizeof(intm), "PX %d %d %.2x%.2x%.2x\n", x + offset_x, y + offset_y , r, g, b); return write(fd, intm, strlen(intm)); } int open_fd(){ #ifndef TEST int fd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in their_addr; struct hostent *he; if ((he=gethostbyname(HOST)) == NULL) { /* get the host info */ perror("gethostbyname"); return EXIT_FAILURE; } their_addr.sin_family = AF_INET; /* host byte order */ their_addr.sin_port = htons(PORT); /* short, network byte order */ their_addr.sin_addr = *((struct in_addr *)he->h_addr); bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */ int n = connect(fd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)); if( n < 0){ perror("Connect"); return EXIT_FAILURE; } #endif #ifdef TEST int fd = 0; #endif return fd; } void* bootstrap_perf(){ pthread_mutex_lock(&get_lock); size_t me = thcnt++; size_t x_frame = me / MAX_X_THREADS; size_t y_frame = me % MAX_X_THREADS; printf("I am %li/%li! \n", x_frame, y_frame); pthread_mutex_unlock(&get_lock); perform_px(x_frame, y_frame); return NULL; } int main(int argc, char** argv){ printf("INIT \n"); signal(SIGPIPE, SIG_IGN); printf("Allocating a %li sized buffer\n", 3 * Y_RES * X_RES * sizeof(unsigned char )); printf("Original picture measurements: %i * %i \n", gimp_image.width, gimp_image.height); if(gimp_image.pixel_data == NULL){ printf("Failed to read image\n"); return EXIT_FAILURE; } for(size_t px = 0; px < sizeof(gimp_image.pixel_data); px+=gimp_image.bytes_per_pixel){ size_t pixn = px / gimp_image.bytes_per_pixel; size_t x = pixn % gimp_image.width; size_t y = pixn / gimp_image.width; memcpy(image[x][y], &gimp_image.pixel_data[px], 3); } //memset(image, 0 , sizeof(image)); printf("Starting program from: %s\n", argv[0]); #ifndef TEST printf("Attempted file: %s\n", argv[1]); #endif pthread_mutex_init(&get_lock, NULL); for(size_t i = 0; i < (MAX_Y_THREADS * MAX_X_THREADS); i++){ printf("Creating thread %li...\n", i); pthread_t th; if(pthread_create(&th,NULL,bootstrap_perf,NULL)){ i--; } } for(;;){ sleep(1); } return EXIT_SUCCESS; } int perform_px(int y_segment, int x_segment){ int fd = open_fd(); printf("I am thread at %i/%i strting up! \n", x_segment, y_segment); for(;;){ int xmin = (X_RES / MAX_X_THREADS) * x_segment; int ymin = (Y_RES / MAX_Y_THREADS) * y_segment; int xmax = (X_RES / MAX_X_THREADS) * (x_segment + 1) ; int ymax = (Y_RES / MAX_Y_THREADS) * (y_segment + 1) ; #if RENDERALG==ROW_WISE for(int x = xmin ; x < xmax ; x++){ for(int y = ymin ; y < ymax; y++){ if(write_px_to_fd(fd, x, y, image[x][y][0], image[x][y][1], image[x][y][2]) < 0){ perror("Failed to write to socket"); close(fd); fd = open_fd(); } } } #elif RENDERALG==COL_WISE for(int y = ymin ; y < ymax; y++){ for(int x = xmin ; x < xmax ; x++){ if(write_px_to_fd(fd, x, y, image[x][y][0], image[x][y][1], image[x][y][2]) < 0){ perror("Failed to write to socket"); close(fd); fd = open_fd(); } } } #elif RENDERALG==PARTIAL_WISE #define PARTIAL_RUNTIME 3 for(size_t offs = 0; offs < PARTIAL_RUNTIME; offs++){ for(int y = ymin ; y < ymax; y++){ for(int x = xmin + offs; x < xmax ; x+=2){ if(write_px_to_fd(fd, x, y, image[x][y][0], image[x][y][1], image[x][y][2]) < 0){ perror("Failed to write to socket"); close(fd); fd = open_fd(); } } } } #endif } close(fd); return 0; }