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

Generated on Wed Sep 5 19:04:01 2007 for funcLib by  doxygen 1.5.1