bird1500
December 1st, 2012, 10:48 AM
Hi,
I'm using libpng12(-dev) to load PNG files but something's wrong when I display them (see screenshot).
Can anyone please spot the problem?
void*
Manager::loadImagePng(const char *path, float &w, float &h,
int &format, int &rowStride) {
char header[8];
FILE *fp = fopen(path, "rb");
if (!fp) {
Print("File %s could not be opened for reading");
return NULL;
}
size_t numBytes = fread(header, 1, sizeof(png_bytep), fp);
if(numBytes != sizeof(png_bytep)) {
fclose(fp);
Print("Read too few bytes");
return NULL;
}
if (png_sig_cmp((png_bytep)header, 0, 8)) {
Print("File is not recognized as a PNG file");
return NULL;
}
png_structp png_ptr = png_create_read_struct(
PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
Print("png_create_read_struct failed");
return NULL;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
Print("png_create_info_struct failed");
return NULL;
}
if (setjmp(png_jmpbuf(png_ptr))) {
Print("Error during init_io");
return NULL;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
int width = png_get_image_width(png_ptr, info_ptr);
w = width;
int height = png_get_image_height(png_ptr, info_ptr);
h = height;
png_byte color_type = png_get_color_type(png_ptr, info_ptr);
if(color_type == PNG_COLOR_TYPE_RGB) {
format = GL_RGB;
} else if(color_type == PNG_COLOR_TYPE_RGBA) {
format = GL_RGBA;
} else {
Print("Unknown png format");
return NULL;
}
png_read_update_info(png_ptr, info_ptr);
/*
png_uint_32 channels = png_get_channels(png_ptr, info_ptr);
png_uint_32 bitdepth = png_get_bit_depth(png_ptr, info_ptr);
rowStride = width * bitdepth * channels / 8;
*/
rowStride = png_get_rowbytes(png_ptr,info_ptr);
if (setjmp(png_jmpbuf(png_ptr))) {
Print("[read_png_file] Error during read_image");
}
png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
for(int y=0; y<height; y++) {
row_pointers[y] = (png_byte*) malloc(rowStride);
}
png_read_image(png_ptr, row_pointers);
fclose(fp);
return row_pointers;
}
The function returns the raw pixels of type void* which are sent to glTexture2D() along with the params width, height, stride, format.
I use a similar function for jpeg files using libjpeg and that one works fine.
The original PNG file is here (http://fwallpapers.com/files/images/beautiful-nature-china.png?iact=hc&vpx=677&vpy=216&dur=427&hovh=139&hovw=239&tx=151&ty=60&sig=103454256490900199261&ei=JNO5UPAnqJrRBZqfgKgD&page=1&tbnh=137&tbnw=234&start=0&ndsp=43&ved=1t:429,r:3,s:0,i:164).
I'm using libpng12(-dev) to load PNG files but something's wrong when I display them (see screenshot).
Can anyone please spot the problem?
void*
Manager::loadImagePng(const char *path, float &w, float &h,
int &format, int &rowStride) {
char header[8];
FILE *fp = fopen(path, "rb");
if (!fp) {
Print("File %s could not be opened for reading");
return NULL;
}
size_t numBytes = fread(header, 1, sizeof(png_bytep), fp);
if(numBytes != sizeof(png_bytep)) {
fclose(fp);
Print("Read too few bytes");
return NULL;
}
if (png_sig_cmp((png_bytep)header, 0, 8)) {
Print("File is not recognized as a PNG file");
return NULL;
}
png_structp png_ptr = png_create_read_struct(
PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
Print("png_create_read_struct failed");
return NULL;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
Print("png_create_info_struct failed");
return NULL;
}
if (setjmp(png_jmpbuf(png_ptr))) {
Print("Error during init_io");
return NULL;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
int width = png_get_image_width(png_ptr, info_ptr);
w = width;
int height = png_get_image_height(png_ptr, info_ptr);
h = height;
png_byte color_type = png_get_color_type(png_ptr, info_ptr);
if(color_type == PNG_COLOR_TYPE_RGB) {
format = GL_RGB;
} else if(color_type == PNG_COLOR_TYPE_RGBA) {
format = GL_RGBA;
} else {
Print("Unknown png format");
return NULL;
}
png_read_update_info(png_ptr, info_ptr);
/*
png_uint_32 channels = png_get_channels(png_ptr, info_ptr);
png_uint_32 bitdepth = png_get_bit_depth(png_ptr, info_ptr);
rowStride = width * bitdepth * channels / 8;
*/
rowStride = png_get_rowbytes(png_ptr,info_ptr);
if (setjmp(png_jmpbuf(png_ptr))) {
Print("[read_png_file] Error during read_image");
}
png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
for(int y=0; y<height; y++) {
row_pointers[y] = (png_byte*) malloc(rowStride);
}
png_read_image(png_ptr, row_pointers);
fclose(fp);
return row_pointers;
}
The function returns the raw pixels of type void* which are sent to glTexture2D() along with the params width, height, stride, format.
I use a similar function for jpeg files using libjpeg and that one works fine.
The original PNG file is here (http://fwallpapers.com/files/images/beautiful-nature-china.png?iact=hc&vpx=677&vpy=216&dur=427&hovh=139&hovw=239&tx=151&ty=60&sig=103454256490900199261&ei=JNO5UPAnqJrRBZqfgKgD&page=1&tbnh=137&tbnw=234&start=0&ndsp=43&ved=1t:429,r:3,s:0,i:164).