libpng -- better documents / resources?
I must first concede that i'm not a guru, however i've used a number of API's some with good docs and some with bad ones.
I'm in the process of writting an pngLoader for libSDL, i won't use the SDL_image because i wanted to write my own lib for various reasons.
MY plan was to decode the png file to a memory location, then load the bmp from memory using the RW functions for SDL.
The problem i'm having is the documents are bloody confusing and i'm having difficulties determining when/where/what type of errors are occuring.
I've tried a google search but haven't had much luck finding a good tutorial site, docs, or examples to search for.
Anyone have any resources they'd like to share or any tips about loading it?
<br />View looking north-east (towards whistler) from on top of burnaby mountain (SFU CAMPUS) in Beautiful Vancouver, B.C.Only in Linux :Pdrivers/usb/printer.c:static char *usblp_messages[] = { "ok", "out of paper", "off-line", "on fire" };
use an easier format. If all you want is transparency, then try TGA. Png's are good for websites, and thats about it. Plus it can take a while to decompress if you have alot of images.
HxRender | Cornerstone SDL TutorialsCurrently picking on: Hedos, Programmer One
August 31, 2004 12:20 AM
I don't care about load times, its trivial and easier format isn't really what i wanted to do know is it?
Well, I guess you can have some of my older code. At least the PNG loader used to work, don't use the other stuff. It's a really old abandoned thing.
gltextureloader.hpp:
gltextureloader.cpp:
In the .cpp, look for the FIXMEs and throw statements, those are the places where errors occur. There are a few more places where null-pointer checks might be in order (e.g. after the row_pointers assignement). Also, this was last touched in June 2003, so there might be problems with newer versions of libpng.
gltextureloader.hpp:
#ifndef _GLTEXTURELOADER_H_#define _GLTEXTURELOADER_H_#include <GL/gl.h> // for types#include <GL/glu.h>namespace NSoft { using namespace std; class GLTextureLoader { protected: GLubyte** Textures; GLsizei Width, Height; GLuint NumLevels; GLenum Type, Format; bool NeedFree; public: /*! \brief Constructor * * Creates a new GLTextureLoader object * * \param f The texture format (hardcoded to GL_UNSIGNED_BYTE, this * parameter is currently ignored. * \param t The texture type (GL_RGB, GL_RGBA, ...) * \param nl The number of mipmap levels (currently ignored, set to 1) */ GLTextureLoader( int f, int t, int nl ); virtual ~GLTextureLoader(); /*! \brief Returns a pointer to a texture map * * This method returns a pointer to a texture map of a given Mipmap * level, suitable for use in GL functions. * * \param mml The required mipmap level * \return A pointer to the pixel data array */ inline GLubyte* getTexture( int mml ) { return Textures[mml]; } /*! \brief Returns the texture type * * This method is currently hardcoded to return GL_UNSIGNED_BYTE * * \return the texture type */ inline GLenum getType( void ) { return GL_UNSIGNED_BYTE; } //FIXME hardcoded /*! \brief Returns the texture format * * Returns the format of the texture (RGB, RGBA, ...) * * \return the texture format */ inline GLenum getFormat( void ) { return Format; } inline GLsizei getWidth( void ) { return Width; } inline GLsizei getHeight( void ) { return Height; } inline GLuint getLevels( void ) { return NumLevels; } }; class GLTextureLoaderPNG : public GLTextureLoader { private: bool* PNGNeedFree; public: GLTextureLoaderPNG( int f, int t, int nl ); ~GLTextureLoaderPNG( void ); void addTexture( int l, char* fn ); };}#endif //_TEXTURELOADER_H_
gltextureloader.cpp:
#include "gltextureloader.hpp"#include <iostream>#include <cstdio>#include <cstdlib>#include <png.h>using namespace NSoft;using namespace std;GLTextureLoader::GLTextureLoader( int f, int t, int nl ) { NumLevels = nl; Type = t; Format = f; NeedFree = false; Textures = NULL; Textures = new (GLubyte*)(NULL); if( !Textures ) { cerr << "Error in constructor!" << endl; throw "Error in constructor!"; //FIXME } NeedFree = true; cerr << "Base constructor reached! Settings:" << endl << " NumLevels: " << NumLevels << endl << " Type: " << Type << "(" << GL_UNSIGNED_BYTE << ")" << endl << " Format: " << Format << "(" << GL_RGB << ")" << endl << endl;}GLTextureLoader::~GLTextureLoader( void ) { if( NeedFree ) { delete[] Textures; }}GLTextureLoaderPNG::GLTextureLoaderPNG( int f, int t, int nl ) : GLTextureLoader( f, t, nl ){ PNGNeedFree = new bool(false);}; GLTextureLoaderPNG::~GLTextureLoaderPNG( void ) { for( int i=0; i<NumLevels; i++ ) { if( PNGNeedFree ) free( Textures ); } delete[] PNGNeedFree;}void GLTextureLoaderPNG::addTexture( int l, char* fn ) { png_byte header[8]; int flags; png_bytep* row_pointers; FILE *fp = fopen( fn, "rb"); if (!fp) { throw "Error opening file"; //FIXME ERROR opening file } // check if this is a PNG file fread( (char*)header, 1, 8, fp ); if ( png_sig_cmp(header, 0, 8) ) { throw "Not a PNG file"; //FIXME NOT_PNG } png_structp pngfile = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); if( !pngfile ) { throw "Error creating read structure"; //FIXME ERROR } png_infop pnginfo = png_create_info_struct( pngfile ); if( !pnginfo ) { png_destroy_read_struct( &pngfile, NULL, NULL ); throw "Error creating info structure"; //FIXME } png_infop pngendinfo = png_create_info_struct( pngfile ); if( !pngendinfo ) { png_destroy_read_struct( &pngfile, &pnginfo, NULL ); } // In case of an error, we want to die here! if( setjmp( png_jmpbuf(pngfile) ) ) { png_destroy_read_struct(&pngfile, &pnginfo, &pngendinfo); fclose(fp); throw "Error! longjmp() called!"; //FIXME } png_init_io( pngfile, fp ); png_set_sig_bytes( pngfile, 8 ); // we read 8 bytes to verify cerr << "PNG: IO initiated." << endl; flags = PNG_TRANSFORM_STRIP_16|PNG_TRANSFORM_PACKING; switch( Format ) { case GL_RGB: // strip alpha channel cerr << "PNG texture DEBUG: stripping alpha channel" << endl; flags |= PNG_TRANSFORM_STRIP_ALPHA; break; case GL_RED: case GL_GREEN: case GL_BLUE: case GL_ALPHA: case GL_LUMINANCE: // single-element map cerr << "Specified unsupported texture type!" << endl; throw "Unsupported texture type!"; //FIXME not implemented break; default: cerr << "PNG texture DEBUG: unknown type given!" << endl; break; } cerr << "Calling png_read_png()..."; png_read_png( pngfile, pnginfo, flags, NULL ); cerr << "done." << endl; // allocate memory //row_pointers = (png_bytep*)png_malloc( pngfile, pnginfo->height*sizeof(png_bytep) ); row_pointers = png_get_rows( pngfile, pnginfo ); cerr << "Allocating " << pnginfo->rowbytes * pnginfo->height * sizeof(GLubyte) << " bytes" << endl; if( PNGNeedFree ) free( Textures[l] ); Textures[l] = (GLubyte*)malloc( pnginfo->rowbytes * pnginfo->height * sizeof(GLubyte) ); PNGNeedFree[l] = true; cerr << "Textures base address: " << Textures << endl; for( int i=0; i<pnginfo->height; i++ ) { memcpy( &(Textures[l][i*pnginfo->rowbytes]), row_pointers, pnginfo->rowbytes ); //row_pointers = &(Textures[l][i*pnginfo->rowbytes]); } if( pnginfo->bit_depth != 8 ) { cerr << "Screwy optics? Bit-depth must be 8! Is: " << pnginfo->bit_depth << endl; } cerr << "PNG texture DEBUG:" << endl << " Format: " << pnginfo->width << "x" << pnginfo->height << "x" << pnginfo->bit_depth*pnginfo->channels << endl; // make the format of an RGB texture RGB even if RGBA was given if( pnginfo->color_type == PNG_COLOR_TYPE_RGB && Format == GL_RGBA ) { cerr << " Overriding alpha setting!" << endl; Format = GL_RGB; } Width = pnginfo->width; Height = pnginfo->height; png_destroy_read_struct( &pngfile, &pnginfo, &pngendinfo ); fclose( fp );}
In the .cpp, look for the FIXMEs and throw statements, those are the places where errors occur. There are a few more places where null-pointer checks might be in order (e.g. after the row_pointers assignement). Also, this was last touched in June 2003, so there might be problems with newer versions of libpng.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement