2015-11-28 65 views
0

我在一個項目,我不得不做一個程序,將從一個JPEG繪製一個ASCII。 程序將根據像素的HSL值選擇一個字符:Hue,Saturation,Lightness 因此,當JPEG文件在RGB中時,我將它轉換爲HSL。 但是我發現我的程序很慢,它減慢了我的整個虛擬機的速度 你知道我可以怎樣改進它讓它更快一點嗎? 它在我寫我調用轉換成RGB HSL 這裏的功能是:將RGB圖像從RGB重寫爲HSL:我如何優化這個?

的main.c:

#include <stdio.h> 
#include <stdlib.h> 
#include <jpeglib.h> 
#include "fonctions.h" 


int main (int argc, char** argv){ 


    int H; 
    int W; 
    int C; 
    FILE *fichier = NULL; //file pour l'image entrée 
    FILE *image = NULL; //file pou l'image à la sortie 
    unsigned char **buffer; //buffer où sera contenue l'image 

    buffer = malloc(256*(sizeof(unsigned char*))); 

    if (argv[1] == NULL) 
     fichier = fopen("cara.jpg", "r"); 
    else 
     fichier = fopen(argv[1], "r"); 
    image = fopen("cara_image_cree.jpg", "wb"); 

    if (fichier == NULL) 
     printf("Probleme lecture"); 

    printf("Cara Delevingne\n"); 
    buffer = lire(fichier, &H, &W, &C); 
    /* afficher 3 sous-pixels : 
    printf("\nBuffer case 1 : %d", buffer[0][0]); 
    printf("\nBuffer case 1 : %d", buffer[0][0+1]); 
    printf("\nBuffer case 1 : %d\n", buffer[0][0+2]);*/ 
    ecrire(&H, &W, &C, buffer, image); 

    fclose(fichier); 
    fclose(image); 
    return 0; 
} 

read.c:

#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <jpeglib.h> 
#include <jerror.h> 

unsigned char** lire (FILE* file, int *H, int *W, int *C){ 

    struct jpeg_decompress_struct cinfo; 
    struct jpeg_error_mgr jerr; 

    int n = 0; 
    unsigned char** buffer; // buffer qui va contenir l'image 

    /*printf("SHITSHITSHITSHITDEBUG\n"); 
     fflush(stdout);*/ 
    cinfo.err = jpeg_std_error(&jerr); 
    jpeg_create_decompress(&cinfo); // Initialisation de la structure 

    jpeg_stdio_src(&cinfo,file); // file est de type FILE * (descripteur de fichier 
    // sur le fichier jpega decompresser) 
    jpeg_read_header(&cinfo,TRUE);// lecture des infos sur l'image jpeg 


    jpeg_start_decompress(&cinfo);// lancement du processus de decompression 


    *H = cinfo.output_height; // on récupère la hauteur 
    *W = cinfo.output_width; // on récupère la largeur 
    *C = cinfo.output_components; // on regarde si l'image est en couleurs ou N&B 


    buffer=malloc((*H) *sizeof(unsigned char*)); // on alloue de la mémoire au buffer selon le nb de lignes de pixels qu'il va devoir prendre 

    while (n < *H) // tant que le compteur n'a pas dépassé l'image 
    { 
     buffer[n] = (unsigned char*) malloc((*W) * (*C) *sizeof(unsigned char *)); // on alloue à chaque ligne, la taille de la largeur 

     jpeg_read_scanlines(&cinfo,buffer+n,1); // lecture des n lignes suivantes de l'image 
     // dans le buffer (de type unsigned char *) 
     n++; 
    } 

    jpeg_finish_decompress(&cinfo); 

    jpeg_destroy_decompress(&cinfo); 

    return buffer; 
} 

write.c:

#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <jpeglib.h> 
#include <jerror.h> 

