1
0
Fork 0
mirror of https://github.com/AquariaOSE/Aquaria.git synced 2024-12-05 01:15:52 +00:00
Aquaria/ExternalLibs/glpng/glpng.c
James Le Cuirot f19011e3dd
Delete duplicate GL headers
Nothing was pointing at BBGE/glext.

Only the VS project was pointing at ExternalLibs/GL. I have pointed it
at the headers under BBGE/GL instead.

I have also adjusted the includes to use the GL prefix as is standard
practise. These will still work as BBGE is in the include path. This
allows users to build against their system GL headers simply by
deleting the BBGE/GL directory.
2017-02-09 21:08:57 +00:00

841 lines
20 KiB
C

/*
* PNG loader library for OpenGL v1.46 (02/06/14)
* 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.
*/
/* Changed things slightly to be compatible with compilers not having stdint.h,
* plus #include changes for static linking into Aquaria. -- fg */
#ifdef _WIN32 /* Stupid Windows needs to include windows.h before gl.h */
#undef FAR
#include <windows.h>
#endif
//#define GL_GLEXT_PROTOTYPES
//#include <GL/glpng.h>
#include "../glpng.h"
#include <GL/gl.h>
#include <GL/glext.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#ifdef _MSC_VER
typedef unsigned __int64 uint64;
#else
# include <stdint.h>
typedef uint64_t uint64;
#endif
#include <png.h>
#include "SDL.h"
static PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
static int s_got_glGenerateMipmapEXT = 0;
/* 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<<p))
return 1<<p;
return MaxTextureSize;
}
/* Resize the texture since gluScaleImage doesn't work on everything */
static void Resize(int components, const png_bytep d1, int w1, int h1, png_bytep d2, int w2, int h2) {
const float sx = (float) w1/w2, sy = (float) h1/h2;
int x, y, xx, yy, c;
png_bytep d;
for (y = 0; y < h2; y++) {
yy = (int) (y*sy)*w1;
for (x = 0; x < w2; x++) {
xx = (int) (x*sx);
d = d1 + (yy+xx)*components;
for (c = 0; c < components; c++)
*d2++ = *d++;
}
}
}
#ifdef SUPPORTS_PALETTE_EXT
#ifdef _WIN32
static int ExtSupported(const char *x) {
static const GLubyte *ext = NULL;
const char *c;
int xlen = strlen(x);
if (ext == NULL) ext = glGetString(GL_EXTENSIONS);
c = (const char*)ext;
while (*c != '\0') {
if (strcmp(c, x) == 0 && (c[xlen] == '\0' || c[xlen] == ' ')) return 1;
c++;
}
return 0;
}
#endif
#endif
#define GET(o) ((int)*(data + (o)))
static int HalfSize(GLint components, GLint width, GLint height, const unsigned char *data, unsigned char *d, int filter) {
int x, y, c;
int line = width*components;
if (width > 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;
const unsigned char *last = data;
glTexImage2D(GL_TEXTURE_2D, level, components, width, height, 0, format, GL_UNSIGNED_BYTE, data);
genmip:
if(glGenerateMipmapEXT)
{
glHint(GL_GENERATE_MIPMAP_HINT, filter ? GL_NICEST : GL_FASTEST);
glGenerateMipmapEXT(GL_TEXTURE_2D);
return;
}
else if(!s_got_glGenerateMipmapEXT)
{
s_got_glGenerateMipmapEXT = 1;
glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC)SDL_GL_GetProcAddress("glGenerateMipmapEXT");
goto genmip;
}
level++;
d = (unsigned char *) malloc((width/2)*(height/2)*components+4);
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 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 pngLoadRawF(FILE *fp, pngRawInfo *pinfo) {
unsigned char header[8];
png_structp png;
png_infop info;
png_infop endinfo;
double fileGamma;
png_uint_32 width, height, i;
int depth, color;
png_bytep data = NULL;
png_bytep *row_p = NULL;
if (pinfo == NULL) return 0;
if (fread(header, 1, 8, fp) != 8) return 0;
if (!png_check_sig(header, 8)) return 0;
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) return 0;
info = png_create_info_struct(png);
if (!info) return 0;
endinfo = png_create_info_struct(png);
if (!endinfo) return 0;
if (setjmp(png_jmpbuf(png)))
goto error;
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);
/* HDG: We allocate all the png data in one linear array, thus
height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
This check fixes CVE-2010-1519. */
if ((uint64)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
goto error;
data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
if (!data || !row_p)
goto error;
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);
row_p = NULL;
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;
error:
png_destroy_read_struct(&png, &info, &endinfo);
free(data);
free(row_p);
return 0;
}
static int pngLoadCommon(int mipmap, int trans, pngInfo *pinfo, png_structp png, png_infop info, png_infop endinfo) {
GLint pack, unpack;
double fileGamma;
png_uint_32 width, height, rw, rh, i;
int depth, color;
png_bytep data = NULL, data2 = NULL;
png_bytep *row_p = NULL;
int ret = 0;
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);
/* HDG: We allocate all the png data in one linear array, thus
height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
This check fixes CVE-2010-1519. */
if ((uint64)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
goto finish;
data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
if (!data || !row_p)
goto finish;
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);
row_p = NULL;
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);
if (!data2)
goto finish;
/* Doesn't work on certain sizes */
/* if (gluScaleImage(glformat, width, height, GL_UNSIGNED_BYTE, data, rw, rh, GL_UNSIGNED_BYTE, data2) != 0)
goto finish;
*/
Resize(channels, data, width, height, data2, rw, rh);
width = rw, height = rh;
free(data);
data = data2;
data2 = NULL;
}
{ /* 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);*/
goto finish;
}
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 || trans == PNG_LUMINANCEALPHA || 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");*/
goto finish;
}
if (trans == PNG_LUMINANCEALPHA)
glformat = GL_LUMINANCE_ALPHA;
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;
/* HDG another potential 32 bit address overflow, the
original png had 3 channels and we are going to
4 channels now! */
if ((uint64)width * height > (PNG_UINT_32_MAX >> 2))
goto finish;
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_CALLBACKT:
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);
}
glPixelStorei(GL_PACK_ALIGNMENT, pack);
glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
} /* OpenGL end */
png_read_end(png, endinfo);
ret = 1;
finish:
free(data);
free(data2);
free(row_p);
return ret;
}
int 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 pngLoadF(FILE *fp, int mipmap, int trans, pngInfo *pinfo) {
unsigned char header[8];
png_structp png;
png_infop info;
png_infop endinfo;
int ret = 0;
if (fread(header, 1, 8, fp) != 8) return 0;
if (!png_check_sig(header, 8)) return 0;
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) return 0;
info = png_create_info_struct(png);
if (!info) return 0;
endinfo = png_create_info_struct(png);
if (!endinfo) return 0;
if (!setjmp(png_jmpbuf(png))) {
png_init_io(png, fp);
ret = pngLoadCommon(mipmap, trans, pinfo, png, info, endinfo);
}
png_destroy_read_struct(&png, &info, &endinfo);
return ret;
}
typedef struct glpng_memread_struct {
png_bytep mem;
png_size_t rpos;
} glpng_memread;
static void glpng_read_mem(png_structp png, png_bytep dst, png_size_t size) {
glpng_memread *mr = (glpng_memread*) png_get_io_ptr(png);
memcpy(dst, mr->mem + mr->rpos, size);
mr->rpos += size;
}
int pngLoadMem(const char *mem, int size, int mipmap, int trans, pngInfo *pinfo) {
unsigned char header[8];
png_structp png;
png_infop info;
png_infop endinfo;
glpng_memread memread;
int ret = 0;
if (size < 8)
return 0; // error
memcpy(header, mem, 8);
if (!png_check_sig(header, 8)) return 0;
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png) return 0;
info = png_create_info_struct(png);
if (!info) return 0;
endinfo = png_create_info_struct(png);
if (!endinfo) return 0;
if (!setjmp(png_jmpbuf(png))) {
memread.rpos = 0;
memread.mem = ((png_bytep) mem) + 8;
png_set_read_fn(png, &memread, glpng_read_mem);
ret = pngLoadCommon(mipmap, trans, pinfo, png, info, endinfo);
}
png_destroy_read_struct(&png, &info, &endinfo);
return ret;
}
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 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 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;
}
unsigned int pngBindMem(const char *mem, int size, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter) {
unsigned int id = SetParams(wrapst, magfilter, minfilter);
if (id != 0 && pngLoadMem(mem, size, mipmap, trans, info))
return id;
return 0;
}
void pngSetStencil(unsigned char red, unsigned char green, unsigned char blue) {
StencilRed = red, StencilGreen = green, StencilBlue = blue;
}
void pngSetAlphaCallback(unsigned char (*callback)(unsigned char red, unsigned char green, unsigned char blue)) {
if (callback == NULL)
AlphaCallback = DefaultAlphaCallback;
else
AlphaCallback = callback;
}
void pngSetViewingGamma(double viewingGamma) {
if(viewingGamma > 0) {
gammaExplicit = 1;
screenGamma = 2.2/viewingGamma;
}
else {
gammaExplicit = 0;
screenGamma = 2.2;
}
}
void pngSetStandardOrientation(int standardorientation) {
StandardOrientation = standardorientation;
}