- Main Page
- Classes
- Files

- File List
- File Members

# flTextureTGA.c

Go to the documentation of this file.

    00001 #include "flGlobal.h"
    00002 #if FL_TEXTURE_TGA != 0
    00003 #include <stdlib.h>
    00004 #include <string.h>
    00005 #include <pspgu.h>
    00006
    00007 #if FL_INCLUDE_ALL_C == 0
    00008 #include "flTextureTGA.h"
    00009 #include "flMemory.h"
    00010 #include "flFile.h"
    00011
    00012 #if FL_DEBUG != 0
    00013 #include "flDebug.h"
    00014 #endif
    00015
    00016 #endif
    00017
    00018 typedef struct {
    00019      u8  tgaIdentSize;
    00020      u8  tgaPaletteType;
    00021      u8  tgaImageType;
    00022      u16 tgaPaletteStart;
    00023      u16 tgaPaletteLen;
    00024      u8  tgaPaletteBPP;
    00025      s16 tgaXStart;
    00026      s16 tgaYStart;
    00027      u16 tgaWidth;
    00028      u16 tgaHeight;
    00029      u8  tgaBPP;
    00030      u8  tgaDescriptor;
    00031 } tgaFileHeader;
    00032
    00033 Texture* texLoadTGA(char* inPath) {
    00034      #if FL_FILE != 0
    00035      File* tempFile = fileOpen(inPath, FILE_MODE_READ | FILE_MODE_BINARY);
    00036      #else
    00037      FILE* tempFile = fopen(inPath, "rb");
    00038      #endif
    00039      if(!tempFile) {
    00040           #if FL_DEBUG_ERROR != 0
    00041           debugError("TGA load error.\nFile(%s) cannot be opened", inPath);
    00042           #endif
    00043           return NULL;
    00044      }
    00045      tgaFileHeader tempHeader;
    00046
    00047      fileRead(&tempHeader.tgaIdentSize, 1, tempFile);
    00048      fileRead(&tempHeader.tgaPaletteType, 1, tempFile);
    00049      fileRead(&tempHeader.tgaImageType, 1, tempFile);
    00050      fileRead(&tempHeader.tgaPaletteStart, 2, tempFile);
    00051      fileRead(&tempHeader.tgaPaletteLen, 2, tempFile);
    00052      fileRead(&tempHeader.tgaPaletteBPP, 1, tempFile);
    00053      fileRead(&tempHeader.tgaXStart, 2, tempFile);
    00054      fileRead(&tempHeader.tgaYStart, 2, tempFile);
    00055      fileRead(&tempHeader.tgaWidth, 2, tempFile);
    00056      fileRead(&tempHeader.tgaHeight, 2, tempFile);
    00057      fileRead(&tempHeader.tgaBPP, 1, tempFile);
    00058      fileRead(&tempHeader.tgaDescriptor, 1, tempFile);
    00059
    00060      if(tempHeader.tgaIdentSize)
    00061           fileSeek(tempFile, tempHeader.tgaIdentSize, FILE_SEEK_CUR);
    00062
    00063      if(tempHeader.tgaImageType == 0) {
    00064           #if FL_DEBUG_ERROR != 0
    00065           debugError("No image data included within tga(%s).", inPath);
    00066           #endif
    00067           fileClose(tempFile);
    00068           return NULL;
    00069      }
    00070
    00071      if(tempHeader.tgaPaletteType & 0xFE) {
    00072           #if FL_DEBUG_ERROR != 0
    00073           debugError("Palette format (%i) unsupported in tga file (%s).", tempHeader.tgaPaletteType, inPath);
    00074           #endif
    00075           fileClose(tempFile);
    00076           return NULL;
    00077      }
    00078
    00079      u8 tempBPP = (tempHeader.tgaPaletteType ? tempHeader.tgaPaletteBPP : tempHeader.tgaBPP);
    00080      if((tempBPP != 15) && (tempBPP != 16) && (tempBPP != 32) && (tempBPP != 24) && (tempBPP != 8)) {
    00081           #if FL_DEBUG_ERROR != 0
    00082           debugError("BPP(%i) value unsupported in tga file (%s).", tempBPP, inPath);
    00083           #endif
    00084           fileClose(tempFile);
    00085           return NULL;
    00086      }
    00087      if(tempHeader.tgaPaletteType && (tempHeader.tgaBPP != 1)  && (tempHeader.tgaBPP != 2) && (tempHeader.tgaBPP != 4) && (tempHeader.tgaBPP != 8)) {
    00088           #if FL_DEBUG_ERROR != 0
    00089           debugError("BPP(%i) value unsupported for palettes in tga file (%s).", tempBPP, inPath);
    00090           #endif
    00091           fileClose(tempFile);
    00092           return NULL;
    00093      }
    00094      if((tempBPP == 8) && (tempHeader.tgaPaletteType || ((tempHeader.tgaImageType & 3) != 3))) {
    00095           #if FL_DEBUG_ERROR != 0
    00096           debugError("Error in tga file (%s), %i bits per pixel in color/shade data is only supported for grayscale images.", inPath, tempBPP);
    00097           #endif
    00098           fileClose(tempFile);
    00099           return NULL;
    00100      }
    00101      if(((tempHeader.tgaImageType & 3) == 3) && (tempBPP != 8)) {
    00102           #if FL_DEBUG_ERROR != 0
    00103           debugError("Error in tga file (%s), only 8 bits per pixel is only supported for grayscale images, not %i.", inPath, tempBPP);
    00104           #endif
    00105           fileClose(tempFile);
    00106           return NULL;
    00107      }
    00108
    00109      u8 tempByPP = ((tempHeader.tgaBPP + 1) >> 3);
    00110
    00111      u8 tempPixelFormat = 0;
    00112      u8 tempPaletteFormat = 0;
    00113      if(tempHeader.tgaPaletteType) {
    00114           if((tempHeader.tgaBPP <= 4) && (tempHeader.tgaBPP != 3)) {
    00115                tempPixelFormat = GU_PSM_T4;
    00116           } else if(tempHeader.tgaBPP == 8) {
    00117                tempPixelFormat = GU_PSM_T8;
    00118           }
    00119           if(tempHeader.tgaPaletteBPP > 16) {
    00120                tempPaletteFormat = GU_PSM_8888;
    00121           } else if(tempHeader.tgaPaletteBPP == 16) {
    00122                if((tempHeader.tgaDescriptor & 0x0F) == 0)
    00123                     tempPaletteFormat = GU_PSM_5650;
    00124                else if((tempHeader.tgaDescriptor & 0x0F) == 1)
    00125                     tempPaletteFormat = GU_PSM_5551;
    00126                else if((tempHeader.tgaDescriptor & 0x0F) == 4)
    00127                     tempPaletteFormat = GU_PSM_4444;
    00128           } else {
    00129                tempPaletteFormat = GU_PSM_5551;
    00130           }
    00131      } else {
    00132           if(tempHeader.tgaBPP > 16) {
    00133                tempPixelFormat = GU_PSM_8888;
    00134           } else if(tempHeader.tgaBPP == 16) {
    00135                if((tempHeader.tgaDescriptor & 0x0F) == 0)
    00136                          tempPixelFormat = GU_PSM_5650;
    00137                     else if((tempHeader.tgaDescriptor & 0x0F) == 1)
    00138                          tempPixelFormat = GU_PSM_5551;
    00139                     else if((tempHeader.tgaDescriptor & 0x0F) == 4)
    00140                          tempPixelFormat = GU_PSM_4444;
    00141           } else {
    00142                tempPixelFormat = GU_PSM_5551;
    00143           }
    00144      }
    00145
    00146      u32 i, j;
    00147      Palette* tempPalette = NULL;
    00148      #if FL_TEXTURE_PRESERVENONALPHA != 0
    00149      bool tempAlpha = (tempHeader.tgaDescriptor & 0x0F);
    00150      #endif
    00151      if(tempHeader.tgaPaletteType) {
    00152           tempPalette = palCreate(tempHeader.tgaPaletteLen, tempPaletteFormat, false);
    00153           switch(tempHeader.tgaPaletteBPP) {
    00154                case 32:
    00155                     for(i = 0; i < tempHeader.tgaPaletteLen; i++) {
    00156                          fileRead(&tempPalette->palData[(i << 2) + 2], 1, tempFile);
    00157                          fileRead(&tempPalette->palData[(i << 2) + 1], 1, tempFile);
    00158                          fileRead(&tempPalette->palData[(i << 2) + 0], 1, tempFile);
    00159                          fileRead(&tempPalette->palData[(i << 2) + 3], 1, tempFile);
    00160                     }
    00161                     break;
    00162                case 24:
    00163                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00164                     tempAlpha = false;
    00165                     #endif
    00166                     for(i = 0; i < tempHeader.tgaPaletteLen; i++) {
    00167                          fileRead(&tempPalette->palData[(i << 2) + 2], 1, tempFile);
    00168                          fileRead(&tempPalette->palData[(i << 2) + 1], 1, tempFile);
    00169                          fileRead(&tempPalette->palData[(i << 2) + 0], 1, tempFile);
    00170                          tempPalette->palData[(i << 2) + 3] = 0xFF;
    00171                     }
    00172                     break;
    00173           }
    00174      } else if((tempHeader.tgaImageType & 3) == 3) {
    00175           tempPalette = palGrayscaleT8();
    00176           tempPixelFormat = GU_PSM_T8;
    00177           tempPaletteFormat = tempPalette->palPixelFormat;
    00178           #if FL_TEXTURE_PRESERVENONALPHA != 0
    00179           tempAlpha = false;
    00180           #endif
    00181      }
    00182
    00183      u32 tempDataSize = ((tempHeader.tgaWidth * tempHeader.tgaHeight * ((tempHeader.tgaBPP + 1) & ~7)) >> 3);
    00184      u8* tempData = (u8*)memQalloc(tempDataSize);
    00185      if(!tempData) {
    00186           #if FL_DEBUG_ERROR != 0
    00187           debugError("Couldn't create temporary data, while loading \"%s\".\nOut of memory.", inPath);
    00188           #endif
    00189           palFree(tempPalette);
    00190           fileClose(tempFile);
    00191           return NULL;
    00192      }
    00193
    00194      u8 tempChar;
    00195      u32 tempPtr = 0;
    00196      u32 tempPixel;
    00197      if(tempHeader.tgaImageType & 8) {
    00198           while(tempPtr < (tempHeader.tgaWidth * tempHeader.tgaHeight)) {
    00199                fileRead(&tempChar, 1, tempFile);
    00200                if(tempChar & 0x80) {
    00201                     fileRead(&tempPixel, tempByPP, tempFile);
    00202                     for(i = 0; i <= (tempChar & 0x7F); i++)
    00203                          memCopy(&tempData[(tempPtr + i) * tempByPP], &tempPixel, tempByPP);
    00204                } else {
    00205                     for(i = 0; i <= (tempChar & 0x7F); i++)
    00206                          fileRead(&tempData[(tempPtr + i) * tempByPP], tempByPP, tempFile);
    00207                }
    00208                tempPtr += ((tempChar & 0x7F) + 1);
    00209           }
    00210      } else {
    00211           fileRead(tempData, tempDataSize, tempFile);
    00212      }
    00213      fileClose(tempFile);
    00214
    00215      u32 tempDataLineSize = ((tempHeader.tgaWidth * ((tempHeader.tgaBPP + 1) & ~7)) >> 3);
    00216      if(!(tempHeader.tgaDescriptor & 0x20)) {
    00217           u8* tempDataLine = (u8*)memQalloc(tempDataLineSize);
    00218           if(!tempDataLine) {
    00219                #if FL_DEBUG_ERROR != 0
    00220                debugError("Couldn't create temporary data cache, while loading \"%s\".\nOut of memory.", inPath);
    00221                #endif
    00222                palFree(tempPalette);
    00223                memFree(tempData);
    00224                return NULL;
    00225           }
    00226           for(i = 0; i < (tempHeader.tgaHeight >> 1); i++) {
    00227                memCopy(tempDataLine, &tempData[i * tempDataLineSize], tempDataLineSize);
    00228                memCopy(&tempData[i * tempDataLineSize], &tempData[((tempHeader.tgaHeight - 1) - i) * tempDataLineSize], tempDataLineSize);
    00229                memCopy(&tempData[((tempHeader.tgaHeight - 1) - i) * tempDataLineSize], tempDataLine, tempDataLineSize);
    00230           }
    00231           memFree(tempDataLine);
    00232      }
    00233      if(tempHeader.tgaDescriptor & 0x10) {
    00234           for(j = 0; j < tempHeader.tgaHeight; j++) {
    00235                for(i = 0; i < (tempHeader.tgaWidth >> 1); i++) {
    00236                     memCopy(&tempPixel, &tempData[(j * tempDataLineSize) + (i * tempByPP)], tempByPP);
    00237                     memCopy(&tempData[(j * tempDataLineSize) + (i * tempByPP)], &tempData[(j * tempDataLineSize) + (((tempHeader.tgaWidth - 1) - i) * tempByPP)], tempByPP);
    00238                     memCopy(&tempData[(j * tempDataLineSize) + (((tempHeader.tgaWidth - 1) - i) * tempByPP)], &tempPixel, tempByPP);
    00239                }
    00240           }
    00241      }
    00242
    00243      Texture* tempOut = texCreate(tempHeader.tgaWidth, tempHeader.tgaHeight, tempPixelFormat);
    00244      if(!tempOut) {
    00245           #if FL_DEBUG_ERROR != 0
    00246           debugError("Couldn't create texture struct, while loading \"%s\".\nProbably out of memory.", inPath);
    00247           #endif
    00248           palFree(tempPalette);
    00249           memFree(tempData);
    00250           return NULL;
    00251      }
    00252      #if FL_TEXTURE_PRESERVENONALPHA != 0
    00253      tempOut->texAlpha = tempAlpha;
    00254      #endif
    00255
    00256      if(tempHeader.tgaPaletteType) {
    00257           tempOut->texPalette = tempPalette;
    00258           if(tempHeader.tgaBPP == 8) {
    00259                for(j = 0; j < tempHeader.tgaHeight; j++) {
    00260                     for(i = 0; i < tempHeader.tgaWidth; i++) {
    00261                          tempOut->texData[((j * tempOut->texDataWidth) + i)] = tempData[(j * tempDataLineSize) + i];
    00262                     }
    00263                }
    00264           } else if(tempHeader.tgaBPP == 4) {
    00265                for(j = 0; j < tempHeader.tgaHeight; j++) {
    00266                     for(i = 0; i < ((tempHeader.tgaWidth + 1) >> 1); i++) {
    00267                          tempOut->texData[((j * tempOut->texDataWidth) + i)] = tempData[(j * tempDataLineSize) + i];
    00268                     }
    00269                }
    00270           }
    00271      } else {
    00272           if((tempHeader.tgaImageType & 3) == 3) {
    00273                if(tempHeader.tgaBPP == 8) {
    00274                     for(j = 0; j < tempHeader.tgaHeight; j++) {
    00275                          for(i = 0; i < tempHeader.tgaWidth; i++) {
    00276                               tempOut->texData[((j * tempOut->texDataWidth) + i)] = tempData[(j * tempDataLineSize) + i];
    00277                          }
    00278                     }
    00279                }
    00280           } else {
    00281                if((tempHeader.tgaBPP == 24) && ((tempHeader.tgaDescriptor & 0x0F) == 0)) {
    00282                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00283                     tempOut->texAlpha = false;
    00284                     #endif
    00285                     for(j = 0; j < tempHeader.tgaHeight; j++) {
    00286                          for(i = 0; i < tempHeader.tgaWidth; i++) {
    00287                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 0] = tempData[(j * tempDataLineSize) + (i * 3) + 2];
    00288                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 1] = tempData[(j * tempDataLineSize) + (i * 3) + 1];
    00289                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 2] = tempData[(j * tempDataLineSize) + (i * 3) + 0];
    00290                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 3] = 0xFF;
    00291                          }
    00292                     }
    00293                } else if((tempHeader.tgaBPP == 32) && ((tempHeader.tgaDescriptor & 0x0F) == 8)) {
    00294                     for(j = 0; j < tempHeader.tgaHeight; j++) {
    00295                          for(i = 0; i < tempHeader.tgaWidth; i++) {
    00296                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 0] = tempData[(j * tempDataLineSize) + (i << 2) + 2];
    00297                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 1] = tempData[(j * tempDataLineSize) + (i << 2) + 1];
    00298                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 2] = tempData[(j * tempDataLineSize) + (i << 2) + 0];
    00299                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 2) + 3] = tempData[(j * tempDataLineSize) + (i << 2) + 3];
    00300                          }
    00301                     }
    00302                } else if((tempHeader.tgaBPP == 15) || ((tempHeader.tgaBPP == 16) && ((tempHeader.tgaDescriptor & 0x0F) == 1))) {
    00303                     for(j = 0; j < tempHeader.tgaHeight; j++) {
    00304                          for(i = 0; i < tempHeader.tgaWidth; i++) {
    00305                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 1) + 0] = tempData[(j * tempDataLineSize) + (i << 1) + 1];
    00306                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 1) + 1] = tempData[(j * tempDataLineSize) + (i << 1)];
    00307                          }
    00308                     }
    00309                } else if((tempHeader.tgaBPP == 16) && ((tempHeader.tgaDescriptor & 0x0F) == 0)) {
    00310                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00311                     tempOut->texAlpha = false;
    00312                     #endif
    00313                     for(j = 0; j < tempHeader.tgaHeight; j++) {
    00314                          for(i = 0; i < tempHeader.tgaWidth; i++) {
    00315                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 1) + 0] = tempData[(j * tempDataLineSize) + (i << 1) + 1];
    00316                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 1) + 1] = tempData[(j * tempDataLineSize) + (i << 1)];
    00317                          }
    00318                     }
    00319                } else if((tempHeader.tgaBPP == 16) && ((tempHeader.tgaDescriptor & 0x0F) == 4)) {
    00320                     for(j = 0; j < tempHeader.tgaHeight; j++) {
    00321                          for(i = 0; i < tempHeader.tgaWidth; i++) {
    00322                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 1) + 0] = tempData[(j * tempDataLineSize) + (i << 1) + 1];
    00323                               tempOut->texData[(((j * tempOut->texDataWidth) + i) << 1) + 1] = tempData[(j * tempDataLineSize) + (i << 1)];
    00324                          }
    00325                     }
    00326                }
    00327           }
    00328      }
    00329
    00330      memFree(tempData);
    00331      return tempOut;
    00332 }
    00333
    00334 bool texSaveTGA(Texture* inTex, char* inPath) {
    00335      if(!inTex) {
    00336           #if FL_DEBUG_ERROR != 0
    00337           debugError("Trying to save NULL texture.");
    00338           #endif
    00339           return false;
    00340      }
    00341      if(texPalettized(inTex)) {
    00342           if(!inTex->texPalette) {
    00343                #if FL_DEBUG_WARNING != 0
    00344                debugError("Trying to save palettized texture without palette.");
    00345                #endif
    00346                return false;
    00347           }
    00348           if(inTex->texPalette->palPixelFormat != GU_PSM_8888) {
    00349                #if FL_DEBUG_WARNING != 0
    00350                debugWarning("Only 24/32 bit textures are supported for saving at the minute.");
    00351                #endif
    00352                return false;
    00353           }
    00354      } else if(inTex->texPixelFormat != GU_PSM_8888) {
    00355           #if FL_DEBUG_WARNING != 0
    00356           debugWarning("Only 32 bit textures are supported for saving at the minute.");
    00357           #endif
    00358           return false;
    00359      }
    00360
    00361      #if FL_GRAPHICS != 0
    00362      bool tempReswizzle = false;
    00363      if(inTex->texSwizzled) {
    00364           if(texUnswizzle(inTex)) {
    00365                tempReswizzle = true;
    00366           } else {
    00367                #if FL_DEBUG_WARNING != 0
    00368                debugWarning("Can't un-swizzle texture for saving.");
    00369                #endif
    00370                return false;
    00371           }
    00372      }
    00373      #else
    00374      if(inTex->texSwizzled) {
    00375           #if FL_DEBUG_WARNING != 0
    00376                debugWarning("Can't un-swizzle texture for saving, because flGraphics isn't compiled in.");
    00377                #endif
    00378           return false;
    00379      }
    00380      #endif
    00381
    00382      tgaFileHeader tempHeader;
    00383      tempHeader.tgaIdentSize = 0;
    00384      if(texPalettized(inTex)) {
    00385           tempHeader.tgaImageType = 1;
    00386           tempHeader.tgaPaletteType = 1;
    00387           tempHeader.tgaPaletteLen = inTex->texPalette->palEntries;
    00388           tempHeader.tgaPaletteStart = 0;
    00389           switch(inTex->texPalette->palPixelFormat) {
    00390                case GU_PSM_8888:
    00391                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00392                     if(inTex->texAlpha) {
    00393                          tempHeader.tgaDescriptor = 8;
    00394                          tempHeader.tgaPaletteBPP = 32;
    00395                     } else {
    00396                          tempHeader.tgaDescriptor = 0;
    00397                          tempHeader.tgaPaletteBPP = 24;
    00398                     }
    00399                     #else
    00400                     tempHeader.tgaDescriptor = 8;
    00401                     tempHeader.tgaPaletteBPP = 32;
    00402                     #endif
    00403                     break;
    00404                case GU_PSM_4444:
    00405                     tempHeader.tgaDescriptor = 4;
    00406                     tempHeader.tgaPaletteBPP = 16;
    00407                     break;
    00408                case GU_PSM_5551:
    00409                     tempHeader.tgaDescriptor = 1;
    00410                     tempHeader.tgaPaletteBPP = 16;
    00411                     break;
    00412                case GU_PSM_5650:
    00413                     tempHeader.tgaDescriptor = 0;
    00414                     tempHeader.tgaPaletteBPP = 16;
    00415                     break;
    00416                default:
    00417                     tempHeader.tgaDescriptor = 0;
    00418                     tempHeader.tgaPaletteBPP = 16;
    00419                     break;
    00420           }
    00421           tempHeader.tgaBPP = texBPP(inTex);
    00422      } else {
    00423           tempHeader.tgaImageType = 2;
    00424           tempHeader.tgaPaletteType = 0;
    00425           tempHeader.tgaPaletteBPP = 0;
    00426           tempHeader.tgaPaletteLen = 0;
    00427           tempHeader.tgaPaletteStart = 0;
    00428           switch(inTex->texPixelFormat) {
    00429                case GU_PSM_8888:
    00430                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00431                     if(inTex->texAlpha) {
    00432                          tempHeader.tgaDescriptor = 8;
    00433                          tempHeader.tgaBPP = 32;
    00434                     } else {
    00435                          tempHeader.tgaDescriptor = 0;
    00436                          tempHeader.tgaBPP = 24;
    00437                     }
    00438                     #else
    00439                     tempHeader.tgaDescriptor = 8;
    00440                     tempHeader.tgaBPP = 32;
    00441                     #endif
    00442                     break;
    00443                case GU_PSM_4444:
    00444                     tempHeader.tgaDescriptor = 4;
    00445                     tempHeader.tgaBPP = 16;
    00446                     break;
    00447                case GU_PSM_5551:
    00448                     tempHeader.tgaDescriptor = 1;
    00449                     tempHeader.tgaBPP = 16;
    00450                     break;
    00451                case GU_PSM_5650:
    00452                     tempHeader.tgaDescriptor = 0;
    00453                     tempHeader.tgaBPP = 16;
    00454                     break;
    00455                default:
    00456                     tempHeader.tgaDescriptor = 0;
    00457                     tempHeader.tgaBPP = texBPP(inTex);
    00458                     break;
    00459           }
    00460      }
    00461      tempHeader.tgaXStart = 0;
    00462      tempHeader.tgaYStart = 0;
    00463      tempHeader.tgaWidth = inTex->texWidth;
    00464      tempHeader.tgaHeight = inTex->texHeight;
    00465
    00466      #if FL_FILE != 0
    00467      File* tempFile = fileOpen(inPath, FILE_MODE_WRITE | FILE_MODE_BINARY);
    00468      #else
    00469      FILE* tempFile = fopen(inPath, "wb");
    00470      #endif
    00471      if(!tempFile) {
    00472           #if FL_DEBUG_ERROR != 0
    00473           debugError("Cannot open TGA file(%s) for writing.", inPath);
    00474           #endif
    00475           return false;
    00476      }
    00477      fileWrite(&tempHeader.tgaIdentSize, 1, tempFile);
    00478      fileWrite(&tempHeader.tgaPaletteType, 1, tempFile);
    00479      fileWrite(&tempHeader.tgaImageType, 1, tempFile);
    00480      fileWrite(&tempHeader.tgaPaletteStart, 2, tempFile);
    00481      fileWrite(&tempHeader.tgaPaletteLen, 2, tempFile);
    00482      fileWrite(&tempHeader.tgaPaletteBPP, 1, tempFile);
    00483      fileWrite(&tempHeader.tgaXStart, 2, tempFile);
    00484      fileWrite(&tempHeader.tgaYStart, 2, tempFile);
    00485      fileWrite(&tempHeader.tgaWidth, 2, tempFile);
    00486      fileWrite(&tempHeader.tgaHeight, 2, tempFile);
    00487      fileWrite(&tempHeader.tgaBPP, 1, tempFile);
    00488      fileWrite(&tempHeader.tgaDescriptor, 1, tempFile);
    00489      int i, j;
    00490      if(texPalettized(inTex)) {
    00491           switch(inTex->texPalette->palPixelFormat) {
    00492                case GU_PSM_8888:
    00493                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00494                     if(inTex->texAlpha) {
    00495                     #endif
    00496                          for(i = 0; i < tempHeader.tgaPaletteLen; i++) {
    00497                               fileWrite(&inTex->texPalette->palData[(i << 2) + 2], 1, tempFile);
    00498                               fileWrite(&inTex->texPalette->palData[(i << 2) + 1], 1, tempFile);
    00499                               fileWrite(&inTex->texPalette->palData[(i << 2) + 0], 1, tempFile);
    00500                               fileWrite(&inTex->texPalette->palData[(i << 2) + 3], 1, tempFile);
    00501                          }
    00502                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00503                     } else {
    00504                          for(i = 0; i < tempHeader.tgaPaletteLen; i++) {
    00505                               fileWrite(&inTex->texPalette->palData[(i << 2) + 2], 1, tempFile);
    00506                               fileWrite(&inTex->texPalette->palData[(i << 2) + 1], 1, tempFile);
    00507                               fileWrite(&inTex->texPalette->palData[(i << 2) + 0], 1, tempFile);
    00508                          }
    00509                     }
    00510                     #endif
    00511                     break;
    00512                case GU_PSM_4444:
    00513                     break;
    00514                case GU_PSM_5650:
    00515                     break;
    00516                case GU_PSM_5551:
    00517                     break;
    00518           }
    00519           for(j = (inTex->texHeight - 1); j >= 0; j--)
    00520                fileWrite(&inTex->texData[(j * inTex->texDataWidth * texBPP(inTex)) >> 3], ((inTex->texWidth * texBPP(inTex)) >> 3), tempFile);
    00521      } else {
    00522           switch(inTex->texPixelFormat) {
    00523                case GU_PSM_8888:
    00524                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00525                     if(inTex->texAlpha) {
    00526                     #endif
    00527                          for(j = (inTex->texHeight - 1); j >= 0; j--) {
    00528                               for(i = 0; i < inTex->texWidth; i++) {
    00529                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 2], 1, tempFile);
    00530                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 1], 1, tempFile);
    00531                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 0], 1, tempFile);
    00532                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 3], 1, tempFile);
    00533                               }
    00534                          }
    00535                     #if FL_TEXTURE_PRESERVENONALPHA != 0
    00536                     } else {
    00537                          for(j = (inTex->texHeight - 1); j >= 0; j--) {
    00538                               for(i = 0; i < inTex->texWidth; i++) {
    00539                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 2], 1, tempFile);
    00540                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 1], 1, tempFile);
    00541                                    fileWrite(&inTex->texData[(((j * inTex->texDataWidth) + i) << 2) + 0], 1, tempFile);
    00542                               }
    00543                          }
    00544                     }
    00545                     #endif
    00546                     break;
    00547                case GU_PSM_4444:
    00548                     break;
    00549                case GU_PSM_5650:
    00550                     break;
    00551                case GU_PSM_5551:
    00552                     break;
    00553           }
    00554      }
    00555
    00556      fileClose(tempFile);
    00557
    00558      #if FL_GRAPHICS != 0
    00559      if(tempReswizzle)
    00560           texSwizzle(inTex);
    00561      #endif
    00562
    00563      return true;
    00564 }
    00565
    00566 #endif