Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: updated debug.h: now possibility to log per module (compile-time)

  1. write in the cc-file at the beginnig !!BEFORE ANY INCLUDES!!

#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_[MODULENAME]
where [MODULNAME] is a name of a module that can be defined in debug.h

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