From: Miriam Ruiz Date: Wed, 3 Dec 2008 00:20:47 +0000 (+0100) Subject: Code released by upstream: v1.45 X-Git-Tag: v1.46~15 X-Git-Url: https://repo.or.cz/w/glpng.git/commitdiff_plain/b2cd947a660f801ebd20d9f390b1119003ef8d22 Code released by upstream: v1.45 --- b2cd947a660f801ebd20d9f390b1119003ef8d22 diff --git a/Example/Stunt.png b/Example/Stunt.png new file mode 100644 index 0000000..19a9a4f Binary files /dev/null and b/Example/Stunt.png differ diff --git a/Example/Test.c b/Example/Test.c new file mode 100644 index 0000000..bfdf97f --- /dev/null +++ b/Example/Test.c @@ -0,0 +1,110 @@ +/* + * Test program for glpng + * by Ben Wyatt ben@wyatt100.freeserve.co.uk + * Featuring a shameless plug for my stunt course program + * Available from the same site as glpng + * http://www.wyatt100.freeserve.co.uk/download.htm + */ + +#include +#include +#include + +int angle = 0; + +/***** GLUT callback functions *****/ + +void KeyPress(unsigned char key, int x, int y) { + switch (key) { + case 27: /*ESC*/ glutDestroyWindow(glutGetWindow()); exit(0); break; + } +} + +void Update(void) { + angle = (angle+1)%360; + glutPostRedisplay(); +} + +void Display(void) { + const float w = 2, h = 2; + + glClear(GL_COLOR_BUFFER_BIT); + + glLoadIdentity(); + glTranslatef(0, 0, -10); + glRotatef(angle, 0, 1, 0); + + glBegin(GL_QUADS); + // Front + glTexCoord2f(1, 1); glVertex3f( w, -h, 0); + glTexCoord2f(1, 0); glVertex3f( w, h, 0); + glTexCoord2f(0, 0); glVertex3f(-w, h, 0); + glTexCoord2f(0, 1); glVertex3f(-w, -h, 0); + + // Back + glTexCoord2f(1, 1); glVertex3f(-w, -h, 0); + glTexCoord2f(1, 0); glVertex3f(-w, h, 0); + glTexCoord2f(0, 0); glVertex3f( w, h, 0); + glTexCoord2f(0, 1); glVertex3f( w, -h, 0); + glEnd(); + + glutSwapBuffers(); +} + +void Reshape(int w, int h) { + glViewport(0, 0, w, h); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(30, (float) w/h, 1, 100); + + glMatrixMode(GL_MODELVIEW); + Display(); +} + +/***** Main function *****/ + +void main() { + pngInfo info; + GLuint texture; + + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); + glutInitWindowSize(300, 300); + glutCreateWindow("glpng test"); + + #if 0 // Using pngLoad and setting texture parameters manually. + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + if (!pngLoad("Stunt.png", PNG_NOMIPMAP, PNG_SOLID, &info)) { + puts("Can't load file"); + exit(1); + } + #else // Using pngLoadAndBind to set texture parameters automatically. + texture = pngBind("Stunt.png", PNG_NOMIPMAP, PNG_ALPHA, &info, GL_CLAMP, GL_NEAREST, GL_NEAREST); + + if (texture == 0) { + puts("Can't load file"); + exit(1); + } + #endif + + printf("Size=%i,%i Depth=%i Alpha=%i\n", info.Width, info.Height, info.Depth, info.Alpha); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); + glEnable(GL_CULL_FACE); + glColor3f(1, 1, 1); + + glutKeyboardFunc(KeyPress); + glutIdleFunc(Update); + glutDisplayFunc(Display); + glutReshapeFunc(Reshape); + + glutMainLoop(); +} diff --git a/glpng.htm b/glpng.htm new file mode 100644 index 0000000..bc49d34 --- /dev/null +++ b/glpng.htm @@ -0,0 +1,442 @@ + + + + + +glpng + + + + +

PNG loader library for OpenGL v1.45 (10/7/2000)

+ +

Ben Wyatt ben@wyatt100.freeserve.co.uk

+ +

Introduction

+ +

This is a library for OpenGL to load PNG graphics files as an +OpenGL texture as easily as possible. It also has a number of +options for generating the alpha channel and mipmaps. It is +implemented using modified versions of the LibPNG 1.0.2 and ZLib +1.1.3 libraries.

+ +

This software is provided 'as-is', without any express or +implied warranty. In no event will the author be held liable for +any damages arising from the use of this software.

+ +

Permission is hereby granted to use, copy, modify, and +distribute this source code, or portions hereof, for any purpose, +without fee, subject to the following restrictions:

+ +
    +
  1. The origin of this source code must not be misrepresented. + You must not claim that you wrote the original software. + If you use this software in a product, an acknowledgment + in the product documentation would be appreciated but is + not required.
  2. +
  3. Altered versions must be plainly marked as such and must + not be misrepresented as being the original source.
  4. +
  5. This notice must not be removed or altered from any + source distribution.
  6. +
+ +

Installation for MSDEV

+ +

Copy glpng.h to your include/GL folder and copy glpng.lib and +glpngd.lib to your lib folder. Then just do #include <GL/glpng.h> +and with a bit of luck, MSDEV will automatically link with glpng.lib +(release lib) or glpngd.lib (debug lib).

+ +

Installation for Any Other Compiler

+ +

Copy glpng.h to your include/GL folder. Then you'll have to +build the library yourself with the included source code. +Included are makefiles for Linux and SGI. If you need to modify +the source code to make it work on your system, please get in +contact so I can make future versions compatible.

+ +

Compiling with LibPNG or ZLib

+ +

If you are using LibPNG or ZLib in your project there may be +problems if you link with the glpng library. To solve this, +include glpng.c in your project and, if you're using MSDEV, +modify glpng.h to not automatically link with glpng.lib or glpngd.lib.

+ +

OpenGL DLL Dynamic Loading using glsetup

+ +

To use glpng with glsetup, include glpng.c, LibPNG and ZLib in +your project. In glpng.c, change #include <GL/gl.h> to +include the glsetup include and modify glpng.h to not +automatically link with glpng.lib or glpngd.lib.

