Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/importer/texture.cc @ 3365

Last change on this file since 3365 was 3365, checked in by bensch, 19 years ago

orxonox/trunk: merged branches/parenting back to the.
merged with command:
svn merge branches/parenting trunk -r 3247:HEAD
resolved all conflicts in favor of parenting.

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