Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moved protoclass to folder proto
added protosingleton
added resourceManager
modiefied some stuff to work better

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