+ +

Functions

+ + + +
success = pngLoad(filename, mipmap, trans, info)
+ +
+ + + + + + + + + + + + + + + + + +
filenameFilename of PNG file, including ".png"
mipmapMipmapping parameter:
    +
  • 0 or PNG_NOMIPMAP if no mipmap or for the + base mipmap level
  • +
  • 1,2,3... for mipmap detail level
  • +
  • PNG_BUILDMIPMAPS to call a clone of gluBuild2DMipmaps + (box filter)
  • +
  • PNG_SIMPLEMIPMAPS to generate mipmaps without + filtering (uses upper-left of each 2x2 box)
  • +
+
transTransparency setting:
    +
  • PNG_ALPHA to use alpha channel in PNG file, + if there is one
  • +
  • PNG_SOLID for no transparency
  • +
  • PNG_STENCIL to set + pixels of a certain value to alpha 0, + otherwise 1 (see pngSetStencil)
  • +
  • PNG_BLEND1 to set alpha to r+g+b
  • +
  • PNG_BLEND2 to set alpha to (r+g+b)/2
  • +
  • PNG_BLEND3 to set alpha to (r+g+b)/3
  • +
  • PNG_BLEND4 to set alpha to r2+g2+b2
  • +
  • PNG_BLEND5 to set alpha to (r2+g2+b2)/2
  • +
  • PNG_BLEND6 to set alpha to (r2+g2+b2)/3
  • +
  • PNG_BLEND7 to set alpha to (r2+g2+b2)/4
  • +
  • PNG_BLEND8 to set alpha to sqrt(r2+g2+b2)
  • +
  • PNG_CALLBACK to + use the callback function defined by pngSetAlphaCallback.
  • +
+
infoPointer to a pngInfo structure to store texture + info or NULL if you don't care. The pngInfo fields + are:
    +
  • Width - width of the original image in pixels
  • +
  • Height - height of the original image in + pixels
  • +
  • Depth - depth of the original image, where + colours = 2Depth
  • +
  • Alpha - the number of bits used for the alpha + channel (0 if no alpha channel)
  • +
+
+

Loads a PNG file and calls glTexImage2D with appropriate + parameters. The texture will be resized if the dimensions are + not powers of 2 or over the maximum texture size. Should be + able to load all colour depths (except 64-bit) and alpha + channels if available. It converts them to an appropriate + format and gives them to glTexImage2D. The OpenGL paletted + texture extension is used if available.

+

Returns 1 on success or 0 if file could not be loaded.

+
+ +
success = pngLoadF(file, mipmap, trans, info)
+ +
+ + + + + +
fileFILE opened with fopen("something.png", + "rb")
+

This is used to load a PNG from an already opened file. + Handy if you want to batch all your data and textures into + one big data file.

+
+ +
id = pngBind(filename, mipmap, trans, info, wrapst, minfilter, magfilter)
+id = pngBindF(file, mipmap, trans, info, wrapst, minfilter, magfilter)
+ +
+ + + + + + + + + + + + + +
wrapstGL_CLAMP or GL_REPEAT (look up glTexParameter)
minfilterMinification function for filtering (look up + glTexParameter)
magfilterMagnification function for filtering (look up + glTexParamter)
+

Automates the process further - loads a PNG file, sets the + OpenGL parameters, binds it to an OpenGL texture and returns + it's ID, or 0 if the file couldn't be loaded.

+
+ +
success = pngLoadRaw(filename, rawinfo)
+success = pngLoadRawF(file, rawinfo)
+ +
+ + + + + +
rawinfoPointer to a pngRawInfo structure in which to + store the PNG data. The pngRawInfo has these fields:
    +
  • Width, Height, Depth, Alpha - as in pngInfo
  • +
  • Components - number of colour components (1, + 2, 3 or 4)
  • +
  • Data - pointer to image data stored as RGBRGB... + or RGBARGBA... or indices to the palette + table. Must be freed manually using free()
  • +
  • Palette - pointer to palette table stored as + RGBRGB... or RGBARGBA... Will be NULL if + there is no palette table. Must be freed + manually using free()
  • +
+
+
+ +
pngSetStencil(red, green, blue)
+ +
+ + + + + +
red,green,blueThe colour to stencil out when using the PNG_STENCIL option
+
+ +
+

This selects the colour to stencil out when using PNG_STENCIL. The parameters are 0 to + 255. By default the colour is 0,0,0 (pure black).

+
+ +
pngSetAlphaCallback(function)
+ +
+ + + + + +
functionPointer to a function taking three unsigned char + parameters (red, green, blue) and returning an + unsigned char (alpha)
+
+ +
+

This sets the function to be called when using PNG_CALLBACK. During the alpha + channel generation process, this function will be called for + every pixel, with the appropriate RGB values, and will use + the result for the alpha value. The RGB and alpha values all + range from 0 to 255. The default callback function simply + returns 255.

+
+ +
pngSetViewingGamma(gamma)
+ +
+ + + + + +
gammaNew gamma correction value
+

By default, gamma correction is set to 1.0 for Windows, 1.7 + for SGI and 1.45 for Macs. If the VIEWING_GAMMA environmental + variable is set, that is used instead. You can override both + of these values using pngSetViewingGamma().

+
+ +
pngSetStandardOrientation(standardorientation)
+ +
+ + + + + +
standardorientationIf to use the standard orientation (0 is default)
+

By default, the image is loaded so that texture + coordinates 0,0 represent the top-left - a result of me not + knowing the OpenGL spec :-). If you wish to use the standard + OpenGL representation where 0,0 is the bottom-left, set this + to 1.

+
+ +

Examples

+ +

Here's an example of pngLoad(), to load "Texture.png" +with nearest filter, clamping on and no mipmaps or alpha channels...

