2016-10-02 1 views
-3

J'essaie d'utiliser libpng library, et je rencontre un problème avec celui-ci. J'utilise maintenant CLion et j'essaie d'inclure cette librairie libpng dans mon projet. Le problème est plutôt avec la configuration de cette bibliothèque pour l'utiliser dans mon projet que d'utiliser cette bibliothèque. Je pense que je peux faire copier tous les fichiers * .c, * .h de libpng dans mon propre projet dans CLion, en faire une bibliothèque statique liblibpng.a et simplement créer un lien. J'ai même compilé liblibpng.a mais quand j'essaie de l'utiliser, c'est-à-dire simple, y compris $ {path} /libpng-x.x.x/png.h il y a des erreurs et des avertissements dans le fichier png.h comme l'absence de définition png_uint_32. Ok, je peux typedefine en quelque sorte comme unsigned int.Comment utiliser libpng library pour convertir le bitmap RGBA en PNG et PNG en bitmap RGBA

J'essaie de lire README.txt, et d'autres manuels/documentations, INSTALL.txt? Mais il y a beaucoup de possibilités, et je veux juste inclure des fonctionnalités png dans mon projet. Pourquoi est-il nécessaire d'installer cette bibliothèque? Je veux que mon application après la création à l'avenir sera facilement portable vers d'autres ordinateurs sans installation de bibliothèques tierces nécessaires.

Ma question est chaude pour facilement utiliser ce libpng, et les bibliothèques porbably également zlib dans mon propre projet CMake, je préfère la liaison de bibliothèque statique, je ne veux pas d'installation spécifique, etc.

Je pense J'ai un problème avec cette déclaration comme ceci au lieu de définir png_uint_32 juste jeter l'erreur! Il est de pngconf.h

#if UINT_MAX > 4294967294 
    typedef unsigned int png_uint_32; 
#elif ULONG_MAX > 4294967294 
    typedef unsigned long int png_uint_32; 
#else 
# error "libpng requires an unsigned 32-bit (or more) type" 
#endif 
+0

Vous aimeriez peut-être essayer: https://www.google.com/search?q=How+to+static+link+with+libpng+%26+zlib – alk

+0

mais comment le faire dans CMake? –

+0

https://www.google.com/search?q=How+to+static+link+with+libpng+%26+zlib+using+CMake – alk

Répondre

3

réponse courte, il suffit d'utiliser lodepng. C'est beaucoup plus simple à utiliser que libpng et il s'agit d'une source unique, donc vous n'avez pas à vous soucier de la liaison et de la configuration des chemins d'inclusion.

Réponse longue

/* 
    write an rgba image to a memory buffer in PNG format, without any fanciness. 

    Params: rgba - the rgba values 
     width - image width 
     height - image height 
     outsize - return for size of output buffer 
    Returns: pointer to allocated buffer holding png data 
*/ 
void *makePNGBuffer(unsigned char *rgba, int width, int height, size_t *outsize) 
{ 
    int code = 0; 
    // FILE *fp; 
    png_structp png_ptr = 0; 
    png_infop info_ptr =0; 
    png_bytep row = 0; 

    struct mem_encode state = {0, 0}; 

    *outsize = 0; 

    // Initialize write structure 
    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 
    if (png_ptr == NULL) { 
     fprintf(stderr, "Could not allocate write struct\n"); 
    code = 1; 
    goto finalise; 
    } 

// Initialize info structure 
    info_ptr = png_create_info_struct(png_ptr); 
    if (info_ptr == NULL) { 
     fprintf(stderr, "Could not allocate info struct\n"); 
     code = 1; 
     goto finalise; 
    } 

    // Setup Exception handling 
    if (setjmp(png_jmpbuf(png_ptr))) { 
     fprintf(stderr, "Error during png creation\n"); 
     code = 1; 
     goto finalise; 
    } 

    // png_init_io(png_ptr, fp); 

    /* if my_png_flush() is not needed, change the arg to NULL */ 
    png_set_write_fn(png_ptr, &state, my_png_write_data, my_png_flush); 

    // Write header (8 bit colour depth) 
    png_set_IHDR(png_ptr, info_ptr, width, height, 
      8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, 
      PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 

    // Set title 
    /* 
    if (title != NULL) { 
    png_text title_text; 
    title_text.compression = PNG_TEXT_COMPRESSION_NONE; 
    title_text.key = "Title"; 
    title_text.text = title; 
    png_set_text(png_ptr, info_ptr, &title_text, 1); 
    } 
    */ 

    png_write_info(png_ptr, info_ptr); 

    // Allocate memory for one row (3 bytes per pixel - RGB) 
    row = (png_bytep) malloc(4 * width * sizeof(png_byte)); 

    // Write image data 
    int x, y; 
    for (y=0 ; y<height ; y++) { 
     for (x=0 ; x<width ; x++) { 
      // setRGB(&(row[x*3]), buffer[y*width + x]); 
      row[x*4] = rgba[(y*width +x)*4]; 
      row[x*4+1] = rgba[(y*width +x)*4+1]; 
      row[x*4+2] = rgba[(y*width +x)*4+2]; 
      row[x*4+3] = rgba[(y*width +x)*4+3]; 
     } 
     png_write_row(png_ptr, row); 
    } 

    // End write 
    png_write_end(png_ptr, NULL); 

finalise: 
    // if (fp != NULL) fclose(fp); 
    if (info_ptr != NULL) png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); 
    if (png_ptr != NULL) png_destroy_write_struct(&png_ptr, (png_infopp)NULL); 
    if (row != NULL) free(row); 

    *outsize = state.size; 
    return state.buffer; 

    } 
+0

pourriez-vous ajouter la direction inverse? pour compiler et utiliser libpng je dois changer #if UINT_MAX> 4294967294 typedef unsigned int png_uint_32; dans #if UINT_MAX> 0xfffffffe typedef unsigned int png_uint_32; –

+0

@ MichałZiobro sur quelle plate-forme avez-vous besoin de faire cela? –

+0

sur OS X El Capitan –

0

Quelle est l'erreur? ANSI-C (alias ISO C90) nécessite ULONG_MAX pour avoir une valeur supérieure ou égale à 4294967295, donc évidemment une comparaison avec 4294967294 réussit toujours sur un compilateur ANSI, et évidemment puisque la norme utilise exactement cette chaîne décimale, un compilateur qui a un problème avec un numéro moins n'est pas un compilateur ANSI-C.

John Bowler

0

S'il vous plaît essayer de faire les grands entiers dans pngconf.h unsigned en mettant un « U » à la fin:

if UINT_MAX > 4294967294U 
    typedef unsigned int png_uint_32; 
#elif ULONG_MAX > 4294967294U 
    typedef unsigned long int png_uint_32; 
#else 

Il se peut que sur votre plate-forme 4.294.967.294 ne peut pas être représentée comme un entier signé de sorte que la première comparaison échoue en raison du nombre indéfini.