1 /*
2   Copyright (C) 2000 Xavier Hosxe <xhosxe@free.fr>
3 
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2 of the License, or
7   (at your option) any later version.
8 
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13 
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18 
19 /*
20  * Png algorithm from the libpng....
21  *
22  */
23 
24 #include "pngtex.hpp"
25 
PngTex()26 PngTex::PngTex()
27 {
28     width=0;
29     height=0;
30     openGL_tex = NULL;
31 }
32 
PngTex(const char * file_name)33 PngTex::PngTex(const char* file_name)
34 {
35     FILE *fp = fopen(file_name, "rb");
36     png_byte header[8];
37     png_structp png_ptr;
38     openGL_tex = NULL;
39     if (!fp)
40     {
41        printf("Error while loading '%s'\n", file_name);
42 	   exit(12);
43     }
44 
45    // Read a chunk to check if this is indeed a png file...
46     fread( header, 1, sizeof(header), fp);
47 
48     if (png_sig_cmp(header, (png_size_t)0, 4)) {
49        printf("not png type %s", file_name);
50 	   exit(12);
51     }
52 
53 
54     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
55         NULL,
56         NULL,
57         NULL);
58     if (!png_ptr) {
59         printf( "error while reading png_structp");
60 	   exit(12);
61     }
62 
63     png_infop info_ptr = png_create_info_struct(png_ptr);
64     if (!info_ptr)
65     {
66         png_destroy_read_struct(&png_ptr,
67             (png_infopp)NULL, (png_infopp)NULL);
68         printf( "error while reading info_struct");
69 	   exit(12);
70     }
71 
72     png_infop end_info = png_create_info_struct(png_ptr);
73     if (!end_info)
74     {
75         png_destroy_read_struct(&png_ptr, &info_ptr,  (png_infopp)NULL);
76         printf( "error while reading info_struct");
77 	   exit(12);
78     }
79 
80 
81     png_init_io(png_ptr, fp);
82     png_set_sig_bytes(png_ptr, sizeof(header));
83 
84     png_read_info(png_ptr, info_ptr);
85 
86     png_get_IHDR(png_ptr, info_ptr, &width, &height,
87         &bit_depth, &color_type, &interlace_type,
88         &compression_type, &filter_type);
89 
90 
91     png_bytep * row_pointers ;
92     row_pointers = new png_bytep[height];
93     png_uint_32 row;
94     for (row = 0; row < height; row++)
95     {
96         int size;
97         row_pointers[row] = new png_byte[(size=png_get_rowbytes(png_ptr, info_ptr))];
98     }
99 
100     png_read_image(png_ptr, row_pointers);
101 
102     openGL_tex= new char[height*width*4];
103     png_uint_32 i,j;
104 
105     for(j = 0; j < height; j++) {
106         for (i=0; i < width;i++)
107         {
108             int scale = 3 + (PNG_COLOR_TYPE_RGB_ALPHA==color_type);
109             openGL_tex[(j*width+i)*4 ] = (char)*(char*)( row_pointers[j] +i*scale) ;
110             openGL_tex[(j*width+i)*4 +1 ] = (char)*(char*)( row_pointers[j] +i*scale +1 ) ;
111             openGL_tex[(j*width+i)*4 +2 ] = (char)*(char*)( row_pointers[j] +i*scale +2 ) ;
112             if (color_type==PNG_COLOR_TYPE_RGB)
113                 openGL_tex[(j*width+i)*4 +3 ] = (char)255 ;
114             else
115                 openGL_tex[(j*width+i)*4 +3 ] = (char)*(char*)( row_pointers[j] +i*scale +3 ) ;
116         }
117     }
118 
119     png_read_end(png_ptr, info_ptr);
120     png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
121     fclose(fp);
122 
123 
124     for (row = 0; row < height; row++)
125     {
126         delete [] row_pointers[row];
127     }
128     delete []row_pointers;
129  }
130 
bindToTexture(GLuint & texture)131 void PngTex::bindToTexture(GLuint &texture)
132 {
133     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
134     glGenTextures(1, & texture );
135     glBindTexture(GL_TEXTURE_2D, texture);
136 
137 	gluBuild2DMipmaps(GL_TEXTURE_2D,  GL_RGBA16,
138         width,
139         height, GL_RGBA,
140         GL_UNSIGNED_BYTE,
141         openGL_tex);
142 
143 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
144     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
145 
146 	/*
147 	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
148     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
149 	*/
150     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
151     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
152 
153 }
154 
155 
~PngTex()156 PngTex::~PngTex()
157 {
158 	if (openGL_tex!=NULL)
159 		delete []openGL_tex;
160 }
161 
162