COPASI API  4.16.103
Public Member Functions | Protected Member Functions | List of all members
CLSimpleImageTexturizer Class Reference

#include <CLSimpleImageTexturizer.h>

Inheritance diagram for CLSimpleImageTexturizer:
Inheritance graph
[legend]
Collaboration diagram for CLSimpleImageTexturizer:
Collaboration graph
[legend]

Public Member Functions

virtual CLTextureSpecoperator() (const std::string &filename, const std::string &basedir)
 

Protected Member Functions

CLTextureSpeccreate_texture_for_image (const std::string &filename, const std::string &basedir)
 
CLTextureSpeccreate_texture_for_jpeg_image (const std::string &filename)
 
CLTextureSpeccreate_texture_for_png_image (const std::string &filename)
 

Additional Inherited Members

- Static Protected Member Functions inherited from CLImageTexturizer
static std::string to_absolute_path (const std::string &filename, const std::string &basedir)
 

Detailed Description

Definition at line 21 of file CLSimpleImageTexturizer.h.

Member Function Documentation

CLTextureSpec * CLSimpleImageTexturizer::create_texture_for_image ( const std::string &  filename,
const std::string &  basedir 
)
protected

This method creates a texture from a given image file. It is up to the caller to free the texture space once it is no longer needed. If no texture could be created, NULL is returned.

Definition at line 26 of file CLSimpleImageTexturizer.cpp.

References create_texture_for_jpeg_image(), create_texture_for_png_image(), CLImageTexturizer::to_absolute_path(), and transform().

Referenced by operator()().

27 {
28  std::string reference = to_absolute_path(filename, basedir);
29  CLTextureSpec* pTexture = NULL;
30  // test if the filename ends in "JPG","JPEG","jpeg" or "jpg"
31  std::string::size_type pos = reference.rfind(".");
32  std::string ending;
33 
34  if (pos != std::string::npos)
35  {
36  ++pos;
37  ending = reference.substr(pos);
38  std::transform(ending.begin(), ending.end(), ending.begin(), (int(*)(int))std::tolower);
39  }
40 
41  if (!ending.empty())
42  {
43  if (ending == "jpeg" || ending == "jpg")
44  {
45  pTexture = create_texture_for_jpeg_image(reference);
46  }
47  else if (ending == "png") // test if the filename ends in "PNG" or "png"
48  {
49  pTexture = create_texture_for_png_image(reference);
50  }
51  }
52 
53  return pTexture;
54 }
static std::string to_absolute_path(const std::string &filename, const std::string &basedir)
void transform(QGraphicsItem *item, const CLTransformation2D *trans, const CLGroup *group)
CLTextureSpec * create_texture_for_jpeg_image(const std::string &filename)
CLTextureSpec * create_texture_for_png_image(const std::string &filename)
CLTextureSpec * CLSimpleImageTexturizer::create_texture_for_jpeg_image ( const std::string &  filename)
protected

This method creates a texture from a given JPEG image file. It is up to the caller to free the texture space once it is no longer needed. If no texture could be created, NULL is returned.

Definition at line 61 of file CLSimpleImageTexturizer.cpp.

References GL_CLAMP_TO_EDGE, CLTextureSpec::mNumComponents, CLTextureSpec::mTextHeight, CLTextureSpec::mTextureHeight, CLTextureSpec::mTextureName, CLTextureSpec::mTextureWidth, and CLTextureSpec::mTextWidth.

Referenced by create_texture_for_image().

