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



writepng_encode_row()

If the user did not request interlacing, we can read and write the image progressively, allowing very large images to be converted to PNG without incurring a huge memory overhead. In this case, we forego the row_pointers array and simply allocate image_data large enough to hold one row. Then we start looping over all of the rows in the image (i.e., height rows), reading the pixel data into our buffer and passing it to writepng_encode_row():

int writepng_encode_row(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_row(png_ptr, mainprog_ptr->image_data);

    return 0;
}

Astute readers will perceive that this function is almost identical to the previous one for interlaced images; the differences are the lack of a png_write_end() call (for obvious reasons) and the call to png_write_row() instead of png_write_image(). image_data now acts as our single row pointer.

Once the loop over rows completes, we call one last function to close out the PNG file:

int writepng_encode_finish(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_end(png_ptr, NULL);

    return 0;
}

Again, the function is exactly like what we've seen before except that it calls png_write_end(). Alternatively, it could have been combined with writepng_encode_row() had we included in our mainprog_info struct a flag indicating whether the given row was the last one in the image.




Last Update: 2010-Nov-26