+ +
+
pngInfo info;
+GLuint id;
+
glGenTextures(1, &id);
+glBindTexture(GL_TEXTURE_2D, id);
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
if (pngLoad("Texture.png", PNG_NOMIPMAP, PNG_SOLID, &info)) {
+   puts("Loaded Texture.png with resounding success");
+   printf("Size=%i,%i Depth=%i Alpha=%i\n", info.Width, info.Height, info.Depth, info.Alpha);
+}
+else {
+   puts("Can't load Texture.png");
+   exit(1);
+}
+
+ +

And here's an example to load the same texture with the same +options using pngBind()...

+ +
+
pngInfo info;
+GLuint id = pngBind("Texture.png", PNG_NOMIPMAP, PNG_SOLID, &info, GL_CLAMP, GL_NEAREST, GL_NEAREST);
+
if (id != 0) {
+   puts("Loaded Texture.png with resounding success");
+   printf("Size=%i,%i Depth=%i Alpha=%i\n", info.Width, info.Height, info.Depth, info.Alpha);
+}
+else {
+   puts("Can't load Texture.png");
+   exit(1);
+}
+
+ +

If those two examples don't make sense, try the included full +source example (which needs GLUT).

+ +

Bugs

+ +
    +
  • 64-bit PNGs can't be loaded (missing LibPNG feature as + far as I can tell).
  • +
+ +

Possible Future Developments

+ +
    +
  • Better attempts could be made to find the optimal texture + format for OpenGL. At the moment, it converts everything + to 24 or 32 bit, or uses the paletted texture extension + in certain (easy to handle) cases.
  • +
  • Other mipmap generating algorithms could be implemented (wavelet + stuff?). Source donations are welcome.
  • +
  • Saving the frame buffer to a PNG file.
  • +
  • Support for GL_INTENSITY, GL_LUMINANCE_ALPHA and others.
  • +
+ +

History

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
1.33 (20/5/99)First public release.
1.34 (27/5/99)Optimised alpha channel generating, + added Alpha property to the pngInfo structure, illegal + texture sizes are resized.
1.35 (4/6/99)Added pngLoadRaw and pngLoadRawF + functions.
1.36 (9/6/99)Fixed problem causing linking warnings/errors + (I think) and reduced the size of the library + considerably.
1.37 (13/6/99)Added alpha channel generation callback + function.
1.38 (22/6/99)Stopped it from disabling texturing on + calls to pngBind and pngBindF.
1.39 (8/7/99)Fixed a bug in the extensions reading + code, which caused some machines to crash.
1.40 (27/9/99)Added support for SGI, Linux, and gamma + correction (thanks to Mark B. Allan!). Fixed bug in raw + reading of gray textures (thanks to Johann Scholtz!). + Removed all use of GLU functions to make it easier to + dynamically load opengl32.dll or 3dfxvgl.dll or whatever. + Added simple mipmap generator.
1.41 (20/10/99)Made a small optimisation and improved + documentation. Remembered to include the makefiles for + Linux and SGI in the zip (!).
1.42 (01/03/00)Fixed problems with compiling on SGI (thanks + to Thomas Sondergaard!). Added pngSetStandardOrientation + (thanks to Scott Franke!).
1.43 (11/05/00)Added debug library and fixed the crash + when there wasn't a terminating png info structure (thanks + to Dan Hawkins!).
1.44 (01/07/00)Fixed release and debug libraries so + they stop producing warnings and errors in MSDEV.
1.45 (10/07/00)Fixed bug where the standard orientation + flag was being ignored in pngLoadRawF (thanks to Mark B. + Allan!).
+ +

Get the latest version from http://www.wyatt100.freeserve.co.uk/download.htm

