Documentation Buy Contact Blog
Blog

How to use libPng in a C++ project

13 November 2013

Don't ;). Use LodePNG instead. It's super easy to add to your project, unlike libPng with its config files that I didn't have the paitence for. Also, lodePNG does the decompression itself without needing you to add zlib to your project either.

Keep reading to see the example PngLoader class, also check out this post to see the matching JpegLoader class.

PngLoader.h
#ifndef PNG_LOADER_H
#define PNG_LOADER_H
	#include 
	#include 
	class PngLoader
	{
		public:
			struct ImageInfo
			{
				uint16_t nWidth;
				uint16_t nHeight;
				uint8_t nNumComponent;
				uint8_t* pData;
			};

			PngLoader();
			~PngLoader();

			const ImageInfo* Load(const char* szFileName);
			const ImageInfo* Load(uint8_t* pData, uint32_t nDataSize);

		private:
			ImageInfo* m_pImageInfo;
			void Cleanup();
	};
#endif
PngLoader.cpp
#include "PngLoader.h"
#include "LodePng/lodepng.h"
#include 

PngLoader :: PngLoader()
{
	m_pImageInfo = NULL;
}

PngLoader :: ~PngLoader()
{
	Cleanup();
}

const PngLoader :: ImageInfo* PngLoader :: Load(const char* szFileName)
{
	Cleanup();

	FILE * pFile = fopen(szFileName, "rb");
	if (pFile!=NULL)
	{
		fseek(pFile, 0, SEEK_END );
			
		uint32_t nDataSize = ftell(pFile);
		rewind(pFile);

		uint8_t* pData = new uint8_t[nDataSize];
		fread(pData, nDataSize, 1, pFile);

		Load(pData, nDataSize);

		delete [] pData; 
	}
	

	return m_pImageInfo;
}

const PngLoader :: ImageInfo* PngLoader :: Load(uint8_t* pData, uint32_t nDataSize)
{
	Cleanup();
	
	std::vector imageByteVector;
	unsigned nWidth, nHeight;
	if (!lodepng::decode(imageByteVector, nWidth, nHeight, pData, nDataSize))
	{
		m_pImageInfo = new ImageInfo();
		m_pImageInfo->nWidth = nWidth;
		m_pImageInfo->nHeight = nHeight;
		m_pImageInfo->nNumComponent = 4;
		m_pImageInfo->pData = new uint8_t[m_pImageInfo->nWidth*m_pImageInfo->nHeight*m_pImageInfo->nNumComponent];
		memcpy(m_pImageInfo->pData, &imageByteVector[0], imageByteVector.size());
	}

	return m_pImageInfo;
}

void PngLoader :: Cleanup()
{
	if (m_pImageInfo)
	{
		delete [] m_pImageInfo->pData;
		delete m_pImageInfo;
		m_pImageInfo = NULL;
	}
}