Dependencies:   mbed

Revision:
0:c546b51ecf0b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/myBMP/myBMP.cpp	Tue Oct 11 01:24:18 2011 +0000
@@ -0,0 +1,456 @@
+#include "myBMP.h"
+
+int BitDepth = 1;
+int Width = 1;
+int Height = 1;
+RGBApixel *Colors;
+
+bool SafeFread( char* buffer, int size, int number, FILE* fp )
+{
+ using namespace std;
+ int ItemsRead;
+ if( feof(fp) )
+ { return false; }
+ ItemsRead = (int) fread( buffer , size , number , fp );
+ if( ItemsRead < number )
+ { return false; }
+ return true;
+}
+
+bool Read32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd)
+{ 
+ int i;
+ char Colors[4];
+ if( Width*4 > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ {
+    memcpy( (char*) &(Colors), (char*) Buffer+4*i, 4 );
+     //Blue, Green, Red, Alpha
+    int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]);
+    (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color);
+ }
+ return true;
+}
+
+bool Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd)
+{ 
+ 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 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]);
+    (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color);
+ }
+ return true;
+}
+
+RGBApixel GetColor( int ColorNumber)
+{ 
+ RGBApixel Output;
+ Output.Red   = 255;
+ Output.Green = 255;
+ Output.Blue  = 255;
+ Output.Alpha = 0;
+ 
+ if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 )
+ {
+  return Output;
+ }
+ if( !Colors )
+ {
+  return Output; 
+ }
+ Output = Colors[ColorNumber];
+ return Output;
+}
+
+bool Read8bitRow(  ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd)
+{
+ int i;
+ if( Width > BufferSize )
+ { return false; }
+ for( i=0 ; i < Width ; i++ )
+ {
+    int Index = Buffer[i];
+     //Blue, Green, Red, Alpha
+    RGBApixel colors = GetColor(Index);
+    int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green);
+    (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color);
+ }
+ return true;
+}
+
+bool Read4bitRow(  ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd)
+{
+ int Shifts[2] = {4  ,0 };
+ int Masks[2]  = {240,15};
+ 
+ int i=0;
+ int j;
+ int k=0;
+ if( Width > 2*BufferSize )
+ { return false; }
+ while( i < Width )
+ {
+  j=0;
+  while( j < 2 && i < Width )
+  {
+   int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]);
+   RGBApixel colors = GetColor(Index);
+   int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green);
+   (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color);
+   i++; j++;   
+  }
+  k++;
+ }
+ return true;
+}
+bool Read1bitRow(  ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd)
+{
+ int Shifts[8] = {7  ,6 ,5 ,4 ,3,2,1,0};
+ int Masks[8]  = {128,64,32,16,8,4,2,1};
+ 
+ int i=0;
+ int j;
+ int k=0;
+ 
+ if( Width > 8*BufferSize )
+ { return false; }
+ while( i < Width )
+ {
+  j=0;
+  while( j < 8 && i < Width )
+  {
+   int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]);
+   RGBApixel colors = GetColor(Index);
+   int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green);
+   (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color);
+   i++; j++;   
+  }
+  k++;
+ }
+ return true;
+}
+
+int TellNumberOfColors( int BitDepth )
+{
+ int output = 1 << BitDepth;
+ if( BitDepth == 32 )
+ { output = 1 << 24; }
+ return output;
+}
+
+bool ReadBMPFromFile( const char* FileName, RGBApixel *Colors, NokiaLCD *lcd)
+{ 
+ 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 WHITE; 
+   WHITE.Red = 255;
+   WHITE.Green = 255;
+   WHITE.Blue = 255;
+   WHITE.Alpha = 0;
+   Colors[n] = WHITE;
+  }
+ }
+ 
+ // 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); }
+    if( BitDepth == 4  )
+    { Success = Read4bitRow(  Buffer, BufferSize, j , lcd); }
+    if( BitDepth == 8  )
+    { Success = Read8bitRow(  Buffer, BufferSize, j , lcd); }
+    if( BitDepth == 24 )
+    { Success = Read24bitRow( Buffer, BufferSize, j , lcd); }
+    if( BitDepth == 32 )
+    { Success = Read32bitRow( Buffer, BufferSize, j , lcd); }
+    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((130-Width)/2+i,(130-Height)/2+j,color);
+    i++;
+   }
+   ReadNumber = 0;
+   while( ReadNumber < PaddingBytes )
+   {
+    ebmpBYTE TempBYTE;
+    SafeFread( (char*) &TempBYTE , 1, 1, fp);
+    ReadNumber++;
+   }
+  }
+
+ }
+ 
+ fclose(fp);
+ return true;
+}
+
+
+BMIH::BMIH()
+{
+ biPlanes = 1;
+ biCompression = 0;
+ biXPelsPerMeter = DefaultXPelsPerMeter;  
+ biYPelsPerMeter = DefaultYPelsPerMeter;
+ biClrUsed = 0;
+ biClrImportant = 0;
+}
+
+BMFH::BMFH()
+{
+ bfType = 19778;
+ bfReserved1 = 0;
+ bfReserved2 = 0;
+}
\ No newline at end of file