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