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
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
00080
00081
00082 if ((m_sTgaHeader.cImageType == 2) || (m_sTgaHeader.cImageType == 3)) {
00083
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
00093
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
00104 if (ucPackedHead & 0x80) {
00105 ucPackedHead &= 0x7f;
00106 ucPackedHead++;
00107
00108 fread(ucTempByte, dBytesPerPixel, 1, file);
00109
00110 for (unsigned int j = 0; j < ucPackedHead; j++) {
00111 memcpy(pAt, ucTempByte, dBytesPerPixel);
00112 i += dBytesPerPixel;
00113 pAt += dBytesPerPixel;
00114 }
00115 }
00116
00117 else if (!(ucPackedHead & 0x80)) {
00118 ucPackedHead &= 0x7f;
00119 ucPackedHead++;
00120
00121 fread(pAt, dBytesPerPixel, ucPackedHead, file);
00122 i += dBytesPerPixel * ucPackedHead;
00123 pAt += dBytesPerPixel * ucPackedHead;
00124 }
00125 }
00126 }
00127
00128
00129
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
00203 m_sTgaHeader.ucFirstEntryIndex = 0;
00204 m_sTgaHeader.ucColorMapLength = 0;
00205 m_sTgaHeader.cColorMapEntrySize = 0;
00206
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
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 }