Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/branches/parenting: :texture.cc: swapping textures-cordinates

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