flTextureBMP.c

Go to the documentation of this file.
00001 #include "flGlobal.h"
00002 #if FL_TEXTURE_BMP != 0
00003 #include <stdlib.h>
00004 #include <string.h>
00005 #include <pspgu.h>
00006 
00007 #if FL_INCLUDE_ALL_C == 0
00008 #include "flTextureBMP.h"
00009 #include "flMemory.h"
00010 #include "flFile.h"
00011 
00012 #if FL_DEBUG != 0
00013 #include "flDebug.h"
00014 #endif
00015 #endif
00016 
00017 #include "flTextureBMPWinPal.c"
00018 
00019 typedef struct {
00020      u8  bmpSignature[2];
00021      u32 bmpFileSize;
00022      s16 bmpReserved[2];
00023      u32 bmpDataOffset;
00024 } bmpHeader;
00025 
00026 /* THESE STRUCTS ARE KEPT HERE FOR REFERENCE
00027 
00028 typedef struct {
00029     u16 Type;
00030     u16 Width;
00031     u16 Height;
00032     u16 bmpByteWidth;
00033     u8  bmpPlanes;
00034     u8  bmpBPP;
00035 } bmpInfoHeaderWV1;
00036 
00037 typedef struct {
00038      u32 bmpSize;
00039      u16 bmpWidth;
00040      u16 bmpHeight;
00041      u16 bmpPlanes;
00042      u16 bmpBPP;
00043 } bmpInfoHeaderWV2;
00044 
00045 typedef struct {
00046      u32 bmpSize;
00047      s32 bmpWidth;
00048      s32 bmpHeight;
00049      u16 bmpPlanes;
00050      u16 bmpBPP;
00051      u32 bmpCompression;
00052      u32 bmpImageSize;
00053      s32 bmpXResolution;
00054      s32 bmpYResolution;
00055      u32 bmpColorsUsed;
00056      u32 bmpColorsImportant;
00057 } bmpInfoHeaderWV3;
00058 
00059 typedef struct {
00060      u32 bmpSize;
00061      s32 bmpWidth;
00062      s32 bmpHeight;
00063      u16 bmpPlanes;
00064      u16 bmpBPP;
00065      u32 bmpCompression;
00066      u32 bmpSizeImage;
00067      s32 bmpXResolution;
00068      s32 bmpYResolution;
00069      u32 bmpColorsUsed;
00070      u32 bmpColorsImportant;
00071      u32 bmpRedMask;
00072      u32 bmpGreenMask;
00073      u32 bmpBlueMask;
00074      u32 bmpAlphaMask;
00075      u32 bmpCSType;
00076      s32 bmpEndpoints[9];
00077      u32 bmpGammaRed;
00078      u32 bmpGammaGreen;
00079      u32 bmpGammaBlue;
00080 } bmpInfoHeaderWV4;
00081 
00082 typedef struct { 
00083      u32 bmpSize;
00084      s32 bmpWidth;
00085      s32 bmpHeight;
00086      u16 bmpPlanes;
00087      u16 bmpBPP;
00088      u32 bmpCompression;
00089      u32 bmpImageSize;
00090      s32 bmpXResolution;
00091      s32 bmpYResolution;
00092      u32 bmpColorsUsed;
00093      u32 bmpColorsImportant;
00094      u32 bmpRedMask;
00095      u32 bmpGreenMask;
00096      u32 bmpBlueMask;
00097      u32 bmpAlphaMask;
00098      u32 bmpCSType;
00099      s32 bmpEndpoints[9];
00100      u32 bmpGammaRed;
00101      u32 bmpGammaGreen;
00102      u32 bmpGammaBlue;
00103      u32 bmpIntent;
00104      u32 bmpProfileData;
00105      u32 bmpProfileSize;
00106      u32 bmpReserved;
00107 } bmpInfoHeaderWV5;
00108 
00109 typedef struct {
00110      u32 bmpSize;
00111      u16 bmpWidth;
00112      u16 bmpHeight;
00113      u16 bmpPlanes;
00114      u16 bmpBPP;
00115 } bmpInfoHeaderOS2V1;
00116 
00117 typedef struct {
00118      u32 bmpSize;
00119      u32 bmpWidth;
00120      u32 bmpHeight;
00121      u16 bmpPlanes;
00122      u16 bmpBPP;
00123      u32 bmpCompression;
00124      u32 bmpImageSize;
00125      u32 bmpXResolution;
00126      u32 bmpYResolution;
00127      u32 bmpColorsUsed;
00128      u32 bmpColorsImportant;
00129      u16 bmpUnits;
00130      u16 bmpReserved;
00131      u16 bmpRecording;
00132      u16 bmpRendering;
00133      u32 bmpSize1;
00134      u32 bmpSize2;
00135      u32 bmpColorEncoding;
00136      u32 bmpIdentifier;
00137 } bmpInfoHeaderOS2V2;*/
00138 
00139 typedef struct {
00140      u16 bmpType;
00141      u32 bmpSize;
00142      s32 bmpWidth;
00143      s32 bmpHeight;
00144      u16 bmpByteWidth;
00145      u16 bmpPlanes;
00146      u16 bmpBPP;
00147      u32 bmpCompression;
00148      u32 bmpImageSize;
00149      s32 bmpXResolution;
00150      s32 bmpYResolution;
00151      u32 bmpColorsUsed;
00152      u32 bmpColorsImportant;
00153      u32 bmpRedMask;
00154      u32 bmpGreenMask;
00155      u32 bmpBlueMask;
00156      u32 bmpAlphaMask;
00157      u32 bmpCSType;
00158      s32 bmpEndpoints[9];
00159      u32 bmpGammaRed;
00160      u32 bmpGammaGreen;
00161      u32 bmpGammaBlue;
00162      u32 bmpIntent;
00163      u32 bmpProfileData;
00164      u32 bmpProfileSize;
00165      u16 bmpUnits;
00166      u16 bmpReserved;
00167      u16 bmpRecording;
00168      u16 bmpRendering;
00169      u32 bmpSize1;
00170      u32 bmpSize2;
00171      u32 bmpColorEncoding;
00172      u32 bmpIdentifier;
00173 } bmpInfoHeaderGeneric;
00174 
00175 #define BMP_WIN_COMPRESSION_RGB       0
00176 #define BMP_WIN_COMPRESSION_RLE8      1
00177 #define BMP_WIN_COMPRESSION_RLE4      2
00178 #define BMP_WIN_COMPRESSION_BITFIELDS 3
00179 #define BMP_WIN_COMPRESSION_JPEG      4
00180 #define BMP_WIN_COMPRESSION_PNG       5
00181 
00182 #define BMP_OS2_COMPRESSION_NONE      0
00183 #define BMP_OS2_COMPRESSION_RLE8      1
00184 #define BMP_OS2_COMPRESSION_RLE4      2
00185 #define BMP_OS2_COMPRESSION_HUFF1D    3
00186 #define BMP_OS2_COMPRESSION_RLE24     4
00187 
00188 #define BMP_GEN_COMPRESSION_RGB       0
00189 #define BMP_GEN_COMPRESSION_RLE4      1
00190 #define BMP_GEN_COMPRESSION_RLE8      2
00191 #define BMP_GEN_COMPRESSION_HUFF1D    3
00192 #define BMP_GEN_COMPRESSION_RLE24     4
00193 #define BMP_GEN_COMPRESSION_BITFIELDS 5
00194 #define BMP_GEN_COMPRESSION_JPEG      6
00195 #define BMP_GEN_COMPRESSION_PNG       7
00196 
00197 #define BMP_HEADER_OS2V1 12
00198 #define BMP_HEADER_OS2V2 64
00199 #define BMP_HEADER_WV1   10
00200 #define BMP_HEADER_WV2   12
00201 #define BMP_HEADER_WV3   40
00202 #define BMP_HEADER_WV4   108
00203 #define BMP_HEADER_WV5   124
00204 
00205 
00206 Texture* texLoadBMP(char* inPath) {
00207      #if FL_FILE != 0
00208      File* tempFile = fileOpen(inPath, FILE_MODE_READ | FILE_MODE_BINARY);
00209      #else
00210      FILE* tempFile = fopen(inPath, "rb");
00211      #endif
00212      if(!tempFile) {
00213           #if FL_DEBUG_ERROR != 0
00214           char tempString[256];
00215           sprintf(tempString, "BMP load error (%s).\nFile cannot be opened", inPath);
00216           debugError(tempString);
00217           #endif
00218           return NULL;
00219      }
00220      
00221      bmpHeader tempHeader;
00222      fileRead(tempHeader.bmpSignature, 2, tempFile);
00223      fileRead(&tempHeader.bmpFileSize, 4, tempFile);
00224      fileRead(tempHeader.bmpReserved, 4, tempFile);
00225      fileRead(&tempHeader.bmpDataOffset, 4, tempFile);
00226      
00227      if((tempHeader.bmpSignature[0] != 'B') || (tempHeader.bmpSignature[1] != 'M')) {
00228           fileClose(tempFile);
00229           #if FL_DEBUG_WARNING != 0
00230           debugWarning("Only BM type bitmaps are supported, not icons, pointers, arrays, etc.");
00231           #endif
00232           return NULL;
00233      }
00234      
00235      int i, j, k;
00236      
00237      bmpInfoHeaderGeneric tempInfoHeader;
00238      fileRead(&tempInfoHeader.bmpSize, 4, tempFile);
00239      tempInfoHeader.bmpType = 0;
00240      tempInfoHeader.bmpSize = tempInfoHeader.bmpSize;
00241      tempInfoHeader.bmpWidth = 0;
00242      tempInfoHeader.bmpHeight = 0;
00243      tempInfoHeader.bmpByteWidth = 0;
00244      tempInfoHeader.bmpPlanes = 1;
00245      tempInfoHeader.bmpBPP = 24;
00246      tempInfoHeader.bmpCompression = 0;
00247      tempInfoHeader.bmpImageSize = 0;
00248      tempInfoHeader.bmpXResolution = 0;
00249      tempInfoHeader.bmpYResolution = 0;
00250      tempInfoHeader.bmpColorsUsed = 0;
00251      tempInfoHeader.bmpColorsImportant = 0;
00252      tempInfoHeader.bmpRedMask = 0;
00253      tempInfoHeader.bmpGreenMask = 0;
00254      tempInfoHeader.bmpBlueMask = 0;
00255      tempInfoHeader.bmpAlphaMask = 0xFF000000;
00256      tempInfoHeader.bmpCSType = 1;
00257      for(i = 0; i < 9; i++)
00258           tempInfoHeader.bmpEndpoints[i] = 0;
00259      tempInfoHeader.bmpGammaRed = 0;
00260      tempInfoHeader.bmpGammaGreen = 0;
00261      tempInfoHeader.bmpGammaBlue = 0;
00262      tempInfoHeader.bmpIntent = 0;
00263      tempInfoHeader.bmpProfileData = 0;
00264      tempInfoHeader.bmpProfileSize = 0;
00265      tempInfoHeader.bmpReserved = 0;
00266      tempInfoHeader.bmpUnits = 0;
00267      tempInfoHeader.bmpRecording = 0;
00268      tempInfoHeader.bmpRendering = 0;
00269      tempInfoHeader.bmpSize1 = 0;
00270      tempInfoHeader.bmpSize2 = 0;
00271      tempInfoHeader.bmpColorEncoding = 0;
00272      tempInfoHeader.bmpIdentifier = 0;
00273      
00274      if(tempInfoHeader.bmpSize == BMP_HEADER_WV1) {
00275           fileRead(&tempInfoHeader.bmpType, 2, tempFile);
00276           if(tempInfoHeader.bmpType) {
00277                fileClose(tempFile);
00278                #if FL_DEBUG_WARNING != 0
00279                debugWarning("Windows bitmap type value not supported.");
00280                #endif
00281                return NULL;
00282           }
00283           fileRead(&tempInfoHeader.bmpWidth, 2, tempFile);
00284           fileRead(&tempInfoHeader.bmpHeight, 2, tempFile);
00285           fileRead(&tempInfoHeader.bmpByteWidth, 2, tempFile);
00286           fileRead(&tempInfoHeader.bmpPlanes, 1, tempFile);
00287           fileRead(&tempInfoHeader.bmpBPP, 1, tempFile);
00288      } else if((tempInfoHeader.bmpSize == BMP_HEADER_WV3) || (tempInfoHeader.bmpSize == BMP_HEADER_WV4) || (tempInfoHeader.bmpSize == BMP_HEADER_WV5)) {
00289           fileRead(&tempInfoHeader.bmpWidth, 4, tempFile);
00290           fileRead(&tempInfoHeader.bmpHeight, 4, tempFile);
00291           fileRead(&tempInfoHeader.bmpPlanes, 2, tempFile);
00292           fileRead(&tempInfoHeader.bmpBPP, 2, tempFile);
00293           fileRead(&tempInfoHeader.bmpCompression, 4, tempFile);
00294           fileRead(&tempInfoHeader.bmpImageSize, 4, tempFile);
00295           fileRead(&tempInfoHeader.bmpXResolution, 4, tempFile);
00296           fileRead(&tempInfoHeader.bmpYResolution, 4, tempFile);
00297           fileRead(&tempInfoHeader.bmpColorsUsed, 4, tempFile);
00298           fileRead(&tempInfoHeader.bmpColorsImportant, 4, tempFile);
00299           if(tempInfoHeader.bmpSize >= BMP_HEADER_WV4) {
00300                fileRead(&tempInfoHeader.bmpRedMask, 4, tempFile);
00301                fileRead(&tempInfoHeader.bmpGreenMask, 4, tempFile);
00302                fileRead(&tempInfoHeader.bmpBlueMask, 4, tempFile);
00303                fileRead(&tempInfoHeader.bmpAlphaMask, 4, tempFile);
00304                fileRead(&tempInfoHeader.bmpCSType, 4, tempFile);
00305                fileRead(tempInfoHeader.bmpEndpoints, 36, tempFile);
00306                fileRead(&tempInfoHeader.bmpGammaRed, 4, tempFile);
00307                fileRead(&tempInfoHeader.bmpGammaGreen, 4, tempFile);
00308                fileRead(&tempInfoHeader.bmpGammaBlue, 4, tempFile);
00309                if(tempInfoHeader.bmpSize == BMP_HEADER_WV5) {
00310                          fileRead(&tempInfoHeader.bmpIntent, 4, tempFile);
00311                          fileRead(&tempInfoHeader.bmpProfileData, 4, tempFile);
00312                          fileRead(&tempInfoHeader.bmpProfileSize, 4, tempFile);
00313                          fileRead(&tempInfoHeader.bmpReserved, 4, tempFile);
00314                }
00315           }
00316           if((tempInfoHeader.bmpCompression == 3) && (tempInfoHeader.bmpSize == BMP_HEADER_WV3)) {
00317                fileRead(&tempInfoHeader.bmpRedMask, 4, tempFile);
00318                fileRead(&tempInfoHeader.bmpGreenMask, 4, tempFile);
00319                fileRead(&tempInfoHeader.bmpBlueMask, 4, tempFile);
00320                tempInfoHeader.bmpCompression += 2;
00321           } else if(tempInfoHeader.bmpCompression >= 3) {
00322                fileClose(tempFile);
00323                #if FL_DEBUG_WARNING != 0
00324                switch(tempInfoHeader.bmpCompression) {
00325                     case BMP_WIN_COMPRESSION_JPEG:
00326                          debugWarning("JPEG compression not supported.");
00327                          return NULL;
00328                     case BMP_WIN_COMPRESSION_PNG:
00329                          debugWarning("PNG compression not supported within bitmaps.");
00330                          return NULL;
00331                }
00332                debugWarning("Unknown bitmap compression type.");
00333                #endif
00334                return NULL;
00335                //tempInfoHeader.bmpCompression += 2;
00336           }
00337      } else if(tempInfoHeader.bmpSize == BMP_HEADER_OS2V1) {
00338           fileRead(&tempInfoHeader.bmpWidth, 2, tempFile);
00339           fileRead(&tempInfoHeader.bmpHeight, 2, tempFile);
00340           fileRead(&tempInfoHeader.bmpPlanes, 2, tempFile);
00341           fileRead(&tempInfoHeader.bmpBPP, 2, tempFile);
00342      } else if(tempInfoHeader.bmpSize == BMP_HEADER_OS2V2) {
00343           fileRead(&tempInfoHeader.bmpWidth, 4, tempFile);
00344           fileRead(&tempInfoHeader.bmpHeight, 4, tempFile);
00345           fileRead(&tempInfoHeader.bmpPlanes, 2, tempFile);
00346           fileRead(&tempInfoHeader.bmpBPP, 2, tempFile);
00347           fileRead(&tempInfoHeader.bmpCompression, 4, tempFile);
00348           fileRead(&tempInfoHeader.bmpImageSize, 4, tempFile);
00349           fileRead(&tempInfoHeader.bmpXResolution, 4, tempFile);
00350           fileRead(&tempInfoHeader.bmpYResolution, 4, tempFile);
00351           fileRead(&tempInfoHeader.bmpColorsUsed, 4, tempFile);
00352           fileRead(&tempInfoHeader.bmpColorsImportant, 4, tempFile);
00353           fileRead(&tempInfoHeader.bmpUnits, 2, tempFile);
00354           fileRead(&tempInfoHeader.bmpReserved, 2, tempFile);
00355           fileRead(&tempInfoHeader.bmpRecording, 2, tempFile);
00356           fileRead(&tempInfoHeader.bmpRendering, 2, tempFile);
00357           fileRead(&tempInfoHeader.bmpSize1, 4, tempFile);
00358           fileRead(&tempInfoHeader.bmpSize2, 4, tempFile);
00359           fileRead(&tempInfoHeader.bmpColorEncoding,4, tempFile);
00360           fileRead(&tempInfoHeader.bmpIdentifier, 4, tempFile);
00361           if(tempInfoHeader.bmpCompression == 3) {
00362                fileClose(tempFile);
00363                #if FL_DEBUG_WARNING != 0
00364                debugWarning("Huffman 1D compression not supported.");
00365                #endif
00366                return NULL;
00367           } else if(tempInfoHeader.bmpCompression >= 5) {
00368                fileClose(tempFile);
00369                #if FL_DEBUG_WARNING != 0
00370                debugWarning("Unknown bitmap compression type.");
00371                #endif
00372                return NULL;
00373           }
00374      } else {
00375           fileClose(tempFile);
00376           #if FL_DEBUG_WARNING != 0
00377           debugWarning("Bitmap header type invalid.");
00378           #endif
00379           return NULL;
00380      }
00381      
00382      if((!tempInfoHeader.bmpWidth) || (!tempInfoHeader.bmpHeight)) {
00383           fileClose(tempFile);
00384           #if FL_DEBUG_WARNING != 0
00385           debugWarning("Bitmap dimensions invalid.");
00386           #endif
00387           return NULL;
00388      }
00389      
00390      if((tempInfoHeader.bmpColorEncoding) || (tempInfoHeader.bmpCSType != 1)) {
00391           fileClose(tempFile);
00392           #if FL_DEBUG_WARNING != 0
00393           debugWarning("Invalid color model / color space.");
00394           #endif
00395           return NULL;
00396      }
00397      if(tempInfoHeader.bmpRecording) {
00398           fileClose(tempFile);
00399           #if FL_DEBUG_WARNING != 0
00400           debugWarning("Invalid recording mode.");
00401           #endif
00402           return NULL;
00403      }
00404      if(tempInfoHeader.bmpPlanes & 0xFE) {
00405           fileClose(tempFile);
00406           #if FL_DEBUG_WARNING != 0
00407           debugWarning("Multiple color planes not supported.");
00408           #endif
00409           return NULL;
00410      }
00411      
00412      bool tempVFlip = !(tempInfoHeader.bmpHeight < 0);
00413      bool tempHFlip = (tempInfoHeader.bmpWidth < 0);
00414      tempInfoHeader.bmpWidth = pos(tempInfoHeader.bmpWidth);
00415      tempInfoHeader.bmpHeight = pos(tempInfoHeader.bmpHeight);
00416 
00417      if(tempInfoHeader.bmpBPP == 1) {
00418           while(tempInfoHeader.bmpWidth & 7)
00419                tempInfoHeader.bmpWidth++;
00420      } else if(tempInfoHeader.bmpBPP == 2) {
00421           while(tempInfoHeader.bmpWidth & 3)
00422                tempInfoHeader.bmpWidth++;
00423      } else if(tempInfoHeader.bmpBPP == 4) {
00424           if(tempInfoHeader.bmpWidth & 1)
00425                tempInfoHeader.bmpWidth++;
00426      }
00427 
00428      if(!tempInfoHeader.bmpByteWidth) {
00429           if(tempInfoHeader.bmpSize == BMP_HEADER_WV1) {
00430                tempInfoHeader.bmpByteWidth = (tempInfoHeader.bmpWidth * tempInfoHeader.bmpBPP);
00431                while(tempInfoHeader.bmpByteWidth & 7)
00432                     tempInfoHeader.bmpByteWidth++;
00433                tempInfoHeader.bmpByteWidth >>= 3;
00434           } else {
00435                tempInfoHeader.bmpByteWidth = (tempInfoHeader.bmpWidth * tempInfoHeader.bmpBPP);
00436                while(tempInfoHeader.bmpByteWidth & 7)
00437                     tempInfoHeader.bmpByteWidth++;
00438                tempInfoHeader.bmpByteWidth >>= 3;
00439                while(tempInfoHeader.bmpByteWidth & 3)
00440                     tempInfoHeader.bmpByteWidth++;
00441           }
00442      }
00443      
00444      if(!tempInfoHeader.bmpImageSize)
00445           tempInfoHeader.bmpImageSize = ((tempInfoHeader.bmpWidth * tempInfoHeader.bmpHeight * tempInfoHeader.bmpBPP) >> 3);
00446      
00447      int tempPixelFormat;
00448      #if FL_TEXTURE_PRESERVENONALPHA != 0
00449      bool tempAlpha = false;
00450      #endif
00451      switch(tempInfoHeader.bmpBPP) {
00452           case 1:
00453           case 2:
00454           case 4:
00455                tempPixelFormat = GU_PSM_T4;
00456                break;
00457           case 8:
00458                tempPixelFormat = GU_PSM_T8;
00459                break;
00460           case 16:
00461                if(tempInfoHeader.bmpSize >= BMP_HEADER_WV4) {
00462                     if(tempInfoHeader.bmpAlphaMask == 0x0000F000) {
00463                          tempPixelFormat = GU_PSM_4444;
00464                          #if FL_TEXTURE_PRESERVENONALPHA != 0
00465                          tempAlpha = true;
00466                          #endif
00467                     } else if(tempInfoHeader.bmpAlphaMask == 0x00008000) {
00468                          tempPixelFormat = GU_PSM_5551;
00469                          #if FL_TEXTURE_PRESERVENONALPHA != 0
00470                          tempAlpha = true;
00471                          #endif
00472                     } else {
00473                          tempPixelFormat = GU_PSM_5650;
00474                     }
00475                } else {
00476                     tempPixelFormat = GU_PSM_5650;
00477                }
00478                break;
00479           case 24:
00480                tempPixelFormat = GU_PSM_8888;
00481                break;
00482           case 32:
00483                tempPixelFormat = GU_PSM_8888;
00484                #if FL_TEXTURE_PRESERVENONALPHA != 0
00485                tempAlpha = true;
00486                #endif
00487                break;
00488           default:
00489                fileClose(tempFile);
00490                #if FL_DEBUG_WARNING != 0
00491                debugWarning("BPP not supported.");
00492                #endif
00493                return NULL;
00494      }
00495      
00496      Palette* tempPal = NULL;
00497      int tempPalEntries = tempInfoHeader.bmpColorsUsed;
00498      if(!tempPalEntries)
00499           tempPalEntries = (1 << tempInfoHeader.bmpBPP);
00500      if(tempPixelFormat > GU_PSM_8888) {
00501           if((tempInfoHeader.bmpSize >= BMP_HEADER_OS2V1) || (tempInfoHeader.bmpBPP == 8))
00502                tempPal = palCreate(tempPalEntries, GU_PSM_8888, false);
00503           else if(tempInfoHeader.bmpBPP == 4)
00504                tempPal = palCreateDefaultColorT4();
00505           else
00506                tempPal = palCreateGrayscaleT4();
00507           if(!tempPal) {
00508                fileClose(tempFile);
00509                #if FL_DEBUG_WARNING != 0
00510                debugWarning("Couldn't create bmp palette, probably out of memory.");
00511                #endif
00512                return NULL;
00513           }
00514           if(tempInfoHeader.bmpSize >= BMP_HEADER_OS2V1) {
00515                for(i = 0; i < tempPalEntries; i++) {
00516                     fileRead(&tempPal->palData[(i << 2) + 0], 1, tempFile);
00517                     fileRead(&tempPal->palData[(i << 2) + 1], 1, tempFile);
00518                     fileRead(&tempPal->palData[(i << 2) + 2], 1, tempFile);
00519                     if(tempInfoHeader.bmpSize > BMP_HEADER_OS2V1)
00520                          fileRead(&tempPal->palData[(i << 2) + 3], 1, tempFile);
00521                     tempPal->palData[(i << 2) + 3] = 0xFF;
00522                }
00523           } else {
00524                memCopy(tempPal->palData, bmpWinPal, 0x300);
00525           }
00526      }
00527      
00528      if(tempHeader.bmpDataOffset != 0)
00529           fileSeek(tempFile, tempHeader.bmpDataOffset, FILE_SEEK_SET);
00530 
00531      u8* tempData = (u8*)memQalloc((tempInfoHeader.bmpWidth * tempInfoHeader.bmpHeight * tempInfoHeader.bmpBPP) >> 3);
00532      if(!tempData) {
00533           fileClose(tempFile);
00534           if(tempPal)
00535                palFree(tempPal);
00536           #if FL_DEBUG_WARNING != 0
00537           debugWarning("Couldn't create data buffer while loading bmp.\nProbably out of memory.");
00538           #endif
00539           return NULL;
00540      }
00541 
00542      int tempLineSize = ((tempInfoHeader.bmpWidth * tempInfoHeader.bmpBPP) >> 3);
00543      u32 tempStride = tempLineSize - tempInfoHeader.bmpByteWidth;     
00544      if(tempInfoHeader.bmpCompression) {
00545           i = 0; j = 0; k = 0;
00546           u8 tempRleBlock[4];
00547           if(tempInfoHeader.bmpCompression == BMP_GEN_COMPRESSION_RLE4) {
00548                while(flRunning && (fileRead(tempRleBlock, 2, tempFile) == 2)) {
00549                     if(!tempRleBlock[0]) {
00550                          if(!tempRleBlock[1]) {
00551                               j++;
00552                               if(j >= tempInfoHeader.bmpHeight)
00553                                    break;
00554                               continue;
00555                          } else if(tempRleBlock[1] == 1) {
00556                               break;
00557                          } else if(tempRleBlock[1] == 2) {
00558                               fileRead(tempRleBlock, 2, tempFile);
00559                               j -= tempRleBlock[0];
00560                               i += ((tempRleBlock[1] + 1) >> 1);
00561                               if(i >= tempInfoHeader.bmpWidth) {
00562                                    j++;
00563                                    i -= tempLineSize;
00564                               }
00565                               if((j < 0) || (j >= tempInfoHeader.bmpHeight)) {
00566                                    #if FL_DEBUG_WARNING != 0
00567                                    debugWarning("BMP RLE4 decoding error.");
00568                                    #endif
00569                                    break;
00570                               }
00571                          } else {
00572                               for(k = 0; k < ((tempRleBlock[0] + 1) >> 1); k++) {
00573                                    if(j >= tempInfoHeader.bmpHeight)
00574                                         break;
00575                                    fileRead(&tempData[(j * tempLineSize) + i], 1, tempFile);
00576                                    if((k == (tempRleBlock[0] >> 1)) && (tempRleBlock[0] & 1))
00577                                         tempData[(j * tempLineSize) + i] &= 0xF0;
00578                                    i++;
00579                                    if(i >= tempInfoHeader.bmpWidth) {
00580                                         j++;
00581                                         i -= tempLineSize;
00582                                    }
00583                               }
00584                               if(j >= tempInfoHeader.bmpHeight) {
00585                                    #if FL_DEBUG_WARNING != 0
00586                                    debugWarning("BMP RLE4 decoding error.");
00587                                    #endif
00588                                    break;
00589                               }
00590                          }
00591                     } else {
00592                          for(k = 0; k < ((tempRleBlock[0] + 1) >> 1); k++) {
00593                               if(j >= tempInfoHeader.bmpHeight)
00594                                    break;
00595                               tempData[(j * tempLineSize) + i] = tempRleBlock[1];
00596                               if((k == (tempRleBlock[0] >> 1)) && (tempRleBlock[0] & 1))
00597                                    tempData[(j * tempLineSize) + i] &= 0xF0;
00598                               i++;
00599                               if(i >= tempInfoHeader.bmpWidth) {
00600                                    j++;
00601                                    i -= tempLineSize;
00602                               }
00603                          }
00604                          if(j >= tempInfoHeader.bmpHeight) {
00605                               #if FL_DEBUG_WARNING != 0
00606                               debugWarning("BMP RLE4 decoding error.");
00607                               #endif
00608                               break;
00609                          }
00610                     }
00611                }
00612           } else if(tempInfoHeader.bmpCompression == BMP_GEN_COMPRESSION_RLE8) {
00613                while(flRunning && (fileRead(tempRleBlock, 2, tempFile) == 2)) {
00614                     if(!tempRleBlock[0]) {
00615                          if(!tempRleBlock[1]) {
00616                               j++;
00617                               if(j >= tempInfoHeader.bmpHeight)
00618                                    break;
00619                               continue;
00620                          } else if(tempRleBlock[1] == 1) {
00621                               break;
00622                          } else if(tempRleBlock[1] == 2) {
00623                               fileRead(tempRleBlock, 2, tempFile);
00624                               j -= tempRleBlock[0];
00625                               i += tempRleBlock[1];
00626                               if(i >= tempInfoHeader.bmpWidth) {
00627                                    j++;
00628                                    i -= tempLineSize;
00629                               }
00630                               if((j < 0) || (j >= tempInfoHeader.bmpHeight)) {
00631                                    #if FL_DEBUG_WARNING != 0
00632                                    debugWarning("BMP RLE8 decoding error.");
00633                                    #endif
00634                                    break;
00635                               }
00636                          } else {
00637                               for(k = 0; k < tempRleBlock[1]; k++) {
00638                                    if(j >= tempInfoHeader.bmpHeight)
00639                                         break;
00640                                    fileRead(&tempData[(j * tempLineSize) + i], 1, tempFile);
00641                                    i++;
00642                                    if(i >= tempInfoHeader.bmpWidth) {
00643                                         j++;
00644                                         i -= tempLineSize;
00645                                    }
00646                               }
00647                               if(j >= tempInfoHeader.bmpHeight) {
00648                                    #if FL_DEBUG_WARNING != 0
00649                                    debugWarning("BMP RLE8 decoding error.");
00650                                    #endif
00651                                    break;
00652                               }
00653                          }
00654                     } else {
00655                          for(k = 0; k < tempRleBlock[0]; k++) {
00656                               if(j >= tempInfoHeader.bmpHeight)
00657                                    break;
00658                               tempData[(j * tempLineSize) + i] = tempRleBlock[1];
00659                               i++;
00660                               if(i >= tempInfoHeader.bmpWidth) {
00661                                    j++;
00662                                    i -= tempLineSize;
00663                               }
00664                          }
00665                          if(j >= tempInfoHeader.bmpHeight) {
00666                               #if FL_DEBUG_WARNING != 0
00667                               debugWarning("BMP RLE8 decoding error.");
00668                               #endif
00669                               break;
00670                          }
00671                     }
00672                }
00673           } else if(tempInfoHeader.bmpCompression == BMP_GEN_COMPRESSION_RLE24) {
00674                while(flRunning && (fileRead(tempRleBlock, 2, tempFile) == 2)) {
00675                     if(!tempRleBlock[0]) {
00676                          if(!tempRleBlock[1]) {
00677                               j++;
00678                               if(j >= tempInfoHeader.bmpHeight)
00679                                    break;
00680                               continue;
00681                          } else if(tempRleBlock[1] == 1) {
00682                               break;
00683                          } else if(tempRleBlock[1] == 2) {
00684                               fileRead(tempRleBlock, 2, tempFile);
00685                               j -= tempRleBlock[0];
00686                               i += (tempRleBlock[1] * 3);
00687                               if(i >= tempLineSize) {
00688                                    j++;
00689                                    i -= tempLineSize;
00690                               }
00691                               if((j < 0) || (j >= tempInfoHeader.bmpHeight)) {
00692                                    #if FL_DEBUG_WARNING != 0
00693                                    debugWarning("BMP RLE24 decoding error.");
00694                                    #endif
00695                                    break;
00696                               }
00697                          } else {
00698                               for(k = 0; k < tempRleBlock[1]; k++) {
00699                                    if(j >= tempInfoHeader.bmpHeight)
00700                                         break;
00701                                    fileRead(&tempData[(j * tempLineSize) + (i * 3)], 3, tempFile);
00702                                    i += 3;
00703                                    if(i >= tempLineSize) {
00704                                         j++;
00705                                         i -= tempLineSize;
00706                                    }
00707                               }
00708                               if(j >= tempInfoHeader.bmpHeight) {
00709                                    #if FL_DEBUG_WARNING != 0
00710                                    debugWarning("BMP RLE24 decoding error.");
00711                                    #endif
00712                                    break;
00713                               }
00714                          }
00715                     } else {
00716                          fileRead(&tempRleBlock[2], 2, tempFile);
00717                          for(k = 0; k < tempRleBlock[0]; k++) {
00718                               if(j >= tempInfoHeader.bmpHeight)
00719                                    break;
00720                               tempData[(j * tempLineSize) + i + 0] = tempRleBlock[1];
00721                               tempData[(j * tempLineSize) + i + 1] = tempRleBlock[2];
00722                               tempData[(j * tempLineSize) + i + 2] = tempRleBlock[3];
00723                               i += 3;
00724                               if(i >= tempLineSize) {
00725                                    j++;
00726                                    i -= tempLineSize;
00727                               }
00728                          }
00729                          if(j >= tempInfoHeader.bmpHeight) {
00730                               #if FL_DEBUG_WARNING != 0
00731                               debugWarning("BMP RLE24 decoding error.");
00732                               #endif
00733                               break;
00734                          }
00735                     }
00736                }
00737           }
00738      } else {
00739           for(i = (tempInfoHeader.bmpHeight - 1); i >= 0; i--) {
00740                fileRead(&tempData[i * tempLineSize], tempLineSize, tempFile);
00741                if(tempStride)
00742                     fileSeek(tempFile, tempStride, SEEK_CUR);
00743           }
00744           tempVFlip = !tempVFlip;
00745      }
00746 
00747      fileClose(tempFile);
00748 
00749      u8* tempLine = NULL;
00750      if(tempVFlip) {
00751           tempLine = memAlloc(tempLineSize);
00752           if(!tempLine) {
00753                if(tempPal)
00754                     palFree(tempPal);
00755                memFree(tempData);
00756                #if FL_DEBUG_WARNING != 0
00757                debugWarning("Couldn't create VFlip buffer while loading bmp.\nProbably out of memory.");
00758                #endif
00759                return NULL;
00760           }
00761           for(i = 0; i < (tempInfoHeader.bmpHeight >> 1); i++) {
00762                memCopy(tempLine, &tempData[i * tempLineSize], tempLineSize);
00763                memCopy(&tempData[i * tempLineSize], &tempData[((tempInfoHeader.bmpHeight - 1) - i) * tempLineSize], tempLineSize);
00764                memCopy(&tempData[((tempInfoHeader.bmpHeight - 1) - i) * tempLineSize], tempLine, tempLineSize);
00765           }
00766           memFree(tempLine);
00767      }
00768      if(tempHFlip) {
00769           u8 tempPixel[4];
00770           for(j = 0; j < tempInfoHeader.bmpHeight; j++) {
00771                for(i = 0; i < (tempInfoHeader.bmpWidth >> 1); i++) {
00772                     memCopy(tempPixel, &tempData[(j * tempLineSize) + (i * (tempInfoHeader.bmpBPP >> 3))], (tempInfoHeader.bmpBPP >> 3));
00773                     memCopy(&tempData[(j * tempLineSize) + (i * (tempInfoHeader.bmpBPP >> 3))], &tempData[(j * tempLineSize) + (((tempInfoHeader.bmpWidth - 1) - i) * (tempInfoHeader.bmpBPP >> 3))], (tempInfoHeader.bmpBPP >> 3));
00774                     memCopy(&tempData[(j * tempLineSize) + (((tempInfoHeader.bmpWidth - 1) - i) * (tempInfoHeader.bmpBPP >> 3))], tempPixel, (tempInfoHeader.bmpBPP >> 3));
00775                }
00776           }
00777      }
00778      
00779      if(tempInfoHeader.bmpRedMask || tempInfoHeader.bmpGreenMask || tempInfoHeader.bmpBlueMask) {
00780           // TODO - Decode bit fields if they exist
00781           #if FL_DEBUG_WARNING != 0
00782           debugWarning("Bitmap contains bit-fields, which are currently unsupported.\nSkipping may cause corruption of colors.");
00783           #endif
00784      }
00785      
00786      Texture* tempOut = texCreate(tempInfoHeader.bmpWidth, tempInfoHeader.bmpHeight, tempPixelFormat);
00787      if(!tempOut) {
00788           if(tempPal)
00789                palFree(tempPal);
00790           memFree(tempData);
00791           fileClose(tempFile);
00792           #if FL_DEBUG_WARNING != 0
00793           char tempString[256];
00794           sprintf(tempString, "Couldn't create texture struct, while loading \"%s\".\nOut of memory.", inPath);
00795           debugWarning(tempString);
00796           #endif
00797           return NULL;
00798      }
00799      tempOut->texPalette = tempPal;
00800      #if FL_TEXTURE_PRESERVENONALPHA != 0
00801      tempOut->texAlpha = tempAlpha;
00802      #endif
00803      
00804      if((tempInfoHeader.bmpBPP == 32) || (tempInfoHeader.bmpBPP == 16) || (tempInfoHeader.bmpBPP == 8) || (tempInfoHeader.bmpBPP == 4)) {
00805           for(i = 0; i < tempInfoHeader.bmpHeight; i++)
00806                memCopy(&tempOut->texData[i * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)], &tempData[i * tempLineSize], tempLineSize);
00807      } else if(tempInfoHeader.bmpBPP == 24) {
00808           for(j = 0; j < tempInfoHeader.bmpHeight; j++) {
00809                for(i = 0; i < tempInfoHeader.bmpWidth; i++) {
00810                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 0] = tempData[(j * tempLineSize) + (i * 3) + 0];
00811                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 1] = tempData[(j * tempLineSize) + (i * 3) + 1];
00812                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 2] = tempData[(j * tempLineSize) + (i * 3) + 2];
00813                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 3] = 0xFF;
00814                }
00815           }
00816      } else if(tempInfoHeader.bmpBPP == 2) {
00817           for(j = 0; j < tempInfoHeader.bmpHeight; j++) {
00818                if(tempInfoHeader.bmpSize == BMP_HEADER_WV1) {
00819                     for(i = 0; i < (tempInfoHeader.bmpWidth >> 2); i++) {
00820                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 0] = (((tempData[(j * tempLineSize) + i] & 0x03) << 4) / 3);
00821                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 0] += ((((tempData[(j * tempLineSize) + i] & 0x0C) << 2) / 3) << 4);
00822                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 1] = ((tempData[(j * tempLineSize) + i] & 0x30) / 3);
00823                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 1] += ((((tempData[(j * tempLineSize) + i] & 0xC0) >> 2) / 3) << 4);
00824                     }
00825                } else {
00826                     for(i = 0; i < (tempInfoHeader.bmpWidth >> 2); i++) {
00827                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 0] = (tempData[(j * tempLineSize) + i] & 0x03);
00828                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 0] += ((tempData[(j * tempLineSize) + i] & 0x0C) >> 2);
00829                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 1] = ((tempData[(j * tempLineSize) + i] & 0x30) >> 4);
00830                          tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 1) + 1] += ((tempData[(j * tempLineSize) + i] & 0xC0) >> 6);
00831                     }
00832                }
00833           }
00834      } else if(tempInfoHeader.bmpBPP == 1) {
00835           for(j = 0; j < tempInfoHeader.bmpHeight; j++) {
00836                for(i = 0; i < (tempInfoHeader.bmpWidth >> 3); i++) {
00837                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 0] = (tempData[(j * tempLineSize) + i] & 0x01);
00838                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 0] += ((tempData[(j * tempLineSize) + i] & 0x02) << 3);
00839                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 1] = ((tempData[(j * tempLineSize) + i] & 0x04) >> 2);
00840                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 1] += ((tempData[(j * tempLineSize) + i] & 0x08) << 1);
00841                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 2] = (tempData[(j * tempLineSize) + i] & 0x10);
00842                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 2] += ((tempData[(j * tempLineSize) + i] & 0x20) >> 1);
00843                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 3] = ((tempData[(j * tempLineSize) + i] & 0x40) >> 6);
00844                      tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 3] += ((tempData[(j * tempLineSize) + i] & 0x80) >> 3);
00845                      if(tempInfoHeader.bmpSize == BMP_HEADER_WV1) {
00846                           tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 0] <<= 3;
00847                           tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 1] <<= 3;
00848                           tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 2] <<= 3;
00849                           tempOut->texData[(j * ((tempOut->texDataWidth * texBPP(tempOut)) >> 3)) + (i << 2) + 3] <<= 3;
00850                      }
00851                }
00852           }
00853      }
00854 
00855      memFree(tempData);
00856      return tempOut;
00857 }
00858 
00859 bool texSaveBMP(Texture* inTex, char* inPath) {
00860      #if FL_DEBUG_WARNING != 0
00861      debugWarning("BMP saving is not yet supported.");
00862      #endif
00863      return false;
00864 }
00865 
00866 #endif

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