If you needsuch information you will have to add the corresponding attributes and methods on class.Now lets create the source file.PngLoader.cpp:#include "PngLoader.h"#include <fstream>#include <string>#include <sstream>void readFileCallback( png_structp png_ptr, png_bytep out, png_size_t count );PngLoader::PngLoader(void) :data(0){}bool PngLoader::load( std::string file ){ png_structp png_ptr; png_infop info_ptr; std::ifstream ifile( file.c_str(), std::ios::binary ); if( !ifile.is_open() ) return false; char assinatura[8]; ifile.read( &assinatura[0], 8 * sizeof(char) ); if(!png_check_sig( (png_bytep)assinatura, 8) ) { return false; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if(png_ptr == 0) { return false; } info_ptr = png_create_info_struct( png_ptr ); if( info_ptr == 0 ) { png_destroy_read_struct( &png_ptr, 0, 0 ); return false; } png_set_read_fn( png_ptr, (void*)&ifile, readFileCallback ); png_set_sig_bytes( png_ptr, 8 ); png_read_info( png_ptr, info_ptr ); png_get_IHDR( png_ptr, info_ptr, (png_uint_32*)&width, (png_uint_32*)&height, &depth, &color_type, 0, 0, 0 ); png_size_t cols = png_get_rowbytes(png_ptr, info_ptr); png_bytepp row_pp = new png_bytep[height]; data = new char[ cols * height ]; for( int i = 0; i < height; ++i ) { row_pp[height - i - 1] = (png_bytep)&data[ i * cols ]; } png_read_image( png_ptr, row_pp ); png_read_end( png_ptr, info_ptr ); png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); delete[] row_pp; return true;}void PngLoader::release(){ if( data ) delete[] data; data = 0;}PngLoader::~PngLoader(void){ release();}void readFileCallback( png_structp png_ptr, png_bytep out, png_size_t count ){ png_voidp io_ptr = png_get_io_ptr( png_ptr ); if( io_ptr == 0 ) { return; } std::ifstream &ifs = *(std::ifstream*)io_ptr; ifs.read( (char*)out, count );}Here the code may seem a little confusing. The libpng guys chosen big names for their functions and data structures.But this way, if you have some pure C programming skills, you know that things get easer to understand.On the constructor there is no special code.The load method is the bigger one, so lets start by seeing other parts of the code.The release method is the one that will release the data attribute from memory. The user will cancall it right after use the data of the image. There is nothing hard to understand here,there is only a check to ensure we will not try to delete from null pointer.The destructor does only a call to the release method, so, if the user forget to call the release method, the data attributememory will be released right when the object is no longer necessary and get destructed.Well, time to the load method. We start by declaring some local variables. The mostimportants variables are png_ptr and info_ptr. The variable png_ptr is used by libpng to decode the image,while info_ptr is used to keep information about the image. Since libpng version 1.5.0 thedirect acess for those structures members were deprecated. So you will need to use the png_get_*and png_set_* functions, where the star means the member on the structure that you need to get from or set to.The next step is to open the image file, what is done by the ifstream object ifile. So its passed, on the instantiationof the object, the filename string and the access mode to the binary file.With the image file opened and checked for success, we verify now the png file signature. What is done by png_check_sig function.For this, we pass a little buffer of eight bytes, that is