-2

I try to use libpng library, and I encounter problem with it.

I am using CLion now, and try to include this libpng library in my project. The problem is rather with configuration of this library to use it in my project than using this library. I think that I can make copy all *.c, *.h files from libpng into my own project in CLion, make from it static library liblibpng.a and just link against it. I even compiled liblibpng.a but when I try to use it, i.e. simple including ${path}/libpng-x.x.x/png.h there are errors and warnings in the png.h file like lack of png_uint_32 definition. Ok I can typedefine this somehow like unsigned int.

I am trying to read README.txt, and other manuals/documantations, INSTALL.txt? But there is a lot os possibilities, and I just want to include png functionalities in my project. Why there is need to install this library? I want that my app after creation in the future will be easly portable to other computers without 3rd party libraries installation needed at all.

My question is hot to easily start using this libpng, and porbably also zlib libraries in my own project in CMake, I prefer static library linking, I don't want any specific installation, etc.

I think I have a problem with this declaration as this instead of defining png_uint_32 just throw error! It is from 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
Michał Ziobro
  • 10,759
  • 11
  • 88
  • 143

3 Answers3

4

Short answer, just use lodepng. It's a lot simpler to use than libpng and it comes in a single source, so you don't have to mess about with linking and setting up include paths.

Long answer

/*
   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;

    }
Malcolm McLean
  • 6,258
  • 1
  • 17
  • 18
0

What is the error?

ANSI-C (aka ISO C90) requires ULONG_MAX to have a value greater than or equal to 4294967295, so obviously a comparison with 4294967294 always succeeds on an ANSI compiler, and obviously since the standard uses exactly that decimal string, a compiler which has a problem with a number one less is not an ANSI-C compiler.

John Bowler

John Bowler
  • 101
  • 3
0

Please try making those big integers in pngconf.h unsigned by putting a "U" at the end:

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

It may be that on your platform 4294967294 cannot be represented as a signed integer so the first comparison fails due to the number being undefined.

Glenn Randers-Pehrson
  • 11,940
  • 3
  • 37
  • 61