The PNG Guide is an eBook based on Greg Roelofs' book, originally published by O'Reilly.


Back in the main program, the first thing we do after returning is to free the text buffer, since all of its data has already been written to the PNG file. Then we calculate the number of bytes per row of image data; since we accept only three basic file types, there are only three possibilities for this: either one, three, or four times the image width.

What happens next depends on whether the user requested that the PNG image be interlaced. If so, there's really no good way to read and write the image progressively, so we simply allocate a buffer large enough for the whole thing and read it in. We also allocate and initialize a row_pointers array, where each element points at the beginning of a row of pixels, and then call writepng_encode_image():

int writepng_encode_image(mainprog_info *mainprog_ptr)
    png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr;
    png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr;

    if (setjmp(mainprog_ptr->jmpbuf)) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        mainprog_ptr->png_ptr = NULL;
        mainprog_ptr->info_ptr = NULL;
        return 2;

    png_write_image(png_ptr, mainprog_ptr->row_pointers);

    png_write_end(png_ptr, NULL);

    return 0;

One can see that the actual process of writing the image data is quite simple. We first restore our two struct pointers; we could simply use them as is, but that would require some ugly typecasts. Next we set up the usual PNG error-handling code, followed by the call that really matters: png_write_image(). This function writes all of the pixel data to the file, reading from the row_pointers array we just set up in the main program. Once that is complete, there is nothing left to do but to write out the end of the PNG file with png_write_end(). As discussed earlier, this will write any new text or time chunks, but not ones that have already been written; in our case, that means it does nothing but write the final IEND chunk. The second parameter to png_write_end() is ordinarily info_ptr, but since we have no extra chunks to write, passing a NULL value is a tiny optimization.

Last Update: 2010-Nov-26