PDA

View Full Version : Does anyone have simple libPNG code?


20thCenturyBoy
05-23-2007, 08:48 AM
All I want to do is load my texture as a png file and access the raw data bits to extract the RGB. I'd like to use libPNG as it's free and offers the smallest overhead in size. Unfortunately being a GNU library it is incomprehensible to mere mortals and I can't find a working example to simply load a file and read the data bits. I have tried other libs like FreeImage which are far more usable but they throw in the kitchen sink and grow my exe by about a meg. I know a meg is nothing these days but I have my reasons for wanting a small exe.

So...anyone got any simple libPNG code they can divulge?

Martin

Mark Sheeky
05-23-2007, 11:22 AM
Would this be any use?:
http://www.codeproject.com/bitmap/cximage.asp

It does seem to be a bit over the top but you might be able to trim off the bits you don't need.

Mark

mot
05-23-2007, 11:45 AM
http://www.catnapgames.com/mess/LoadPNG.zip

It won't compile as-is but the png decoding is there. You will probably want to strip the Boost-specific parts, but there aren't many.

jlv
05-24-2007, 12:27 AM
You're welcome to use this if you like.


typedef unsigned char color_type[4];

static void *
jmalloc(long int size)
{
void *p;

p = malloc(size);

if (p == NULL)
exit(1);

return p;
}

static int
read_png(FILE *fp, color_type **p, int *w, int *h)
{
unsigned char *pixels;
png_bytep *row_pointers;
png_structp png_ptr;
png_infop info_ptr, end_info;
png_uint_32 width, height;
int i, bit_depth, color_type, interlace_type;

png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL)
return 0;

info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL) {
png_destroy_read_struct(&png_ptr, NULL, NULL);
return 0;
}

end_info = png_create_info_struct(png_ptr);
if (end_info == NULL) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 0;
}

if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
return 0;
}

png_init_io(png_ptr, fp);

png_read_info(png_ptr, info_ptr);

png_get_IHDR(png_ptr, info_ptr, &width, &height,
&bit_depth, &color_type, &interlace_type,
NULL, NULL);

pixels = jmalloc(width * height * 4);
row_pointers = jmalloc(height * sizeof(*row_pointers));

for (i = 0; i < height; i++)
row_pointers[i] = (void *)(pixels + width * 4 * i);

if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);

if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_gray_1_2_4_to_8(png_ptr);

if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);

if (bit_depth == 16)
png_set_strip_16(png_ptr);

if (bit_depth < 8)
png_set_packing(png_ptr);

if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY)
png_set_add_alpha(png_ptr, 0xff, PNG_FILLER_AFTER);

if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);

png_read_image(png_ptr, row_pointers);

png_read_end(png_ptr, end_info);
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
free(row_pointers);

*p = (void *)pixels;
*w = width;
*h = height;

return 1;
}

20thCenturyBoy
05-24-2007, 05:52 AM
Thankyou everyone, I'll try them all out and report back :)

Sol_HSA
05-25-2007, 02:47 AM
If you want to use a lightweight alternative, there's Lightzpng:

http://www.xmunkki.org/wiki/doku.php?id=projects:lightzpng

lightweight zlib decompressor and png loader. MIT license.

20thCenturyBoy
05-25-2007, 08:24 PM
Sol_HSA - that's precisely what I was looking for! Thank you so much. A single function that returns the image data. Bliss! :D