Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/images/importer/material.cc @ 3095

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

orxonox/branches/images: jpeg made to one function, the function was really not used as a function, but as a gosub→return

File size: 25.3 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#include "material.h"
19
20/**
21   \brief creates a default Material with no Name
22   normally you call this to create a material List (for an obj-file) and then append with addMaterial()
23*/
24Material::Material()
25{
26  init();
27 
28  setName ("");
29}
30
31/**
32   \brief creates a Material.
33   \param mtlName Name of the Material to be added to the Material List
34*/
35Material::Material (char* mtlName)
36{
37  init();
38 
39  setName (mtlName);
40}
41
42/**
43    \brief deletes a Material
44*/
45Material::~Material()
46{
47  if (name)
48    delete []name;
49  if (diffuseTextureSet)
50    glDeleteTextures (1, &diffuseTexture);
51  if (verbose >= 2)
52    printf ("delete Material %s.\n", name);
53  if (nextMat != NULL)
54    delete nextMat;
55}
56
57/**
58   \brief adds a new Material to the List.
59   this Function will append a new Material to the end of a Material List.
60   \param mtlName The name of the Material to be added.
61*/
62Material* Material::addMaterial(char* mtlName)
63{
64  if (verbose >=2)
65    printf ("adding Material %s.\n", mtlName);
66  Material* newMat = new Material(mtlName);
67  Material* tmpMat = this;
68  while (tmpMat->nextMat != NULL)
69    {
70      tmpMat = tmpMat->nextMat;
71    }
72  tmpMat->nextMat = newMat;
73  return newMat;
74 
75}
76
77/**
78   \brief initializes a new Material with its default Values
79*/
80void Material::init(void)
81{
82  if (verbose >= 3)
83    printf ("initializing new Material.\n");
84  nextMat = NULL;
85
86  setIllum(1);
87  setDiffuse(0,0,0);
88  setAmbient(0,0,0);
89  setSpecular(.5,.5,.5);
90  setShininess(2.0);
91  setTransparency(0.0);
92
93  diffuseTextureSet = false;
94  ambientTextureSet = false;
95  specularTextureSet = false;
96
97 
98}
99
100/**
101   \brief Search for a Material called mtlName
102   \param mtlName the Name of the Material to search for
103   \returns Material named mtlName if it is found. NULL otherwise.
104*/
105Material* Material::search (char* mtlName)
106{
107  if (verbose >=3)
108    printf ("Searching for material %s", mtlName);
109  Material* searcher = this;
110  while (searcher != NULL)
111    {
112      if (verbose >= 3)
113        printf (".");
114      if (!strcmp (searcher->getName(), mtlName))
115        {
116          if (verbose >= 3)
117            printf ("found.\n");
118          return searcher;
119        }
120      searcher = searcher->nextMat;
121    }
122  if (verbose >=3)
123    printf ("not found\n");
124  return NULL;
125}
126
127/**
128   \brief sets the material with which the following Faces will be painted
129*/
130bool Material::select (void)
131{
132  // setting diffuse color
133  //  glColor3f (diffuse[0], diffuse[1], diffuse[2]);
134  glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
135
136  // setting ambient color
137  glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
138
139  // setting up Sprecular
140  glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
141
142  // setting up Shininess
143  glMaterialf(GL_FRONT, GL_SHININESS, shininess);
144 
145  // setting illumination Model
146  if (illumModel == 1)
147    glShadeModel(GL_FLAT);
148  else if (illumModel >= 2)
149    glShadeModel(GL_SMOOTH);
150
151  if (diffuseTextureSet)
152    glBindTexture(GL_TEXTURE_2D, diffuseTexture);
153  else
154    glBindTexture(GL_TEXTURE_2D, 0);
155 
156}
157
158
159/**
160   \brief Set the Name of the Material. (Important for searching)
161   \param mtlName the Name of the Material to be set.
162*/ 
163void Material::setName (char* mtlName)
164{
165  if (verbose >= 3)
166    printf("setting Material Name to %s.\n", mtlName);
167  name = new char [strlen(mtlName)];
168  strcpy(name, mtlName);
169  //  printf ("adding new Material: %s, %p\n", this->getName(), this);
170
171}
172/**
173   \returns The Name of The Material
174*/
175char* Material::getName (void)
176{
177  return name;
178}
179
180/**
181   \brief Sets the Material Illumination Model.
182   \brief illu illumination Model in int form
183*/
184void Material::setIllum (int illum)
185{
186  if (verbose >= 3)
187    printf("setting illumModel of Material %s to %i", name, illum);
188  illumModel = illum;
189  //  printf ("setting illumModel to: %i\n", illumModel);
190}
191/**
192   \brief Sets the Material Illumination Model.
193   \brief illu illumination Model in char* form
194*/void Material::setIllum (char* illum)
195{
196  setIllum (atoi(illum));
197}
198
199/**
200   \brief Sets the Material Diffuse Color.
201   \param r Red Color Channel.
202   \param g Green Color Channel.
203   \param b Blue Color Channel.
204*/
205void Material::setDiffuse (float r, float g, float b)
206{
207  if (verbose >= 3)
208    printf ("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
209  diffuse[0] = r;
210  diffuse[1] = g;
211  diffuse[2] = b; 
212  diffuse[3] = 1.0;
213
214}
215/**
216   \brief Sets the Material Diffuse Color.
217   \param rgb The red, green, blue channel in char format (with spaces between them)
218*/
219void Material::setDiffuse (char* rgb)
220{
221  char r[20],g[20],b[20];
222  sscanf (rgb, "%s %s %s", r, g, b);
223  setDiffuse (atof(r), atof(g), atof(b));
224}
225
226/**
227   \brief Sets the Material Ambient Color.
228   \param r Red Color Channel.
229   \param g Green Color Channel.
230   \param b Blue Color Channel.
231*/
232void Material::setAmbient (float r, float g, float b)
233{
234  if (verbose >=3)
235    printf ("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
236  ambient[0] = r;
237  ambient[1] = g;
238  ambient[2] = b;
239  ambient[3] = 1.0;
240}
241/**
242   \brief Sets the Material Ambient Color.
243   \param rgb The red, green, blue channel in char format (with spaces between them)
244*/
245void Material::setAmbient (char* rgb)
246{
247  char r[20],g[20],b[20];
248  sscanf (rgb, "%s %s %s", r, g, b);
249  setAmbient (atof(r), atof(g), atof(b));
250}
251
252/**
253   \brief Sets the Material Specular Color.
254   \param r Red Color Channel.
255   \param g Green Color Channel.
256   \param b Blue Color Channel.
257*/
258void Material::setSpecular (float r, float g, float b)
259{
260  if (verbose >= 3)
261    printf ("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", name, r, g, b);
262  specular[0] = r;
263  specular[1] = g;
264  specular[2] = b;
265  specular[3] = 1.0;
266 }
267/**
268   \brief Sets the Material Specular Color.
269   \param rgb The red, green, blue channel in char format (with spaces between them)
270*/
271void Material::setSpecular (char* rgb)
272{
273  char r[20],g[20],b[20];
274  sscanf (rgb, "%s %s %s", r, g, b);
275  setSpecular (atof(r), atof(g), atof(b));
276}
277
278/**
279   \brief Sets the Material Shininess.
280   \param shini stes the Shininess from float.
281*/
282void Material::setShininess (float shini)
283{
284  shininess = shini;
285}
286/**
287   \brief Sets the Material Shininess.
288   \param shini stes the Shininess from char*.
289*/
290void Material::setShininess (char* shini)
291{
292  setShininess (atof(shini));
293}
294
295/**
296   \brief Sets the Material Transparency.
297   \param trans stes the Transparency from int.
298*/
299void Material::setTransparency (float trans)
300{
301  if (verbose >= 3)
302    printf ("setting Transparency of Material %s to %f.\n", name, trans);
303  transparency = trans;
304}
305/**
306   \brief Sets the Material Transparency.
307   \param trans stes the Transparency from char*.
308*/
309void Material::setTransparency (char* trans)
310{
311  char tr[20];
312  sscanf (trans, "%s", tr);
313  setTransparency (atof(tr));
314}
315
316// MAPPING //
317
318/**
319   \brief Sets the Materials Diffuse Map
320   \param dMap the Name of the Image to Use
321*/
322void Material::setDiffuseMap(char* dMap)
323{
324  if (verbose>=2)
325    printf ("setting Diffuse Map %s\n", dMap);
326
327  //  diffuseTextureSet = loadBMP(dMap, &diffuseTexture);
328  diffuseTextureSet = loadImage(dMap, &diffuseTexture);
329
330}
331
332/**
333   \brief Sets the Materials Ambient Map
334   \param aMap the Name of the Image to Use
335*/
336void Material::setAmbientMap(char* aMap)
337{
338  SDL_Surface* ambientMap;
339
340}
341
342/**
343   \brief Sets the Materials Specular Map
344   \param sMap the Name of the Image to Use
345*/
346void Material::setSpecularMap(char* sMap)
347{
348  SDL_Surface* specularMap;
349
350}
351
352/**
353   \brief Sets the Materials Bumpiness
354   \param bump the Name of the Image to Use
355*/
356void Material::setBump(char* bump)
357{
358
359}
360
361bool Material::loadTexToGL (Image* pImage, GLuint* texture)
362{
363  glGenTextures(1, texture);
364  glBindTexture(GL_TEXTURE_2D, *texture);
365  /* not Working, and not needed.
366  glTexImage2D( GL_TEXTURE_2D, 0, 3, width,
367                height, 0, GL_BGR,
368                GL_UNSIGNED_BYTE, map->pixels );
369  */ 
370  gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pImage->width, pImage->height, GL_RGB, GL_UNSIGNED_BYTE, pImage->data);
371 
372  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
373  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); 
374}
375
376
377
378/**
379   \brief Makes the Programm ready to Read-in a texture-File
380   1. Checks what type of Image should be imported
381   2. ToDO: Checks where to find the Image
382*/
383bool Material::loadImage(char* imageName, GLuint* texture)
384{
385  if (!strncmp(imageName+strlen(imageName)-4, ".bmp", 4))
386    {
387      if (verbose >=2)
388        printf ("Requested bmp-image. Trying to Import.\n");
389      return loadBMP(imageName, texture);
390    }
391
392  else if (!strncmp(imageName+strlen(imageName)-4, ".jpg", 4) || !strncmp(imageName+strlen(imageName)-5, ".jpg", 5))
393    {
394      if (verbose >=2)
395        printf ("Requested jpeg-image. Trying to Import\n");
396      return loadJPG(imageName, texture);
397    }
398  else if (!strncmp(imageName+strlen(imageName)-4, ".tga", 4))
399    {
400      if (verbose >=2)
401        printf ("Requested tga-image. Trying to Import\n");
402      return loadTGA(imageName, texture);
403    }
404  else
405    {
406      if (verbose >=1)
407        printf ("Requested Image was not recognized in its type. (Maybe a type-Cast-error.)\n FileName: %s", imageName);
408      return false;
409    }
410
411}
412
413/**
414   \brief reads in a Windows BMP-file, and imports it to openGL.
415   \param bmpName The name of the Image to load.
416   \param texture A pointer to the Texture which should be read to.
417*/
418bool Material::loadBMP (char* bmpName, GLuint* texture)
419{
420  Image* pImage = new Image;
421  FILE *file;
422  unsigned long size;                 // size of the image in bytes.
423  unsigned long i;                    // standard counter.
424  unsigned short int planes;          // number of planes in image (must be 1)
425  unsigned short int bpp;             // number of bits per pixel (must be 24)
426  GLuint temp;                          // temporary color storage for bgr-rgb conversion.
427
428  // make sure the file is there.
429  if ((file = fopen(bmpName, "rb"))==NULL)
430    {
431      if (verbose >=1)
432        printf("File Not Found : %s\n",bmpName);
433      return false;
434    }
435  // seek through the bmp header, up to the width/height:
436  fseek(file, 18, SEEK_CUR);
437 
438  // read the width
439  if ((i = fread(&pImage->width, 4, 1, file)) != 1) 
440    {
441      if (verbose >=1)
442        printf("Error reading width from %s.\n", bmpName);
443      return false;
444    }
445  // read the height
446  if ((i = fread(&pImage->height, 4, 1, file)) != 1) 
447    {
448      if (verbose>=1)
449        printf("Error reading height from %s.\n", bmpName);
450      return false;
451    }
452 
453  // calculate the size (assuming 24 bits or 3 bytes per pixel).
454  size = pImage->width * pImage->height * 3;
455 
456  // read the planes
457  if ((fread(&planes, 2, 1, file)) != 1) 
458    {
459      if (verbose>=1)
460        printf("Error reading planes from %s.\n", bmpName);
461      return false;
462    }
463  if (planes != 1) 
464    {
465      if (verbose>=1)
466        printf("Planes from %s is not 1: %u\n", bmpName, planes);
467      return false;
468    }
469 
470  // read the bpp
471  if ((i = fread(&bpp, 2, 1, file)) != 1) 
472    {
473      if (verbose>=1)
474        printf("Error reading bpp from %s.\n", bmpName);
475      return false;
476    }
477  if (bpp != 24) 
478    {
479      if (verbose>=1)
480        printf("Bpp from %s is not 24: %u\n", bmpName, bpp);
481      return false;
482    }
483 
484  // seek past the rest of the bitmap header.
485  fseek(file, 24, SEEK_CUR);
486 
487  // read the data.
488  pImage->data = (GLubyte *) malloc(size);
489  if (pImage->data == NULL) 
490    {
491      if (verbose>=1)
492        printf("Error allocating memory for color-corrected image data");
493      return false;     
494    }
495 
496  if ((i = fread(pImage->data, size, 1, file)) != 1) 
497    {
498      if (verbose>=1)
499        printf("Error reading image data from %s.\n", bmpName);
500      return false;
501    }
502  fclose(file);
503
504  // reverse all of the colors. (bgr -> rgb)
505  for (i=0;i<size;i+=3) 
506    { 
507      temp = pImage->data[i];
508      pImage->data[i] = pImage->data[i+2];
509      pImage->data[i+2] = temp;
510    }
511  loadTexToGL (pImage, texture);
512 
513  return true;
514
515  if (pImage)
516    {
517      if (pImage->data)
518        {
519          free(pImage->data);
520        }
521     
522      free(pImage);
523    }
524
525}
526
527bool Material::loadJPG (char* jpgName, GLuint* texture)
528{
529  struct jpeg_decompress_struct cinfo;
530  Image *pImage = NULL;
531  FILE *pFile;
532 
533  // Open a file pointer to the jpeg file and check if it was found and opened
534  if((pFile = fopen(jpgName, "rb")) == NULL) 
535    {
536      // Display an error message saying the file was not found, then return NULL
537      printf("Unable to load JPG File %s.\n", jpgName);
538      return false;
539    }
540 
541  // Create an error handler
542  jpeg_error_mgr jerr;
543 
544  // Have our compression info object point to the error handler address
545  cinfo.err = jpeg_std_error(&jerr);
546 
547  // Initialize the decompression object
548  jpeg_create_decompress(&cinfo);
549 
550  // Specify the data source (Our file pointer)
551  jpeg_stdio_src(&cinfo, pFile);
552 
553  // Allocate the structure that will hold our eventual jpeg data (must free it!)
554  pImage = (Image*)malloc(sizeof(Image));
555 
556  // DECOFING
557  // Read in the header of the jpeg file
558  jpeg_read_header(&cinfo, TRUE);
559 
560  // Start to decompress the jpeg file with our compression info
561  jpeg_start_decompress(&cinfo);
562 
563  // Get the image dimensions and row span to read in the pixel data
564  pImage->rowSpan = cinfo.image_width * cinfo.num_components;
565  pImage->width   = cinfo.image_width;
566  pImage->height   = cinfo.image_height;
567 
568  // Allocate memory for the pixel buffer
569  pImage->data = new unsigned char[pImage->rowSpan * pImage->height];
570 
571  // Here we use the library's state variable cinfo.output_scanline as the
572  // loop counter, so that we don't have to keep track ourselves.
573 
574  // Create an array of row pointers
575  unsigned char** rowPtr = new unsigned char*[pImage->height];
576  for (int i = 0; i < pImage->height; i++)
577    rowPtr[i] = &(pImage->data[i*pImage->rowSpan]);
578 
579  // Now comes the juice of our work, here we extract all the pixel data
580  int rowsRead = 0;
581  while (cinfo.output_scanline < cinfo.output_height) 
582    {
583      // Read in the current row of pixels and increase the rowsRead count
584      rowsRead += jpeg_read_scanlines(&cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead);
585    }
586 
587  // Delete the temporary row pointers
588  delete [] rowPtr;
589 
590  // Finish decompressing the data
591  jpeg_finish_decompress(&cinfo);//  decodeJPG(&cinfo, pImage);
592 
593  // This releases all the stored memory for reading and decoding the jpeg
594  jpeg_destroy_decompress(&cinfo);
595 
596  // Close the file pointer that opened the file
597  fclose(pFile);
598 
599
600  if(pImage == NULL)
601    exit(0);
602 
603  loadTexToGL (pImage, texture);
604  if (pImage)
605    {
606      if (pImage->data)
607        {
608          free(pImage->data);
609        }
610     
611      free(pImage);
612    }
613  return true;
614}
615
616bool Material::loadTGA(const char * tgaName, GLuint* texture)
617{
618  typedef struct
619  {
620    GLubyte Header[12];                                                                 /* TGA File Header */
621  } TGAHeader;
622 TGAHeader tgaHeader;                   
623
624  GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; /* Uncompressed TGA Header */
625  GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; /* Compressed TGA Header */
626  FILE * fTGA;
627  fTGA = fopen(tgaName, "rb");
628
629  if(fTGA == NULL)
630    {
631      printf("Error could not open texture file: %s\n", tgaName);
632      return false;
633    }
634 
635  if(fread(&tgaHeader, sizeof(TGAHeader), 1, fTGA) == 0) /// hmm... don't know if this is io
636    {
637      printf("Error could not read file header of %s\n", tgaName);
638      if(fTGA != NULL)
639        {
640          fclose(fTGA);
641        }
642      return false;
643    }
644 
645  if(memcmp(uTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
646    {
647      loadUncompressedTGA(tgaName, fTGA, texture);
648      if (fTGA)
649        fclose (fTGA);
650    }
651  else if(memcmp(cTGAcompare, &tgaHeader, sizeof(TGAHeader)) == 0)
652    {
653      //loadCompressedTGA(tgaName, fTGA, texture);
654        if (fTGA)
655          fclose (fTGA);
656    }
657  else
658    {
659      printf("Error TGA file be type 2 or type 10\n");
660      if (fTGA)
661        fclose(fTGA);
662      return false;
663    }
664  return true;
665}
666
667bool Material::loadUncompressedTGA(const char * filename, FILE * fTGA, GLuint* texture)
668{
669  GLubyte header[6];      // First 6 Useful Bytes From The Header
670  GLuint  bytesPerPixel;  // Holds Number Of Bytes Per Pixel Used In The TGA File
671  GLuint  imageSize;      // Used To Store The Image Size When Setting Aside Ram
672  GLuint  temp;           // Temporary Variable
673  GLuint  type;
674  GLuint  Height;         // Height of Image
675  GLuint  Width;          // Width of Image
676  GLuint  Bpp;            // Bits Per Pixel
677
678  Image* pImage = new Image;
679  GLuint cswap;
680  if(fread(header, sizeof(header), 1, fTGA) == 0)
681    {
682      printf("Error could not read info header\n");
683      return false;
684    }
685 
686  Width = pImage->width  = header[1] * 256 + header[0];
687  Height =  pImage->height = header[3] * 256 + header[2];
688  Bpp = pImage->bpp = header[4];
689  // Make sure all information is valid
690  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))
691    {
692      printf("Error invalid texture information\n");
693      return false;
694    }
695 
696  if(pImage->bpp == 24) 
697    {
698      pImage->type = GL_RGB;
699    }
700  else
701    {
702      pImage->type = GL_RGBA;
703    }
704 
705  bytesPerPixel = (Bpp / 8);
706  imageSize = (bytesPerPixel * Width * Height);
707  pImage->data = (GLubyte*) malloc(imageSize);
708 
709  if(pImage->data == NULL)
710    {
711      printf("Error could not allocate memory for image\n");
712      return false;
713    }
714 
715  if(fread(pImage->data, 1, imageSize, fTGA) != imageSize)
716    {
717      printf("Error could not read image data\n");
718      if(pImage->data != NULL)
719        {
720          free(pImage->data);
721        }
722      return false;
723    }
724 
725  /* Byte Swapping Optimized By Steve Thomas */
726  for(cswap = 0; cswap < (int)imageSize; cswap += bytesPerPixel)
727    {
728      pImage->data[cswap] ^= pImage->data[cswap+2] ^=
729        pImage->data[cswap] ^= pImage->data[cswap+2];
730    }
731 
732  loadTexToGL (pImage, texture);
733
734  return true;
735}
736
737#ifdef __auskomentiert__
738bool Material::LoadCompressedTGA(Texture * texture,const char * filename, FILE * fTGA)
739{
740  GLuint pixelcount     = Height * Width;                                                       /* Nuber of pixels in the image */
741  GLuint currentpixel   = 0;                                                                                            /* Current pixel being read */
742  GLuint currentbyte    = 0;                                                                                            /* Current byte */
743  GLubyte * colorbuffer = (GLubyte *)malloc(bytesPerPixel);                     /* Storage for 1 pixel */
744 
745  if(fread(header, sizeof(header), 1, fTGA) == 0)                               /* Attempt to read header */
746    {
747      printf("Error could not read info header");                                                       /* Display Error */
748      if(fTGA != NULL)                                                                                                  /* If file is open */
749        {
750          fclose(fTGA);                                                                                                 /* Close it */
751        }
752      return false;                                                                                                             /* Return failed */
753    }
754 
755  pImage->width  = header[1] * 256 + header[0];                                 /* Determine The TGA Width      (highbyte*256+lowbyte) */
756  pImage->height = header[3] * 256 + header[2];                                 /* Determine The TGA Height     (highbyte*256+lowbyte) */
757  pImage->bpp   = header[4];                                                                            /* Determine Bits Per Pixel */
758  Width         = pImage->width;                                                                                /* Copy width to local structure */
759  Height                = pImage->height;                                                                               /* Copy width to local structure */
760  Bpp                   = pImage->bpp;                                                                                  /* Copy width to local structure */
761 
762  if((pImage->width <= 0) || (pImage->height <= 0) || ((pImage->bpp != 24) && (pImage->bpp !=32)))      /*Make sure all pImage info is ok */
763    {
764      printf("Error Invalid pImage information");                                               /* If it isnt...Display error */
765      if(fTGA != NULL)                                                                                                  /* Check if file is open */
766        {
767          fclose(fTGA);                                                                                                 /* Ifit is, close it */
768        }
769      return false;                                                                                                             /* Return failed */
770    }
771 
772  bytesPerPixel = (Bpp / 8);                                                                    /* Compute BYTES per pixel */
773  imageSize             = (bytesPerPixel * Width * Height);             /* Compute amout of memory needed to store image */
774  pImage->data  = (GLubyte *)malloc(imageSize);                                 /* Allocate that much memory */
775 
776  if(pImage->data == NULL)                                                                                      /* If it wasnt allocated correctly.. */
777    {
778      printf("Error could not allocate memory for image");                              /* Display Error */
779      fclose(fTGA);                                                                                                             /* Close file */
780      return false;                                                                                                             /* Return failed */
781    }
782 
783  do
784    {
785      GLubyte chunkheader = 0;                                                                                  /* Storage for "chunk" header */
786     
787      if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)                            /* Read in the 1 byte header */
788        {
789          printf("Error could not read RLE header");                                            /*Display Error */
790          if(fTGA != NULL)                                                                                              /* If file is open */
791            {
792              fclose(fTGA);                                                                                             /* Close file */
793            }
794          if(pImage->data != NULL)                                                                      /* If there is stored image data */
795            {
796              free(pImage->data);                                                                       /* Delete image data */
797            }
798          return false;                                                                                                 /* Return failed */
799        }
800     
801      if(chunkheader < 128)                                                                                             /* If the ehader is < 128, it means the that is the number of RAW color packets minus 1 */
802        {
803          short counter;                                                                                                        /* that follow the header */
804          chunkheader++;                                                                                                        /* add 1 to get number of following color values */
805          for(counter = 0; counter < chunkheader; counter++)                            /* Read RAW color values */
806            {
807              if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel) /* Try to read 1 pixel */
808                {
809                  printf("Error could not read image data");                            /* IF we cant, display an error */
810                 
811                  if(fTGA != NULL)                                                                              /* See if file is open */
812                    {
813                      fclose(fTGA);                                                                             /* If so, close file */
814                    }
815                 
816                  if(colorbuffer != NULL)                                                                       /* See if colorbuffer has data in it */
817                    {
818                      free(colorbuffer);                                                                        /* If so, delete it */
819                    }
820                 
821                  if(pImage->data != NULL)                                                                              /* See if there is stored Image data */
822                    {
823                      free(pImage->data);                                                                               /* If so, delete it too */
824                    }
825                 
826                  return false;                                                                                                         /* Return failed */
827                }
828              /* write to memory */
829              pImage->data[currentbyte          ] = colorbuffer[2];                                 /* Flip R and B vcolor values around in the process */
830              pImage->data[currentbyte + 1      ] = colorbuffer[1];
831              pImage->data[currentbyte + 2      ] = colorbuffer[0];
832             
833              if(bytesPerPixel == 4)                                                                                            /* if its a 32 bpp image */
834                {
835                  pImage->data[currentbyte + 3] = colorbuffer[3];                               /* copy the 4th byte */
836                }
837             
838              currentbyte += bytesPerPixel;                                                                             /* Increase thecurrent byte by the number of bytes per pixel */
839              currentpixel++;                                                                                                                   /* Increase current pixel by 1 */
840             
841              if(currentpixel > pixelcount)                                                                                     /* Make sure we havent read too many pixels */
842                {
843                  printf("Error too many pixels read");                                                         /* if there is too many... Display an error! */
844                 
845                  if(fTGA != NULL)                                                                                                      /* If there is a file open */
846                    {
847                      fclose(fTGA);                                                                                                     /* Close file */
848                    }
849                 
850                  if(colorbuffer != NULL)                                                                                               /* If there is data in colorbuffer */
851                    {
852                      free(colorbuffer);                                                                                                /* Delete it */
853                    }
854                 
855                  if(pImage->data != NULL)                                                                              /* If there is Image data */
856                    {
857                      free(pImage->data);                                                                               /* delete it */
858                    }
859                 
860                  return false;                                                                                                         /* Return failed */
861                }
862            }
863        }
864      else                                                                                                                                                      /* chunkheader > 128 RLE data, next color  reapeated chunkheader - 127 times */
865        {
866          short counter;
867          chunkheader -= 127;                                                                                                                   /* Subteact 127 to get rid of the ID bit */
868          if(fread(colorbuffer, 1, bytesPerPixel, fTGA) != bytesPerPixel)               /* Attempt to read following color values */
869            {
870              printf("Error could not read from file");                 /* If attempt fails.. Display error (again) */
871             
872              if(fTGA != NULL)                                                                                                          /* If thereis a file open */
873                {
874                  fclose(fTGA);                                                                                                         /* Close it */
875                }
876             
877              if(colorbuffer != NULL)                                                                                                   /* If there is data in the colorbuffer */
878                {
879                  free(colorbuffer);                                                                                                    /* delete it */
880                }
881             
882              if(pImage->data != NULL)                                                                                  /* If thereis image data */
883                {
884                  free(pImage->data);                                                                                   /* delete it */
885                }
886             
887              return false;                                                                                                                     /* return failed */
888            }
889         
890          for(counter = 0; counter < chunkheader; counter++)                                    /* copy the color into the image data as many times as dictated */
891            {                                                                                                                                                   /* by the header */
892              pImage->data[currentbyte          ] = colorbuffer[2];                                     /* switch R and B bytes areound while copying */
893              pImage->data[currentbyte + 1      ] = colorbuffer[1];
894              pImage->data[currentbyte + 2      ] = colorbuffer[0];
895             
896              if(bytesPerPixel == 4)                                                                                            /* If TGA images is 32 bpp */
897                {
898                  pImage->data[currentbyte + 3] = colorbuffer[3];                               /* Copy 4th byte */
899                }
900             
901              currentbyte += bytesPerPixel;                                                                             /* Increase current byte by the number of bytes per pixel */
902              currentpixel++;                                                                                                                   /* Increase pixel count by 1 */
903             
904              if(currentpixel > pixelcount)                                                                                     /* Make sure we havent written too many pixels */
905                {
906                  printf("Error too many pixels read");                                                         /* if there is too many... Display an error! */
907                 
908                  if(fTGA != NULL)                                                                                                      /* If there is a file open */
909                    {
910                      fclose(fTGA);                                                                                                     /* Close file */
911                    }
912                 
913                  if(colorbuffer != NULL)                                                                                               /* If there is data in colorbuffer */
914                    {
915                      free(colorbuffer);                                                                                                /* Delete it */
916                    }
917                 
918                  if(pImage->data != NULL)                                                                              /* If there is Image data */
919                    {
920                      free(pImage->data);                                                                               /* delete it */
921                    }
922                 
923                  return false;                                                                                                         /* Return failed */
924                }
925            }
926        }
927    }
928 
929  while(currentpixel < pixelcount);                                                                                                     /* Loop while there are still pixels left */
930  fclose(fTGA);                                                                                                                                         /* Close the file */
931  return true;                                                                                                                                          /* return success */
932}
933
934#endif
Note: See TracBrowser for help on using the repository browser.