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

Generated on Thu Jan 23 12:32:15 2003 by doxygen1.3-rc2