You are not logged in.

#1 2010-01-11 15:31:53

mamacken
Member
From: Waterloo, Ontario, Canada
Registered: 2009-12-03
Posts: 9

libpng help

I am trying for create a program that performs 2-dimensional fast fourier transforms on each pixel of data in an image. I am going to transform each channel seperately, then map the coefficients to colours and recombine them into an image.

But I cannot seem to figure out how to read/interpret the pixel data using libpng. Can someone help me find out how I would read a png image and read each pixel's data into an array?


"In questions of science the authority of a thousand is not worth the humble reasoning of a single individual."
    - Galileo Galilei

Offline

#2 2010-01-11 16:43:51

tavianator
Member
From: Waterloo, ON, Canada
Registered: 2007-08-21
Posts: 858
Website

Re: libpng help

I agree, libpng's interface isn't the world's most intuitive.  I'm using it in a raytracer I'm writing, and the relevant code is here.  The actual reading process begins on line 444.  Feel free to copy it and tweak it to your needs (the code is GPLv3) or use it as a reference to write your own.  You can probably safely ignore the multithreading-related parts of the code.  And reply with any questions you have.

Last edited by tavianator (2010-01-11 16:51:39)

Offline

#3 2010-01-11 18:00:29

mamacken
Member
From: Waterloo, Ontario, Canada
Registered: 2009-12-03
Posts: 9

Re: libpng help

Wow thanks man, from what I've looked at it seems to perform exactly the mechanism I need to implement.


"In questions of science the authority of a thousand is not worth the humble reasoning of a single individual."
    - Galileo Galilei

Offline

#4 2010-01-11 20:13:57

mamacken
Member
From: Waterloo, Ontario, Canada
Registered: 2009-12-03
Posts: 9

Re: libpng help

Your program has been very helpful as a reference guide, but I just have one question about the byte format of each pixel:

sRGB.R = ((double)((png_pixel[0] << UINT16_C(8)) + png_pixel[1])) / UINT16_MAX;
sRGB.G = ((double)((png_pixel[2] << UINT16_C(8)) + png_pixel[3])) / UINT16_MAX;
sRGB.B = ((double)((png_pixel[4] << UINT16_C(8)) + png_pixel[5])) / UINT16_MAX;

I don't understand why you're adding various elements in the byte arrays, and I'm not totally sure what format they're in to begin with. I myself am not interested in converting them to sRGB either, so perhaps some other the operations that you were performing would be irrelevent to me.

Last edited by mamacken (2010-01-11 20:14:51)


"In questions of science the authority of a thousand is not worth the humble reasoning of a single individual."
    - Galileo Galilei

Offline

#5 2010-01-11 21:21:55

tavianator
Member
From: Waterloo, ON, Canada
Registered: 2007-08-21
Posts: 858
Website

Re: libpng help

That code handles 16-bit colours.  Since each component (red, green, and blue) is two bytes, the byte order matters.  Earlier I tested whether we were little- or big-endian with htonl() and told libpng to swap the byte order appropriately with png_set_swap().  After doing that, each row has pixels in the form RrGgBb[Aa], with each letter being one byte.  The code you pasted simply calculates red to be R*256 + r, etc.

Technically it would be way easier to just use uint16_t's, not bother with png_set_swap(), and just treat the row as and array of 16-bit components.  I really have no idea why I didn't do that, although it may have to do with wanting to avoid pointer aliasing.

Regarding sRGB: sRGB is just one of many RGB colour spaces, and my raytracer uses it, so I earlier used png_set_sRGB_gAMA_and_cHRM() to ensure that the image was given to me in the sRGB space.  Most PNG files are already in sRGB anyway.

Last edited by tavianator (2010-01-11 21:24:50)

Offline

#6 2010-01-11 23:45:40

Grazz256
Member
Registered: 2009-06-28
Posts: 69

Re: libpng help

mamacken, Just out of interest how are you doing the fast fourier transforms? Did you write your own code or are you going to use a library?

Offline

#7 2010-01-12 14:33:04

mamacken
Member
From: Waterloo, Ontario, Canada
Registered: 2009-12-03
Posts: 9

Re: libpng help

Grazz256 wrote:

mamacken, Just out of interest how are you doing the fast fourier transforms? Did you write your own code or are you going to use a library?

I used the book "Numerical Recipes in C" as a guiding reference in implementing it. The GSL doesn't have a multidimensional FFT function.


"In questions of science the authority of a thousand is not worth the humble reasoning of a single individual."
    - Galileo Galilei

Offline

Board footer

Powered by FluxBB