mbed code for Farrari board
Dependencies: DDRO_Farrari mbed
Fork of DDRO_Farrari by
EasyBMP.cpp
00001 /************************************************* 00002 * * 00003 * EasyBMP Cross-Platform Windows Bitmap Library * 00004 * * 00005 * Author: Paul Macklin * 00006 * email: macklin01@users.sourceforge.net * 00007 * support: http://easybmp.sourceforge.net * 00008 * * 00009 * file: EasyBMP.cpp * 00010 * date added: 03-31-2006 * 00011 * date modified: 12-01-2006 * 00012 * version: 1.06 * 00013 * * 00014 * License: BSD (revised/modified) * 00015 * Copyright: 2005-6 by the EasyBMP Project * 00016 * * 00017 * description: Actual source file * 00018 * * 00019 *************************************************/ 00020 00021 #include "EasyBMP.h" 00022 00023 /* These functions are defined in EasyBMP_DataStructures.h */ 00024 00025 int ceildiv(int n, int d) 00026 { 00027 return 1 + ((n - 1) / d); 00028 } 00029 00030 int IntPow( int base, int exponent ) 00031 { 00032 int i; 00033 int output = 1; 00034 for( i=0 ; i < exponent ; i++ ) 00035 { output *= base; } 00036 return output; 00037 } 00038 00039 BMFH::BMFH() 00040 { 00041 bfType = 19778; 00042 bfReserved1 = 0; 00043 bfReserved2 = 0; 00044 } 00045 00046 BMIH::BMIH() 00047 { 00048 biPlanes = 1; 00049 biCompression = 0; 00050 biXPelsPerMeter = DefaultXPelsPerMeter; 00051 biYPelsPerMeter = DefaultYPelsPerMeter; 00052 biClrUsed = 0; 00053 biClrImportant = 0; 00054 } 00055 00056 00057 /* These functions are defined in EasyBMP_BMP.h */ 00058 00059 unsigned char BMP::GetPixel( int i, int j ) const 00060 { 00061 if(PixelsBW[i / 32][j] & ( 0x1 << (31 - i % 32))){ 00062 return 1; // white 00063 }else{ 00064 return 0; // black 00065 } 00066 } 00067 00068 bool BMP::SetPixel( int i, int j ) 00069 { 00070 PixelsR[i / 32][j] |= ( 0x1 << (31 - i % 32)); 00071 return true; 00072 } 00073 00074 BMP::BMP() 00075 { 00076 Width = 1; 00077 Height = 1; 00078 BitDepth = 24; 00079 PixelsBW = new unsigned int* [1]; 00080 PixelsBW[0] = new unsigned int [1]; 00081 PixelsR = new unsigned int* [1]; 00082 PixelsR[0] = new unsigned int [1]; 00083 00084 Colors = NULL; 00085 00086 XPelsPerMeter = 0; 00087 YPelsPerMeter = 0; 00088 00089 MetaData1 = NULL; 00090 SizeOfMetaData1 = 0; 00091 MetaData2 = NULL; 00092 SizeOfMetaData2 = 0; 00093 } 00094 00095 00096 BMP::~BMP() 00097 { 00098 int i; 00099 for(i=0;i<ceildiv(Width,32);i++) 00100 { delete [] PixelsBW[i]; } 00101 delete [] PixelsBW; 00102 00103 for(i=0;i<ceildiv(Width,32);i++) 00104 { delete [] PixelsR[i]; } 00105 delete [] PixelsR; 00106 00107 if( Colors ) 00108 { delete [] Colors; } 00109 00110 if( MetaData1 ) 00111 { delete [] MetaData1; } 00112 if( MetaData2 ) 00113 { delete [] MetaData2; } 00114 } 00115 00116 // int BMP::TellBitDepth( void ) const 00117 int BMP::TellBitDepth( void ) 00118 { return BitDepth; } 00119 00120 // int BMP::TellHeight( void ) const 00121 int BMP::TellHeight( void ) 00122 { return Height; } 00123 00124 // int BMP::TellWidth( void ) const 00125 int BMP::TellWidth( void ) 00126 { return Width; } 00127 00128 // int BMP::TellNumberOfColors( void ) const 00129 int BMP::TellNumberOfColors( void ) 00130 { 00131 int output = IntPow( 2, BitDepth ); 00132 return output; 00133 } 00134 00135 bool BMP::SetBitDepth( int NewDepth ) 00136 { 00137 using namespace std; 00138 if( NewDepth != 1 && NewDepth != 4) 00139 { 00140 return false; 00141 } 00142 00143 BitDepth = NewDepth; 00144 if( Colors ) 00145 { delete [] Colors; } 00146 int NumberOfColors = IntPow( 2, BitDepth ); 00147 00148 { Colors = new RGBApixel [NumberOfColors]; } 00149 { CreateStandardColorTable(); } 00150 00151 return true; 00152 } 00153 00154 bool BMP::SetSize(int NewWidth , int NewHeight ) 00155 { 00156 using namespace std; 00157 if( NewWidth <= 0 || NewHeight <= 0 ) 00158 { 00159 return false; 00160 } 00161 00162 int i,j; 00163 00164 for(i=0;i<ceildiv(Width,32);i++) 00165 { delete [] PixelsBW[i]; } 00166 delete [] PixelsBW; 00167 00168 for(i=0;i<ceildiv(Width,32);i++) 00169 { delete [] PixelsR[i]; } 00170 delete [] PixelsR; 00171 00172 Width = NewWidth; 00173 Height = NewHeight; 00174 PixelsBW = new unsigned int* [ ceildiv(Width,32) ]; 00175 PixelsR = new unsigned int* [ ceildiv(Width,32) ]; 00176 00177 for(i=0;i<ceildiv(Width,32);i++){ 00178 PixelsBW[i] = new unsigned int [ Height ]; 00179 PixelsR[i] = new unsigned int [ Height ]; 00180 for( j=0 ; j < Height ; j++ ){ 00181 PixelsBW[i][j] = 0; 00182 PixelsR[i][j] = 0; 00183 } 00184 } 00185 00186 return true; 00187 } 00188 #include<iostream> 00189 00190 bool BMP::WriteToFile( const char* FileName ) 00191 { 00192 00193 using namespace std; 00194 00195 cout << "called" << endl; 00196 if( !EasyBMPcheckDataSize() ) 00197 { 00198 return false; 00199 } 00200 00201 FILE* fp = fopen( FileName, "wb" ); 00202 00203 00204 if( fp == NULL ) 00205 { 00206 cout << "can't write\r\n" << endl; 00207 fclose( fp ); 00208 return false; 00209 } 00210 00211 // some preliminaries 00212 00213 double dBytesPerPixel = ( (double) BitDepth ) / 8.0; 00214 double dBytesPerRow = dBytesPerPixel * (Width+0.0); 00215 dBytesPerRow = ceil(dBytesPerRow); 00216 00217 int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4; 00218 if( BytePaddingPerRow == 4 ) 00219 { BytePaddingPerRow = 0; } 00220 00221 double dActualBytesPerRow = dBytesPerRow + BytePaddingPerRow; 00222 00223 double dTotalPixelBytes = Height * dActualBytesPerRow; 00224 00225 double dPaletteSize = 0; 00226 if( BitDepth == 1 || BitDepth == 4) 00227 { dPaletteSize = IntPow(2,BitDepth)*4.0; } 00228 00229 double dTotalFileSize = 14 + 40 + dPaletteSize + dTotalPixelBytes; 00230 00231 // write the file header 00232 00233 BMFH bmfh; 00234 bmfh.bfSize = (ebmpDWORD) dTotalFileSize; 00235 bmfh.bfReserved1 = 0; 00236 bmfh.bfReserved2 = 0; 00237 bmfh.bfOffBits = (ebmpDWORD) (14+40+dPaletteSize); 00238 00239 fwrite( (char*) &(bmfh.bfType) , sizeof(ebmpWORD) , 1 , fp ); 00240 fwrite( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1 , fp ); 00241 fwrite( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1 , fp ); 00242 fwrite( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1 , fp ); 00243 fwrite( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp ); 00244 00245 // write the info header 00246 00247 BMIH bmih; 00248 bmih.biSize = 40; 00249 bmih.biWidth = Width; 00250 bmih.biHeight = Height; 00251 bmih.biPlanes = 1; 00252 bmih.biBitCount = BitDepth; 00253 bmih.biCompression = 0; 00254 bmih.biSizeImage = (ebmpDWORD) dTotalPixelBytes; 00255 if( XPelsPerMeter ) 00256 { bmih.biXPelsPerMeter = XPelsPerMeter; } 00257 else 00258 { bmih.biXPelsPerMeter = DefaultXPelsPerMeter; } 00259 if( YPelsPerMeter ) 00260 { bmih.biYPelsPerMeter = YPelsPerMeter; } 00261 else 00262 { bmih.biYPelsPerMeter = DefaultYPelsPerMeter; } 00263 00264 bmih.biClrUsed = 0; 00265 bmih.biClrImportant = 0; 00266 00267 // indicates that we'll be using bit fields for 16-bit files 00268 if( BitDepth == 16 ) 00269 { bmih.biCompression = 3; } 00270 00271 fwrite( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp ); 00272 fwrite( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp ); 00273 fwrite( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp ); 00274 fwrite( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1 , fp ); 00275 fwrite( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1 , fp ); 00276 fwrite( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp ); 00277 fwrite( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp ); 00278 fwrite( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp ); 00279 fwrite( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp ); 00280 fwrite( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp); 00281 fwrite( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp); 00282 00283 // write the palette 00284 if( BitDepth == 1 || BitDepth == 4 ) 00285 { 00286 int NumberOfColors = IntPow(2,BitDepth); 00287 00288 // if there is no palette, create one 00289 if( !Colors ) 00290 { 00291 if( !Colors ) 00292 { Colors = new RGBApixel [NumberOfColors]; } 00293 CreateStandardColorTable(); 00294 } 00295 00296 int n; 00297 for( n=0 ; n < NumberOfColors ; n++ ) 00298 { fwrite( (char*) &(Colors[n]) , 4 , 1 , fp ); } 00299 } 00300 00301 // write the pixels 00302 int j; 00303 { 00304 ebmpBYTE* Buffer; 00305 int BufferSize = (int) ( (Width*BitDepth)/8.0 ); 00306 while( 8*BufferSize < Width*BitDepth ) 00307 { BufferSize++; } 00308 while( BufferSize % 4 ) 00309 { BufferSize++; } 00310 00311 Buffer = new ebmpBYTE [BufferSize]; 00312 for( j=0 ; j < BufferSize; j++ ) 00313 { Buffer[j] = 0; } 00314 00315 j=Height-1; 00316 00317 while( j > -1 ) 00318 { 00319 bool Success = false; 00320 if( BitDepth == 4 ) 00321 { Success = Write4bitRow( Buffer, BufferSize, j ); } 00322 if( Success ) 00323 { 00324 int BytesWritten = (int) fwrite( (char*) Buffer, 1, BufferSize, fp ); 00325 if( BytesWritten != BufferSize ) 00326 { Success = false; } 00327 } 00328 if( !Success ) 00329 { 00330 j = -1; 00331 } 00332 j--; 00333 } 00334 00335 delete [] Buffer; 00336 } 00337 00338 cout << "done " << endl; 00339 fclose(fp); 00340 return true; 00341 } 00342 00343 bool BMP::ReadFromFile( const char* FileName ) 00344 { 00345 using namespace std; 00346 if( !EasyBMPcheckDataSize() ) 00347 { 00348 return false; 00349 } 00350 00351 FILE* fp = fopen( FileName, "rb" ); 00352 if( fp == NULL ) 00353 { 00354 00355 SetBitDepth(1); 00356 SetSize(1,1); 00357 return false; 00358 } 00359 00360 // read the file header 00361 00362 BMFH bmfh; 00363 bool NotCorrupted = true; 00364 00365 NotCorrupted &= SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD), 1, fp); 00366 00367 bool IsBitmap = false; 00368 00369 if( bmfh.bfType == 19778 ) 00370 { IsBitmap = true; } 00371 00372 if( !IsBitmap ) 00373 { 00374 fclose( fp ); 00375 return false; 00376 } 00377 00378 NotCorrupted &= SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1, fp); 00379 NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1, fp); 00380 NotCorrupted &= SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1, fp); 00381 NotCorrupted &= SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp); 00382 00383 // read the info header 00384 00385 BMIH bmih; 00386 00387 NotCorrupted &= SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp); 00388 NotCorrupted &= SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp); 00389 NotCorrupted &= SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp); 00390 NotCorrupted &= SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1, fp); 00391 NotCorrupted &= SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1, fp); 00392 00393 NotCorrupted &= SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp); 00394 NotCorrupted &= SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp); 00395 NotCorrupted &= SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); 00396 NotCorrupted &= SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp); 00397 NotCorrupted &= SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp); 00398 NotCorrupted &= SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp); 00399 00400 // a safety catch: if any of the header information didn't read properly, abort 00401 // future idea: check to see if at least most is self-consistent 00402 00403 if( !NotCorrupted ) 00404 { 00405 SetSize(1,1); 00406 SetBitDepth(1); 00407 fclose(fp); 00408 return false; 00409 } 00410 00411 XPelsPerMeter = bmih.biXPelsPerMeter; 00412 YPelsPerMeter = bmih.biYPelsPerMeter; 00413 00414 // set the bit depth 00415 00416 int TempBitDepth = (int) bmih.biBitCount; 00417 if( TempBitDepth != 1 && TempBitDepth != 4 ) 00418 { 00419 SetSize(1,1); 00420 SetBitDepth(1); 00421 fclose(fp); 00422 return false; 00423 } 00424 SetBitDepth( (int) bmih.biBitCount ); 00425 00426 // set the size 00427 00428 if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) 00429 { 00430 SetSize(1,1); 00431 SetBitDepth(1); 00432 fclose(fp); 00433 return false; 00434 } 00435 SetSize( (int) bmih.biWidth , (int) bmih.biHeight ); 00436 00437 // some preliminaries 00438 00439 double dBytesPerPixel = ( (double) BitDepth ) / 8.0; 00440 double dBytesPerRow = dBytesPerPixel * (Width+0.0); 00441 dBytesPerRow = ceil(dBytesPerRow); 00442 00443 int BytePaddingPerRow = 4 - ( (int) (dBytesPerRow) )% 4; 00444 if( BytePaddingPerRow == 4 ) 00445 { BytePaddingPerRow = 0; } 00446 00447 // skip blank data if bfOffBits so indicates 00448 00449 int BytesToSkip = bmfh.bfOffBits - 54;; 00450 if( BitDepth == 16 && bmih.biCompression == 3 ) 00451 { BytesToSkip -= 3*4; } 00452 if( BytesToSkip < 0 ) 00453 { BytesToSkip = 0; } 00454 if( BytesToSkip > 0 && BitDepth != 16 ) 00455 { 00456 ebmpBYTE* TempSkipBYTE; 00457 TempSkipBYTE = new ebmpBYTE [BytesToSkip]; 00458 SafeFread( (char*) TempSkipBYTE , BytesToSkip , 1 , fp); 00459 delete [] TempSkipBYTE; 00460 } 00461 00462 // This code reads 1, 4, 8, 24, and 32-bpp files 00463 // with a more-efficient buffered technique. 00464 00465 int j; 00466 if( BitDepth != 16 ) 00467 { 00468 int BufferSize = (int) ( (Width*BitDepth) / 8.0 ); 00469 while( 8*BufferSize < Width*BitDepth ) 00470 { BufferSize++; } 00471 while( BufferSize % 4 ) 00472 { BufferSize++; } 00473 ebmpBYTE* Buffer; 00474 Buffer = new ebmpBYTE [BufferSize]; 00475 j= Height-1; 00476 while( j > -1 ) 00477 { 00478 int BytesRead = (int) fread( (char*) Buffer, 1, BufferSize, fp ); 00479 if( BytesRead < BufferSize ) 00480 { 00481 j = -1; 00482 } 00483 else 00484 { 00485 bool Success = false; 00486 if( BitDepth == 1 ) 00487 { Success = Read1bitRow( Buffer, BufferSize, j ); } 00488 if( !Success ) 00489 { 00490 j = -1; 00491 } 00492 } 00493 j--; 00494 } 00495 delete [] Buffer; 00496 } 00497 fclose(fp); 00498 return true; 00499 } 00500 00501 bool BMP::CreateStandardColorTable( void ) 00502 { 00503 using namespace std; 00504 if( BitDepth != 1 && BitDepth != 4) 00505 { 00506 return false; 00507 } 00508 00509 if( BitDepth == 1 ) 00510 { 00511 int i; 00512 for( i=0 ; i < 2 ; i++ ) 00513 { 00514 Colors[i].Red = i*255; 00515 Colors[i].Green = i*255; 00516 Colors[i].Blue = i*255; 00517 Colors[i].Alpha = 0; 00518 } 00519 return true; 00520 } 00521 00522 for(int i=0; i<16; i++){ 00523 Colors[i].Red = 0; 00524 Colors[i].Blue = 0; 00525 Colors[i].Green = 0; 00526 Colors[i].Alpha = 0; 00527 } 00528 00529 Colors[1].Red = 255; 00530 00531 Colors[15].Red = 255; 00532 Colors[15].Blue = 255; 00533 Colors[15].Green = 255; 00534 00535 return true; 00536 } 00537 00538 bool SafeFread( char* buffer, int size, int number, FILE* fp ) 00539 { 00540 using namespace std; 00541 int ItemsRead; 00542 if( feof(fp) ) 00543 { return false; } 00544 ItemsRead = (int) fread( buffer , size , number , fp ); 00545 if( ItemsRead < number ) 00546 { return false; } 00547 return true; 00548 } 00549 00550 #include<iostream> 00551 bool BMP::Read1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) 00552 { 00553 using namespace std; 00554 if( Width > 8*BufferSize ) 00555 { return false; } 00556 00557 int i=0; 00558 for(i=0; i < BufferSize; i++){ 00559 PixelsBW[i/4][Row] |= Buffer[i] << (8 * (3 - i%4)); 00560 } 00561 return true; 00562 } 00563 00564 bool BMP::Write4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) 00565 { 00566 int PositionWeights[2] = {16,1}; 00567 00568 int i=0; 00569 int j; 00570 int k=0; 00571 if( Width > 2*BufferSize ) 00572 { return false; } 00573 while( i < Width ) 00574 { 00575 j=0; 00576 int Index = 0; 00577 while( j < 2 && i < Width ) 00578 { 00579 int closest = 0; // black 00580 if(PixelsBW[i / 32][Row] & ( 0x1 << (31 - i % 32))){ 00581 closest = 15; // white 00582 } 00583 if(PixelsR[i / 32][Row] & ( 0x1 << (31 - i % 32))){ 00584 closest = 1; // red 00585 } 00586 Index += ( PositionWeights[j]* closest ); 00587 i++; j++; 00588 } 00589 Buffer[k] = (ebmpBYTE) Index; 00590 k++; 00591 } 00592 return true; 00593 } 00594 00595 bool EasyBMPcheckDataSize( void ) 00596 { 00597 using namespace std; 00598 bool ReturnValue = true; 00599 if( sizeof( ebmpBYTE ) != 1 ) 00600 { 00601 ReturnValue = false; 00602 } 00603 if( sizeof( ebmpWORD ) != 2 ) 00604 { 00605 ReturnValue = false; 00606 } 00607 if( sizeof( ebmpDWORD ) != 4 ) 00608 { 00609 ReturnValue = false; 00610 } 00611 return ReturnValue; 00612 }
Generated on Wed Jul 27 2022 00:15:18 by
1.7.2
