Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 3455 was 3454, checked in by bensch, 20 years ago

orxonox/trunk/importer: doxygen-tags

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