Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
myBMP.cpp
00001 #include "myBMP.h" 00002 00003 int BitDepth = 1; 00004 int Width = 1; 00005 int Height = 1; 00006 RGBApixel *Colors; 00007 00008 bool SafeFread( char* buffer, int size, int number, FILE* fp ) 00009 { 00010 using namespace std; 00011 int ItemsRead; 00012 if( feof(fp) ) 00013 { return false; } 00014 ItemsRead = (int) fread( buffer , size , number , fp ); 00015 if( ItemsRead < number ) 00016 { return false; } 00017 return true; 00018 } 00019 00020 bool Read32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) 00021 { 00022 int i; 00023 char Colors[4]; 00024 if( Width*4 > BufferSize ) 00025 { return false; } 00026 for( i=0 ; i < Width ; i++ ) 00027 { 00028 memcpy( (char*) &(Colors), (char*) Buffer+4*i, 4 ); 00029 //Blue, Green, Red, Alpha 00030 int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); 00031 (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); 00032 } 00033 return true; 00034 } 00035 00036 bool Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) 00037 { 00038 int i; 00039 char Colors[4]; 00040 if( Width*3 > BufferSize ) 00041 { return false; } 00042 for( i=0 ; i < Width ; i++ ) 00043 { 00044 memcpy( (char*) &(Colors), (char*) Buffer+3*i, 3 ); 00045 //Blue, Green, Red, Alpha 00046 int color = 0x00000000 | (Colors[2] << 16) | (Colors[1] << 8) | (Colors[0]); 00047 (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); 00048 } 00049 return true; 00050 } 00051 00052 RGBApixel GetColor( int ColorNumber) 00053 { 00054 RGBApixel Output; 00055 Output.Red = 255; 00056 Output.Green = 255; 00057 Output.Blue = 255; 00058 Output.Alpha = 0; 00059 00060 if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) 00061 { 00062 return Output; 00063 } 00064 if( !Colors ) 00065 { 00066 return Output; 00067 } 00068 Output = Colors[ColorNumber]; 00069 return Output; 00070 } 00071 00072 bool Read8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) 00073 { 00074 int i; 00075 if( Width > BufferSize ) 00076 { return false; } 00077 for( i=0 ; i < Width ; i++ ) 00078 { 00079 int Index = Buffer[i]; 00080 //Blue, Green, Red, Alpha 00081 RGBApixel colors = GetColor(Index); 00082 int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); 00083 (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); 00084 } 00085 return true; 00086 } 00087 00088 bool Read4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) 00089 { 00090 int Shifts[2] = {4 ,0 }; 00091 int Masks[2] = {240,15}; 00092 00093 int i=0; 00094 int j; 00095 int k=0; 00096 if( Width > 2*BufferSize ) 00097 { return false; } 00098 while( i < Width ) 00099 { 00100 j=0; 00101 while( j < 2 && i < Width ) 00102 { 00103 int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); 00104 RGBApixel colors = GetColor(Index); 00105 int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); 00106 (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); 00107 i++; j++; 00108 } 00109 k++; 00110 } 00111 return true; 00112 } 00113 bool Read1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row, NokiaLCD *lcd) 00114 { 00115 int Shifts[8] = {7 ,6 ,5 ,4 ,3,2,1,0}; 00116 int Masks[8] = {128,64,32,16,8,4,2,1}; 00117 00118 int i=0; 00119 int j; 00120 int k=0; 00121 00122 if( Width > 8*BufferSize ) 00123 { return false; } 00124 while( i < Width ) 00125 { 00126 j=0; 00127 while( j < 8 && i < Width ) 00128 { 00129 int Index = (int) ( (Buffer[k]&Masks[j]) >> Shifts[j]); 00130 RGBApixel colors = GetColor(Index); 00131 int color = 0x00000000 | (colors.Red<< 16) | (colors.Blue << 8) | (colors.Green); 00132 (*lcd).pixel((130-Width)/2+i,(130-Height)/2+Row,color); 00133 i++; j++; 00134 } 00135 k++; 00136 } 00137 return true; 00138 } 00139 00140 int TellNumberOfColors( int BitDepth ) 00141 { 00142 int output = 1 << BitDepth; 00143 if( BitDepth == 32 ) 00144 { output = 1 << 24; } 00145 return output; 00146 } 00147 00148 bool ReadBMPFromFile( const char* FileName, RGBApixel *Colors, NokiaLCD *lcd) 00149 { 00150 FILE* fp = fopen( FileName, "rb" ); 00151 if( fp == NULL ) 00152 { 00153 return false; 00154 } 00155 00156 // read the file header 00157 00158 BMFH bmfh; 00159 bool NotCorrupted = true; 00160 00161 NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp); 00162 00163 bool IsBitmap = false; 00164 00165 if( bmfh.bfType == 19778 ) 00166 { IsBitmap = true; } 00167 00168 if( !IsBitmap ) 00169 { 00170 fclose( fp ); 00171 return false; 00172 } 00173 00174 NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); 00175 NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp); 00176 NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp); 00177 NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp); 00178 00179 // read the info header 00180 00181 BMIH bmih; 00182 00183 NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp); 00184 NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); 00185 NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp); 00186 NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); 00187 NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp); 00188 00189 NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp); 00190 NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp); 00191 NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); 00192 NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); 00193 NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp); 00194 NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp); 00195 00196 // a safety catch: if any of the header information didn't read properly, abort 00197 // future idea: check to see if at least most is self-consistent 00198 00199 if( !NotCorrupted ) 00200 { 00201 fclose(fp); 00202 return false; 00203 } 00204 00205 // if bmih.biCompression 1 or 2, then the file is RLE compressed 00206 00207 if( bmih.biCompression == 1 || bmih.biCompression == 2 ) 00208 { 00209 fclose(fp); 00210 return false; 00211 } 00212 00213 // if bmih.biCompression > 3, then something strange is going on 00214 // it's probably an OS2 bitmap file. 00215 00216 if( bmih.biCompression > 3 ) 00217 { 00218 fclose(fp); 00219 return false; 00220 } 00221 00222 if( bmih.biCompression == 3 && bmih.biBitCount != 16 ) 00223 { 00224 fclose(fp); 00225 return false; 00226 } 00227 00228 // set the bit depth 00229 00230 int TempBitDepth = (int) bmih.biBitCount; 00231 if( TempBitDepth != 1 && TempBitDepth != 4 00232 && TempBitDepth != 8 && TempBitDepth != 16 00233 && TempBitDepth != 24 && TempBitDepth != 32 ) 00234 { 00235 fclose(fp); 00236 return false; 00237 } 00238 BitDepth = (int)bmih.biBitCount; 00239 // set the size 00240 00241 if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) 00242 { 00243 fclose(fp); 00244 return false; 00245 } 00246 Width = (int) bmih.biWidth; 00247 Height = (int) bmih.biHeight; 00248 // some preliminaries 00249 00250 double dBytesPerPixel = ( (double) BitDepth ) / 8.0; 00251 double dBytesPerRow = dBytesPerPixel * (Width+0.0); 00252 dBytesPerRow = ceil(dBytesPerRow); 00253 00254 int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4; 00255 if( BytePaddingPerRow == 4 ) 00256 { BytePaddingPerRow = 0; } 00257 00258 // if < 16 bits, read the palette 00259 00260 if( BitDepth < 16 ) 00261 { 00262 // determine the number of colors specified in the 00263 // color table 00264 00265 int NumberOfColorsToRead = ((int) bmfh.bfOffBits - 54 )/4; 00266 if( NumberOfColorsToRead > (1 << BitDepth) ) 00267 { NumberOfColorsToRead = (1 << BitDepth); } 00268 00269 int n; 00270 for( n=0; n < NumberOfColorsToRead ; n++ ) 00271 { 00272 SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp); 00273 } 00274 for( n=NumberOfColorsToRead ; n < TellNumberOfColors(BitDepth) ; n++ ) 00275 { 00276 RGBApixel WHITE; 00277 WHITE.Red = 255; 00278 WHITE.Green = 255; 00279 WHITE.Blue = 255; 00280 WHITE.Alpha = 0; 00281 Colors[n] = WHITE; 00282 } 00283 } 00284 00285 // skip blank data if bfOffBits so indicates 00286 00287 int BytesToSkip = bmfh.bfOffBits - 54;; 00288 if( BitDepth < 16 ) 00289 { BytesToSkip -= 4*(1 << BitDepth); } 00290 if( BitDepth == 16 && bmih.biCompression == 3 ) 00291 { BytesToSkip -= 3*4; } 00292 if( BytesToSkip < 0 ) 00293 { BytesToSkip = 0; } 00294 if( BytesToSkip > 0 && BitDepth != 16 ) 00295 { 00296 ebmpBYTE* TempSkipBYTE; 00297 TempSkipBYTE = new ebmpBYTE [BytesToSkip]; 00298 SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); 00299 delete [] TempSkipBYTE; 00300 } 00301 00302 // This code reads 1, 4, 8, 24, and 32-bpp files 00303 // with a more-efficient buffered technique. 00304 00305 int i,j; 00306 if( BitDepth != 16 ) 00307 { 00308 int BufferSize = (int) ( (Width*BitDepth) / 8.0 ); 00309 while( 8*BufferSize < Width*BitDepth ) 00310 { BufferSize++; } 00311 while( BufferSize % 4 ) 00312 { BufferSize++; } 00313 ebmpBYTE* Buffer; 00314 Buffer = new ebmpBYTE [BufferSize]; 00315 j= Height-1; 00316 while( j > -1 ) 00317 { 00318 int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp ); 00319 if( BytesRead < BufferSize ) 00320 { 00321 j = -1; 00322 } 00323 else 00324 { 00325 bool Success = false; 00326 if( BitDepth == 1 ) 00327 { Success = Read1bitRow( Buffer, BufferSize, j , lcd); } 00328 if( BitDepth == 4 ) 00329 { Success = Read4bitRow( Buffer, BufferSize, j , lcd); } 00330 if( BitDepth == 8 ) 00331 { Success = Read8bitRow( Buffer, BufferSize, j , lcd); } 00332 if( BitDepth == 24 ) 00333 { Success = Read24bitRow( Buffer, BufferSize, j , lcd); } 00334 if( BitDepth == 32 ) 00335 { Success = Read32bitRow( Buffer, BufferSize, j , lcd); } 00336 if( !Success ) 00337 { 00338 j = -1; 00339 } 00340 } 00341 j--; 00342 } 00343 delete [] Buffer; 00344 } 00345 00346 if( BitDepth == 16 ) 00347 { 00348 int DataBytes = Width*2; 00349 int PaddingBytes = ( 4 - DataBytes % 4 ) % 4; 00350 00351 // set the default mask 00352 00353 ebmpWORD BlueMask = 31; // bits 12-16 00354 ebmpWORD GreenMask = 992; // bits 7-11 00355 ebmpWORD RedMask = 31744; // bits 2-6 00356 00357 // read the bit fields, if necessary, to 00358 // override the default 5-5-5 mask 00359 00360 if( bmih.biCompression != 0 ) 00361 { 00362 // read the three bit masks 00363 00364 ebmpWORD TempMaskWORD; 00365 00366 SafeFread( (char*) &RedMask , 2 , 1 , fp ); 00367 SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); 00368 00369 SafeFread( (char*) &GreenMask , 2 , 1 , fp ); 00370 SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); 00371 00372 SafeFread( (char*) &BlueMask , 2 , 1 , fp ); 00373 SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); 00374 } 00375 00376 // read and skip any meta data 00377 00378 if( BytesToSkip > 0 ) 00379 { 00380 ebmpBYTE* TempSkipBYTE; 00381 TempSkipBYTE = new ebmpBYTE [BytesToSkip]; 00382 SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); 00383 delete [] TempSkipBYTE; 00384 } 00385 00386 // determine the red, green and blue shifts 00387 00388 int GreenShift = 0; 00389 ebmpWORD TempShiftWORD = GreenMask; 00390 while( TempShiftWORD > 31 ) 00391 { TempShiftWORD = TempShiftWORD>>1; GreenShift++; } 00392 int BlueShift = 0; 00393 TempShiftWORD = BlueMask; 00394 while( TempShiftWORD > 31 ) 00395 { TempShiftWORD = TempShiftWORD>>1; BlueShift++; } 00396 int RedShift = 0; 00397 TempShiftWORD = RedMask; 00398 while( TempShiftWORD > 31 ) 00399 { TempShiftWORD = TempShiftWORD>>1; RedShift++; } 00400 00401 // read the actual pixels 00402 00403 for( j=Height-1 ; j >= 0 ; j-- ) 00404 { 00405 i=0; 00406 int ReadNumber = 0; 00407 while( ReadNumber < DataBytes ) 00408 { 00409 ebmpWORD TempWORD; 00410 SafeFread( (char*) &TempWORD , 2 , 1 , fp ); 00411 ReadNumber += 2; 00412 00413 ebmpWORD Red = RedMask & TempWORD; 00414 ebmpWORD Green = GreenMask & TempWORD; 00415 ebmpWORD Blue = BlueMask & TempWORD; 00416 00417 ebmpBYTE BlueBYTE = (ebmpBYTE) 8*(Blue>>BlueShift); 00418 ebmpBYTE GreenBYTE = (ebmpBYTE) 8*(Green>>GreenShift); 00419 ebmpBYTE RedBYTE = (ebmpBYTE) 8*(Red>>RedShift); 00420 00421 int color = 0x00000000 | (RedBYTE << 16) | (GreenBYTE << 8) | (BlueBYTE); 00422 (*lcd).pixel((130-Width)/2+i,(130-Height)/2+j,color); 00423 i++; 00424 } 00425 ReadNumber = 0; 00426 while( ReadNumber < PaddingBytes ) 00427 { 00428 ebmpBYTE TempBYTE; 00429 SafeFread( (char*) &TempBYTE , 1, 1, fp); 00430 ReadNumber++; 00431 } 00432 } 00433 00434 } 00435 00436 fclose(fp); 00437 return true; 00438 } 00439 00440 00441 BMIH::BMIH() 00442 { 00443 biPlanes = 1; 00444 biCompression = 0; 00445 biXPelsPerMeter = DefaultXPelsPerMeter; 00446 biYPelsPerMeter = DefaultYPelsPerMeter; 00447 biClrUsed = 0; 00448 biClrImportant = 0; 00449 } 00450 00451 BMFH::BMFH() 00452 { 00453 bfType = 19778; 00454 bfReserved1 = 0; 00455 bfReserved2 = 0; 00456 }
Generated on Wed Jul 13 2022 18:08:25 by
1.7.2