Download libpng140 and zlib, add both libs to project. Then create this class:
// ========= LoadPng.h =========
#ifndef _LoadPng_h__
#define _LoadPng_h__
#include "png.h"
class CLoadPng
{
public:
CLoadPng();
virtual ~CLoadPng();
bool Load(const char* fname);
int GetWidht();
int GetHeight();
int GetBPP();
unsigned char* GetData();
protected:
png_uint_32 m_Width;
png_uint_32 m_Height;
int m_BPP;
int m_iColorType;
png_byte* m_Data;
};
#endif // _LoadPng_h__
// ========= LoadPng.cpp =========
#include <stdlib.h>
#include <png/LoadPng.h>
CLoadPng::CLoadPng()
{
m_Width = 0;
m_Height = 0;
m_BPP = 0;
m_iColorType = 0;
m_Data = NULL;
}
CLoadPng::~CLoadPng()
{
if (m_Data != NULL)
{
free(m_Data);
m_Data = NULL;
}
}
bool CLoadPng::Load( const char* fname )
{
if (fname == NULL) return false;
FILE* f = fopen(fname, "rb");
if (f == NULL) return false;
png_byte pbSig[8];
fread(pbSig, 1, 8, f);
if (png_sig_cmp(pbSig, 0, 8))
{
fclose(f);
return false;
}
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, (png_error_ptr)NULL, (png_error_ptr)NULL);
if (!png_ptr)
{
fclose(f);
return false;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(f);
return false;
}
png_init_io(png_ptr, f);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
int iBitDepth;
// get width, height, bit-depth and color-type
png_get_IHDR(png_ptr, info_ptr, &m_Width, &m_Height, &iBitDepth, &m_iColorType, NULL, NULL, NULL);
if (iBitDepth == 16) png_set_strip_16(png_ptr);
if (m_iColorType == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr);
if (iBitDepth < 8) png_set_expand(png_ptr);
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr);
// need to update info to reflect changes
png_read_update_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &m_Width, &m_Height, &iBitDepth, &m_iColorType, NULL, NULL, NULL);
// now we can read png
png_uint_32 ulRowBytes = png_get_rowbytes(png_ptr, info_ptr);
png_uint_32 ulChannels = png_get_channels(png_ptr, info_ptr);
m_BPP = ulChannels;
if (m_Data != NULL)
{
free(m_Data);
m_Data = NULL;
}
if ((m_Data = (png_byte *) malloc(ulRowBytes * m_Height * sizeof(png_byte))) == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(f);
m_Width = m_Height = m_BPP = 0;
return false;
}
png_byte **ppbRowPointers = NULL;
if ((ppbRowPointers = (png_bytepp) malloc(m_Height * sizeof(png_bytep))) == NULL)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(f);
free(m_Data);
m_Data = NULL;
m_Width = m_Height = m_BPP = 0;
return false;
}
for (int i = 0; i < m_Height; i++) ppbRowPointers[i] = m_Data + i * ulRowBytes;
png_read_image(png_ptr, ppbRowPointers);
png_read_end(png_ptr, NULL);
free (ppbRowPointers);
ppbRowPointers = NULL;
fclose(f);
return true;
}
int CLoadPng::GetWidht()
{
return m_Width;
}
int CLoadPng::GetHeight()
{
return m_Height;
}
int CLoadPng::GetBPP()
{
return m_BPP;
}
unsigned char* CLoadPng::GetData()
{
return m_Data;
}
To use:
CLoadPng l;
if (l.Load("Test.png"))
{
// image is loaded... use l.GetWidth(), l.GetHeight(), l.GetBPP() and l.GetData() to access image
}