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