Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/parenting/src/importer/texture.cc @ 3341

Last change on this file since 3341 was 3341, checked in by bensch, 21 years ago

orxonox/branches/parentin: :importer: added missing files

File size: 23.3 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15   TGA-code: borrowed from nehe-Tutorials
16
17*/
18
19
20#include "texture.h"
21
22// headers only for PathList
23#include <unistd.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <stdlib.h>
27#include <fstream>
28
29/**
30   \brief creates a ned PathList.
31   
32   It is a good idea to use this as an initial List,
33   because if you give on a name the Path will not be checked for its existence.
34*/
35PathList::PathList()
36{
37  this->pathName = NULL;
38  this->next = NULL;
39}
40
41/**
42   \brief Creates a new PathList with a Name.
43   \param pName the Name of The Path.
44
45   This function just adds the Path without checking if it exists.
46*/
47PathList::PathList(char* pName)
48{
49  this->pathName = new char [strlen(pName)+1];
50  strcpy (this->pathName, pName);
51  this->next = NULL;
52}
53
54/**
55   \brief destroys a PathList
56
57   It does this by deleting the Name and then delete its preceding PathList.
58*/
59PathList::~PathList()
60{
61  if (this->pathName)
62    delete []this->pathName;
63  if (this->next)
64    delete this->next;
65}
66
67PathList* PathList::firstPath = NULL;
68
69/**
70   \returns A Pointer to the first Path of the Pathlist
71*/
72PathList* PathList::getInstance(void)
73{
74  if (firstPath)
75    return firstPath;
76  firstPath = new PathList();
77}
78/**
79   \brief Adds a new Pathlist Element.
80   \param pName
81   
82   Adding a Path automatically checks if the Path exists,
83   and if it does not it will not add it to the List.
84*/
85void PathList::addPath (char* pName)
86{
87  if (pName[0] == '\0')
88    {
89      PRINTF(3)("not Adding empty Path to the List.\n");
90      return;
91    }
92  char* tmpPName = new char[strlen(pName)];
93  strncpy(tmpPName, pName, strlen(pName)-1);
94  tmpPName[strlen(pName)-1] = '\0';
95  if (access (tmpPName, F_OK) == 0)
96    {
97      struct stat status;
98      stat(tmpPName, &status);
99      if (status.st_mode & S_IFDIR)
100        {
101          PRINTF(2)("Adding Path %s to the PathList.\n", pName);
102          PathList* tmpPathList = this;
103          while (tmpPathList->next)
104            tmpPathList = tmpPathList->next;
105          tmpPathList->next = new PathList(pName);
106        }
107      else
108        PRINTF(2)("You tried to add non-folder %s to a PathList.\n", tmpPName);
109    }
110  else
111      PRINTF(2)("You tried to add non-existing folder %s to a PathList.\n", tmpPName);
112  delete []tmpPName;
113}
114
115
116/**
117   \brief Searches for a Texture inside one of the defined Paths
118   \param texName The name of the texture o search for.
119   \returns pathName+texName if texName was found in the pathList. NULL if the Texture is not found.
120*/
121char* Texture::searchTextureInPaths(char* texName) const
122{
123  char* tmpName = NULL;
124  PathList* pList = PathList::getInstance();
125  while (pList)
126    {
127      if (pList->pathName)
128        {
129          tmpName = new char [strlen(pList->pathName)+strlen(texName)+1];
130          strcpy(tmpName, pList->pathName);
131        }
132      else
133        {
134          tmpName = new char [strlen(texName)+1];
135          tmpName[0]='\0';
136        }
137      strcat(tmpName, texName);
138      if (access (tmpName, F_OK) == 0)
139        return tmpName;
140     
141      if (tmpName)
142        delete []tmpName;
143      tmpName = NULL;
144      pList = pList->next;
145    }
146  return NULL;
147}
148
149/**
150   \brief Loads a Texture to the openGL-environment.
151   \param pImage The Image to load to openGL
152   \param texture The Texture to apply it to.
153*/
154bool Texture::loadTexToGL (Image* pImage, GLuint* texture)
155{
156  PRINTF(2)("Loading texture to OpenGL-Environment.\n");
157  glGenTextures(1, texture);
158  glBindTexture(GL_TEXTURE_2D, *texture);
159  /* not Working, and not needed.
160  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
161                height, 0, GL_BGR,
162                GL_UNSIGNED_BYTE, map->pixels );
163  */ 
164  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
165 
166  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
167  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
168}
169
170
171#ifdef HAVE_SDL_SDL_IMAGE_H
172bool Texture::loadImage(char* imageName, GLuint* texture)
173{
174  char* imgNameWithPath = searchTextureInPaths(imageName);
175  if (imgNameWithPath)
176    {
177      SDL_Surface* map;
178      Image* pImage = new Image;
179      map=IMG_Load(imgNameWithPath);
180      if(!map)
181        {
182          PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
183          return false;
184        }
185      pImage->height = map->h;
186      pImage->width  = map->w;
187      pImage->data   = (GLubyte*)map->pixels;
188      if( !IMG_isPNG(SDL_RWFromFile(imgNameWithPath, "rb")) && !IMG_isJPG(SDL_RWFromFile(imgNameWithPath, "rb")))
189        for (int i=0;i<map->h * map->w *3;i+=3)
190          { 
191            GLuint temp = pImage->data[i];
192            pImage->data[i] = pImage->data[i+2];
193            pImage->data[i+2] = temp;
194          }
195      this->loadTexToGL (pImage, texture);
196    }
197  else
198    {
199      PRINTF(1)("Image not Found: %s\n", imgNameWithPath);
200      return false;
201    }
202}
203
204
205#else /* HAVE_SDL_SDL_IMAGE_H */
206/**
207   \brief Makes the Programm ready to Read-in a texture-File
208   1. Checks what type of Image should be imported
209   2. ToDO: Checks where to find the Image
210*/
211bool Texture::loadImage(char* imageName, GLuint* texture)
212{
213  char* imgNameWithPath = searchTextureInPaths(imageName);
214  if (imgNameWithPath)
215    {
216      if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".bmp", 4))
217        {
218          PRINTF(3)("Requested bmp-image. Trying to Import.\n");
219          return this->loadBMP(imgNameWithPath, texture);
220        }
221     
222      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".jpg", 4) || !strncmp(imgNameWithPath+strlen(imgNameWithPath)-5, ".jpg", 5))
223        {
224          PRINTF(3)("Requested jpeg-image. Trying to Import\n");
225          return this->loadJPG(imgNameWithPath, texture);
226        }
227      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".tga", 4))
228        {
229          PRINTF(3)("Requested tga-image. Trying to Import\n");
230          return this->loadTGA(imgNameWithPath, texture);
231        }
232      else if (!strncmp(imgNameWithPath+strlen(imgNameWithPath)-4, ".png", 4))
233        {
234          PRINTF(3)("Requested png-image. Trying to Import\n");
235          return this->loadPNG(imgNameWithPath, texture);
236        }
237      else
238        {
239          PRINTF(1)("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imgNameWithPath);
240          return false;
241        }
242    }
243  else
244    {
245      PRINTF(1)("Image not Found: %s\n", imgNameWithPath);
246      return false;
247    }
248}
249
250/**
251   \brief reads in a Windows BMP-file, and imports it to openGL.
252   \param bmpName The name of the Image to load.
253   \param texture A pointer to the Texture which should be read to.
254*/
255bool Texture::loadBMP (char* bmpName, GLuint* texture)
256{
257  Image* pImage = new Image;
258  FILE *file;
259  unsigned long size;                 // size of the image in bytes.
260  unsigned long i;                    // standard counter.
261  unsigned short int planes;          // number of planes in image (must be 1)
262  unsigned short int bpp;             // number of bits per pixel (must be 24)
263  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
264
265  // make sure the file is there.
266  if ((file = fopen(bmpName, "rb"))==NULL)
267    {
268      PRINTF(1)("File Not Found : %s\n",bmpName);
269      return false;
270    }
271  // seek through the bmp header, up to the width/height:
272  fseek(file, 18, SEEK_CUR);
273 
274  // read the width
275  if ((i = fread(&pImage->width, 4, 1, file)) != 1) 
276    {
277      PRINTF(1)("Error reading width from %s.\n", bmpName);
278      return false;
279    }
280  // read the height
281  if ((i = fread(&pImage->height, 4, 1, file)) != 1) 
282    {
283      PRINTF(1)("Error reading height from %s.\n", bmpName);
284      return false;
285    }
286 
287  // calculate the size (assuming 24 bits or 3 bytes per pixel).
288  size = pImage->width * pImage->height * 3;
289 
290  // read the planes
291  if ((fread(&planes, 2, 1, file)) != 1) 
292    {
293      PRINTF(1)("Error reading planes from %s.\n", bmpName);
294      return false;
295    }
296  if (planes != 1) 
297    {
298      PRINTF(1)("Planes from %s is not 1: %u\n", bmpName, planes);
299      return false;
300    }
301 
302  // read the bpp
303  if ((i = fread(&bpp, 2, 1, file)) != 1) 
304    {
305      PRINTF(1)("Error reading bpp from %s.\n", bmpName);
306      return false;
307    }
308  if (bpp != 24) 
309    {
310      PRINTF(1)("Bpp from %s is not 24: %u\n", bmpName, bpp);
311      return false;
312    }
313 
314  // seek past the rest of the bitmap header.
315  fseek(file, 24, SEEK_CUR);
316 
317  // read the data.
318  pImage->data = (GLubyte *) malloc(size);
319  if (pImage->data == NULL) 
320    {
321      PRINTF(1)("Error allocating memory for color-corrected image data");
322      return false;     
323    }
324 
325  if ((i = fread(pImage->data, size, 1, file)) != 1) 
326    {
327      PRINTF(1)("Error reading image data from %s.\n", bmpName);
328      return false;
329    }
330  fclose(file);
331
332  // reverse all of the colors. (bgr -> rgb)
333  for (i=0;i<size;i+=3) 
334    { 
335      temp = pImage->data[i];
336      pImage->data[i] = pImage->data[i+2];
337      pImage->data[i+2] = temp;
338    }
339  this->loadTexToGL (pImage, texture);
340 
341
342  if (pImage)
343    {
344      if (pImage->data)
345        {
346          free(pImage->data);
347        }
348     
349      free(pImage);
350    }
351  return true;
352
353}
354
355/**
356   \brief reads in a jpg-file
357   \param jpgName the Name of the Image to load
358   \param texture a reference to the Texture to write the image to
359*/
360bool Texture::loadJPG (char* jpgName, GLuint* texture)
361{
362#ifdef HAVE_JPEGLIB_H
363  struct jpeg_decompress_struct cinfo;
364  Image *pImage = NULL;
365  FILE *pFile;
366 
367  // Open a file pointer to the jpeg file and check if it was found and opened
368  if((pFile = fopen(jpgName, "rb")) == NULL) 
369    {
370      // Display an error message saying the file was not found, then return NULL
371      PRINTF(1)("Unable to load JPG File %s.\n", jpgName);
372      return false;
373    }
374 
375  // Create an error handler
376  jpeg_error_mgr jerr;
377 
378  // Have our compression info object point to the error handler address
379  cinfo.err = jpeg_std_error(&jerr);
380 
381  // Initialize the decompression object
382  jpeg_create_decompress(&cinfo);
383 
384  // Specify the data source (Our file pointer)
385  jpeg_stdio_src(&cinfo, pFile);
386 
387  // Allocate the structure that will hold our eventual jpeg data (must free it!)
388  pImage = (Image*)malloc(sizeof(Image));
389 
390  // DECOFING
391  // Read in the header of the jpeg file
392  jpeg_read_header(&cinfo, TRUE);
393 
394  // Start to decompress the jpeg file with our compression info
395  jpeg_start_decompress(&cinfo);
396 
397  // Get the image dimensions and row span to read in the pixel data
398  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
399  pImage->width   = cinfo.image_width;
400  pImage->height   = cinfo.image_height;
401 
402  // Allocate memory for the pixel buffer
403  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
404 
405  // Here we use the library's state variable cinfo.output_scanline as the
406  // loop counter, so that we don't have to keep track ourselves.
407 
408  // Create an array of row pointers
409  unsigned char** rowPtr = new unsigned char*[pImage->height];
410  for (int i = 0; i < pImage->height; i++)
411    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
412 
413  // Now comes the juice of our work, here we extract all the pixel data
414  int rowsRead = 0;
415  while (cinfo.output_scanline < cinfo.output_height) 
416    {
417      // Read in the current row of pixels and increase the rowsRead count
418      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
419    }
420 
421  // Delete the temporary row pointers
422  delete [] rowPtr;
423 
424  // Finish decompressing the data
425  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
426 
427  // This releases all the stored memory for reading and decoding the jpeg
428  jpeg_destroy_decompress(&cinfo);
429 
430  // Close the file pointer that opened the file
431  fclose(pFile);
432 
433
434  if(pImage == NULL)
435    exit(0);
436 
437  this->loadTexToGL (pImage, texture);
438  if (pImage)
439    {
440      if (pImage->data)
441        {
442          free(pImage->data);
443        }
444     
445      free(pImage);
446    }
447  return true;
448#else /* HAVE_JPEGLIB_H */
449  PRINTF(1)("sorry, but you did not compile with jpeg-support.\nEither install SDL_image or jpeglib, and recompile to see the image\n");
450  return false;
451#endif /* HAVE_JPEGLIB_H */
452
453}
454
455/**
456   \brief reads in a tga-file
457   \param tgaName the Name of the Image to load
458   \param texture a reference to the Texture to write the image to
459*/
460bool Texture::loadTGA(const char * tgaName, GLuint* texture)
461{
462  typedef struct
463  {
464    GLubyte Header[12];
465  } TGAHeader;
466  TGAHeader tgaHeader;                 
467 
468  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
469  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; // Compressed TGA Header
470  FILE * fTGA;
471  fTGA = fopen(tgaName, "rb");
472
473  if(fTGA == NULL)
474    {
475      PRINTF(1)("Error could not open texture file: %s\n", tgaName);
476      return false;
477    }
478 
479  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0)
480    {
481      PRINTF(1)("Error could not read file header of %s\n", tgaName);
482      if(fTGA != NULL)
483        {
484          fclose(fTGA);
485        }
486      return false;
487    }
488 
489  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
490    {
491      loadUncompressedTGA(tgaName, fTGA, texture);
492      if (fTGA)
493        fclose (fTGA);
494    }
495  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
496    {
497      loadCompressedTGA(tgaName, fTGA, texture);
498        if (fTGA)
499          fclose (fTGA);
500    }
501  else
502    {
503      PRINTF(1)("Error TGA file be type 2 or type 10\n");
504      if (fTGA)
505        fclose(fTGA);
506      return false;
507    }
508  return true;
509}
510
511/**
512   \brief reads in an uncompressed tga-file
513   \param filename the Name of the Image to load
514   \param fTGA a Pointer to a File, that should be read
515   \param texture a reference to the Texture to write the image to
516*/
517bool Texture::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
518{
519  GLubyte header[6];      // First 6 Useful Bytes From The Header
520  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
521  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
522  GLuint  temp;           // Temporary Variable
523  GLuint  type;
524  GLuint  Height;         // Height of Image
525  GLuint  Width;          // Width of Image
526  GLuint  Bpp;            // Bits Per Pixel
527
528  Image* pImage = new Image;
529  GLuint cswap;
530  if(fread(header, sizeof(header), 1, fTGA) == 0)
531    {
532      PRINTF(1)("Error could not read info header\n");
533      return false;
534    }
535 
536  Width = pImage->width  = header[1] * 256 + header[0];
537  Height =  pImage->height = header[3] * 256 + header[2];
538  Bpp = pImage->bpp = header[4];
539  // Make sure all information is valid
540  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
541    {
542      PRINTF(1)("Error invalid texture information\n");
543      return false;
544    }
545 
546  if(pImage->bpp == 24) 
547    {
548      pImage->type = GL_RGB;
549    }
550  else
551    {
552      pImage->type = GL_RGBA;
553    }
554 
555  bytesPerPixel = (Bpp / 8);
556  imageSize = (bytesPerPixel * Width * Height);
557  pImage->data = (GLubyte*) malloc(imageSize);
558 
559  if(pImage->data == NULL)
560    {
561      PRINTF(1)("Error could not allocate memory for image\n");
562      return false;
563    }
564 
565  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
566    {
567      PRINTF(1)("Error could not read image data\n");
568      if(pImage->data != NULL)
569        {
570          free(pImage->data);
571        }
572      return false;
573    }
574 
575  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
576    {
577      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
578        pImage->data[cswap] ^= pImage->data[cswap+2];
579    }
580 
581  this->loadTexToGL (pImage, texture);
582
583  return true;
584}
585
586/**
587   \brief reads in a compressed tga-file
588   \param filename the Name of the Image to load
589   \param fTGA a Pointer to a File, that should be read
590   \param texture a reference to the Texture to write the image to
591*/
592bool Texture::loadCompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
593{
594  GLubyte header[6];      // First 6 Useful Bytes From The Header
595  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
596  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
597  GLuint  temp;           // Temporary Variable
598  GLuint  type;
599  GLuint  Height;         // Height of Image
600  GLuint  Width;          // Width of Image
601  GLuint  Bpp;            // Bits Per Pixel
602
603  Image* pImage = new Image;
604
605 
606  if(fread(header, sizeof(header), 1, fTGA) == 0)
607    {
608      PRINTF(1)("Error could not read info header\n");
609      return false;
610    }
611 
612  Width = pImage->width  = header[1] * 256 + header[0];
613  Height = pImage->height = header[3] * 256 + header[2];
614  Bpp = pImage->bpp     = header[4];
615
616  GLuint pixelcount     = Height * Width;
617  GLuint currentpixel   = 0;
618  GLuint currentbyte    = 0;
619  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);
620
621  //Make sure all pImage info is ok
622  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
623    {
624      PRINTF(1)("Error Invalid pImage information\n");
625      return false;
626    }
627 
628  bytesPerPixel = (Bpp / 8);
629  imageSize             = (bytesPerPixel * Width * Height);
630  pImage->data  = (GLubyte*) malloc(imageSize);
631 
632  if(pImage->data == NULL)
633    {
634      PRINTF(1)("Error could not allocate memory for image\n");
635      return false;
636    }
637 
638  do
639    {
640      GLubyte chunkheader = 0;
641     
642      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
643        {
644          PRINTF(1)("Error could not read RLE header\n");
645          if(pImage->data != NULL)
646            {
647              free(pImage->data);
648            }
649          return false;
650        }
651      // If the ehader is < 128, it means the that is the number of RAW color packets minus 1
652      if(chunkheader < 128)
653        {
654          short counter;
655          chunkheader++;
656          // Read RAW color values
657          for(counter = 0; counter < chunkheader; counter++)
658            { 
659              // Try to read 1 pixel
660              if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)
661                {
662                  PRINTF(1)("Error could not read image data\n");
663                  if(colorbuffer != NULL)
664                    {
665                      free(colorbuffer);
666                    }
667                 
668                  if(pImage->data != NULL)
669                    {
670                      free(pImage->data);
671                    }
672                 
673                  return false; 
674                }
675              // write to memory
676              // Flip R and B vcolor values around in the process
677              pImage->data[currentbyte    ] = colorbuffer[2];                               
678              pImage->data[currentbyte + 1] = colorbuffer[1];
679              pImage->data[currentbyte + 2] = colorbuffer[0];
680             
681              if(bytesPerPixel == 4) // if its a 32 bpp image
682                {
683                  pImage->data[currentbyte + 3] = colorbuffer[3];// copy the 4th byte
684                }
685             
686              currentbyte += bytesPerPixel;
687              currentpixel++;
688
689              // Make sure we haven't read too many pixels
690              if(currentpixel > pixelcount)     
691                {
692                  PRINTF(1)("Error too many pixels read\n");
693                  if(colorbuffer != NULL)
694                    {
695                      free(colorbuffer);
696                    }
697                 
698                  if(pImage->data != NULL)
699                    {
700                      free(pImage->data);
701                    }
702                 
703                  return false;
704                }
705            }
706        }
707      // chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times
708      else
709        {
710          short counter;
711          chunkheader -= 127;   // Subteact 127 to get rid of the ID bit
712          if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) // Attempt to read following color values
713            {
714              PRINTF(1)("Error could not read from file");
715              if(colorbuffer != NULL)
716                {
717                  free(colorbuffer);
718                }
719             
720              if(pImage->data != NULL)
721                {
722                  free(pImage->data);
723                }
724             
725              return false;
726            }
727         
728          for(counter = 0; counter < chunkheader; counter++) //copy the color into the image data as many times as dictated
729            {                                                   
730              // switch R and B bytes areound while copying
731              pImage->data[currentbyte    ] = colorbuffer[2];
732              pImage->data[currentbyte + 1] = colorbuffer[1];
733              pImage->data[currentbyte + 2] = colorbuffer[0];
734             
735              if(bytesPerPixel == 4)
736                {
737                  pImage->data[currentbyte + 3] = colorbuffer[3];
738                }
739             
740              currentbyte += bytesPerPixel;
741              currentpixel++;
742             
743              if(currentpixel > pixelcount)
744                {
745                  PRINTF(1)("Error too many pixels read\n");
746                  if(colorbuffer != NULL)
747                    {
748                      free(colorbuffer);
749                    }
750                 
751                  if(pImage->data != NULL)
752                    {
753                      free(pImage->data);
754                    }
755                 
756                  return false;
757                }
758            }
759        }
760    }
761 
762  while(currentpixel < pixelcount);     // Loop while there are still pixels left
763
764  this->loadTexToGL (pImage, texture);
765
766  return true;
767}
768
769
770/*
771static int ST_is_power_of_two(unsigned int number)
772{
773  return (number & (number - 1)) == 0;
774}
775*/
776
777/**
778   \brief reads in a png-file
779   \param pngName the Name of the Image to load
780   \param texture a reference to the Texture to write the image to
781*/
782bool Texture::loadPNG(const char* pngName, GLuint* texture)
783{
784#ifdef HAVE_PNG_H
785  Image* pImage = new Image;
786
787  FILE *PNG_file = fopen(pngName, "rb");
788  if (PNG_file == NULL)
789    {
790      return 0;
791    }
792 
793  GLubyte PNG_header[8];
794 
795  fread(PNG_header, 1, 8, PNG_file);
796  if (png_sig_cmp(PNG_header, 0, 8) != 0)
797    {
798      PRINTF(2)("Not Recognized as a pngFile\n");
799      fclose (PNG_file);
800      return 0;
801    }
802 
803  png_structp PNG_reader = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
804  if (PNG_reader == NULL)
805    {
806      fclose(PNG_file);
807      return 0;
808    }
809 
810  png_infop PNG_info = png_create_info_struct(PNG_reader);
811  if (PNG_info == NULL)
812    {
813      png_destroy_read_struct(&PNG_reader, NULL, NULL);
814      fclose(PNG_file);
815      return 0;
816    }
817 
818  png_infop PNG_end_info = png_create_info_struct(PNG_reader);
819  if (PNG_end_info == NULL)
820    {
821      png_destroy_read_struct(&PNG_reader, &PNG_info, NULL);
822      fclose(PNG_file);
823      return 0;
824    }
825 
826  if (setjmp(png_jmpbuf(PNG_reader)))
827    {
828      png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
829      fclose(PNG_file);
830      return (0);
831    }
832 
833  png_init_io(PNG_reader, PNG_file);
834  png_set_sig_bytes(PNG_reader, 8);
835 
836  png_read_info(PNG_reader, PNG_info);
837 
838  pImage->width = png_get_image_width(PNG_reader, PNG_info);
839  pImage->height = png_get_image_height(PNG_reader, PNG_info);
840 
841  png_uint_32 bit_depth, color_type;
842  bit_depth = png_get_bit_depth(PNG_reader, PNG_info);
843  color_type = png_get_color_type(PNG_reader, PNG_info);
844 
845  if (color_type == PNG_COLOR_TYPE_PALETTE)
846    {
847      png_set_palette_to_rgb(PNG_reader);
848    }
849 
850  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
851    {
852      png_set_gray_1_2_4_to_8(PNG_reader);
853    }
854 
855  if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
856    {
857      png_set_gray_to_rgb(PNG_reader);
858    }
859 
860  if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS))
861    {
862      png_set_tRNS_to_alpha(PNG_reader);
863    }
864  else
865    {
866      png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER);
867    }
868 
869  if (bit_depth == 16)
870    {
871      png_set_strip_16(PNG_reader);
872    }
873 
874  png_read_update_info(PNG_reader, PNG_info);
875 
876  pImage->data = (png_byte*)malloc(4 * pImage->width * pImage->height);
877  png_byte** PNG_rows = (png_byte**)malloc(pImage->height * sizeof(png_byte*));
878 
879  unsigned int row;
880  for (row = 0; row < pImage->height; ++row)
881    {
882      PNG_rows[pImage->height - 1 - row] = pImage->data + (row * 4 * pImage->width);
883    }
884 
885  png_read_image(PNG_reader, PNG_rows);
886 
887  free(PNG_rows);
888 
889  png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
890  fclose(PNG_file);
891 
892  /*  if (!ST_is_power_of_two(pImage->width) || !ST_is_power_of_two(pImage->height))
893    {
894      free(pImage->data);
895      return 0;
896    }
897  */
898  this->loadTexToGL (pImage, texture); 
899 
900  free(pImage->data);
901 
902  return true;
903#else /* HAVE_PNG_H */
904  PRINTF(1)("sorry, but you did not compile with png-support.\nEither install SDL_image or libpng, and recompile to see the image\n");
905  return false;
906#endif /* HAVE_PNG_H */
907
908}
909#endif /* HAVE_SDL_SDL_IMAGE_H */
Note: See TracBrowser for help on using the repository browser.