62 {
63  CLTextureSpec* pTexture = NULL;
64  FILE *fp = fopen(filename.c_str(), "rb");
65 
66  if (fp)
67  {
68  struct jpeg_decompress_struct cinfo;
69  struct jpeg_error_mgr jerr;
70  cinfo.err = jpeg_std_error(&jerr);
71  jpeg_create_decompress(&cinfo);
72  jpeg_stdio_src(&cinfo, fp);
73  jpeg_read_header(&cinfo, true);
74  cinfo.out_color_space = JCS_RGB;
75  jpeg_start_decompress(&cinfo);
76  // read the size and allocate the memory needed
77  unsigned int width = cinfo.output_width;
78  assert(cinfo.output_components == 3);
79  unsigned int row_stride = width * cinfo.output_components;
80  unsigned int height = cinfo.output_height;
81  pTexture = new CLTextureSpec();
82  pTexture->mTextureWidth = width;
83  pTexture->mTextureHeight = height;
84  pTexture->mTextureName = 0;
85  pTexture->mNumComponents = 3;
86  GLubyte* pData = new GLubyte[3 * width * height];
87  JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)
88  ((j_common_ptr) & cinfo, JPOOL_IMAGE, row_stride, 1);
89 
90  while (cinfo.output_scanline < cinfo.output_height)
91  {
92  jpeg_read_scanlines(&cinfo, buffer, 1);
93  memcpy(pData + (cinfo.output_scanline - 1)*row_stride, buffer[0], row_stride);
94  }
95 
96  jpeg_finish_decompress(&cinfo);
97  jpeg_destroy_decompress(&cinfo);
98  fclose(fp);
99 
100  // right now the texture is not a power of two, but it has the same size as the image
101  // we need to scale it to a power of two, for this we check which size of the texture
102  // supported by the OpenGL implementation and rescale it
103  GLint w = 0;
104  width = (unsigned int)ceil(log(pTexture->mTextureWidth) / log(2.0));
105  height = (unsigned int)ceil(log(pTexture->mTextureHeight) / log(2.0));
106  width = (1 << width);
107  height = (1 << height);
108  GLenum format = GL_RGB;
109  GLint internalFormat = GL_RGB;
110  glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
111  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
112 
113  while (w == 0 && width > 0 && height > 0)
114  {
115  // divide the size by two in each direction
116  width = width >> 1;
117  height = height >> 1;
118  glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
119  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
120  }
121 
122  if (w == 0)
123  {
124  // delete the texture since we can not draw it anyway
125  delete pTexture;
126  pTexture = NULL;
127  }
128  else if (w != pTexture->mTextureWidth)
129  {
130  if (w < pTexture->mTextureWidth)
131  {
132  // create a warning that the texture had to be scaled down
133  std::cerr << "Image texture to large. Scaling down to size that is supported by current OpenGL implementation." << std::endl;
134  }
135 
136  // rescale the texture
137  GLubyte* newData = new GLubyte[pTexture->mNumComponents * width * height];
138 
139  if (gluScaleImage(format, (GLint)pTexture->mTextureWidth, (GLint)pTexture->mTextureHeight, GL_UNSIGNED_BYTE, pData, width, height, GL_UNSIGNED_BYTE, newData) == 0)
140  {
141  delete[] pData;
142  pData = newData;
143  pTexture->mTextureWidth = width;
144  pTexture->mTextureHeight = height;
145  pTexture->mTextWidth = pTexture->mTextureWidth;
146  pTexture->mTextHeight = pTexture->mTextureHeight;
147  }
148  else
149  {
150  // an error has occured
151  delete[] newData;
152  delete pTexture;
153  pTexture = NULL;
154  }
155 
156  if (pTexture != NULL)
157  {
158  glGenTextures(1, &pTexture->mTextureName);
159  assert(pTexture->mTextureName != 0);
160  glBindTexture(GL_TEXTURE_2D, pTexture->mTextureName);
161  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
162  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
163  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
164  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
165  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
166  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pTexture->mTextureWidth, (GLsizei)pTexture->mTextureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);
167  }
168  }
169 
170  delete[] pData;
171  }
172 
173  return pTexture;
174 }
#define GL_CLAMP_TO_EDGE
Definition: glext.h:95
double mTextureWidth
double mTextureHeight
unsigned int mNumComponents
CLTextureSpec * CLSimpleImageTexturizer::create_texture_for_png_image ( const std::string &  filename)
protected

This method creates a texture from a given PNG image file. It is up to the caller to free the texture space once it is no longer needed. If no texture could be created, NULL is returned.

Definition at line 181 of file CLSimpleImageTexturizer.cpp.

References GL_CLAMP_TO_EDGE, CLTextureSpec::mNumComponents, CLTextureSpec::mTextHeight, CLTextureSpec::mTextureHeight, CLTextureSpec::mTextureName, CLTextureSpec::mTextureWidth, and CLTextureSpec::mTextWidth.

Referenced by create_texture_for_image().

