Nick Pirollo
Nick Pirollo

Reputation: 191

Creating a PNG from char buffer and size data using libpng

I am currently modifying Android Screenshot Library to accept outside connections. When it connects for Java, I know I can get the raw data and pass it into Java's Bitmap through createBitmapFromBuffer(data). The end goal here is to use C though, and I cannot figure out how to popular the pixel data into libpng to make it write correctly.

Some points: The C server sends height, width and bpp. It then sends the buffer data converted from the frame buffer on Android over the socket.

The client can get all the data successfully and I know how to generate the headers from the data I have. The issue is taking a char[] and converting it into something png_set_rows and png_write_png will accept, or how to append it separately and save the headers without any row data.

Upvotes: 1

Views: 2742

Answers (2)

OregonTrail
OregonTrail

Reputation: 9039

Let's take a look at the prototype and description for png_set_rows

void png_set_rows(png_structp png_ptr, 
                  png_infop info_ptr, 
                  png_bytepp row_pointers);

png_set_rows() shall put rows of image data into the info_ptr structure, where row_pointers is an array of pointers to the pixel data for each row.

I'm going to assume that you have already initialized a png_stuctp to pass as the first argument, and you have an empty png_infop that you are passing in as the second argument.

So your question is what to pass in as the third argument.

Well, let's take a look at the definition for png_byte:

typedef unsigned char png_byte;

Great, a png_byte is an unsigned char.

Now let's take a look at the definition for a png_bytepp:

typedef png_byte FAR * FAR * png_bytepp;

It's a two dimensional array of unsigned chars.

So, all you have to do is create a 2D array of unsigned chars and cast it to a png_bytepp:

unsigned int IMAGE_HEIGHT = 720, IMAGE_WIDTH = 1280;

unsigned char row_pointers[IMAGE_HEIGHT][IMAGE_WIDTH];

/* test image initialization */
unsigned int i, j;
for (i = 0; i < IMAGE_HEIGHT; i++) {
    for (j = 0; j < IMAGE_WIDTH; j++) {
        row_pointers[i][j] = i * j;
    }   
}

png_set_rows(png_ptr, info_ptr, (png_bytepp)row_pointers);

Upvotes: 3

Rahul Banerjee
Rahul Banerjee

Reputation: 2363

Take a look at lodepng. It's an easy-to-use wrapper around libpng, with high-level functions (like encode()).

Upvotes: 1

Related Questions