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