- Main Page
- Classes
- Files

- File List
- File Members

# flTexturePCX.c

Go to the documentation of this file.

    00001 #include "flGlobal.h"
    00002 #if FL_TEXTURE_PCX != 0
    00003 #include <stdlib.h>
    00004 #include <string.h>
    00005 #include <pspgu.h>
    00006
    00007 #if FL_INCLUDE_ALL_C == 0
    00008 #include "flTexturePCX.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      char  manufacturer;
    00020      char  version;
    00021      char  encoding;
    00022      char  bpp;
    00023      short xMin;
    00024      short yMin;
    00025      short xMax;
    00026      short yMax;
    00027      short horizontalDPI;
    00028      short verticalDPI;
    00029      char  palette[48];
    00030      char  reserved;
    00031      char  colorPlanes;
    00032      short bytesPerLine;
    00033      short paletteType;
    00034      short hScrSize;
    00035      short vScrSize;
    00036      char  filler[54];
    00037 } pcxFileHeader;
    00038
    00039 Texture* texLoadPCX(char* inPath) {
    00040      #if FL_FILE != 0
    00041      File* tempFile = fileOpen(inPath, FILE_MODE_READ | FILE_MODE_BINARY);
    00042      #else
    00043      FILE* tempFile = fopen(inPath, "rb");
    00044      #endif
    00045      if(!tempFile) {
    00046           #if FL_DEBUG_ERROR != 0
    00047           debugError("PCX load error (%s).\nFile cannot be opened", inPath);
    00048           #endif
    00049           return NULL;
    00050      }
    00051      pcxFileHeader tempHeader;
    00052
    00053      fileRead(&tempHeader.manufacturer, 1, tempFile);
    00054      fileRead(&tempHeader.version, 1, tempFile);
    00055      if((tempHeader.version != 0) && (tempHeader.version != 2) && (tempHeader.version != 5)) {
    00056           #if FL_DEBUG_ERROR != 0
    00057           debugError("PCX file error (%s).\nVersion not supported (%i).\nSupported versions are 0, 2 & 5.", inPath, tempHeader.version);
    00058           #endif
    00059           fileClose(tempFile);
    00060           return NULL;
    00061      }
    00062      fileRead(&tempHeader.encoding, 1, tempFile);
    00063      fileRead(&tempHeader.bpp, 1, tempFile);
    00064      if((tempHeader.bpp != 1) && (tempHeader.bpp != 4) && (tempHeader.bpp != 8) && (tempHeader.bpp != 24)) {
    00065           #if FL_DEBUG_ERROR != 0
    00066           debugError("PCX file error (%s).\nBPP not supported (%i).\nSupported BPPs are 1, 4, 8 & 24.", inPath, tempHeader.bpp);
    00067           #endif
    00068           fileClose(tempFile);
    00069           return NULL;
    00070      }
    00071
    00072      fileRead(&tempHeader.xMin, 2, tempFile);
    00073      fileRead(&tempHeader.yMin, 2, tempFile);
    00074      fileRead(&tempHeader.xMax, 2, tempFile);
    00075      fileRead(&tempHeader.yMax, 2, tempFile);
    00076      fileRead(&tempHeader.horizontalDPI, 2, tempFile);
    00077      fileRead(&tempHeader.verticalDPI, 2, tempFile);
    00078      fileRead(&tempHeader.palette[0], 48, tempFile);
    00079      fileRead(&tempHeader.reserved, 1, tempFile);
    00080      fileRead(&tempHeader.colorPlanes, 1, tempFile);
    00081      //if((tempHeader.colorPlanes != 3) && (tempHeader.colorPlanes != 4))
    00082      //     tempHeader.colorPlanes = 1;
    00083      fileRead(&tempHeader.bytesPerLine, 2, tempFile);
    00084      fileRead(&tempHeader.paletteType, 2, tempFile);
    00085      fileRead(&tempHeader.hScrSize, 2, tempFile);
    00086      fileRead(&tempHeader.vScrSize, 2, tempFile);
    00087      fileRead(&tempHeader.filler[0], 54, tempFile);
    00088
    00089      int tempWidth = (tempHeader.xMax - tempHeader.xMin);
    00090      int tempHeight = (tempHeader.yMax - tempHeader.yMin);
    00091      if(tempWidth <= 0)
    00092           tempWidth = 0 - tempWidth;
    00093      if(tempHeight <= 0)
    00094           tempHeight = 0 - tempHeight;
    00095      tempHeight++;
    00096      tempWidth++;
    00097
    00098      u8* tempData = (u8*)memQalloc(tempHeader.bytesPerLine * tempHeader.colorPlanes * tempHeight);
    00099      if(!tempData) {
    00100           #if FL_DEBUG_ERROR != 0
    00101           debugError("PCX load error (%s).\nOut of memory.", inPath);
    00102           #endif
    00103           fileClose(tempFile);
    00104           return NULL;
    00105      }
    00106      u8    tempChar;
    00107      u32   tempX = 0;
    00108      u32   tempLine;
    00109      u32   tempPlane;
    00110      u8    tempCount;
    00111      u32   i;
    00112      if(tempHeader.encoding == 1) {
    00113           for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00114                for(tempPlane = 0; tempPlane < tempHeader.colorPlanes; tempPlane++) {
    00115                     tempX = 0;
    00116                     while(tempX < tempHeader.bytesPerLine) {
    00117                          fileRead(&tempChar, 1, tempFile);
    00118                          if((tempChar & 0xC0) == 0xC0) {
    00119                               tempCount = (tempChar & 0x3F);
    00120                               fileRead(&tempChar, 1, tempFile);
    00121                          } else
    00122                               tempCount = 1;
    00123                          for(i = 0; i < tempCount; i++)
    00124                               tempData[(((tempLine * tempHeader.colorPlanes) + tempPlane) * tempHeader.bytesPerLine) + tempX + i] = tempChar;
    00125                          tempX += tempCount;
    00126                     }
    00127                }
    00128           }
    00129      } else if(tempHeader.encoding == 0) {
    00130           for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00131                for(tempPlane = 0; tempPlane < tempHeader.colorPlanes; tempPlane++)
    00132                     fileRead(&tempData[((tempLine * tempHeader.colorPlanes) + tempPlane) * tempHeader.bytesPerLine], tempHeader.bytesPerLine, tempFile);
    00133           }
    00134      } else {
    00135           #if FL_DEBUG_ERROR != 0
    00136           debugError("PCX load error (%s).\nEncoding type %i not supported.", inPath, tempHeader.encoding);
    00137           #endif
    00138           fileClose(tempFile);
    00139           return NULL;
    00140      }
    00141
    00142      char* tempPalette = tempHeader.palette;
    00143      char tempBigPalette[768];
    00144      if((tempHeader.bpp == 8) && (tempHeader.colorPlanes == 1)) {
    00145           fileSeek(tempFile, -769, FILE_SEEK_END);
    00146           fileRead(&tempChar, 1, tempFile);
    00147           if(tempChar == 12) {
    00148                fileRead(&tempBigPalette[0], 768, tempFile);
    00149                tempPalette = tempBigPalette;
    00150           }
    00151      }
    00152      fileClose(tempFile);
    00153
    00154
    00155      u8 tempPixelFormat = GU_PSM_8888;
    00156      u8 tempRealBPP = (tempHeader.colorPlanes * tempHeader.bpp);
    00157      if(tempRealBPP <= 4) {
    00158           tempPixelFormat = GU_PSM_T4;
    00159      } else if(tempRealBPP == 8) {
    00160           tempPixelFormat = GU_PSM_T8;
    00161      }
    00162      Texture* tempOut = texCreate(tempWidth, tempHeight, tempPixelFormat);
    00163      if(!tempOut) {
    00164           #if FL_DEBUG_ERROR != 0
    00165           debugError("PCX load error (%s).\nCouldn't create texture struct.", inPath);
    00166           #endif
    00167           return NULL;
    00168      }
    00169      #if FL_TEXTURE_PRESERVENONALPHA != 0
    00170      tempOut->texAlpha = false;
    00171      #endif
    00172
    00173
    00174      if(texPalettized(tempOut)) {
    00175           tempOut->texPalette = palCreate((tempPixelFormat == GU_PSM_T4 ? 16 : 256) , GU_PSM_8888, false);
    00176           for(i = 0; i < (1 << tempHeader.bpp); i++) {
    00177                tempOut->texPalette->palData[i << 2] = tempPalette[i * 3];
    00178                tempOut->texPalette->palData[(i << 2) + 1] = tempPalette[(i * 3) + 1];
    00179                tempOut->texPalette->palData[(i << 2) + 2] = tempPalette[(i * 3) + 2];
    00180                tempOut->texPalette->palData[(i << 2) + 3] = 0xFF;
    00181           }
    00182      }
    00183
    00184      if(tempHeader.colorPlanes <= 1) {
    00185           if(tempHeader.bpp == 1) {
    00186                for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00187                     for(tempX = 0; tempX < ((tempWidth + 7) >> 3); tempX++) {
    00188                          tempOut->texData[(tempLine * tempOut->texDataWidth) + (tempX << 2)] = ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x80) >> 3) + ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x40) >> 6);
    00189                          tempOut->texData[(tempLine * tempOut->texDataWidth) + (tempX << 2) + 1] = ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x20) >> 1) + ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x10) >> 4);
    00190                          tempOut->texData[(tempLine * tempOut->texDataWidth) + (tempX << 2) + 2] = ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x08) << 1) + ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x04) >> 2);
    00191                          tempOut->texData[(tempLine * tempOut->texDataWidth) + (tempX << 2) + 3] = ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x02) << 3) + (tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x01);
    00192                     }
    00193                }
    00194           } else if(tempHeader.bpp == 2) {
    00195                for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00196                     for(tempX = 0; tempX < ((tempWidth + 3) >> 2); tempX++) {
    00197                          tempOut->texData[(tempLine * tempOut->texDataWidth) + (tempX << 1)] = ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0xC0) >> 2) + ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x30) >> 4);
    00198                          tempOut->texData[(tempLine * tempOut->texDataWidth) + (tempX << 1) + 1] = ((tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x0C) << 2) + (tempData[(tempLine * tempHeader.bytesPerLine) + tempX] & 0x03);
    00199                     }
    00200                }
    00201           } else if(tempHeader.bpp == 4) {
    00202                for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00203                     for(tempX = 0; tempX < ((tempWidth + 1) >> 1); tempX++) {
    00204                          tempOut->texData[(tempLine * tempOut->texDataWidth) + tempX] = tempData[(tempLine * tempHeader.bytesPerLine) + tempX];
    00205                     }
    00206                }
    00207           } else if(tempHeader.bpp == 8) {
    00208                if(tempPalette == tempHeader.palette) {
    00209                     #if FL_DEBUG_ERROR != 0
    00210                     debugError("PCX load error (%s).\n256 color image doesn't contain a palette.", inPath);
    00211                     #endif
    00212                     memFree(tempData);
    00213                     texFree(tempOut);
    00214                     return NULL;
    00215                }
    00216                for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00217                     for(tempX = 0; tempX < tempWidth; tempX++) {
    00218                          tempOut->texData[(tempLine * tempOut->texDataWidth) + tempX] =  tempData[(tempLine * tempHeader.bytesPerLine) + tempX];
    00219                     }
    00220                }
    00221           } else {
    00222                #if FL_DEBUG_ERROR != 0
    00223                debugError("PCX load error (%s).\nUnsupported BPP(%i)/ColorPlane(%i) combo.", inPath, tempHeader.bpp, tempHeader.colorPlanes);
    00224                #endif
    00225                memFree(tempData);
    00226                texFree(tempOut);
    00227                return NULL;
    00228           }
    00229      } else if(tempHeader.colorPlanes == 3) {
    00230           if(tempHeader.bpp == 8) {
    00231                for(tempLine = 0; tempLine < tempHeight; tempLine++) {
    00232                     for(tempX = 0; tempX < tempWidth; tempX++) {
    00233                          tempOut->texData[((tempLine * 3) * (tempOut->texDataWidth << 2)) + (tempX << 2)] = tempData[((tempLine * 3) * tempHeader.bytesPerLine) + tempX];
    00234                          tempOut->texData[((tempLine * 3) * (tempOut->texDataWidth << 2)) + (tempX << 2) + 1] = tempData[(((tempLine * 3) + 1) * tempHeader.bytesPerLine) + tempX];
    00235                          tempOut->texData[((tempLine * 3) * (tempOut->texDataWidth << 2)) + (tempX << 2) + 2] = tempData[(((tempLine * 3) + 2) * tempHeader.bytesPerLine) + tempX];
    00236                          tempOut->texData[((tempLine * 3) * (tempOut->texDataWidth << 2)) + (tempX << 2) + 3] = 0xFF;
    00237                     }
    00238                }
    00239           } else {
    00240                #if FL_DEBUG_ERROR != 0
    00241                debugError("PCX load error (%s).\nUnsupported BPP(%i)/ColorPlane(%i) combo.", inPath, tempHeader.bpp, tempHeader.colorPlanes);
    00242                #endif
    00243                memFree(tempData);
    00244                texFree(tempOut);
    00245                return NULL;
    00246           }
    00247      } else {
    00248           #if FL_DEBUG_ERROR != 0
    00249           debugError("PCX load error (%s).\nUnsupported BPP(%i)/ColorPlane(%i) combo.", inPath, tempHeader.bpp, tempHeader.colorPlanes);
    00250           #endif
    00251           memFree(tempData);
    00252           texFree(tempOut);
    00253           return NULL;
    00254      }
    00255
    00256      memFree(tempData);
    00257      return tempOut;
    00258 }
    00259
    00260 bool texSavePCX(Texture* inTex, char* inPath) {
    00261      #if FL_DEBUG_WARNING != 0
    00262      debugWarning("PCX saving not yet implemented.");
    00263      #endif
    00264      return false;
    00265 }
    00266
    00267 #endif