Advertisement
Guest User

Untitled

a guest
Jan 6th, 2022
168
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.78 KB | None | 0 0
  1. // Tomado y adaptado de http://zarb.org/~gc/html/libpng.html
  2.  
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <stdarg.h>
  8. #include <sys/time.h>
  9. #include <omp.h>
  10. #include <png.h>
  11. #include <sched.h>
  12. // For the CUDA runtime routines (prefixed with "cuda_")
  13. #include <cuda_runtime.h>
  14.  
  15. void abort_(const char * s, ...)
  16. {
  17.         va_list args;
  18.         va_start(args, s);
  19.         vfprintf(stderr, s, args);
  20.         fprintf(stderr, "\n");
  21.         va_end(args);
  22.         abort();
  23. }
  24.  
  25. int x, y;
  26.  
  27. int width, height;
  28. int * d_width, *d_height;
  29. png_byte color_type;
  30. png_byte bit_depth;
  31.  
  32. png_structp png_ptr;
  33. png_infop info_ptr;
  34. int number_of_passes;
  35. png_bytep * row_pointers;
  36. png_bytep * d_row_pointers;
  37. struct timeval tval_before, tval_after, tval_result, tval_before1, tval_after1, tval_result1;
  38.  
  39. void read_png_file(char* file_name)
  40. {
  41.         gettimeofday(&tval_before, NULL);
  42.        
  43.        
  44.         char header[8];    // 8 is the maximum size that can be checked
  45.  
  46.         // Lee el archivo y verifica si es un PNG
  47.         FILE *fp = fopen(file_name, "rb");
  48.         if (!fp)
  49.                 abort_("[read_png_file] File %s could not be opened for reading", file_name);
  50.         fread(header, 1, 8, fp);
  51.         // if (png_sig_cmp(header, 0, 8))
  52.         //         abort_("[read_png_file] File %s is not recognized as a PNG file", file_name);
  53.  
  54.  
  55.         //Inicializa variables necesarias para libpng
  56.         png_ptr =   png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  57.  
  58.         if (!png_ptr)
  59.                 abort_("[read_png_file] png_create_read_struct failed");
  60.  
  61.         info_ptr = png_create_info_struct(png_ptr);
  62.         if (!info_ptr)
  63.                 abort_("[read_png_file] png_create_info_struct failed");
  64.  
  65.         if (setjmp(png_jmpbuf(png_ptr)))
  66.                 abort_("[read_png_file] Error during init_io");
  67.  
  68.         //Inicializa el input/output para el archivo PNG
  69.         png_init_io(png_ptr, fp);
  70.         png_set_sig_bytes(png_ptr, 8);
  71.  
  72.         //Lee la información anterior a los datos de los píxeles como tal
  73.         png_read_info(png_ptr, info_ptr);
  74.  
  75.         //Almacena información del archivo PNG
  76.         width = png_get_image_width(png_ptr, info_ptr);
  77.         height = png_get_image_height(png_ptr, info_ptr);
  78.         color_type = png_get_color_type(png_ptr, info_ptr);
  79.         bit_depth = png_get_bit_depth(png_ptr, info_ptr);
  80.  
  81.         number_of_passes = png_set_interlace_handling(png_ptr);
  82.         png_read_update_info(png_ptr, info_ptr);
  83.  
  84.  
  85.         // Lectura del archivo PNG
  86.         if (setjmp(png_jmpbuf(png_ptr)))
  87.                 abort_("[read_png_file] Error during read_image");
  88.  
  89.         // Reserva el espacio necesario para almacenar los datos del archivo PNG por filas
  90.         row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
  91.         for (y=0; y<height; y++)
  92.                 row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
  93.  
  94.         // Y para la copia para el device
  95.         d_row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
  96.         for (y=0; y<height; y++)
  97.                 d_row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
  98.  
  99.  
  100.         png_read_image(png_ptr, row_pointers);
  101.        
  102.         fclose(fp);
  103.         gettimeofday(&tval_after, NULL);
  104.         timersub(&tval_after, &tval_before, &tval_result);
  105.         printf("BnW Read: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
  106. }
  107.  
  108. void write_png_file(char* file_name)
  109. {
  110.         gettimeofday(&tval_before, NULL);
  111.         // Crea el archivo
  112.         FILE *fp = fopen(file_name, "wb");
  113.         if (!fp)
  114.                 abort_("[write_png_file] File %s could not be opened for writing", file_name);
  115.  
  116.  
  117.         //Inicializa variables necesarias para libpng
  118.         png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  119.  
  120.         if (!png_ptr)
  121.                 abort_("[write_png_file] png_create_write_struct failed");
  122.  
  123.         info_ptr = png_create_info_struct(png_ptr);
  124.         if (!info_ptr)
  125.                 abort_("[write_png_file] png_create_info_struct failed");
  126.  
  127.         if (setjmp(png_jmpbuf(png_ptr)))
  128.                 abort_("[write_png_file] Error during init_io");
  129.  
  130.         png_init_io(png_ptr, fp);
  131.  
  132.  
  133.         // Escribe el header del archivo PNG
  134.         if (setjmp(png_jmpbuf(png_ptr)))
  135.                 abort_("[write_png_file] Error during writing header");
  136.  
  137.         png_set_IHDR(png_ptr, info_ptr, width, height,
  138.                      bit_depth, color_type, PNG_INTERLACE_NONE,
  139.                      PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
  140.  
  141.         png_write_info(png_ptr, info_ptr);
  142.  
  143.  
  144.         // Escribe los bytes del archivo PNG
  145.         if (setjmp(png_jmpbuf(png_ptr)))
  146.                 abort_("[write_png_file] Error during writing bytes");
  147.  
  148.         png_write_image(png_ptr, row_pointers);
  149.  
  150.  
  151.         // Termina la escritura
  152.         if (setjmp(png_jmpbuf(png_ptr)))
  153.                 abort_("[write_png_file] Error during end of write");
  154.  
  155.         png_write_end(png_ptr, NULL);
  156.  
  157.         // Libera el espacio reservado previamente
  158.         for (y=0; y<height; y++)
  159.                 free(row_pointers[y]);
  160.         free(row_pointers);
  161.  
  162.         fclose(fp);
  163.  
  164.         gettimeofday(&tval_after, NULL);
  165.         timersub(&tval_after, &tval_before, &tval_result);
  166.         printf("BnW Write: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
  167. }
  168.  
  169.  
  170. __global__ void process_file(png_bytep * d_row_pointers, int * d_width, int * d_height)
  171. {
  172.         // Se realizan los cambios deseados en la imagen
  173.        
  174.         //Verificar los datos recibidos
  175.         printf("Width = %d , Height = %d ", *d_width, *d_height);
  176.  
  177.         int rgb_total = 0;  
  178.         float rgb_average = 0.0;
  179.         int x = 0;
  180.         int y = 0;
  181.         png_byte *row;
  182.         png_byte *ptr;
  183.  
  184.         for (y=0; y<*d_height-1; y++) {
  185.  
  186.                 for (x=0; x<*d_width; x++) {
  187.                
  188.                         rgb_total = 0;
  189.                         rgb_average = 0;
  190.  
  191.                         row             = d_row_pointers[y];
  192.                         ptr             = &(row[x*3]);
  193.                        
  194.                         printf("Pixel  %d - %d, Rgb values: %d - %d - %d \n", x, y, ptr[0], ptr[1], ptr[2]);
  195.                         rgb_total      += ptr[0] + ptr[1] + ptr[2];
  196.                        
  197.                         // Calculando el promedios RGB
  198.                         rgb_average = rgb_total / 3;
  199.                         // printf("Average: %d \n", (int)rgb_average);
  200.                        
  201.                         ptr[0]  = (int)rgb_average;
  202.                         ptr[1]  = (int)rgb_average;
  203.                         ptr[2]  = (int)rgb_average;
  204.                        
  205.                         // printf("Changed to  %d - %d - %d \n",ptr[0], ptr[1], ptr[2]);
  206.                         // printf("Pixel  %d - %d done\n",x,y);  
  207.                 }
  208.  
  209.         }
  210.         // printf("Para la imagen de resolución: %d x %d - ", *width, *height);
  211.        
  212. }
  213.  
  214.  
  215. int main(int argc, char **argv)
  216. {      
  217.         png_byte *row;
  218.         png_byte *ptr;
  219.         // Verifica los parámetros para ejecutar el programa
  220.         if (argc != 3)
  221.                 abort_("Uso: ./Nombre_del_Programa <file_in> <file_out>");
  222.  
  223.         // Timer de inicio total
  224.         gettimeofday(&tval_before1, NULL);
  225.         printf("-0");
  226.         read_png_file(argv[1]);
  227.         printf("-1");
  228.  
  229.         row             = d_row_pointers[0];
  230.         ptr             = &(row[x*3]);
  231.        
  232.         printf("Pixel  %d - %d, Rgb values: %d - %d - %d \n", x, y, ptr[0], ptr[1], ptr[2]);
  233.  
  234.         // CUDA
  235.         // Tiempo de inicio para el procesamiento de la imagen
  236.         gettimeofday(&tval_before, NULL);
  237.         // Reservar el espacio para las copias de row_pointers, widht y height en el device
  238.         int size = sizeof(png_bytep);
  239.         int int_size = sizeof(int);
  240.         printf("-2");
  241.         cudaMalloc((void **)&d_row_pointers, size);
  242.         // for (y=0; y<height; y++)
  243.         //         cudaMalloc((void **)&d_row_pointers[y],png_get_rowbytes(png_ptr,info_ptr));
  244.         printf("-3");
  245.         cudaMalloc((void **)&d_width, int_size);
  246.         cudaMalloc((void **)&d_height, int_size);
  247.  
  248.         // Copiar los inputs al device
  249.         cudaMemcpy(d_row_pointers, &row_pointers, size, cudaMemcpyHostToDevice);
  250.         // for (y=0; y<height; y++)
  251.         //         cudaMemcpy(d_row_pointers[y], &row_pointers[y], png_get_rowbytes(png_ptr,info_ptr), cudaMemcpyHostToDevice);
  252.         cudaMemcpy(d_width, &width, int_size, cudaMemcpyHostToDevice);
  253.         cudaMemcpy(d_height, &height, int_size, cudaMemcpyHostToDevice);
  254.  
  255.         // Lanzar el kernel
  256.         process_file<<<1,1>>>(d_row_pointers, d_width, d_height);
  257.  
  258.         // Copiar los resultados de vuelta al host
  259.         cudaMemcpy(&row_pointers, d_row_pointers, size, cudaMemcpyDeviceToHost);
  260.  
  261.         // Limpieza
  262.         for (y=0; y<height; y++)
  263.                 cudaFree(d_row_pointers[y]);
  264.         cudaFree(d_row_pointers);
  265.         cudaFree(d_width);
  266.         cudaFree(d_height);
  267.  
  268.         // Tiempo de fin para el procesamiento de la imagen
  269.         gettimeofday(&tval_after, NULL);
  270.         timersub(&tval_after, &tval_before, &tval_result);
  271.         printf("BnW Process: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
  272.  
  273.         // Escritura de la imagen con los resultados
  274.         write_png_file(argv[2]);
  275.  
  276.         // Tiempo de fin total
  277.         gettimeofday(&tval_after1, NULL);
  278.         timersub(&tval_after1, &tval_before1, &tval_result1);
  279.         printf("Tiempo de ejecución de efecto blanco y negro: %ld.%06ld\n \n", (long int)tval_result1.tv_sec, (long int)tval_result1.tv_usec);
  280.  
  281.         return 0;
  282. }
  283.  
Advertisement
Comments
Add Comment
Please, Sign In to add comment
Advertisement