void ecrire (int *H, int *W, int *C, unsigned char **buffer, FILE *file){ 

    struct jpeg_compress_struct cinfo; 
    struct jpeg_error_mgr jerr; 

    float** bufferHSL; 
    int n = 0; // parcoureurs pour écrire l'image 

    int i = 0; // parcoureurs pour transformer en HSL 
    int j = 0; 

    float h = 0; // variables pour stocker le résultat HSL 
    float s = 0; 
    float l = 0; 
    int r, g, b; 
    cinfo.err = jpeg_std_error(&jerr); 
    jpeg_create_compress(&cinfo); // Initialisation de la structure 

    jpeg_stdio_dest(&cinfo,file); // file est de type FILE * (descripteur de fichier 
    // sur le fichier jpeg compressé final) 
    cinfo.image_width= *W;   // nombre de ligne de l'image 
    cinfo.image_height= *H;   // nombre de pixel par ligne 
    cinfo.input_components = *C;  // 3 pour une image couleur, 1 pour une N&B 
    cinfo.in_color_space= JCS_RGB; 
    // JCS_GRAYSCALE pour une image N&B 
    jpeg_set_defaults(&cinfo); // initialisation des paramètres de compression 
    jpeg_start_compress(&cinfo,TRUE); // lancement du processus de decompression 

    bufferHSL = (float **) malloc((*H) *sizeof(long int*)); 
    while (i < *H){ // lecture des lignes pour transformation HSL 
     j = 0; 
     while (j < *W){ 
      /*printf("i : %d /t j : %d \n",i , j); 
      fflush(stdout);*/ 
      bufferHSL[i] = (float*)malloc((*W) *sizeof(long int*)); 
      r = buffer[i][j]; 
      g = buffer[i][j+1]; 
      b = buffer[i][j+2]; 
      rgbToHsl(r, g, b, &h, &s, &l); 

      bufferHSL[i][j] = h; 
      bufferHSL[i][j+1] = s; 
      bufferHSL[i][j+2] = l; 
      j++; 
      /*printf("TESTTEST\n"); 
      fflush(stdout);*/ 

     } 
     i++; 
    } 


    while (n < *H) 
    { 
     jpeg_write_scanlines(&cinfo,buffer+n,1);// écriture des n lignes suivantes de l'image 
     // stockées dans le buffer (de type unsigned char *) 
     n++; 
    } 

    jpeg_finish_compress(&cinfo); 

    jpeg_destroy_compress(&cinfo); 

} 

RGB_to_HSL.c:

void rgbToHsl(int r, int g, int b, int *h, int *s, int *l){ 
    r/=255; g /= 255; b/=255; 
    int max = maximum(r, g, b); 
    int min = minimum(r, g, b); 
    *l = (max + min)/2; 

    if (max == min) 
     *h = *s = 0; // achromatique 
    else{ 
     int d = max - min; 
     *s = *l > 0.5 ? d/(2 - max - min) : d/(max + min); 
     if (max == r) 
      *h = (g-b)/d + (g < b ? 6 : 0); 
     if (max == g) 
      *h = (b-r)/d + 2; 
     if (max == b) 
      *h = (r-g)/d + 4; 

     /*case r: *h = r; 
      case g: *h = g; 
      case b: *h = b; */ 
    } 
    *h /= 6; 





} 

int maximum (int a, int b, int c){ 
    if (a > b){ 
     if (a > c) 
      return a; 
     else 
      return c; 
    } 
    else{ 
     if (b > c) 
      return b; 
     if (c > b) 
      return c; 
    } 
} 

int minimum (int a, int b, int c){ 
    if (a < b){ 
     if (a < c) 
      return a; 
     else 
      return c; 
    } 
    else{ 
     if (b < c) 
      return b; 
     if (c < b) 
      return c; 
    } 


} 

回答

1

你應該運行一些分析工具,看看究竟哪些部分需要多長時間來執行和優化。

如果沒有,咋一看顯示您所呼叫malloc很多的內部循環,在這裏:

bufferHSL = (float **) malloc((*H) *sizeof(long int*)); 
while (i < *H){ // lecture des lignes pour transformation HSL 
    j = 0; 
    while (j < *W){ 
     bufferHSL[i] = (float*)malloc((*W) *sizeof(long int*)); 

其實,這似乎只是錯誤的 - 只有你叫它爲每j < *W迭代,但你每i需要一次。你正在泄漏分配,並且只在最後一次迭代中對它做任何事情 - 你確定你的輸出是正確的嗎?

作爲第一步,我建議將該行從內部while循環移出。

還有幾個其他微型優化的空間,但我認爲你不需要這樣做。只要確保代碼是第一次正確的,然後找到速度慢的部分(通常是最內層的循環),並且只關注那個部分。

+0

好的,謝謝,我會盡力的! –