PNG转换OpenGL Texture
29 Mar 2013
bool loadPngImage(char *name, int *outWidth, int *outHeight, bool *outHasAlpha, GLubyte **outData)
{
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = false;
int color_type, interlace_type;
FILE *fp;
printf("png file : %s\n", name);
if((fp = fopen(name, "rb")) == NULL)
{
printf("%s: open png file error: \n", __FILE__);
perror("open filed:\n");
return false;
}
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(NULL == png_ptr)
{
fclose(fp);
return false;
}
info_ptr = png_create_info_struct(png_ptr);
if(NULL == info_ptr)
{
fclose(fp);
return false;
}
if(setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
pclose(fp);
return false;
}
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, sig_read);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, png_voidp_NULL);
*outWidth = info_ptr->width;
*outHeight = info_ptr->height;
switch(info_ptr->color_type)
{
case PNG_COLOR_TYPE_RGBA:
*outHasAlpha = true;
break;
case PNG_COLOR_TYPE_RGB:
*outHasAlpha = false;
break;
default:
printf("%s: color type: %d not supported\n", __FILE__, info_ptr->color_type);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(fp);
return false;
}
unsigned int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
*outData = (unsigned char*)malloc(row_bytes * *outHeight);
png_bytepp row_pointer = png_get_rows(png_ptr, info_ptr);
int i;
for(i = 0; i < *outHeight; i++)
{
//note that png is ordered top to buttom,
//but OpenGL expect it bottom to top
//so the order swapped
memcpy(*outData + (row_bytes * (*outHeight - 1 -i)), row_pointer[i], row_bytes);
}
png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
fclose(fp);
printf("read png finished\n");
return true;
}