182 {
183  CLTextureSpec* pTexture = NULL;
184  FILE *fp = fopen(filename.c_str(), "rb");
185 
186  if (fp)
187  {
188  png_byte header[8];
189  fread(header, 1, 8, fp);
190 
191  if (!png_sig_cmp(header, 0, 8))
192  {
193  png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
194 
195  if (png_ptr)
196  {
197  png_infop info_ptr = png_create_info_struct(png_ptr);
198  png_infop end_info = NULL;
199 
200  if (info_ptr)
201  {
202  end_info = png_create_info_struct(png_ptr);
203 
204  if (end_info)
205  {
206  png_init_io(png_ptr, fp);
207  png_set_sig_bytes(png_ptr, 8);
208  png_read_info(png_ptr, info_ptr);
209  unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
210  unsigned int color_type = png_get_color_type(png_ptr, info_ptr);
211 
212  // convert a palette to an RGB image
213  if (color_type == PNG_COLOR_TYPE_PALETTE)
214  {
215  png_set_palette_to_rgb(png_ptr);
216  }
217 
218  // convert low bit_depth grayscale images to 8 Bit
219  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
220  {
221  png_set_gray_1_2_4_to_8(png_ptr);
222  }
223 
224  // add an alpha channel from info
225  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
226  {
227  png_set_tRNS_to_alpha(png_ptr);
228  }
229 
230  // convert 16Bit images to 8 Bit
231  if (bit_depth == 16)
232  {
233  png_set_strip_16(png_ptr);
234  }
235 
236  // convert low bit_depth images to 8 Bit
237  if (bit_depth < 8)
238  {
239  png_set_packing(png_ptr);
240  }
241 
242  // convert grayscale to RGB
243  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
244  {
245  png_set_gray_to_rgb(png_ptr);
246  }
247 
248  // add an alpha channel to RGB images
249  if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY)
250  {
251  png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
252  }
253 
254  // enable interlace handling to expand the image if it
255  // is interlaced
256  /*unsigned int num_passes=*/png_set_interlace_handling(png_ptr);
257  // now we reread the info and get the width and height
258  // in order to allocate enough memory
259  png_read_update_info(png_ptr, info_ptr);
260  unsigned int width = png_get_image_width(png_ptr, info_ptr);
261  unsigned int height = png_get_image_height(png_ptr, info_ptr);
262 
263  if (height > 0)
264  {
265  // create the texture object
266  pTexture = new CLTextureSpec();
267  // we have to reserve enough memory for a width*height
268  // RGBA image
269  GLubyte* pData = new GLubyte[4 * width * height];
270  pTexture->mTextureWidth = width;
271  pTexture->mTextureHeight = height;
272  pTexture->mNumComponents = 4;
273  pTexture->mTextureName = 0;
274  // create an array with pointers to the rows
275  png_bytepp pRow_pointers = new png_bytep[height];
276  unsigned int i;
277 
278  for (i = 0; i < height; ++i)
279  {
280  pRow_pointers[i] = (&(pData[4 * width * i]));
281  }
282 
283  png_read_image(png_ptr, pRow_pointers);
284  png_read_end(png_ptr, end_info);
285  fclose(fp);
286  // right now the texture is not a power of two, but it has the same size as the image
287  // we need to scale it to a power of two, for this we check which size of the texture
288  // supported by the OpenGL implementation and rescale it
289  GLint w = 0;
290  width = (unsigned int)ceil(log(pTexture->mTextureWidth) / log(2.0));
291  height = (unsigned int)ceil(log(pTexture->mTextureHeight) / log(2.0));
292  width = (1 << width);
293  height = (1 << height);
294  GLenum format = GL_RGBA;
295  GLint internalFormat = GL_RGBA;
296  glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
297  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
298 
299  while (w == 0 && width > 0 && height > 0)
300  {
301  // divide the size by two in each direction
302  width = width >> 1;
303  height = height >> 1;
304  glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
305  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
306  }
307 
308  if (w == 0)
309  {
310  // delete the texture since we can not draw it anyway
311  delete pTexture;
312  pTexture = NULL;
313  }
314  else if (w != pTexture->mTextureWidth)
315  {
316  if (w < pTexture->mTextureWidth)
317  {
318  // create a warning that the texture had to be scaled down
319  std::cerr << "Image texture to large. Scaling down to size that is supported by current OpenGL implementation." << std::endl;
320  }
321 
322  // rescale the texture
323  GLubyte* newData = new GLubyte[pTexture->mNumComponents * width * height];
324 
325  if (gluScaleImage(format, (GLint)pTexture->mTextureWidth, (GLint)pTexture->mTextureHeight, GL_UNSIGNED_BYTE, pData, width, height, GL_UNSIGNED_BYTE, newData) == 0)
326  {
327  delete[] pData;
328  pData = newData;
329  pTexture->mTextureWidth = width;
330  pTexture->mTextureHeight = height;
331  pTexture->mTextWidth = pTexture->mTextureWidth;
332  pTexture->mTextHeight = pTexture->mTextureHeight;
333  }
334  else
335  {
336  // an error has occured
337  delete[] newData;
338  delete pTexture;
339  pTexture = NULL;
340  }
341 
342  if (pTexture != NULL)
343  {
344  glGenTextures(1, &pTexture->mTextureName);
345  assert(pTexture->mTextureName != 0);
346  glBindTexture(GL_TEXTURE_2D, pTexture->mTextureName);
347  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
348  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
349  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
350  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
351  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
352  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)pTexture->mTextureWidth, (GLsizei)pTexture->mTextureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, pData);
353  }
354  }
355 
356  delete[] pData;
357  delete[] pRow_pointers;
358  }
359  }
360  }
361 
362  // delete the png structures again
363  png_destroy_read_struct(&png_ptr, (png_infopp)&info_ptr, (png_infopp)&end_info);
364  }
365  }
366  }
367 
368  return pTexture;
369 }
#define GL_CLAMP_TO_EDGE
Definition: glext.h:95
double mTextureWidth
double mTextureHeight
unsigned int mNumComponents
CLTextureSpec * CLSimpleImageTexturizer::operator() ( const std::string &  filename,
const std::string &  basedir 
)
virtual

Implements CLImageTexturizer.

Definition at line 16 of file CLSimpleImageTexturizer.cpp.

References create_texture_for_image().

17 {
18  return this->create_texture_for_image(filename, basedir);
19 }
CLTextureSpec * create_texture_for_image(const std::string &filename, const std::string &basedir)

The documentation for this class was generated from the following files: