Simplified Doodle Jump game for mbed

Dependencies:   4DGL-uLCD-SE LSM9DS1_Library_cal SDFileSystem mbed-rtos mbed wave_player

Revision:
3:141c57be5a2d
Parent:
1:bdeb188cb474
--- a/myBMP/myBMP.cpp	Mon Mar 14 20:36:52 2016 +0000
+++ b/myBMP/myBMP.cpp	Tue Mar 15 02:34:14 2016 +0000
@@ -108,13 +108,8 @@
 bool Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, uLCD_4DGL *lcd, int x, int y)
 { 
  int i;
- //char Colors[4];
- //if( Width*3 > BufferSize )
- //{ return false; }
  for( i=0 ; i < Width ; i++ )
  {
-    //memcpy( (char*) &(Colors), (char*) Buffer+3*i, 3 );
-     //Blue, Green, Red, Alpha
     int color = 0x00000000 | (Buffer[3*i+2] << 16) | (Buffer[3*i+1] << 8) | (Buffer[3*i+0]);
     (*lcd).pixel(x+i,y+Row,color);
  }
@@ -558,296 +553,231 @@
  return true;
 }
 
-bool ReadBMPFromFile(const char * FileName, RGBApixel *Colors, uLCD_4DGL *lcd, int x, int y)
+bool ReadColorsFromFile(const char * FileName, RGBApixel *Colors, int * color_array, int x, int y)
 { 
- FILE* fp = fopen( FileName, "rb" );
- if( fp == NULL )
- {
-  return false;
- }
- 
- // read the file header 
- 
- BMFH bmfh;
- bool NotCorrupted = true;
- 
- NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp);
- 
- bool IsBitmap = false;
- 
- if( bmfh.bfType == 19778 )
- { IsBitmap = true; }
- 
- if( !IsBitmap ) 
- {
-  fclose( fp ); 
-  return false;
- }
+    FILE* fp = fopen( FileName, "rb" );
+    if( fp == NULL )
+    {
+        return false;
+    }
+
+    // read the file header 
+
+    BMFH bmfh;
+    bool NotCorrupted = true;
+
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp);
+
+    bool IsBitmap = false;
+
+    if( bmfh.bfType == 19778 )
+    { IsBitmap = true; }
+
+    if( !IsBitmap ) 
+    {
+        fclose( fp ); 
+        return false;
+    }
 
- NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); 
- NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp);
- NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp);
- NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp);
- 
- // read the info header
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); 
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp);
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp);
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp);
+
+    // read the info header
+
+    BMIH bmih; 
 
- BMIH bmih; 
- 
- NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); 
- NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); 
- NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); 
+    NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); 
+    NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp);
+
+    NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp);
+
+    // a safety catch: if any of the header information didn't read properly, abort
+    // future idea: check to see if at least most is self-consistent
 
- NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp);
- NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp);
- 
- // a safety catch: if any of the header information didn't read properly, abort
- // future idea: check to see if at least most is self-consistent
-  
- if( !NotCorrupted )
- {
-  fclose(fp);
-  return false;
- } 
- 
- // if bmih.biCompression 1 or 2, then the file is RLE compressed
- 
- if( bmih.biCompression == 1 || bmih.biCompression == 2 )
- {
-  fclose(fp);
-  return false; 
- }
- 
- // if bmih.biCompression > 3, then something strange is going on 
- // it's probably an OS2 bitmap file.
- 
- if( bmih.biCompression > 3 )
- {
-  fclose(fp);
-  return false; 
- }
- 
- if( bmih.biCompression == 3 && bmih.biBitCount != 16 )
- {
-  fclose(fp);
-  return false; 
- }
+    if( !NotCorrupted )
+    {
+        fclose(fp);
+        return false;
+    } 
+
+    // if bmih.biCompression 1 or 2, then the file is RLE compressed
+
+    if( bmih.biCompression == 1 || bmih.biCompression == 2 )
+    {
+        fclose(fp);
+        return false; 
+    }
+
+    // if bmih.biCompression > 3, then something strange is going on 
+    // it's probably an OS2 bitmap file.
+
+    if( bmih.biCompression > 3 )
+    {
+        fclose(fp);
+        return false; 
+    }
+
+    if( bmih.biCompression == 3 && bmih.biBitCount != 16 )
+    {
+        fclose(fp);
+        return false; 
+    }
 
- // set the bit depth
- 
- int TempBitDepth = (int) bmih.biBitCount;
- if(    TempBitDepth != 1  && TempBitDepth != 4 
-     && TempBitDepth != 8  && TempBitDepth != 16
-     && TempBitDepth != 24 && TempBitDepth != 32 )
- {
-  fclose(fp);
-  return false;
- }
- BitDepth = (int)bmih.biBitCount;
- // set the size
+    // set the bit depth
+
+    int TempBitDepth = (int) bmih.biBitCount;
+    if(    TempBitDepth != 1  && TempBitDepth != 4 
+    && TempBitDepth != 8  && TempBitDepth != 16
+    && TempBitDepth != 24 && TempBitDepth != 32 )
+    {
+        fclose(fp);
+        return false;
+    }
+    BitDepth = (int)bmih.biBitCount;
+    // set the size
+
+    if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) 
+    {
+        fclose(fp);
+        return false;
+    } 
+    Width = (int) bmih.biWidth;
+    Height = (int) bmih.biHeight;
+    // some preliminaries
+
+    double dBytesPerPixel = ( (double) BitDepth ) / 8.0;
+    double dBytesPerRow = dBytesPerPixel * (Width+0.0);
+    dBytesPerRow = ceil(dBytesPerRow);
+
+    int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4;
+    if( BytePaddingPerRow == 4 )
+    { BytePaddingPerRow = 0; }  
+
+    // if < 16 bits, read the palette
 
- if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) 
- {
-  fclose(fp);
-  return false;
- } 
- Width = (int) bmih.biWidth;
- Height = (int) bmih.biHeight;
- // some preliminaries
- 
- double dBytesPerPixel = ( (double) BitDepth ) / 8.0;
- double dBytesPerRow = dBytesPerPixel * (Width+0.0);
- dBytesPerRow = ceil(dBytesPerRow);
-  
- int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4;
- if( BytePaddingPerRow == 4 )
- { BytePaddingPerRow = 0; }  
- 
- // if < 16 bits, read the palette
- 
- if( BitDepth < 16 )
- {
-  // determine the number of colors specified in the 
-  // color table
-  
-  int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4;  
-  if( NumberOfColorsToRead > (1 << BitDepth) )
-  { NumberOfColorsToRead = (1 << BitDepth); }
- 
-  int n;
-  for( n=0; n < NumberOfColorsToRead ; n++ )
-  {
-   SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp);     
-  }
-  for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ )
-  {
-   RGBApixel HWITE; 
-   HWITE.Red = 255;
-   HWITE.Green = 255;
-   HWITE.Blue = 255;
-   HWITE.Alpha = 0;
-   Colors[n] = HWITE;
-  }
- }
- 
- // skip blank data if bfOffBits so indicates
- 
- int BytesToSkip = bmfh.bfOffBits - 54;;
- if( BitDepth < 16 )
- { BytesToSkip -= 4*(1 << BitDepth); }
- if( BitDepth == 16 && bmih.biCompression == 3 )
- { BytesToSkip -= 3*4; }
- if( BytesToSkip < 0 )
- { BytesToSkip = 0; }
- if( BytesToSkip > 0 && BitDepth != 16 )
- {
-  ebmpBYTE* TempSkipBYTE;
-  TempSkipBYTE = new ebmpBYTE [BytesToSkip];
-  SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);   
-  delete [] TempSkipBYTE;
- } 
-  
- // This code reads 1, 4, 8, 24, and 32-bpp files 
- // with a more-efficient buffered technique.
+    if( BitDepth < 16 )
+    {
+    // determine the number of colors specified in the 
+    // color table
+
+    int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4;  
+    if( NumberOfColorsToRead > (1 << BitDepth) )
+    { NumberOfColorsToRead = (1 << BitDepth); }
 
- int i,j;
- if( BitDepth != 16 )
- {
-  int BufferSize = (int) ( (Width*BitDepth) / 8.0 );
-  while( 8*BufferSize < Width*BitDepth )
-  { BufferSize++; }
-  while( BufferSize % 4 )
-  { BufferSize++; }
-  ebmpBYTE* Buffer;
-  Buffer = new ebmpBYTE [BufferSize];
-  j= Height-1;
-  while( j > -1 )
-  {
-   int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp );
-   if( BytesRead < BufferSize )
-   {
-    j = -1; 
-   }
-   else
-   {
-    bool Success = false;
-    if( BitDepth == 1  )
-    { Success = Read1bitRow(  Buffer, BufferSize, j , lcd, x, y); }
-    if( BitDepth == 4  )
-    { Success = Read4bitRow(  Buffer, BufferSize, j , lcd, x, y); }
-    if( BitDepth == 8  )
-    { Success = Read8bitRow(  Buffer, BufferSize, j , lcd, x, y); }
-    if( BitDepth == 24 )
-    { Success = Read24bitRow( Buffer, BufferSize, j , lcd, x, y); }
-    if( BitDepth == 32 )
-    { Success = Read32bitRow( Buffer, BufferSize, j , lcd, x, y); }
-    if( !Success )
+    int n;
+    for( n=0; n < NumberOfColorsToRead ; n++ )
+    {
+    SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp);     
+    }
+    for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ )
     {
-     j = -1;
+        RGBApixel HWITE; 
+        HWITE.Red = 255;
+        HWITE.Green = 255;
+        HWITE.Blue = 255;
+        HWITE.Alpha = 0;
+        Colors[n] = HWITE;
+    }
     }
-   }   
-   j--;
-  }
-  delete [] Buffer; 
- }
 
- if( BitDepth == 16 )
- {
-  int DataBytes = Width*2;
-  int PaddingBytes = ( 4 - DataBytes % 4 ) % 4;
-
-  // set the default mask
-  
-  ebmpWORD BlueMask = 31; // bits 12-16
-  ebmpWORD GreenMask = 992; // bits 7-11
-  ebmpWORD RedMask = 31744; // bits 2-6
+    // skip blank data if bfOffBits so indicates
 
-  // read the bit fields, if necessary, to 
-  // override the default 5-5-5 mask
-  
-  if( bmih.biCompression != 0 )
-  {
-   // read the three bit masks
+    int BytesToSkip = bmfh.bfOffBits - 54;;
+    if( BitDepth < 16 )
+    { BytesToSkip -= 4*(1 << BitDepth); }
+    if( BitDepth == 16 && bmih.biCompression == 3 )
+    { BytesToSkip -= 3*4; }
+    if( BytesToSkip < 0 )
+    { BytesToSkip = 0; }
+    if( BytesToSkip > 0 && BitDepth != 16 )
+    {
+        ebmpBYTE* TempSkipBYTE;
+        TempSkipBYTE = new ebmpBYTE [BytesToSkip];
+        SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);   
+        delete [] TempSkipBYTE;
+    } 
 
-   ebmpWORD TempMaskWORD;
-  
-   SafeFread( (char*) &RedMask , 2 , 1 , fp );
-   SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
-  
-   SafeFread( (char*) &GreenMask , 2 , 1 , fp );
-   SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
-
-   SafeFread( (char*) &BlueMask , 2 , 1 , fp );
-   SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
-  }
-  
-  // read and skip any meta data
+    // This code reads 1, 4, 8, 24, and 32-bpp files 
+    // with a more-efficient buffered technique.
 
-  if( BytesToSkip > 0 )
-  {
-   ebmpBYTE* TempSkipBYTE;
-   TempSkipBYTE = new ebmpBYTE [BytesToSkip];
-   SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);
-   delete [] TempSkipBYTE;   
-  } 
-  
-  // determine the red, green and blue shifts
-  
-  int GreenShift = 0; 
-  ebmpWORD TempShiftWORD = GreenMask;
-  while( TempShiftWORD > 31 )
-  { TempShiftWORD = TempShiftWORD>>1; GreenShift++; }  
-  int BlueShift = 0;
-  TempShiftWORD = BlueMask;
-  while( TempShiftWORD > 31 )
-  { TempShiftWORD = TempShiftWORD>>1; BlueShift++; }  
-  int RedShift = 0;  
-  TempShiftWORD = RedMask;
-  while( TempShiftWORD > 31 )
-  { TempShiftWORD = TempShiftWORD>>1; RedShift++; }  
-  
-  // read the actual pixels
-  
-  for( j=Height-1 ; j >= 0 ; j-- )
-  {
-   i=0;
-   int ReadNumber = 0;
-   while( ReadNumber < DataBytes )
-   {
-    ebmpWORD TempWORD;
-    SafeFread( (char*) &TempWORD , 2 , 1 , fp );
-    ReadNumber += 2;
-  
-    ebmpWORD Red = RedMask & TempWORD;
-    ebmpWORD Green = GreenMask & TempWORD;
-    ebmpWORD Blue = BlueMask & TempWORD;
-                
-    ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift);
-    ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift);
-    ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift);
-        
-    int color = 0x00000000 | (RedBYTE << 16) | (GreenBYTE << 8) | (BlueBYTE);
-    (*lcd).pixel(x+i,y+j,color);
-    i++;
-   }
-   ReadNumber = 0;
-   while( ReadNumber < PaddingBytes )
-   {
-    ebmpBYTE TempBYTE;
-    SafeFread( (char*) &TempBYTE , 1, 1, fp);
-    ReadNumber++;
-   }
-  }
+    int i,j;
+    if( BitDepth != 16 )
+    {
+        int BufferSize = (int) ( (Width*BitDepth) / 8.0 );
+        while( 8*BufferSize < Width*BitDepth )
+        { BufferSize++; }
+        while( BufferSize % 4 )
+        { BufferSize++; }
+        ebmpBYTE* Buffer;
+        Buffer = new ebmpBYTE [BufferSize];
+        j= Height-1;
+        while( j > -1 )
+        {
+            int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp );
+            if( BytesRead < BufferSize )
+            {
+                j = -1; 
+            }
+            else
+            {
+                bool Success = false;
+                if( BitDepth == 1  )
+                { return -1; }
+                if( BitDepth == 4  )
+                { return -1; }
+                if( BitDepth == 8  )
+                { return -1; }
+                if( BitDepth == 24 )
+                {
+                    // don't do BufferSize bounds checking, also NOTE: only bothering for 24 because that is what our image uses
+                    Success = true;
+                    for(int i=0 ; i < Width ; i++ )
+                    {
+                        int color = 0x00000000 | (Buffer[3*i+2] << 16) | (Buffer[3*i+1] << 8) | (Buffer[3*i+0]);
+                        color_array[Width*j + i] = color; // width * row + col
+                        //(*lcd).pixel(x+i,y+j,color);
+                    }
+                }
+                if( BitDepth == 32 )
+                { return -1; }
+                if( !Success )
+                {
+                    j = -1;
+                }
+            }   
+            j--;
+        }
+        delete [] Buffer; 
+    }
 
- }
- 
- fclose(fp);
- return true;
+    if( BitDepth == 16 )
+    {
+        return -1;
+    }
+
+    fclose(fp);
+    return true;
+}
+
+void DrawColorstoLCD(int * color_array, uLCD_4DGL *lcd, int x, int y, int w, int h) 
+{
+    for (int i = 0; i < w; i++)
+    {
+        for (int j = 0; j < h; j++)
+        {
+            (*lcd).pixel(x+i,y+j,color_array[w*j + i]);
+        }
+    }
 }
 
 
@@ -866,4 +796,297 @@
  bfType = 19778;
  bfReserved1 = 0;
  bfReserved2 = 0;
+}
+
+
+bool ReadBMPFromFile(const char * FileName, RGBApixel *Colors, uLCD_4DGL *lcd, int x, int y)
+{ 
+    FILE* fp = fopen( FileName, "rb" );
+    if( fp == NULL )
+    {
+        return false;
+    }
+
+    // read the file header 
+
+    BMFH bmfh;
+    bool NotCorrupted = true;
+
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp);
+
+    bool IsBitmap = false;
+
+    if( bmfh.bfType == 19778 )
+    { IsBitmap = true; }
+
+    if( !IsBitmap ) 
+    {
+        fclose( fp ); 
+        return false;
+    }
+
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); 
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp);
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp);
+    NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp);
+
+    // read the info header
+
+    BMIH bmih; 
+
+    NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); 
+    NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); 
+    NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp);
+
+    NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp);
+    NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp);
+
+    // a safety catch: if any of the header information didn't read properly, abort
+    // future idea: check to see if at least most is self-consistent
+
+    if( !NotCorrupted )
+    {
+        fclose(fp);
+        return false;
+    } 
+
+    // if bmih.biCompression 1 or 2, then the file is RLE compressed
+
+    if( bmih.biCompression == 1 || bmih.biCompression == 2 )
+    {
+        fclose(fp);
+        return false; 
+    }
+
+    // if bmih.biCompression > 3, then something strange is going on 
+    // it's probably an OS2 bitmap file.
+
+    if( bmih.biCompression > 3 )
+    {
+        fclose(fp);
+        return false; 
+    }
+
+    if( bmih.biCompression == 3 && bmih.biBitCount != 16 )
+    {
+        fclose(fp);
+        return false; 
+    }
+
+    // set the bit depth
+
+    int TempBitDepth = (int) bmih.biBitCount;
+    if(    TempBitDepth != 1  && TempBitDepth != 4 
+     && TempBitDepth != 8  && TempBitDepth != 16
+     && TempBitDepth != 24 && TempBitDepth != 32 )
+    {
+        fclose(fp);
+        return false;
+    }
+    BitDepth = (int)bmih.biBitCount;
+    // set the size
+
+    if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) 
+    {
+        fclose(fp);
+        return false;
+    } 
+    Width = (int) bmih.biWidth;
+    Height = (int) bmih.biHeight;
+    // some preliminaries
+
+    double dBytesPerPixel = ( (double) BitDepth ) / 8.0;
+    double dBytesPerRow = dBytesPerPixel * (Width+0.0);
+    dBytesPerRow = ceil(dBytesPerRow);
+
+    int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4;
+    if( BytePaddingPerRow == 4 )
+    { BytePaddingPerRow = 0; }  
+
+    // if < 16 bits, read the palette
+
+    if( BitDepth < 16 )
+    {
+    // determine the number of colors specified in the 
+    // color table
+
+    int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4;  
+    if( NumberOfColorsToRead > (1 << BitDepth) )
+    { NumberOfColorsToRead = (1 << BitDepth); }
+
+    int n;
+    for( n=0; n < NumberOfColorsToRead ; n++ )
+    {
+    SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp);     
+    }
+    for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ )
+    {
+    RGBApixel HWITE; 
+    HWITE.Red = 255;
+    HWITE.Green = 255;
+    HWITE.Blue = 255;
+    HWITE.Alpha = 0;
+    Colors[n] = HWITE;
+    }
+    }
+
+    // skip blank data if bfOffBits so indicates
+
+    int BytesToSkip = bmfh.bfOffBits - 54;;
+    if( BitDepth < 16 )
+    { BytesToSkip -= 4*(1 << BitDepth); }
+    if( BitDepth == 16 && bmih.biCompression == 3 )
+    { BytesToSkip -= 3*4; }
+    if( BytesToSkip < 0 )
+    { BytesToSkip = 0; }
+    if( BytesToSkip > 0 && BitDepth != 16 )
+    {
+    ebmpBYTE* TempSkipBYTE;
+    TempSkipBYTE = new ebmpBYTE [BytesToSkip];
+    SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);   
+    delete [] TempSkipBYTE;
+    } 
+
+    // This code reads 1, 4, 8, 24, and 32-bpp files 
+    // with a more-efficient buffered technique.
+
+    int i,j;
+    if( BitDepth != 16 )
+    {
+    int BufferSize = (int) ( (Width*BitDepth) / 8.0 );
+    while( 8*BufferSize < Width*BitDepth )
+    { BufferSize++; }
+    while( BufferSize % 4 )
+    { BufferSize++; }
+    ebmpBYTE* Buffer;
+    Buffer = new ebmpBYTE [BufferSize];
+    j= Height-1;
+    while( j > -1 )
+    {
+    int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp );
+    if( BytesRead < BufferSize )
+    {
+    j = -1; 
+    }
+    else
+    {
+    bool Success = false;
+    if( BitDepth == 1  )
+    { Success = Read1bitRow(  Buffer, BufferSize, j , lcd, x, y); }
+    if( BitDepth == 4  )
+    { Success = Read4bitRow(  Buffer, BufferSize, j , lcd, x, y); }
+    if( BitDepth == 8  )
+    { Success = Read8bitRow(  Buffer, BufferSize, j , lcd, x, y); }
+    if( BitDepth == 24 )
+    { Success = Read24bitRow( Buffer, BufferSize, j , lcd, x, y); }
+    if( BitDepth == 32 )
+    { Success = Read32bitRow( Buffer, BufferSize, j , lcd, x, y); }
+    if( !Success )
+    {
+     j = -1;
+    }
+    }   
+    j--;
+    }
+    delete [] Buffer; 
+    }
+
+    if( BitDepth == 16 )
+    {
+    int DataBytes = Width*2;
+    int PaddingBytes = ( 4 - DataBytes % 4 ) % 4;
+
+    // set the default mask
+
+    ebmpWORD BlueMask = 31; // bits 12-16
+    ebmpWORD GreenMask = 992; // bits 7-11
+    ebmpWORD RedMask = 31744; // bits 2-6
+
+    // read the bit fields, if necessary, to 
+    // override the default 5-5-5 mask
+
+    if( bmih.biCompression != 0 )
+    {
+    // read the three bit masks
+
+    ebmpWORD TempMaskWORD;
+
+    SafeFread( (char*) &RedMask , 2 , 1 , fp );
+    SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
+
+    SafeFread( (char*) &GreenMask , 2 , 1 , fp );
+    SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
+
+    SafeFread( (char*) &BlueMask , 2 , 1 , fp );
+    SafeFread( (char*) &TempMaskWORD , 2, 1, fp );
+    }
+
+    // read and skip any meta data
+
+    if( BytesToSkip > 0 )
+    {
+    ebmpBYTE* TempSkipBYTE;
+    TempSkipBYTE = new ebmpBYTE [BytesToSkip];
+    SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp);
+    delete [] TempSkipBYTE;   
+    } 
+
+    // determine the red, green and blue shifts
+
+    int GreenShift = 0; 
+    ebmpWORD TempShiftWORD = GreenMask;
+    while( TempShiftWORD > 31 )
+    { TempShiftWORD = TempShiftWORD>>1; GreenShift++; }  
+    int BlueShift = 0;
+    TempShiftWORD = BlueMask;
+    while( TempShiftWORD > 31 )
+    { TempShiftWORD = TempShiftWORD>>1; BlueShift++; }  
+    int RedShift = 0;  
+    TempShiftWORD = RedMask;
+    while( TempShiftWORD > 31 )
+    { TempShiftWORD = TempShiftWORD>>1; RedShift++; }  
+
+    // read the actual pixels
+
+    for( j=Height-1 ; j >= 0 ; j-- )
+    {
+    i=0;
+    int ReadNumber = 0;
+    while( ReadNumber < DataBytes )
+    {
+    ebmpWORD TempWORD;
+    SafeFread( (char*) &TempWORD , 2 , 1 , fp );
+    ReadNumber += 2;
+
+    ebmpWORD Red = RedMask & TempWORD;
+    ebmpWORD Green = GreenMask & TempWORD;
+    ebmpWORD Blue = BlueMask & TempWORD;
+                
+    ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift);
+    ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift);
+    ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift);
+        
+    int color = 0x00000000 | (RedBYTE << 16) | (GreenBYTE << 8) | (BlueBYTE);
+    (*lcd).pixel(x+i,y+j,color);
+    i++;
+    }
+    ReadNumber = 0;
+    while( ReadNumber < PaddingBytes )
+    {
+    ebmpBYTE TempBYTE;
+    SafeFread( (char*) &TempBYTE , 1, 1, fp);
+    ReadNumber++;
+    }
+    }
+
+    }
+
+    fclose(fp);
+    return true;
 }
\ No newline at end of file