From Wikipedia, the free encyclopedia
// The following code loads a png file into a bitmap image in Windows.
// No error handling
void PNGAPI user_error_fn (png_structp png, png_const_charp sz) { }
void PNGAPI user_warning_fn (png_structp png, png_const_charp sz) { }
HBITMAP
load_png (const char *szFile)
{
FILE *fp = fopen (szFile, "rb");
if (!fp)
return NULL;
BYTE header[8];
fread (header, 1, 8, fp);
if (png_sig_cmp (header, 0, 8))
return NULL;
fseek (fp, 0, SEEK_SET);
// set up
png_structp png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
NULL, user_error_fn, user_warning_fn);
if (!png_ptr)
return NULL;
png_infop info = png_create_info_struct (png_ptr);
if (!info) {
png_destroy_read_struct (&png_ptr, NULL, NULL);
return NULL;
}
png_init_io (png_ptr, fp);
png_read_info (png_ptr, info);
int width = info->width, height = info->height, channels = info->channels;
if (height > PNG_UINT_32_MAX / sizeof (png_bytep))
return NULL; // too big
png_bytep buf = malloc (height * width * channels);
png_bytep *rows = malloc (sizeof (png_bytep) * height);
int i;
for (i = 0; i < height; i++)
rows[i] = buf + width * channels * i;
png_set_strip_16 (png_ptr); // ensure bbp <= 8
png_set_packing (png_ptr);
png_set_expand (png_ptr);
png_set_bgr (png_ptr); // flip the RGB pixels to BGR (or RGBA to BGRA)
png_read_image (png_ptr, rows);
png_read_end (png_ptr, info);
png_destroy_read_struct (&png_ptr, &info, NULL);
fclose (fp);
free (rows);
return CreateBitmap (width, height, 1, 32, buf);
}