Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

tga.cpp

Go to the documentation of this file.
00001 /*
00002                                                  Source Code for the TGA library
00003 
00004 
00005                           You may use this library for whatever you want. This library is provide as is, meaning that I won't take any
00006                           responsability for any damages that you may incur from its usage.
00007 */
00008 
00009 
00010                               
00011                           #include <stdio.h>
00012                           #include <stdlib.h>
00013                           #include <string.h>
00014                           #include "shared.h"  
00015                           #include "tga.h"
00016                           #include "mmgr.h"
00017 
00018                           // this variable is used for image series
00019                           static int savedImages=0;
00020 
00021                           // load the image header fields. We only keep those that matter!
00022                           void tgaLoadHeader(FILE *file, tgaInfo *info) {
00023 
00024                                   unsigned char cGarbage;
00025                                   short int iGarbage;
00026 
00027                                   fread(&cGarbage, sizeof(unsigned char), 1, file);
00028                                   fread(&cGarbage, sizeof(unsigned char), 1, file);
00029 
00030                           // type must be 2 or 3
00031                                   fread(&info->type, sizeof(unsigned char), 1, file);
00032 
00033                                   fread(&iGarbage, sizeof(short int), 1, file);
00034                                   fread(&iGarbage, sizeof(short int), 1, file);
00035                                   fread(&cGarbage, sizeof(unsigned char), 1, file);
00036                                   fread(&iGarbage, sizeof(short int), 1, file);
00037                                   fread(&iGarbage, sizeof(short int), 1, file);
00038 
00039                                   fread(&info->width, sizeof(short int), 1, file);
00040                                   fread(&info->height, sizeof(short int), 1, file);
00041                                   fread(&info->pixelDepth, sizeof(unsigned char), 1, file);
00042 
00043                                   fread(&cGarbage, sizeof(unsigned char), 1, file);
00044                           }
00045 
00046                           // loads the image pixels. You shouldn't call this function
00047                           // directly
00048                           void tgaLoadImageData(FILE *file, tgaInfo *info) {
00049 
00050                                   int mode,total,i;
00051                                   unsigned char aux;
00052 
00053                           // mode equal the number of components for each pixel
00054                                   mode = info->pixelDepth / 8;
00055                           // total is the number of bytes we'll have to read
00056                                   total = info->height * info->width * mode;
00057                                   
00058                                   fread(info->imageData,sizeof(unsigned char),total,file);
00059 
00060                           // mode=3 or 4 implies that the image is RGB(A). However TGA
00061                           // stores it as BGR(A) so we'll have to swap R and B.
00062                                   if (mode >= 3)
00063                                           for (i=0; i < total; i+= mode) {
00064                                                   aux = info->imageData[i];
00065                                                   info->imageData[i] = info->imageData[i+2];
00066                                                   info->imageData[i+2] = aux;
00067                                           }
00068                           }       
00069 
00070                           // this is the function to call when we want to load
00071                           // an image
00072                           tgaInfo * tgaLoad(char *filename) {
00073                                   
00074                                   FILE *file;
00075                                   tgaInfo *info;
00076                                   int mode,total;
00077 
00078                           // allocate memory for the info struct and check!
00079                                   info = (tgaInfo *)malloc(sizeof(tgaInfo));
00080                                   if (info == NULL)
00081                                           return(NULL);
00082 
00083 
00084                           // open the file for reading (binary mode)
00085                                   file = fopen(filename, "rb");
00086                                   if (file == NULL) {
00087                                           info->status = TGA_ERROR_FILE_OPEN;
00088                                           return(info);
00089                                   }
00090 
00091                           // load the header
00092                                   tgaLoadHeader(file,info);
00093 
00094                           // check for errors when loading the header
00095                                   if (ferror(file)) {
00096                                           info->status = TGA_ERROR_READING_FILE;
00097                                           fclose(file);
00098                                           return(info);
00099                                   }
00100 
00101                           // check if the image is color indexed
00102                                   if (info->type == 1) {
00103                                           info->status = TGA_ERROR_INDEXED_COLOR;
00104                                           fclose(file);
00105                                           return(info);
00106                                   }
00107                           // check for other types (compressed images)
00108                                   if ((info->type != 2) && (info->type !=3)) {
00109                                           info->status = TGA_ERROR_COMPRESSED_FILE;
00110                                           fclose(file);
00111                                           return(info);
00112                                   }
00113 
00114                           // mode equals the number of image components
00115                                   mode = info->pixelDepth / 8;
00116                           // total is the number of bytes to read
00117                                   total = info->height * info->width * mode;
00118                           // allocate memory for image pixels
00119                                   info->imageData = (unsigned char *)malloc(sizeof(unsigned char) * 
00120                                                                                           total);
00121 
00122                           // check to make sure we have the memory required
00123                                   if (info->imageData == NULL) {
00124                                           info->status = TGA_ERROR_MEMORY;
00125                                           fclose(file);
00126                                           return(info);
00127                                   }
00128                           // finally load the image pixels
00129                                   tgaLoadImageData(file,info);
00130 
00131                           // check for errors when reading the pixels
00132                                   if (ferror(file)) {
00133                                           info->status = TGA_ERROR_READING_FILE;
00134                                           fclose(file);
00135                                           return(info);
00136                                   }
00137                                   fclose(file);
00138                                   info->status = TGA_OK;
00139                                   return(info);
00140                           }               
00141 
00142                           // converts RGB to greyscale
00143                           void tgaRGBtogreyscale(tgaInfo *info) {
00144 
00145                                   int mode,i,j;
00146 
00147                                   unsigned char *newImageData;
00148 
00149                           // if the image is already greyscale do nothing
00150                                   if (info->pixelDepth == 8)
00151                                           return;
00152 
00153                           // compute the number of actual components
00154                                   mode = info->pixelDepth / 8;
00155 
00156                           // allocate an array for the new image data
00157                                   newImageData = (unsigned char *)malloc(sizeof(unsigned char) * 
00158                                                                           info->height * info->width);
00159                                   if (newImageData == NULL) {
00160                                           return;
00161                                   }
00162 
00163                           // convert pixels: greyscale = o.30 * R + 0.59 * G + 0.11 * B
00164                                   for (i = 0,j = 0; j < info->width * info->height; i +=mode, j++)
00165                                           newImageData[j] =       
00166                                                   (unsigned char)(0.30 * info->imageData[i] + 
00167                                                                   0.59 * info->imageData[i+1] +
00168                                                                   0.11 * info->imageData[i+2]);
00169 
00170 
00171                           //free old image data
00172                                   free(info->imageData);
00173 
00174                           // reassign pixelDepth and type according to the new image type
00175                                   info->pixelDepth = 8;
00176                                   info->type = 3;
00177                           // reassing imageData to the new array.
00178                                   info->imageData = newImageData;
00179                           }
00180 
00181                           // takes a screen shot and saves it to a TGA image
00182                           int tgaGrabScreenSeries(char *filename, int xmin,int ymin, int xmax, int ymax) {
00183 
00184                                   int w, h;
00185                                   unsigned char *imageData;
00186 
00187                           // compute width and heidth of the image
00188                                   w = xmax - xmin;
00189                                   h = ymax - ymin;
00190 
00191                           // allocate memory for the pixels
00192                                   imageData = (unsigned char *)malloc(sizeof(unsigned char) * w * h * 4);
00193 
00194                           // read the pixels from the frame buffer
00195                                   glReadPixels(xmin,ymin,xmax,ymax,GL_RGBA,GL_UNSIGNED_BYTE, (void *)imageData);
00196 
00197                           // save the image
00198                                   return (tgaSaveSeries(filename,(short int)w,(short int)h,32,imageData));
00199                           }
00200 
00201 
00202 
00203 
00204                           // saves an array of pixels as a TGA image
00205                           int tgaSave(    char            *filename,
00206                                           short int       width,
00207                                           short int       height,
00208                                           unsigned char   pixelDepth,
00209                                           unsigned char   *imageData) {
00210 
00211                                   unsigned char cGarbage = 0, type,mode,aux;
00212                                   short int iGarbage = 0;
00213                                   int i;
00214                                   FILE *file;
00215 
00216                           // open file and check for errors
00217                                   file = fopen(filename, "wb");
00218                                   if (file == NULL) {
00219                                           return(TGA_ERROR_FILE_OPEN);
00220                                   }
00221 
00222                           // compute image type: 2 for RGB(A), 3 for greyscale
00223                                   mode = (unsigned char)(pixelDepth / 8);
00224                                   if ((pixelDepth == 24) || (pixelDepth == 32))
00225                                           type = 2;
00226                                   else
00227                                           type = 3;
00228 
00229                           // write the header
00230                                   fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00231                                   fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00232 
00233                                   fwrite(&type, sizeof(unsigned char), 1, file);
00234 
00235                                   fwrite(&iGarbage, sizeof(short int), 1, file);
00236                                   fwrite(&iGarbage, sizeof(short int), 1, file);
00237                                   fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00238                                   fwrite(&iGarbage, sizeof(short int), 1, file);
00239                                   fwrite(&iGarbage, sizeof(short int), 1, file);
00240 
00241                                   fwrite(&width, sizeof(short int), 1, file);
00242                                   fwrite(&height, sizeof(short int), 1, file);
00243                                   fwrite(&pixelDepth, sizeof(unsigned char), 1, file);
00244 
00245                                   fwrite(&cGarbage, sizeof(unsigned char), 1, file);
00246 
00247                           // convert the image data from RGB(a) to BGR(A)
00248                                   if (mode >= 3)
00249                                   for (i=0; i < width * height * mode ; i+= mode) {
00250                                           aux = imageData[i];
00251                                           imageData[i] = imageData[i+2];
00252                                           imageData[i+2] = aux;
00253                                   }
00254 
00255                           // save the image data
00256                                   fwrite(imageData, sizeof(unsigned char),
00257                                                   width * height * mode, file);
00258                                   fclose(file);
00259                           // release the memory
00260                                  // free(imageData);
00261 
00262                                   return(TGA_OK);
00263                           }
00264 
00265                           // saves a series of files with names "filenameX.tga"
00266                           int tgaSaveSeries(char          *filename,
00267                                                    short int              width,
00268                                                    short int              height,
00269                                                    unsigned char  pixelDepth,
00270                                                    unsigned char  *imageData) {
00271 
00272                                   char *newFilename;
00273                                   int status;
00274 
00275                           // compute the new filename by adding the 
00276                           // series number and the extension
00277                                   newFilename = (char *)malloc(sizeof(char) * strlen(filename)+8);
00278 
00279                                   sprintf(newFilename,"%s%d.tga",filename,savedImages);
00280                                   
00281                           // save the image
00282                                   status = tgaSave(newFilename,width,height,pixelDepth,imageData);
00283                                   
00284                           //increase the counter
00285                                   savedImages++;
00286                                   return(status);
00287                           }
00288 
00289 
00290                           // releases the memory used for the image
00291                           void tgaDestroy(tgaInfo *info) {
00292 
00293                                   if (info != NULL) {
00294                                           free(info->imageData);
00295                                           free(info);
00296                                   }
00297                           }
00298 

Generated on Fri Dec 23 05:15:48 2005 for Constructive Solid Geometry by doxygen1.2.15