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

ctgaloader.cpp

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 #include "stdafx.h"
00006 #include "ctgaloader.h"
00007 #include <stdio.h>
00008 
00009 
00010 int CTGALoader::m_GetHeader(char *filename) {
00011         FILE *file = fopen(filename, "rb");
00012 
00013         if (!file)
00014                 return 1;
00015 
00016 
00017         if (fread(&m_sTgaHeader, 1, sizeof(m_sTgaHeader), file) != sizeof(m_sTgaHeader)) {
00018                 fclose(file);
00019                 return 1;
00020         }
00021 
00022 
00023         if (!m_sTgaHeader.cImageType)
00024                 return 1;
00025 
00026         
00027         return 0;
00028 }
00029 
00030 
00031 int CTGALoader::m_GetFooter(char *filename) {
00032         FILE *file = fopen(filename, "rb");
00033 
00034         if (!file)
00035                 return 1;
00036 
00037         fseek(file, -26L, SEEK_END);
00038         if (fread(&m_sTgaFooter, 1, sizeof(m_sTgaFooter.cFooter), file) != sizeof(m_sTgaFooter.cFooter)) {
00039                 fclose(file);
00040                 return 1;
00041         }
00042 
00043         //handle footer
00044         memcpy(&m_sTgaFooter.udExtensionAreaOffset, m_sTgaFooter.cFooter, 4);
00045         memcpy(&m_sTgaFooter.udDeveloperDirectoryOffset, m_sTgaFooter.cFooter + 4, 4);
00046         memcpy(&m_sTgaFooter.cSignature, m_sTgaFooter.cFooter + 8, 16);
00047         memcpy(&m_sTgaFooter.cAsciiChar, m_sTgaFooter.cFooter + 24, 1);
00048         memcpy(&m_sTgaFooter.cStringTerminator, m_sTgaFooter.cFooter + 25, 1);
00049         m_sTgaFooter.cSignature[16] = '\0';
00050 
00051         return 0;
00052 }
00053 
00054 
00055 int CTGALoader::m_ExtractImageData(char *filename, ImageData_t *psImage) {
00056         int dBytesPerPixel;
00057         
00058         FILE *file = fopen(filename, "rb");
00059         if (!file)
00060                 return 1;
00061 
00062         fseek(file, HEADER_SIZE, SEEK_SET);
00063 
00064         psImage->dWidth = m_sTgaHeader.ucImageWidth;
00065         psImage->dHeight = m_sTgaHeader.ucImageHeight;
00066         psImage->dBpp = m_sTgaHeader.cPixelDepth;
00067         psImage->cColorInfo = (m_sTgaHeader.cImageType & 0x01);
00068         dBytesPerPixel = psImage->dBpp / 8;
00069         psImage->dSize = psImage->dHeight * psImage->dWidth * dBytesPerPixel;
00070 
00071         psImage->pcImageData = (unsigned char *)malloc(psImage->dSize);
00072         if (!psImage->pcImageData) {
00073                 fclose(file);
00074                 return 1;
00075         }
00076 
00077 
00078         /*
00079                 2 -> uncompressed true color image
00080                 3 -> uncompressed black and white image
00081         */
00082         if ((m_sTgaHeader.cImageType == 2) || (m_sTgaHeader.cImageType == 3)) {
00083                 //if uncompressed, load the whole data in one step
00084                 if (fread(psImage->pcImageData, 1, psImage->dSize, file) != psImage->dSize) {
00085                         if (psImage->pcImageData != NULL)
00086                                 free(psImage->pcImageData);
00087                         fclose(file);
00088                         return 1;
00089                 }
00090         }
00091         /*
00092                 10 -> compressed true color image
00093                 11 -> compressed black and white image
00094         */
00095         else if ((m_sTgaHeader.cImageType == 10) || (m_sTgaHeader.cImageType == 11)) {
00096                 unsigned char ucTempByte[4];
00097                 unsigned char ucPackedHead;
00098                 unsigned char *pAt;
00099 
00100                 pAt = psImage->pcImageData;
00101                 for (unsigned int i = 0; i < psImage->dSize; ) {
00102                         ucPackedHead = (unsigned char) fgetc(file);
00103                         //run length encoded
00104                         if (ucPackedHead & 0x80) {
00105                                 ucPackedHead &= 0x7f;
00106                                 ucPackedHead++;
00107                                 //load the data
00108                                 fread(ucTempByte, dBytesPerPixel, 1, file);
00109                                 //and copy it as told in the packed head
00110                                 for (unsigned int j = 0; j < ucPackedHead; j++) {
00111                                         memcpy(pAt, ucTempByte, dBytesPerPixel);
00112                                         i += dBytesPerPixel;
00113                                         pAt += dBytesPerPixel;
00114                                 }
00115                         }
00116                         //raw mode
00117                         else if (!(ucPackedHead & 0x80)) {
00118                                 ucPackedHead &= 0x7f;
00119                                 ucPackedHead++;
00120                                         //load the data, told in the packed head
00121                                         fread(pAt, dBytesPerPixel, ucPackedHead, file);
00122                                         i += dBytesPerPixel * ucPackedHead;
00123                                         pAt += dBytesPerPixel * ucPackedHead;
00124                         }
00125                 }
00126         }
00127 
00128 
00129         //if true color image change red and blue, cause tga is stored in BGR!!!
00130         if (!psImage->cColorInfo) {
00131                 unsigned char ucTemp; 
00132                 for (unsigned int i = 0; i < psImage->dSize; i += dBytesPerPixel) {
00133                         ucTemp = psImage->pcImageData[i];
00134                         psImage->pcImageData[i] = psImage->pcImageData[i+2];
00135                         psImage->pcImageData[i+2] = ucTemp;
00136                 }
00137         }
00138 
00139         fclose(file);
00140 
00141         return 0;
00142 }
00143 
00144 
00145 ImageData_t *CTGALoader::LoadTgaImage(char *filename) {
00146 
00147         ImageData_t *psImage = new ImageData_t;
00148         
00149 
00150         if (m_GetHeader(filename))
00151                 return NULL;
00152 
00153         if (m_GetFooter(filename))
00154                 return NULL;
00155 
00156         if (m_ExtractImageData(filename, psImage))
00157                 return NULL;
00158 
00159 
00160         return psImage;
00161 }
00162 
00163 
00164 bool CTGALoader::SaveTgaImage(string path, ImageData_t *psImage) {
00165 
00166         FILE *file;
00167         char *buf = NULL;
00168         int buflen = 0;
00169 
00170         buflen = GetCurrentDirectory(0, buf);
00171         buf = new char[buflen];
00172         GetCurrentDirectory(buflen, buf);
00173 
00174 
00175         SetCurrentDirectory((path.substr(0, path.size() - 1)).c_str());
00176         int x = CreateDirectory("screenshots", NULL);
00177         if (x == 0) {
00178                 if (GetLastError() != ERROR_ALREADY_EXISTS)
00179                         return false;
00180         }
00181 
00182 
00183         std::string name = path;
00184         name.append("screenshots\\");
00185         name.append("shot__.tga");
00186 
00187 
00188         for (int i = 0; i < 100; i++) {
00189                 name[name.length() - 6] = (i / 10) + '0';
00190                 name[name.length() - 5] = (i % 10) + '0';
00191                 if ((file = fopen(name.c_str(), "rb")) == NULL)
00192                         break;
00193         }
00194 
00195         if (i == 100)
00196                 return false;
00197 
00198 
00199         m_sTgaHeader.cIDLength = 0;
00200         m_sTgaHeader.cColorMapType = 0;
00201         m_sTgaHeader.cImageType = 2;
00202         //color map spec
00203         m_sTgaHeader.ucFirstEntryIndex = 0;
00204         m_sTgaHeader.ucColorMapLength = 0;
00205         m_sTgaHeader.cColorMapEntrySize = 0;
00206         //image spec
00207         m_sTgaHeader.ucXOrigin = 0;
00208         m_sTgaHeader.ucYOrigin = 0;
00209         m_sTgaHeader.ucImageWidth = psImage->dWidth;
00210         m_sTgaHeader.ucImageHeight = psImage->dHeight;
00211         m_sTgaHeader.cPixelDepth = psImage->dBpp * 8;
00212         m_sTgaHeader.cImageDescriptor = 0x0000;
00213 
00214         if ((file = fopen(name.c_str(), "wb")) == NULL)
00215                 return false;
00216 
00217 
00218         unsigned char *image = new unsigned char[psImage->dSize];
00219         memcpy(image, psImage->pcImageData, psImage->dWidth * psImage->dHeight * 3);
00220         //if true color image change red and blue, cause tga is stored in BGR!!!
00221         if (!psImage->cColorInfo) {
00222                 unsigned char ucTemp; 
00223                 for (unsigned int i = 0; i < psImage->dSize; i += psImage->dBpp) {
00224                         ucTemp = image[i];
00225                         image[i] = image[i+2];
00226                         image[i+2] = ucTemp;
00227                 }
00228         }
00229         
00230         
00231         fwrite(&m_sTgaHeader, sizeof(m_sTgaHeader), 1, file);
00232         fwrite(image, psImage->dSize, 1, file);
00233         fclose(file);
00234 
00235         if (image) {
00236                 delete[] image;
00237                 image = NULL;
00238         }
00239 
00240         if (buf) {
00241                 SetCurrentDirectory(buf);
00242                 delete[] buf;
00243                 buf = NULL;
00244         }
00245 
00246 
00247         return true;
00248 }

Generated on Thu Jan 30 21:35:43 2003 for 3DVis by doxygen1.3-rc2