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
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
00076
00077
00078 if ((m_sTgaHeader.cImageType == 2) || (m_sTgaHeader.cImageType == 3)) {
00079
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
00089
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
00100 if (ucPackedHead & 0x80) {
00101 ucPackedHead &= 0x7f;
00102 ucPackedHead++;
00103
00104 fread(ucTempByte, dBytesPerPixel, 1, file);
00105
00106 for (unsigned int j = 0; j < ucPackedHead; j++) {
00107 memcpy(pAt, ucTempByte, dBytesPerPixel);
00108 i += dBytesPerPixel;
00109 pAt += dBytesPerPixel;
00110 }
00111 }
00112
00113 else if (!(ucPackedHead & 0x80)) {
00114 ucPackedHead &= 0x7f;
00115 ucPackedHead++;
00116
00117 fread(pAt, dBytesPerPixel, ucPackedHead, file);
00118 i += dBytesPerPixel * ucPackedHead;
00119 pAt += dBytesPerPixel * ucPackedHead;
00120 }
00121 }
00122 }
00123
00124
00125
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
00199 m_sTgaHeader.ucFirstEntryIndex = 0;
00200 m_sTgaHeader.ucColorMapLength = 0;
00201 m_sTgaHeader.cColorMapEntrySize = 0;
00202
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
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 }