+ + diff --git a/include/GL/glpng.h b/include/GL/glpng.h new file mode 100644 index 0000000..b98ab88 --- /dev/null +++ b/include/GL/glpng.h @@ -0,0 +1,109 @@ +/* + * PNG loader library for OpenGL v1.45 (10/07/00) + * by Ben Wyatt ben@wyatt100.freeserve.co.uk + * Using LibPNG 1.0.2 and ZLib 1.1.3 + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the author be held liable for any damages arising from the + * use of this software. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject to + * the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. You must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered versions must be plainly marked as such and must not be + * misrepresented as being the original source. + * 3. This notice must not be removed or altered from any source distribution. + */ + +#ifndef _GLPNG_H_ +#define _GLPNG_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER + #ifdef _DEBUG + #pragma comment (lib, "glpngd.lib") + #else + #pragma comment (lib, "glpng.lib") + #endif +#endif + +/* XXX This is from Win32's */ +#ifndef APIENTRY + #if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED) + #define APIENTRY __stdcall + #else + #define APIENTRY + #endif +#endif + +/* Mipmapping parameters */ +#define PNG_NOMIPMAPS 0 /* No mipmapping */ +#define PNG_BUILDMIPMAPS -1 /* Calls a clone of gluBuild2DMipmaps() */ +#define PNG_SIMPLEMIPMAPS -2 /* Generates mipmaps without filtering */ + +/* Who needs an "S" anyway? */ +#define PNG_NOMIPMAP PNG_NOMIPMAPS +#define PNG_BUILDMIPMAP PNG_BUILDMIPMAPS +#define PNG_SIMPLEMIPMAP PNG_SIMPLEMIPMAPS + +/* Transparency parameters */ +#define PNG_CALLBACK -3 /* Call the callback function to generate alpha */ +#define PNG_ALPHA -2 /* Use alpha channel in PNG file, if there is one */ +#define PNG_SOLID -1 /* No transparency */ +#define PNG_STENCIL 0 /* Sets alpha to 0 for r=g=b=0, 1 otherwise */ +#define PNG_BLEND1 1 /* a = r+g+b */ +#define PNG_BLEND2 2 /* a = (r+g+b)/2 */ +#define PNG_BLEND3 3 /* a = (r+g+b)/3 */ +#define PNG_BLEND4 4 /* a = r*r+g*g+b*b */ +#define PNG_BLEND5 5 /* a = (r*r+g*g+b*b)/2 */ +#define PNG_BLEND6 6 /* a = (r*r+g*g+b*b)/3 */ +#define PNG_BLEND7 7 /* a = (r*r+g*g+b*b)/4 */ +#define PNG_BLEND8 8 /* a = sqrt(r*r+g*g+b*b) */ + +typedef struct { + unsigned int Width; + unsigned int Height; + unsigned int Depth; + unsigned int Alpha; +} pngInfo; + +typedef struct { + unsigned int Width; + unsigned int Height; + unsigned int Depth; + unsigned int Alpha; + + unsigned int Components; + unsigned char *Data; + unsigned char *Palette; +} pngRawInfo; + +extern int APIENTRY pngLoadRaw(const char *filename, pngRawInfo *rawinfo); +extern int APIENTRY pngLoadRawF(FILE *file, pngRawInfo *rawinfo); + +extern int APIENTRY pngLoad(const char *filename, int mipmap, int trans, pngInfo *info); +extern int APIENTRY pngLoadF(FILE *file, int mipmap, int trans, pngInfo *info); + +extern unsigned int APIENTRY pngBind(const char *filename, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter); +extern unsigned int APIENTRY pngBindF(FILE *file, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter); + +extern void APIENTRY pngSetStencil(unsigned char red, unsigned char green, unsigned char blue); +extern void APIENTRY pngSetAlphaCallback(unsigned char (*callback)(unsigned char red, unsigned char green, unsigned char blue)); +extern void APIENTRY pngSetViewingGamma(double viewingGamma); +extern void APIENTRY pngSetStandardOrientation(int standardorientation); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/Makefile.LINUX b/src/Makefile.LINUX new file mode 100644 index 0000000..55d1fc2 --- /dev/null +++ b/src/Makefile.LINUX @@ -0,0 +1,250 @@ +############################################################################# +# Makefile for building libglpng.a +# Generated by tmake at 17:31, 1999/08/27 +# Project: glpng +# Template: lib +############################################################################# + +####### Compiler, tools and options + +CC = gcc +CXX = g++ +CFLAGS = -pipe -Wall -W -O2 -fno-strength-reduce +CXXFLAGS= -pipe -Wall -W -O2 -fno-strength-reduce +INCPATH = -I../include +AR = ar cqs +RANLIB = +MOC = moc + +TAR = tar -cf +GZIP = gzip -9f + +####### Files + +HEADERS = png/png.h \ + png/pngconf.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/inffast.h \ + zlib/inffixed.h \ + zlib/inftrees.h \ + zlib/infutil.h \ + zlib/zconf.h \ + zlib/zlib.h \ + zlib/zutil.h +SOURCES = glpng.c \ + png/png.c \ + png/pngerror.c \ + png/pngget.c \ + png/pngmem.c \ + png/pngpread.c \ + png/pngread.c \ + png/pngrio.c \ + png/pngrtran.c \ + png/pngrutil.c \ + png/pngset.c \ + png/pngtrans.c \ + zlib/adler32.c \ + zlib/crc32.c \ + zlib/infblock.c \ + zlib/infcodes.c \ + zlib/inffast.c \ + zlib/inflate.c \ + zlib/inftrees.c \ + zlib/infutil.c \ + zlib/zutil.c +OBJECTS = glpng.o \ + png/png.o \ + png/pngerror.o \ + png/pngget.o \ + png/pngmem.o \ + png/pngpread.o \ + png/pngread.o \ + png/pngrio.o \ + png/pngrtran.o \ + png/pngrutil.o \ + png/pngset.o \ + png/pngtrans.o \ + zlib/adler32.o \ + zlib/crc32.o \ + zlib/infblock.o \ + zlib/infcodes.o \ + zlib/inffast.o \ + zlib/inflate.o \ + zlib/inftrees.o \ + zlib/infutil.o \ + zlib/zutil.o +SRCMOC = +OBJMOC = +DIST = +TARGET = libglpng.a + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(OBJECTS) $(OBJMOC) + -rm -f ../lib/$(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + mv $(TARGET) ../lib + +moc: $(SRCMOC) + +tmake: Makefile + +Makefile: glpng.pro + tmake glpng.pro -o Makefile + +dist: + $(TAR) glpng.tar glpng.pro $(SOURCES) $(HEADERS) $(DIST) + $(GZIP) glpng.tar + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET) + -rm -f *~ core *.bck + +####### Compile + +glpng.o: glpng.c \ + png/png.h + +png/png.o: png/png.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngerror.o: png/pngerror.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngget.o: png/pngget.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngmem.o: png/pngmem.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngpread.o: png/pngpread.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngread.o: png/pngread.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngrio.o: png/pngrio.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngrtran.o: png/pngrtran.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngrutil.o: png/pngrutil.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngset.o: png/pngset.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngtrans.o: png/pngtrans.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +zlib/adler32.o: zlib/adler32.c \ + zlib/zlib.h \ + zlib/zconf.h + +zlib/crc32.o: zlib/crc32.c \ + zlib/zlib.h \ + zlib/zconf.h + +zlib/infblock.o: zlib/infblock.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/infblock.h \ + zlib/inftrees.h \ + zlib/infcodes.h \ + zlib/infutil.h + +zlib/infcodes.o: zlib/infcodes.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/inftrees.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/infutil.h \ + zlib/inffast.h + +zlib/inffast.o: zlib/inffast.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/inftrees.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/infutil.h \ + zlib/inffast.h + +zlib/inflate.o: zlib/inflate.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/infblock.h + +zlib/inftrees.o: zlib/inftrees.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/inftrees.h \ + zlib/inffixed.h + +zlib/infutil.o: zlib/infutil.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/infblock.h \ + zlib/inftrees.h \ + zlib/infcodes.h \ + zlib/infutil.h + +zlib/zutil.o: zlib/zutil.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h + diff --git a/src/Makefile.SGI b/src/Makefile.SGI new file mode 100644 index 0000000..cbcd271 --- /dev/null +++ b/src/Makefile.SGI @@ -0,0 +1,250 @@ +############################################################################# +# Makefile for building libglpng.a +# Generated by tmake at 13:41, 1999/08/27 +# Project: glpng +# Template: lib +############################################################################# + +####### Compiler, tools and options + +CC = CC +CXX = CC +CFLAGS = -n32 LANG:bool\=ON -woff 3201,1209,1233,1314,1355,1375,1506 -fullwarn -DSGI +CXXFLAGS= -n32 LANG:bool\=ON -woff 3201,1209,1233,1314,1355,1375,1506 -fullwarn -DSGI +INCPATH = -I../include +AR = ar cq +RANLIB = +MOC = moc + +TAR = tar -cf +GZIP = gzip -9f + +####### Files + +HEADERS = png/png.h \ + png/pngconf.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/inffast.h \ + zlib/inffixed.h \ + zlib/inftrees.h \ + zlib/infutil.h \ + zlib/zconf.h \ + zlib/zlib.h \ + zlib/zutil.h +SOURCES = glpng.c \ + png/png.c \ + png/pngerror.c \ + png/pngget.c \ + png/pngmem.c \ + png/pngpread.c \ + png/pngread.c \ + png/pngrio.c \ + png/pngrtran.c \ + png/pngrutil.c \ + png/pngset.c \ + png/pngtrans.c \ + zlib/adler32.c \ + zlib/crc32.c \ + zlib/infblock.c \ + zlib/infcodes.c \ + zlib/inffast.c \ + zlib/inflate.c \ + zlib/inftrees.c \ + zlib/infutil.c \ + zlib/zutil.c +OBJECTS = glpng.o \ + png/png.o \ + png/pngerror.o \ + png/pngget.o \ + png/pngmem.o \ + png/pngpread.o \ + png/pngread.o \ + png/pngrio.o \ + png/pngrtran.o \ + png/pngrutil.o \ + png/pngset.o \ + png/pngtrans.o \ + zlib/adler32.o \ + zlib/crc32.o \ + zlib/infblock.o \ + zlib/infcodes.o \ + zlib/inffast.o \ + zlib/inflate.o \ + zlib/inftrees.o \ + zlib/infutil.o \ + zlib/zutil.o +SRCMOC = +OBJMOC = +DIST = +TARGET = libglpng.a + +####### Implicit rules + +.SUFFIXES: .cpp .cxx .cc .C .c + +.cpp.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cxx.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.cc.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.C.o: + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $< + +.c.o: + $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $< + +####### Build rules + +all: $(TARGET) + +staticlib: $(TARGET) + +$(TARGET): $(OBJECTS) $(OBJMOC) + -rm -f $(TARGET) + $(AR) $(TARGET) $(OBJECTS) $(OBJMOC) + +moc: $(SRCMOC) + +tmake: Makefile + +Makefile: glpng.pro + tmake glpng.pro -o Makefile + +dist: + $(TAR) glpng.tar glpng.pro $(SOURCES) $(HEADERS) $(DIST) + $(GZIP) glpng.tar + +clean: + -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(TARGET) + -rm -f so_locations + -rm -f *~ core + +####### Compile + +glpng.o: glpng.c \ + png/png.h + +png/png.o: png/png.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngerror.o: png/pngerror.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngget.o: png/pngget.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngmem.o: png/pngmem.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngpread.o: png/pngpread.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngread.o: png/pngread.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngrio.o: png/pngrio.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngrtran.o: png/pngrtran.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngrutil.o: png/pngrutil.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngset.o: png/pngset.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +png/pngtrans.o: png/pngtrans.c \ + png/png.h \ + png/../zlib/zlib.h \ + png/pngconf.h + +zlib/adler32.o: zlib/adler32.c \ + zlib/zlib.h \ + zlib/zconf.h + +zlib/crc32.o: zlib/crc32.c \ + zlib/zlib.h \ + zlib/zconf.h + +zlib/infblock.o: zlib/infblock.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/infblock.h \ + zlib/inftrees.h \ + zlib/infcodes.h \ + zlib/infutil.h + +zlib/infcodes.o: zlib/infcodes.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/inftrees.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/infutil.h \ + zlib/inffast.h + +zlib/inffast.o: zlib/inffast.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/inftrees.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/infutil.h \ + zlib/inffast.h + +zlib/inflate.o: zlib/inflate.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/infblock.h + +zlib/inftrees.o: zlib/inftrees.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/inftrees.h \ + zlib/inffixed.h + +zlib/infutil.o: zlib/infutil.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h \ + zlib/infblock.h \ + zlib/inftrees.h \ + zlib/infcodes.h \ + zlib/infutil.h + +zlib/zutil.o: zlib/zutil.c \ + zlib/zutil.h \ + zlib/zlib.h \ + zlib/zconf.h + diff --git a/src/glpng.c b/src/glpng.c new file mode 100644 index 0000000..1ddceac --- /dev/null +++ b/src/glpng.c @@ -0,0 +1,707 @@ +/* + * PNG loader library for OpenGL v1.45 (10/07/00) + * by Ben Wyatt ben@wyatt100.freeserve.co.uk + * Using LibPNG 1.0.2 and ZLib 1.1.3 + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the author be held liable for any damages arising from the + * use of this software. + * + * Permission is hereby granted to use, copy, modify, and distribute this + * source code, or portions hereof, for any purpose, without fee, subject to + * the following restrictions: + * + * 1. The origin of this source code must not be misrepresented. You must not + * claim that you wrote the original software. If you use this software in + * a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered versions must be plainly marked as such and must not be + * misrepresented as being the original source. + * 3. This notice must not be removed or altered from any source distribution. + */ + +#ifdef _WIN32 /* Stupid Windows needs to include windows.h before gl.h */ + #undef FAR + #include +#endif + +#include +#include +#include +#include +#include "png/png.h" + +/* Used to decide if GL/gl.h supports the paletted extension */ +#ifdef GL_COLOR_INDEX1_EXT +#define SUPPORTS_PALETTE_EXT +#endif + +static unsigned char DefaultAlphaCallback(unsigned char red, unsigned char green, unsigned char blue) { + return 255; +} + +static unsigned char StencilRed = 0, StencilGreen = 0, StencilBlue = 0; +static unsigned char (*AlphaCallback)(unsigned char red, unsigned char green, unsigned char blue) = DefaultAlphaCallback; +static int StandardOrientation = 0; + +#ifdef SUPPORTS_PALETTE_EXT +#ifdef _WIN32 +static PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL; +#endif +#endif + +static int PalettedTextures = -1; +static GLint MaxTextureSize = 0; + +/* screenGamma = displayGamma/viewingGamma + * displayGamma = CRT has gamma of ~2.2 + * viewingGamma depends on platform. PC is 1.0, Mac is 1.45, SGI defaults + * to 1.7, but this can be checked and changed w/ /usr/sbin/gamma command. + * If the environment variable VIEWING_GAMMA is set, adjust gamma per this value. + */ +#ifdef _MAC + static double screenGamma = 2.2 / 1.45; +#elif SGI + static double screenGamma = 2.2 / 1.7; +#else /* PC/default */ + static double screenGamma = 2.2 / 1.0; +#endif + +static char gammaExplicit = 0; /*if */ + +static void checkForGammaEnv() +{ + double viewingGamma; + char *gammaEnv = getenv("VIEWING_GAMMA"); + + if(gammaEnv && !gammaExplicit) + { + sscanf(gammaEnv, "%lf", &viewingGamma); + screenGamma = 2.2/viewingGamma; + } +} + +/* Returns a safe texture size to use (ie a power of 2), based on the current texture size "i" */ +static int SafeSize(int i) { + int p; + + if (i > MaxTextureSize) return MaxTextureSize; + + for (p = 0; p < 24; p++) + if (i <= (1< 1 && height > 1) { + if (filter) + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 2) { + for (c = 0; c < components; c++) { + *d++ = (GET(0)+GET(components)+GET(line)+GET(line+components)) / 4; + data++; + } + data += components; + } + data += line; + } + else + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 2) { + for (c = 0; c < components; c++) { + *d++ = GET(0); + data++; + } + data += components; + } + data += line; + } + } + else if (width > 1 && height == 1) { + if (filter) + for (y = 0; y < height; y += 1) { + for (x = 0; x < width; x += 2) { + for (c = 0; c < components; c++) { + *d++ = (GET(0)+GET(components)) / 2; + data++; + } + data += components; + } + } + else + for (y = 0; y < height; y += 1) { + for (x = 0; x < width; x += 2) { + for (c = 0; c < components; c++) { + *d++ = GET(0); + data++; + } + data += components; + } + } + } + else if (width == 1 && height > 1) { + if (filter) + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 1) { + for (c = 0; c < components; c++) { + *d++ = (GET(0)+GET(line)) / 2; + data++; + } + } + data += line; + } + else + for (y = 0; y < height; y += 2) { + for (x = 0; x < width; x += 1) { + for (c = 0; c < components; c++) { + *d++ = GET(0); + data++; + } + } + data += line; + } + } + else { + return 0; + } + + return 1; +} + +#undef GET + +/* Replacement for gluBuild2DMipmaps so GLU isn't needed */ +static void Build2DMipmaps(GLint components, GLint width, GLint height, GLenum format, const unsigned char *data, int filter) { + int level = 0; + unsigned char *d = (unsigned char *) malloc((width/2)*(height/2)*components+4); + const unsigned char *last = data; + + glTexImage2D(GL_TEXTURE_2D, level, components, width, height, 0, format, GL_UNSIGNED_BYTE, data); + level++; + + while (HalfSize(components, width, height, last, d, filter)) { + if (width > 1) width /= 2; + if (height > 1) height /= 2; + + glTexImage2D(GL_TEXTURE_2D, level, components, width, height, 0, format, GL_UNSIGNED_BYTE, d); + level++; + last = d; + } + + free(d); +} + +int APIENTRY pngLoadRaw(const char *filename, pngRawInfo *pinfo) { + int result; + FILE *fp = fopen(filename, "rb"); + if (fp == NULL) return 0; + + result = pngLoadRawF(fp, pinfo); + + if (fclose(fp) != 0) { + if (result) { + free(pinfo->Data); + free(pinfo->Palette); + } + return 0; + } + + return result; +} + +int APIENTRY pngLoadRawF(FILE *fp, pngRawInfo *pinfo) { + unsigned char header[8]; + png_structp png; + png_infop info; + png_infop endinfo; + png_bytep data; + png_bytep *row_p; + double fileGamma; + + png_uint_32 width, height; + int depth, color; + + png_uint_32 i; + + if (pinfo == NULL) return 0; + + fread(header, 1, 8, fp); + if (!png_check_sig(header, 8)) return 0; + + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info = png_create_info_struct(png); + endinfo = png_create_info_struct(png); + + // DH: added following lines + if (setjmp(png->jmpbuf)) + { + png_destroy_read_struct(&png, &info, &endinfo); + return 0; + } + // ~DH + + png_init_io(png, fp); + png_set_sig_bytes(png, 8); + png_read_info(png, info); + png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL); + + pinfo->Width = width; + pinfo->Height = height; + pinfo->Depth = depth; + + /*--GAMMA--*/ + checkForGammaEnv(); + if (png_get_gAMA(png, info, &fileGamma)) + png_set_gamma(png, screenGamma, fileGamma); + else + png_set_gamma(png, screenGamma, 1.0/2.2); + + png_read_update_info(png, info); + + data = (png_bytep) malloc(png_get_rowbytes(png, info)*height); + row_p = (png_bytep *) malloc(sizeof(png_bytep)*height); + + for (i = 0; i < height; i++) { + if (StandardOrientation) + row_p[height - 1 - i] = &data[png_get_rowbytes(png, info)*i]; + else + row_p[i] = &data[png_get_rowbytes(png, info)*i]; + } + + png_read_image(png, row_p); + free(row_p); + + if (color == PNG_COLOR_TYPE_PALETTE) { + int cols; + png_get_PLTE(png, info, (png_colorp *) &pinfo->Palette, &cols); + } + else { + pinfo->Palette = NULL; + } + + if (color&PNG_COLOR_MASK_ALPHA) { + if (color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA) + pinfo->Components = 2; + else + pinfo->Components = 4; + pinfo->Alpha = 8; + } + else { + if (color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY) + pinfo->Components = 1; + else + pinfo->Components = 3; + pinfo->Alpha = 0; + } + + pinfo->Data = data; + + png_read_end(png, endinfo); + png_destroy_read_struct(&png, &info, &endinfo); + + return 1; +} + +int APIENTRY pngLoad(const char *filename, int mipmap, int trans, pngInfo *pinfo) { + int result; + FILE *fp = fopen(filename, "rb"); + if (fp == NULL) return 0; + + result = pngLoadF(fp, mipmap, trans, pinfo); + + if (fclose(fp) != 0) return 0; + + return result; +} + +int APIENTRY pngLoadF(FILE *fp, int mipmap, int trans, pngInfo *pinfo) { + GLint pack, unpack; + unsigned char header[8]; + png_structp png; + png_infop info; + png_infop endinfo; + png_bytep data, data2; + png_bytep *row_p; + double fileGamma; + + png_uint_32 width, height, rw, rh; + int depth, color; + + png_uint_32 i; + + fread(header, 1, 8, fp); + if (!png_check_sig(header, 8)) return 0; + + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info = png_create_info_struct(png); + endinfo = png_create_info_struct(png); + + // DH: added following lines + if (setjmp(png->jmpbuf)) + { + png_destroy_read_struct(&png, &info, &endinfo); + return 0; + } + // ~DH + + png_init_io(png, fp); + png_set_sig_bytes(png, 8); + png_read_info(png, info); + png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL); + + if (pinfo != NULL) { + pinfo->Width = width; + pinfo->Height = height; + pinfo->Depth = depth; + } + + if (MaxTextureSize == 0) + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTextureSize); + + #ifdef SUPPORTS_PALETTE_EXT + #ifdef _WIN32 + if (PalettedTextures == -1) + PalettedTextures = ExtSupported("GL_EXT_paletted_texture") && (strstr((const char *) glGetString(GL_VERSION), "1.1.0 3Dfx Beta") == NULL); + + if (PalettedTextures) { + if (glColorTableEXT == NULL) { + glColorTableEXT = (PFNGLCOLORTABLEEXTPROC) wglGetProcAddress("glColorTableEXT"); + if (glColorTableEXT == NULL) + PalettedTextures = 0; + } + } + #endif + #endif + + if (PalettedTextures == -1) + PalettedTextures = 0; + + if (color == PNG_COLOR_TYPE_GRAY || color == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + if (color&PNG_COLOR_MASK_ALPHA && trans != PNG_ALPHA) { + png_set_strip_alpha(png); + color &= ~PNG_COLOR_MASK_ALPHA; + } + + if (!(PalettedTextures && mipmap >= 0 && trans == PNG_SOLID)) + if (color == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png); + + /*--GAMMA--*/ + checkForGammaEnv(); + if (png_get_gAMA(png, info, &fileGamma)) + png_set_gamma(png, screenGamma, fileGamma); + else + png_set_gamma(png, screenGamma, 1.0/2.2); + + png_read_update_info(png, info); + + data = (png_bytep) malloc(png_get_rowbytes(png, info)*height); + row_p = (png_bytep *) malloc(sizeof(png_bytep)*height); + + for (i = 0; i < height; i++) { + if (StandardOrientation) + row_p[height - 1 - i] = &data[png_get_rowbytes(png, info)*i]; + else + row_p[i] = &data[png_get_rowbytes(png, info)*i]; + } + + png_read_image(png, row_p); + free(row_p); + + rw = SafeSize(width), rh = SafeSize(height); + + if (rw != width || rh != height) { + const int channels = png_get_rowbytes(png, info)/width; + + data2 = (png_bytep) malloc(rw*rh*channels); + + /* Doesn't work on certain sizes */ +/* if (gluScaleImage(glformat, width, height, GL_UNSIGNED_BYTE, data, rw, rh, GL_UNSIGNED_BYTE, data2) != 0) + return 0; +*/ + Resize(channels, data, width, height, data2, rw, rh); + + width = rw, height = rh; + free(data); + data = data2; + } + + { /* OpenGL stuff */ + glGetIntegerv(GL_PACK_ALIGNMENT, &pack); + glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + #ifdef SUPPORTS_PALETTE_EXT + if (PalettedTextures && mipmap >= 0 && trans == PNG_SOLID && color == PNG_COLOR_TYPE_PALETTE) { + png_colorp pal; + int cols; + GLint intf; + + if (pinfo != NULL) pinfo->Alpha = 0; + png_get_PLTE(png, info, &pal, &cols); + + switch (cols) { + case 1<<1: intf = GL_COLOR_INDEX1_EXT; break; + case 1<<2: intf = GL_COLOR_INDEX2_EXT; break; + case 1<<4: intf = GL_COLOR_INDEX4_EXT; break; + case 1<<8: intf = GL_COLOR_INDEX8_EXT; break; + case 1<<12: intf = GL_COLOR_INDEX12_EXT; break; + case 1<<16: intf = GL_COLOR_INDEX16_EXT; break; + default: + /*printf("Warning: Colour depth %i not recognised\n", cols);*/ + return 0; + } + glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, cols, GL_RGB, GL_UNSIGNED_BYTE, pal); + glTexImage2D(GL_TEXTURE_2D, mipmap, intf, width, height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, data); + } + else + #endif + if (trans == PNG_SOLID || trans == PNG_ALPHA || color == PNG_COLOR_TYPE_RGB_ALPHA || color == PNG_COLOR_TYPE_GRAY_ALPHA) { + GLenum glformat; + GLint glcomponent; + + switch (color) { + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_PALETTE: + glformat = GL_RGB; + glcomponent = 3; + if (pinfo != NULL) pinfo->Alpha = 0; + break; + + case PNG_COLOR_TYPE_GRAY_ALPHA: + case PNG_COLOR_TYPE_RGB_ALPHA: + glformat = GL_RGBA; + glcomponent = 4; + if (pinfo != NULL) pinfo->Alpha = 8; + break; + + default: + /*puts("glformat not set");*/ + return 0; + } + + if (mipmap == PNG_BUILDMIPMAPS) + Build2DMipmaps(glcomponent, width, height, glformat, data, 1); + else if (mipmap == PNG_SIMPLEMIPMAPS) + Build2DMipmaps(glcomponent, width, height, glformat, data, 0); + else + glTexImage2D(GL_TEXTURE_2D, mipmap, glcomponent, width, height, 0, glformat, GL_UNSIGNED_BYTE, data); + } + else { + png_bytep p, endp, q; + int r, g, b, a; + + p = data, endp = p+width*height*3; + q = data2 = (png_bytep) malloc(sizeof(png_byte)*width*height*4); + + if (pinfo != NULL) pinfo->Alpha = 8; + + #define FORSTART \ + do { \ + r = *p++; /*red */ \ + g = *p++; /*green*/ \ + b = *p++; /*blue */ \ + *q++ = r; \ + *q++ = g; \ + *q++ = b; + + #define FOREND \ + q++; \ + } while (p != endp); + + #define ALPHA *q + + switch (trans) { + case PNG_CALLBACK: + FORSTART + ALPHA = AlphaCallback((unsigned char) r, (unsigned char) g, (unsigned char) b); + FOREND + break; + + case PNG_STENCIL: + FORSTART + if (r == StencilRed && g == StencilGreen && b == StencilBlue) + ALPHA = 0; + else + ALPHA = 255; + FOREND + break; + + case PNG_BLEND1: + FORSTART + a = r+g+b; + if (a > 255) ALPHA = 255; else ALPHA = a; + FOREND + break; + + case PNG_BLEND2: + FORSTART + a = r+g+b; + if (a > 255*2) ALPHA = 255; else ALPHA = a/2; + FOREND + break; + + case PNG_BLEND3: + FORSTART + ALPHA = (r+g+b)/3; + FOREND + break; + + case PNG_BLEND4: + FORSTART + a = r*r+g*g+b*b; + if (a > 255) ALPHA = 255; else ALPHA = a; + FOREND + break; + + case PNG_BLEND5: + FORSTART + a = r*r+g*g+b*b; + if (a > 255*2) ALPHA = 255; else ALPHA = a/2; + FOREND + break; + + case PNG_BLEND6: + FORSTART + a = r*r+g*g+b*b; + if (a > 255*3) ALPHA = 255; else ALPHA = a/3; + FOREND + break; + + case PNG_BLEND7: + FORSTART + a = r*r+g*g+b*b; + if (a > 255*255) ALPHA = 255; else ALPHA = (int) sqrt(a); + FOREND + break; + } + + #undef FORSTART + #undef FOREND + #undef ALPHA + + if (mipmap == PNG_BUILDMIPMAPS) + Build2DMipmaps(4, width, height, GL_RGBA, data2, 1); + else if (mipmap == PNG_SIMPLEMIPMAPS) + Build2DMipmaps(4, width, height, GL_RGBA, data2, 0); + else + glTexImage2D(GL_TEXTURE_2D, mipmap, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2); + + free(data2); + } + + glPixelStorei(GL_PACK_ALIGNMENT, pack); + glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); + } /* OpenGL end */ + + png_read_end(png, endinfo); + png_destroy_read_struct(&png, &info, &endinfo); + + free(data); + + return 1; +} + +static unsigned int SetParams(int wrapst, int magfilter, int minfilter) { + unsigned int id; + + glGenTextures(1, &id); + glBindTexture(GL_TEXTURE_2D, id); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapst); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapst); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter); + + return id; +} + +unsigned int APIENTRY pngBind(const char *filename, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter) { + unsigned int id = SetParams(wrapst, magfilter, minfilter); + + if (id != 0 && pngLoad(filename, mipmap, trans, info)) + return id; + return 0; +} + +unsigned int APIENTRY pngBindF(FILE *file, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter) { + unsigned int id = SetParams(wrapst, magfilter, minfilter); + + if (id != 0 && pngLoadF(file, mipmap, trans, info)) + return id; + return 0; +} + +void APIENTRY pngSetStencil(unsigned char red, unsigned char green, unsigned char blue) { + StencilRed = red, StencilGreen = green, StencilBlue = blue; +} + +void APIENTRY pngSetAlphaCallback(unsigned char (*callback)(unsigned char red, unsigned char green, unsigned char blue)) { + if (callback == NULL) + AlphaCallback = DefaultAlphaCallback; + else + AlphaCallback = callback; +} + +void APIENTRY pngSetViewingGamma(double viewingGamma) { + if(viewingGamma > 0) { + gammaExplicit = 1; + screenGamma = 2.2/viewingGamma; + } + else { + gammaExplicit = 0; + screenGamma = 2.2; + } +} + +void APIENTRY pngSetStandardOrientation(int standardorientation) { + StandardOrientation = standardorientation; +} diff --git a/src/glpng.pro b/src/glpng.pro new file mode 100644 index 0000000..3fe5d45 --- /dev/null +++ b/src/glpng.pro @@ -0,0 +1,38 @@ +TARGET = glpng +TEMPLATE = lib +CONFIG = staticlib warn_on release +INCLUDEPATH = ../include +#DEFINES = SGI + +HEADERS = png/png.h \ + png/pngconf.h \ + zlib/infblock.h \ + zlib/infcodes.h \ + zlib/inffast.h \ + zlib/inffixed.h \ + zlib/inftrees.h \ + zlib/infutil.h \ + zlib/zconf.h \ + zlib/zlib.h \ + zlib/zutil.h +SOURCES = glpng.c \ + png/png.c \ + png/pngerror.c \ + png/pngget.c \ + png/pngmem.c \ + png/pngpread.c \ + png/pngread.c \ + png/pngrio.c \ + png/pngrtran.c \ + png/pngrutil.c \ + png/pngset.c \ + png/pngtrans.c \ + zlib/adler32.c \ + zlib/crc32.c \ + zlib/infblock.c \ + zlib/infcodes.c \ + zlib/inffast.c \ + zlib/inflate.c \ + zlib/inftrees.c \ + zlib/infutil.c \ + zlib/zutil.c