Fix compiler warnings
[glpng.git] / src / glpng.c
blobe671bd1a72e619ef636d4fbe6bd2b22fd6d64175
1 /*
2 * PNG loader library for OpenGL v1.45 (10/07/00)
3 * by Ben Wyatt ben@wyatt100.freeserve.co.uk
4 * Using LibPNG 1.0.2 and ZLib 1.1.3
6 * This software is provided 'as-is', without any express or implied warranty.
7 * In no event will the author be held liable for any damages arising from the
8 * use of this software.
10 * Permission is hereby granted to use, copy, modify, and distribute this
11 * source code, or portions hereof, for any purpose, without fee, subject to
12 * the following restrictions:
14 * 1. The origin of this source code must not be misrepresented. You must not
15 * claim that you wrote the original software. If you use this software in
16 * a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
18 * 2. Altered versions must be plainly marked as such and must not be
19 * misrepresented as being the original source.
20 * 3. This notice must not be removed or altered from any source distribution.
23 #ifdef _WIN32 /* Stupid Windows needs to include windows.h before gl.h */
24 #undef FAR
25 #include <windows.h>
26 #endif
28 #define GL_GLEXT_PROTOTYPES
30 #include <GL/glpng.h>
31 #include <GL/gl.h>
32 #include <GL/glext.h>
33 #include <stdlib.h>
34 #include <stdint.h>
35 #include <string.h>
36 #include <math.h>
37 #include <png.h>
39 /* Used to decide if GL/gl.h supports the paletted extension */
40 #ifdef GL_COLOR_INDEX1_EXT
41 #define SUPPORTS_PALETTE_EXT
42 #endif
44 static unsigned char DefaultAlphaCallback(unsigned char red, unsigned char green, unsigned char blue) {
45 return 255;
48 static unsigned char StencilRed = 0, StencilGreen = 0, StencilBlue = 0;
49 static unsigned char (*AlphaCallback)(unsigned char red, unsigned char green, unsigned char blue) = DefaultAlphaCallback;
50 static int StandardOrientation = 0;
52 #ifdef SUPPORTS_PALETTE_EXT
53 #ifdef _WIN32
54 static PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
55 #endif
56 #endif
58 static int PalettedTextures = -1;
59 static GLint MaxTextureSize = 0;
61 /* screenGamma = displayGamma/viewingGamma
62 * displayGamma = CRT has gamma of ~2.2
63 * viewingGamma depends on platform. PC is 1.0, Mac is 1.45, SGI defaults
64 * to 1.7, but this can be checked and changed w/ /usr/sbin/gamma command.
65 * If the environment variable VIEWING_GAMMA is set, adjust gamma per this value.
67 #ifdef _MAC
68 static double screenGamma = 2.2 / 1.45;
69 #elif SGI
70 static double screenGamma = 2.2 / 1.7;
71 #else /* PC/default */
72 static double screenGamma = 2.2 / 1.0;
73 #endif
75 static char gammaExplicit = 0; /*if */
77 static void checkForGammaEnv()
79 double viewingGamma;
80 char *gammaEnv = getenv("VIEWING_GAMMA");
82 if(gammaEnv && !gammaExplicit)
84 sscanf(gammaEnv, "%lf", &viewingGamma);
85 screenGamma = 2.2/viewingGamma;
89 /* Returns a safe texture size to use (ie a power of 2), based on the current texture size "i" */
90 static int SafeSize(int i) {
91 int p;
93 if (i > MaxTextureSize) return MaxTextureSize;
95 for (p = 0; p < 24; p++)
96 if (i <= (1<<p))
97 return 1<<p;
99 return MaxTextureSize;
102 /* Resize the texture since gluScaleImage doesn't work on everything */
103 static void Resize(int components, const png_bytep d1, int w1, int h1, png_bytep d2, int w2, int h2) {
104 const float sx = (float) w1/w2, sy = (float) h1/h2;
105 int x, y, xx, yy, c;
106 png_bytep d;
108 for (y = 0; y < h2; y++) {
109 yy = (int) (y*sy)*w1;
111 for (x = 0; x < w2; x++) {
112 xx = (int) (x*sx);
113 d = d1 + (yy+xx)*components;
115 for (c = 0; c < components; c++)
116 *d2++ = *d++;
121 #ifdef SUPPORTS_PALETTE_EXT
122 #ifdef _WIN32
123 static int ExtSupported(const char *x) {
124 static const GLubyte *ext = NULL;
125 const char *c;
126 int xlen = strlen(x);
128 if (ext == NULL) ext = glGetString(GL_EXTENSIONS);
130 c = (const char*)ext;
132 while (*c != '\0') {
133 if (strcmp(c, x) == 0 && (c[xlen] == '\0' || c[xlen] == ' ')) return 1;
134 c++;
137 return 0;
139 #endif
140 #endif
142 #define GET(o) ((int)*(data + (o)))
144 static int HalfSize(GLint components, GLint width, GLint height, const unsigned char *data, unsigned char *d, int filter) {
145 int x, y, c;
146 int line = width*components;
148 if (width > 1 && height > 1) {
149 if (filter)
150 for (y = 0; y < height; y += 2) {
151 for (x = 0; x < width; x += 2) {
152 for (c = 0; c < components; c++) {
153 *d++ = (GET(0)+GET(components)+GET(line)+GET(line+components)) / 4;
154 data++;
156 data += components;
158 data += line;
160 else
161 for (y = 0; y < height; y += 2) {
162 for (x = 0; x < width; x += 2) {
163 for (c = 0; c < components; c++) {
164 *d++ = GET(0);
165 data++;
167 data += components;
169 data += line;
172 else if (width > 1 && height == 1) {
173 if (filter)
174 for (y = 0; y < height; y += 1) {
175 for (x = 0; x < width; x += 2) {
176 for (c = 0; c < components; c++) {
177 *d++ = (GET(0)+GET(components)) / 2;
178 data++;
180 data += components;
183 else
184 for (y = 0; y < height; y += 1) {
185 for (x = 0; x < width; x += 2) {
186 for (c = 0; c < components; c++) {
187 *d++ = GET(0);
188 data++;
190 data += components;
194 else if (width == 1 && height > 1) {
195 if (filter)
196 for (y = 0; y < height; y += 2) {
197 for (x = 0; x < width; x += 1) {
198 for (c = 0; c < components; c++) {
199 *d++ = (GET(0)+GET(line)) / 2;
200 data++;
203 data += line;
205 else
206 for (y = 0; y < height; y += 2) {
207 for (x = 0; x < width; x += 1) {
208 for (c = 0; c < components; c++) {
209 *d++ = GET(0);
210 data++;
213 data += line;
216 else {
217 return 0;
220 return 1;
223 #undef GET
225 /* Replacement for gluBuild2DMipmaps so GLU isn't needed */
226 static void Build2DMipmaps(GLint components, GLint width, GLint height, GLenum format, const unsigned char *data, int filter) {
227 int level = 0;
228 unsigned char *d = (unsigned char *) malloc((width/2)*(height/2)*components+4);
229 const unsigned char *last = data;
231 glTexImage2D(GL_TEXTURE_2D, level, components, width, height, 0, format, GL_UNSIGNED_BYTE, data);
232 level++;
234 while (HalfSize(components, width, height, last, d, filter)) {
235 if (width > 1) width /= 2;
236 if (height > 1) height /= 2;
238 glTexImage2D(GL_TEXTURE_2D, level, components, width, height, 0, format, GL_UNSIGNED_BYTE, d);
239 level++;
240 last = d;
243 free(d);
246 int APIENTRY pngLoadRaw(const char *filename, pngRawInfo *pinfo) {
247 int result;
248 FILE *fp = fopen(filename, "rb");
249 if (fp == NULL) return 0;
251 result = pngLoadRawF(fp, pinfo);
253 if (fclose(fp) != 0) {
254 if (result) {
255 free(pinfo->Data);
256 free(pinfo->Palette);
258 return 0;
261 return result;
264 int APIENTRY pngLoadRawF(FILE *fp, pngRawInfo *pinfo) {
265 unsigned char header[8];
266 png_structp png;
267 png_infop info;
268 png_infop endinfo;
269 double fileGamma;
271 png_uint_32 width, height, i;
272 int depth, color;
274 png_bytep data = NULL;
275 png_bytep *row_p = NULL;
277 if (pinfo == NULL) return 0;
279 if (fread(header, 1, 8, fp) != 8) return 0;
280 if (!png_check_sig(header, 8)) return 0;
282 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
283 if (!png) return 0;
284 info = png_create_info_struct(png);
285 if (!info) return 0;
286 endinfo = png_create_info_struct(png);
287 if (!endinfo) return 0;
289 if (setjmp(png_jmpbuf(png)))
290 goto error;
292 png_init_io(png, fp);
293 png_set_sig_bytes(png, 8);
294 png_read_info(png, info);
295 png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
297 pinfo->Width = width;
298 pinfo->Height = height;
299 pinfo->Depth = depth;
301 /*--GAMMA--*/
302 checkForGammaEnv();
303 if (png_get_gAMA(png, info, &fileGamma))
304 png_set_gamma(png, screenGamma, fileGamma);
305 else
306 png_set_gamma(png, screenGamma, 1.0/2.2);
308 png_read_update_info(png, info);
310 /* HDG: We allocate all the png data in one linear array, thus
311 height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
312 This check fixes CVE-2010-1519. */
313 if ((uint64_t)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
314 goto error;
316 data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
317 row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
318 if (!data || !row_p)
319 goto error;
321 for (i = 0; i < height; i++) {
322 if (StandardOrientation)
323 row_p[height - 1 - i] = &data[png_get_rowbytes(png, info)*i];
324 else
325 row_p[i] = &data[png_get_rowbytes(png, info)*i];
328 png_read_image(png, row_p);
329 free(row_p);
330 row_p = NULL;
332 if (color == PNG_COLOR_TYPE_PALETTE) {
333 int cols;
334 png_get_PLTE(png, info, (png_colorp *) &pinfo->Palette, &cols);
336 else {
337 pinfo->Palette = NULL;
340 if (color&PNG_COLOR_MASK_ALPHA) {
341 if (color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY_ALPHA)
342 pinfo->Components = 2;
343 else
344 pinfo->Components = 4;
345 pinfo->Alpha = 8;
347 else {
348 if (color&PNG_COLOR_MASK_PALETTE || color == PNG_COLOR_TYPE_GRAY)
349 pinfo->Components = 1;
350 else
351 pinfo->Components = 3;
352 pinfo->Alpha = 0;
355 pinfo->Data = data;
357 png_read_end(png, endinfo);
358 png_destroy_read_struct(&png, &info, &endinfo);
359 return 1;
361 error:
362 png_destroy_read_struct(&png, &info, &endinfo);
363 free(data);
364 free(row_p);
365 return 0;
368 static int pngLoadCommon(int mipmap, int trans, pngInfo *pinfo, png_structp png, png_infop info, png_infop endinfo) {
369 GLint pack, unpack;
370 double fileGamma;
372 png_uint_32 width, height, rw, rh, i;
373 int depth, color;
375 png_bytep data = NULL, data2 = NULL;
376 png_bytep *row_p = NULL;
378 int ret = 0;
380 png_set_sig_bytes(png, 8);
381 png_read_info(png, info);
382 png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
384 if (pinfo != NULL) {
385 pinfo->Width = width;
386 pinfo->Height = height;
387 pinfo->Depth = depth;
390 if (MaxTextureSize == 0)
391 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &MaxTextureSize);
393 #ifdef SUPPORTS_PALETTE_EXT
394 #ifdef _WIN32
395 if (PalettedTextures == -1)
396 PalettedTextures = ExtSupported("GL_EXT_paletted_texture") && (strstr((const char *) glGetString(GL_VERSION), "1.1.0 3Dfx Beta") == NULL);
398 if (PalettedTextures) {
399 if (glColorTableEXT == NULL) {
400 glColorTableEXT = (PFNGLCOLORTABLEEXTPROC) wglGetProcAddress("glColorTableEXT");
401 if (glColorTableEXT == NULL)
402 PalettedTextures = 0;
405 #endif
406 #endif
408 if (PalettedTextures == -1)
409 PalettedTextures = 0;
411 if (color == PNG_COLOR_TYPE_GRAY || color == PNG_COLOR_TYPE_GRAY_ALPHA)
412 png_set_gray_to_rgb(png);
414 if (color&PNG_COLOR_MASK_ALPHA && trans != PNG_ALPHA) {
415 png_set_strip_alpha(png);
416 color &= ~PNG_COLOR_MASK_ALPHA;
419 if (!(PalettedTextures && mipmap >= 0 && trans == PNG_SOLID))
420 if (color == PNG_COLOR_TYPE_PALETTE)
421 png_set_expand(png);
423 /*--GAMMA--*/
424 checkForGammaEnv();
425 if (png_get_gAMA(png, info, &fileGamma))
426 png_set_gamma(png, screenGamma, fileGamma);
427 else
428 png_set_gamma(png, screenGamma, 1.0/2.2);
430 png_read_update_info(png, info);
432 /* HDG: We allocate all the png data in one linear array, thus
433 height * png_get_rowbytes() may not be > PNG_UINT_32_MAX !
434 This check fixes CVE-2010-1519. */
435 if ((uint64_t)height * png_get_rowbytes(png, info) > PNG_UINT_32_MAX)
436 goto finish;
438 data = (png_bytep) malloc(png_get_rowbytes(png, info)*height);
439 row_p = (png_bytep *) malloc(sizeof(png_bytep)*height);
440 if (!data || !row_p)
441 goto finish;
443 for (i = 0; i < height; i++) {
444 if (StandardOrientation)
445 row_p[height - 1 - i] = &data[png_get_rowbytes(png, info)*i];
446 else
447 row_p[i] = &data[png_get_rowbytes(png, info)*i];
450 png_read_image(png, row_p);
451 free(row_p);
452 row_p = NULL;
454 rw = SafeSize(width), rh = SafeSize(height);
456 if (rw != width || rh != height) {
457 const int channels = png_get_rowbytes(png, info)/width;
459 data2 = (png_bytep) malloc(rw*rh*channels);
460 if (!data2)
461 goto finish;
463 /* Doesn't work on certain sizes */
464 /* if (gluScaleImage(glformat, width, height, GL_UNSIGNED_BYTE, data, rw, rh, GL_UNSIGNED_BYTE, data2) != 0)
465 goto finish;
467 Resize(channels, data, width, height, data2, rw, rh);
469 width = rw, height = rh;
470 free(data);
471 data = data2;
472 data2 = NULL;
475 { /* OpenGL stuff */
476 glGetIntegerv(GL_PACK_ALIGNMENT, &pack);
477 glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack);
478 glPixelStorei(GL_PACK_ALIGNMENT, 1);
479 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
481 #ifdef SUPPORTS_PALETTE_EXT
482 if (PalettedTextures && mipmap >= 0 && trans == PNG_SOLID && color == PNG_COLOR_TYPE_PALETTE) {
483 png_colorp pal;
484 int cols;
485 GLint intf;
487 if (pinfo != NULL) pinfo->Alpha = 0;
488 png_get_PLTE(png, info, &pal, &cols);
490 switch (cols) {
491 case 1<<1: intf = GL_COLOR_INDEX1_EXT; break;
492 case 1<<2: intf = GL_COLOR_INDEX2_EXT; break;
493 case 1<<4: intf = GL_COLOR_INDEX4_EXT; break;
494 case 1<<8: intf = GL_COLOR_INDEX8_EXT; break;
495 case 1<<12: intf = GL_COLOR_INDEX12_EXT; break;
496 case 1<<16: intf = GL_COLOR_INDEX16_EXT; break;
497 default:
498 /*printf("Warning: Colour depth %i not recognised\n", cols);*/
499 goto finish;
501 glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, cols, GL_RGB, GL_UNSIGNED_BYTE, pal);
502 glTexImage2D(GL_TEXTURE_2D, mipmap, intf, width, height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, data);
504 else
505 #endif
506 if (trans == PNG_SOLID || trans == PNG_ALPHA || color == PNG_COLOR_TYPE_RGB_ALPHA || color == PNG_COLOR_TYPE_GRAY_ALPHA) {
507 GLenum glformat;
508 GLint glcomponent;
510 switch (color) {
511 case PNG_COLOR_TYPE_GRAY:
512 case PNG_COLOR_TYPE_RGB:
513 case PNG_COLOR_TYPE_PALETTE:
514 glformat = GL_RGB;
515 glcomponent = 3;
516 if (pinfo != NULL) pinfo->Alpha = 0;
517 break;
519 case PNG_COLOR_TYPE_GRAY_ALPHA:
520 case PNG_COLOR_TYPE_RGB_ALPHA:
521 glformat = GL_RGBA;
522 glcomponent = 4;
523 if (pinfo != NULL) pinfo->Alpha = 8;
524 break;
526 default:
527 /*puts("glformat not set");*/
528 goto finish;
531 if (mipmap == PNG_BUILDMIPMAPS)
532 Build2DMipmaps(glcomponent, width, height, glformat, data, 1);
533 else if (mipmap == PNG_SIMPLEMIPMAPS)
534 Build2DMipmaps(glcomponent, width, height, glformat, data, 0);
535 else
536 glTexImage2D(GL_TEXTURE_2D, mipmap, glcomponent, width, height, 0, glformat, GL_UNSIGNED_BYTE, data);
538 else {
539 png_bytep p, endp, q;
540 int r, g, b, a;
542 /* HDG another potential 32 bit address overflow, the
543 original png had 3 channels and we are going to
544 4 channels now! */
545 if ((uint64_t)width * height > (PNG_UINT_32_MAX >> 2))
546 goto finish;
548 p = data, endp = p+width*height*3;
549 q = data2 = (png_bytep) malloc(sizeof(png_byte)*width*height*4);
551 if (pinfo != NULL) pinfo->Alpha = 8;
553 #define FORSTART \
554 do { \
555 r = *p++; /*red */ \
556 g = *p++; /*green*/ \
557 b = *p++; /*blue */ \
558 *q++ = r; \
559 *q++ = g; \
560 *q++ = b;
562 #define FOREND \
563 q++; \
564 } while (p != endp);
566 #define ALPHA *q
568 switch (trans) {
569 case PNG_CALLBACKT:
570 FORSTART
571 ALPHA = AlphaCallback((unsigned char) r, (unsigned char) g, (unsigned char) b);
572 FOREND
573 break;
575 case PNG_STENCIL:
576 FORSTART
577 if (r == StencilRed && g == StencilGreen && b == StencilBlue)
578 ALPHA = 0;
579 else
580 ALPHA = 255;
581 FOREND
582 break;
584 case PNG_BLEND1:
585 FORSTART
586 a = r+g+b;
587 if (a > 255) ALPHA = 255; else ALPHA = a;
588 FOREND
589 break;
591 case PNG_BLEND2:
592 FORSTART
593 a = r+g+b;
594 if (a > 255*2) ALPHA = 255; else ALPHA = a/2;
595 FOREND
596 break;
598 case PNG_BLEND3:
599 FORSTART
600 ALPHA = (r+g+b)/3;
601 FOREND
602 break;
604 case PNG_BLEND4:
605 FORSTART
606 a = r*r+g*g+b*b;
607 if (a > 255) ALPHA = 255; else ALPHA = a;
608 FOREND
609 break;
611 case PNG_BLEND5:
612 FORSTART
613 a = r*r+g*g+b*b;
614 if (a > 255*2) ALPHA = 255; else ALPHA = a/2;
615 FOREND
616 break;
618 case PNG_BLEND6:
619 FORSTART
620 a = r*r+g*g+b*b;
621 if (a > 255*3) ALPHA = 255; else ALPHA = a/3;
622 FOREND
623 break;
625 case PNG_BLEND7:
626 FORSTART
627 a = r*r+g*g+b*b;
628 if (a > 255*255) ALPHA = 255; else ALPHA = (int) sqrt(a);
629 FOREND
630 break;
633 #undef FORSTART
634 #undef FOREND
635 #undef ALPHA
637 if (mipmap == PNG_BUILDMIPMAPS)
638 Build2DMipmaps(4, width, height, GL_RGBA, data2, 1);
639 else if (mipmap == PNG_SIMPLEMIPMAPS)
640 Build2DMipmaps(4, width, height, GL_RGBA, data2, 0);
641 else
642 glTexImage2D(GL_TEXTURE_2D, mipmap, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
646 glPixelStorei(GL_PACK_ALIGNMENT, pack);
647 glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
648 } /* OpenGL end */
650 png_read_end(png, endinfo);
651 ret = 1;
653 finish:
654 free(data);
655 free(data2);
656 free(row_p);
657 return ret;
660 int APIENTRY pngLoad(const char *filename, int mipmap, int trans, pngInfo *pinfo) {
661 int result;
662 FILE *fp = fopen(filename, "rb");
663 if (fp == NULL) return 0;
665 result = pngLoadF(fp, mipmap, trans, pinfo);
667 if (fclose(fp) != 0) return 0;
669 return result;
672 int APIENTRY pngLoadF(FILE *fp, int mipmap, int trans, pngInfo *pinfo) {
673 unsigned char header[8];
674 png_structp png;
675 png_infop info;
676 png_infop endinfo;
678 int ret = 0;
680 if (fread(header, 1, 8, fp) != 8) return 0;
681 if (!png_check_sig(header, 8)) return 0;
683 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
684 if (!png) return 0;
685 info = png_create_info_struct(png);
686 if (!info) return 0;
687 endinfo = png_create_info_struct(png);
688 if (!endinfo) return 0;
690 if (!setjmp(png_jmpbuf(png))) {
691 png_init_io(png, fp);
692 ret = pngLoadCommon(mipmap, trans, pinfo, png, info, endinfo);
695 png_destroy_read_struct(&png, &info, &endinfo);
696 return ret;
699 typedef struct glpng_memread_struct {
700 png_bytep mem;
701 png_size_t rpos;
702 } glpng_memread;
704 static void glpng_read_mem(png_structp png, png_bytep dst, png_size_t size) {
705 glpng_memread *mr = (glpng_memread*) png_get_io_ptr(png);
706 memcpy(dst, mr->mem + mr->rpos, size);
707 mr->rpos += size;
710 int APIENTRY pngLoadMem(const char *mem, int size, int mipmap, int trans, pngInfo *pinfo) {
711 unsigned char header[8];
712 png_structp png;
713 png_infop info;
714 png_infop endinfo;
715 glpng_memread memread;
717 int ret = 0;
719 if (size < 8)
720 return 0; // error
722 memcpy(header, mem, 8);
723 if (!png_check_sig(header, 8)) return 0;
725 png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
726 if (!png) return 0;
727 info = png_create_info_struct(png);
728 if (!info) return 0;
729 endinfo = png_create_info_struct(png);
730 if (!endinfo) return 0;
732 if (!setjmp(png_jmpbuf(png))) {
733 memread.rpos = 0;
734 memread.mem = ((png_bytep) mem) + 8;
735 png_set_read_fn(png, &memread, glpng_read_mem);
736 ret = pngLoadCommon(mipmap, trans, pinfo, png, info, endinfo);
739 png_destroy_read_struct(&png, &info, &endinfo);
740 return ret;
743 static unsigned int SetParams(int wrapst, int magfilter, int minfilter) {
744 unsigned int id;
746 glGenTextures(1, &id);
747 glBindTexture(GL_TEXTURE_2D, id);
749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapst);
750 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapst);
752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magfilter);
753 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minfilter);
755 return id;
758 unsigned int APIENTRY pngBind(const char *filename, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter) {
759 unsigned int id = SetParams(wrapst, magfilter, minfilter);
761 if (id != 0 && pngLoad(filename, mipmap, trans, info))
762 return id;
763 return 0;
766 unsigned int APIENTRY pngBindF(FILE *file, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter) {
767 unsigned int id = SetParams(wrapst, magfilter, minfilter);
769 if (id != 0 && pngLoadF(file, mipmap, trans, info))
770 return id;
771 return 0;
774 unsigned int APIENTRY pngBindMem(const char *mem, int size, int mipmap, int trans, pngInfo *info, int wrapst, int minfilter, int magfilter) {
775 unsigned int id = SetParams(wrapst, magfilter, minfilter);
777 if (id != 0 && pngLoadMem(mem, size, mipmap, trans, info))
778 return id;
779 return 0;
782 void APIENTRY pngSetStencil(unsigned char red, unsigned char green, unsigned char blue) {
783 StencilRed = red, StencilGreen = green, StencilBlue = blue;
786 void APIENTRY pngSetAlphaCallback(unsigned char (*callback)(unsigned char red, unsigned char green, unsigned char blue)) {
787 if (callback == NULL)
788 AlphaCallback = DefaultAlphaCallback;
789 else
790 AlphaCallback = callback;
793 void APIENTRY pngSetViewingGamma(double viewingGamma) {
794 if(viewingGamma > 0) {
795 gammaExplicit = 1;
796 screenGamma = 2.2/viewingGamma;
798 else {
799 gammaExplicit = 0;
800 screenGamma = 2.2;
804 void APIENTRY pngSetStandardOrientation(int standardorientation) {
805 StandardOrientation = standardorientation;