Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/importer/texture.cc @ 3622

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

orxonox/trunk: small patch to enable/disable textures with one single switch: GraphicsEngine::textureEnabled

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