From 044ad7c3987460ede48ff27afd6bdb0ca05a0432 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 4 Jul 2011 20:52:54 +0200 Subject: import at91lib from at91lib_20100901_softpack_1_9_v_1_0_svn_v15011 it's sad to see that atmel doesn't publish their svn repo or has a centralized location or even puts proper version/release info into the library itself --- .../pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp | 1917 ++++++++++++++++++++ 1 file changed, 1917 insertions(+) create mode 100644 utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp (limited to 'utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp') diff --git a/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp new file mode 100644 index 0000000..07d33ef --- /dev/null +++ b/utility/demo-fw/pc-tools/CreateDemoBin/lib/EasyBMP/EasyBMP.cpp @@ -0,0 +1,1917 @@ +/************************************************* +* * +* EasyBMP Cross-Platform Windows Bitmap Library * +* * +* Author: Paul Macklin * +* email: macklin01@users.sourceforge.net * +* support: http://easybmp.sourceforge.net * +* * +* file: EasyBMP.cpp * +* date added: 03-31-2006 * +* date modified: 12-01-2006 * +* version: 1.06 * +* * +* License: BSD (revised/modified) * +* Copyright: 2005-6 by the EasyBMP Project * +* * +* description: Actual source file * +* * +*************************************************/ + +#include "EasyBMP.h" + +/* These functions are defined in EasyBMP.h */ + +bool EasyBMPwarnings = true; + +void SetEasyBMPwarningsOff( void ) +{ EasyBMPwarnings = false; } +void SetEasyBMPwarningsOn( void ) +{ EasyBMPwarnings = true; } +bool GetEasyBMPwarningState( void ) +{ return EasyBMPwarnings; } + +/* These functions are defined in EasyBMP_DataStructures.h */ + +int IntPow( int base, int exponent ) +{ + int i; + int output = 1; + for( i=0 ; i < exponent ; i++ ) + { output *= base; } + return output; +} + +BMFH::BMFH() +{ + bfType = 19778; + bfReserved1 = 0; + bfReserved2 = 0; +} + +void BMFH::SwitchEndianess( void ) +{ + bfType = FlipWORD( bfType ); + bfSize = FlipDWORD( bfSize ); + bfReserved1 = FlipWORD( bfReserved1 ); + bfReserved2 = FlipWORD( bfReserved2 ); + bfOffBits = FlipDWORD( bfOffBits ); + return; +} + +BMIH::BMIH() +{ + biPlanes = 1; + biCompression = 0; + biXPelsPerMeter = DefaultXPelsPerMeter; + biYPelsPerMeter = DefaultYPelsPerMeter; + biClrUsed = 0; + biClrImportant = 0; +} + +void BMIH::SwitchEndianess( void ) +{ + biSize = FlipDWORD( biSize ); + biWidth = FlipDWORD( biWidth ); + biHeight = FlipDWORD( biHeight ); + biPlanes = FlipWORD( biPlanes ); + biBitCount = FlipWORD( biBitCount ); + biCompression = FlipDWORD( biCompression ); + biSizeImage = FlipDWORD( biSizeImage ); + biXPelsPerMeter = FlipDWORD( biXPelsPerMeter ); + biYPelsPerMeter = FlipDWORD( biYPelsPerMeter ); + biClrUsed = FlipDWORD( biClrUsed ); + biClrImportant = FlipDWORD( biClrImportant ); + return; +} + +void BMIH::display( void ) +{ + using namespace std; + cout << "biSize: " << (int) biSize << endl + << "biWidth: " << (int) biWidth << endl + << "biHeight: " << (int) biHeight << endl + << "biPlanes: " << (int) biPlanes << endl + << "biBitCount: " << (int) biBitCount << endl + << "biCompression: " << (int) biCompression << endl + << "biSizeImage: " << (int) biSizeImage << endl + << "biXPelsPerMeter: " << (int) biXPelsPerMeter << endl + << "biYPelsPerMeter: " << (int) biYPelsPerMeter << endl + << "biClrUsed: " << (int) biClrUsed << endl + << "biClrImportant: " << (int) biClrImportant << endl << endl; +} + +void BMFH::display( void ) +{ + using namespace std; + cout << "bfType: " << (int) bfType << endl + << "bfSize: " << (int) bfSize << endl + << "bfReserved1: " << (int) bfReserved1 << endl + << "bfReserved2: " << (int) bfReserved2 << endl + << "bfOffBits: " << (int) bfOffBits << endl << endl; +} + +/* These functions are defined in EasyBMP_BMP.h */ + +RGBApixel BMP::GetPixel( int i, int j ) const +{ + using namespace std; + bool Warn = false; + if( i >= Width ) + { i = Width-1; Warn = true; } + if( i < 0 ) + { i = 0; Warn = true; } + if( j >= Height ) + { j = Height-1; Warn = true; } + if( j < 0 ) + { j = 0; Warn = true; } + if( Warn && EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to access non-existent pixel;" << endl + << " Truncating request to fit in the range [0," + << Width-1 << "] x [0," << Height-1 << "]." << endl; + } + return Pixels[i][j]; +} + +bool BMP::SetPixel( int i, int j, RGBApixel NewPixel ) +{ + Pixels[i][j] = NewPixel; + return true; +} + + +bool BMP::SetColor( int ColorNumber , RGBApixel NewColor ) +{ + using namespace std; + if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to change color table for a BMP object" << endl + << " that lacks a color table. Ignoring request." << endl; + } + return false; + } + if( !Colors ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to set a color, but the color table" << endl + << " is not defined. Ignoring request." << endl; + } + return false; + } + if( ColorNumber >= TellNumberOfColors() ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Requested color number " + << ColorNumber << " is outside the allowed" << endl + << " range [0," << TellNumberOfColors()-1 + << "]. Ignoring request to set this color." << endl; + } + return false; + } + Colors[ColorNumber] = NewColor; + return true; +} + +// RGBApixel BMP::GetColor( int ColorNumber ) const +RGBApixel BMP::GetColor( int ColorNumber ) +{ + RGBApixel Output; + Output.Red = 255; + Output.Green = 255; + Output.Blue = 255; + Output.Alpha = 0; + + using namespace std; + if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to access color table for a BMP object" << endl + << " that lacks a color table. Ignoring request." << endl; + } + return Output; + } + if( !Colors ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Requested a color, but the color table" << endl + << " is not defined. Ignoring request." << endl; + } + return Output; + } + if( ColorNumber >= TellNumberOfColors() ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Requested color number " + << ColorNumber << " is outside the allowed" << endl + << " range [0," << TellNumberOfColors()-1 + << "]. Ignoring request to get this color." << endl; + } + return Output; + } + Output = Colors[ColorNumber]; + return Output; +} + +BMP::BMP() +{ + Width = 1; + Height = 1; + BitDepth = 24; + Pixels = new RGBApixel* [Width]; + Pixels[0] = new RGBApixel [Height]; + Colors = NULL; + + XPelsPerMeter = 0; + YPelsPerMeter = 0; + + MetaData1 = NULL; + SizeOfMetaData1 = 0; + MetaData2 = NULL; + SizeOfMetaData2 = 0; +} + +// BMP::BMP( const BMP& Input ) +BMP::BMP( BMP& Input ) +{ + // first, make the image empty. + + Width = 1; + Height = 1; + BitDepth = 24; + Pixels = new RGBApixel* [Width]; + Pixels[0] = new RGBApixel [Height]; + Colors = NULL; + XPelsPerMeter = 0; + YPelsPerMeter = 0; + + MetaData1 = NULL; + SizeOfMetaData1 = 0; + MetaData2 = NULL; + SizeOfMetaData2 = 0; + + // now, set the correct bit depth + + SetBitDepth( Input.TellBitDepth() ); + + // set the correct pixel size + + SetSize( Input.TellWidth() , Input.TellHeight() ); + + // set the DPI information from Input + + SetDPI( Input.TellHorizontalDPI() , Input.TellVerticalDPI() ); + + // if there is a color table, get all the colors + + if( BitDepth == 1 || BitDepth == 4 || + BitDepth == 8 ) + { + for( int k=0 ; k < TellNumberOfColors() ; k++ ) + { + SetColor( k, Input.GetColor( k )); + } + } + + // get all the pixels + + for( int j=0; j < Height ; j++ ) + { + for( int i=0; i < Width ; i++ ) + { + Pixels[i][j] = *Input(i,j); +// Pixels[i][j] = Input.GetPixel(i,j); // *Input(i,j); + } + } +} + +BMP::~BMP() +{ + int i; + for(i=0;i= Width ) + { i = Width-1; Warn = true; } + if( i < 0 ) + { i = 0; Warn = true; } + if( j >= Height ) + { j = Height-1; Warn = true; } + if( j < 0 ) + { j = 0; Warn = true; } + if( Warn && EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to access non-existent pixel;" << endl + << " Truncating request to fit in the range [0," + << Width-1 << "] x [0," << Height-1 << "]." << endl; + } + return &(Pixels[i][j]); +} + +// int BMP::TellBitDepth( void ) const +int BMP::TellBitDepth( void ) +{ return BitDepth; } + +// int BMP::TellHeight( void ) const +int BMP::TellHeight( void ) +{ return Height; } + +// int BMP::TellWidth( void ) const +int BMP::TellWidth( void ) +{ return Width; } + +// int BMP::TellNumberOfColors( void ) const +int BMP::TellNumberOfColors( void ) +{ + int output = IntPow( 2, BitDepth ); + if( BitDepth == 32 ) + { output = IntPow( 2, 24 ); } + return output; +} + +bool BMP::SetBitDepth( int NewDepth ) +{ + using namespace std; + if( NewDepth != 1 && NewDepth != 4 && + NewDepth != 8 && NewDepth != 16 && + NewDepth != 24 && NewDepth != 32 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: User attempted to set unsupported bit depth " + << NewDepth << "." << endl + << " Bit depth remains unchanged at " + << BitDepth << "." << endl; + } + return false; + } + + BitDepth = NewDepth; + if( Colors ) + { delete [] Colors; } + int NumberOfColors = IntPow( 2, BitDepth ); + if( BitDepth == 1 || BitDepth == 4 || BitDepth == 8 ) + { Colors = new RGBApixel [NumberOfColors]; } + else + { Colors = NULL; } + if( BitDepth == 1 || BitDepth == 4 || BitDepth == 8 ) + { CreateStandardColorTable(); } + + return true; +} + +bool BMP::SetSize(int NewWidth , int NewHeight ) +{ + using namespace std; + if( NewWidth <= 0 || NewHeight <= 0 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: User attempted to set a non-positive width or height." << endl + << " Size remains unchanged at " + << Width << " x " << Height << "." << endl; + } + return false; + } + + int i,j; + + for(i=0;i -1 ) + { + bool Success = false; + if( BitDepth == 32 ) + { Success = Write32bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 24 ) + { Success = Write24bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 8 ) + { Success = Write8bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 4 ) + { Success = Write4bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 1 ) + { Success = Write1bitRow( Buffer, BufferSize, j ); } + if( Success ) + { + int BytesWritten = (int) fwrite( (char*) Buffer, 1, BufferSize, fp ); + if( BytesWritten != BufferSize ) + { Success = false; } + } + if( !Success ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: Could not write proper amount of data." << endl; + } + j = -1; + } + j--; + } + + delete [] Buffer; + } + + if( BitDepth == 16 ) + { + // write the bit masks + + ebmpWORD BlueMask = 31; // bits 12-16 + ebmpWORD GreenMask = 2016; // bits 6-11 + ebmpWORD RedMask = 63488; // bits 1-5 + ebmpWORD ZeroWORD; + + if( IsBigEndian() ) + { RedMask = FlipWORD( RedMask ); } + fwrite( (char*) &RedMask , 2 , 1 , fp ); + fwrite( (char*) &ZeroWORD , 2 , 1 , fp ); + + if( IsBigEndian() ) + { GreenMask = FlipWORD( GreenMask ); } + fwrite( (char*) &GreenMask , 2 , 1 , fp ); + fwrite( (char*) &ZeroWORD , 2 , 1 , fp ); + + if( IsBigEndian() ) + { BlueMask = FlipWORD( BlueMask ); } + fwrite( (char*) &BlueMask , 2 , 1 , fp ); + fwrite( (char*) &ZeroWORD , 2 , 1 , fp ); + + int DataBytes = Width*2; + int PaddingBytes = ( 4 - DataBytes % 4 ) % 4; + + // write the actual pixels + + for( j=Height-1 ; j >= 0 ; j-- ) + //int WriteNumber; + //for(j=0, WriteNumber=0; j < Height; ++j) + { + // write all row pixel data + i=0; + int WriteNumber = 0; + while( WriteNumber < DataBytes ) + //for(i = 0; i 3, then something strange is going on + // it's probably an OS2 bitmap file. + + if( bmih.biCompression > 3 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: " << FileName << " is in an unsupported format." + << endl + << " (bmih.biCompression = " + << bmih.biCompression << ")" << endl + << " The file is probably an old OS2 bitmap or corrupted." + << endl; + } + SetSize(1,1); + SetBitDepth(1); + fclose(fp); + return false; + } + + if( bmih.biCompression == 3 && bmih.biBitCount != 16 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: " << FileName + << " uses bit fields and is not a" << endl + << " 16-bit file. This is not supported." << endl; + } + SetSize(1,1); + SetBitDepth(1); + 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 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: " << FileName << " has unrecognized bit depth." << endl; + } + SetSize(1,1); + SetBitDepth(1); + fclose(fp); + return false; + } + SetBitDepth( (int) bmih.biBitCount ); + + // set the size + + if( (int) bmih.biWidth <= 0 || (int) bmih.biHeight <= 0 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: " << FileName + << " has a non-positive width or height." << endl; + } + SetSize(1,1); + SetBitDepth(1); + fclose(fp); + return false; + } + SetSize( (int) bmih.biWidth , (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 > IntPow(2,BitDepth) ) + { NumberOfColorsToRead = IntPow(2,BitDepth); } + + if( NumberOfColorsToRead < TellNumberOfColors() ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: file " << FileName << " has an underspecified" << endl + << " color table. The table will be padded with extra" << endl + << " white (255,255,255,0) entries." << endl; + } + } + + int n; + for( n=0; n < NumberOfColorsToRead ; n++ ) + { + SafeFread( (char*) &(Colors[n]) , 4 , 1 , fp); + } + for( n=NumberOfColorsToRead ; n < TellNumberOfColors() ; n++ ) + { + RGBApixel WHITE; + WHITE.Red = 255; + WHITE.Green = 255; + WHITE.Blue = 255; + WHITE.Alpha = 0; + SetColor( n , WHITE ); + } + + + } + + // skip blank data if bfOffBits so indicates + + int BytesToSkip = bmfh.bfOffBits - 54;; + if( BitDepth < 16 ) + { BytesToSkip -= 4*IntPow(2,BitDepth); } + if( BitDepth == 16 && bmih.biCompression == 3 ) + { BytesToSkip -= 3*4; } + if( BytesToSkip < 0 ) + { BytesToSkip = 0; } + if( BytesToSkip > 0 && BitDepth != 16 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Extra meta data detected in file " << FileName << endl + << " Data will be skipped." << endl; + } + 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; + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: Could not read proper amount of data." << endl; + } + } + else + { + bool Success = false; + if( BitDepth == 1 ) + { Success = Read1bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 4 ) + { Success = Read4bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 8 ) + { Success = Read8bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 24 ) + { Success = Read24bitRow( Buffer, BufferSize, j ); } + if( BitDepth == 32 ) + { Success = Read32bitRow( Buffer, BufferSize, j ); } + if( !Success ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: Could not read enough pixel data!" << endl; + } + 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; + ebmpWORD ZeroWORD=0; + + SafeFread( (char*) &RedMask , 2 , 1 , fp ); + if( IsBigEndian() ) + { RedMask = FlipWORD(RedMask); } + SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); + + SafeFread( (char*) &GreenMask , 2 , 1 , fp ); + if( IsBigEndian() ) + { GreenMask = FlipWORD(GreenMask); } + SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); + + SafeFread( (char*) &BlueMask , 2 , 1 , fp ); + if( IsBigEndian() ) + { BlueMask = FlipWORD(BlueMask); } + SafeFread( (char*) &TempMaskWORD , 2, 1, fp ); + } + + // read and skip any meta data + + if( BytesToSkip > 0 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Extra meta data detected in file " + << FileName << endl + << " Data will be skipped." << endl; + } + 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 ); + if( IsBigEndian() ) + { TempWORD = FlipWORD(TempWORD); } + 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); + + (Pixels[i][j]).Red = RedBYTE; + (Pixels[i][j]).Green = GreenBYTE; + (Pixels[i][j]).Blue = BlueBYTE; + + i++; + } + ReadNumber = 0; + while( ReadNumber < PaddingBytes ) + { + ebmpBYTE TempBYTE; + SafeFread( (char*) &TempBYTE , 1, 1, fp); + ReadNumber++; + } + } + + } + + fclose(fp); + return true; +} + +bool BMP::CreateStandardColorTable( void ) +{ + using namespace std; + if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to create color table at a bit" << endl + << " depth that does not require a color table." << endl + << " Ignoring request." << endl; + } + return false; + } + + if( BitDepth == 1 ) + { + int i; + for( i=0 ; i < 2 ; i++ ) + { + Colors[i].Red = i*255; + Colors[i].Green = i*255; + Colors[i].Blue = i*255; + Colors[i].Alpha = 0; + } + return true; + } + + if( BitDepth == 4 ) + { + int i = 0; + int j,k,ell; + + // simplify the code for the first 8 colors + for( ell=0 ; ell < 2 ; ell++ ) + { + for( k=0 ; k < 2 ; k++ ) + { + for( j=0 ; j < 2 ; j++ ) + { + Colors[i].Red = j*128; + Colors[i].Green = k*128; + Colors[i].Blue = ell*128; + i++; + } + } + } + + // simplify the code for the last 8 colors + for( ell=0 ; ell < 2 ; ell++ ) + { + for( k=0 ; k < 2 ; k++ ) + { + for( j=0 ; j < 2 ; j++ ) + { + Colors[i].Red = j*255; + Colors[i].Green = k*255; + Colors[i].Blue = ell*255; + i++; + } + } + } + + // overwrite the duplicate color + i=8; + Colors[i].Red = 192; + Colors[i].Green = 192; + Colors[i].Blue = 192; + + for( i=0 ; i < 16 ; i++ ) + { Colors[i].Alpha = 0; } + return true; + } + + if( BitDepth == 8 ) + { + int i=0; + int j,k,ell; + + // do an easy loop, which works for all but colors + // 0 to 9 and 246 to 255 + for( ell=0 ; ell < 4 ; ell++ ) + { + for( k=0 ; k < 8 ; k++ ) + { + for( j=0; j < 8 ; j++ ) + { + Colors[i].Red = j*32; + Colors[i].Green = k*32; + Colors[i].Blue = ell*64; + Colors[i].Alpha = 0; + i++; + } + } + } + + // now redo the first 8 colors + i=0; + for( ell=0 ; ell < 2 ; ell++ ) + { + for( k=0 ; k < 2 ; k++ ) + { + for( j=0; j < 2 ; j++ ) + { + Colors[i].Red = j*128; + Colors[i].Green = k*128; + Colors[i].Blue = ell*128; + i++; + } + } + } + + // overwrite colors 7, 8, 9 + i=7; + Colors[i].Red = 192; + Colors[i].Green = 192; + Colors[i].Blue = 192; + i++; // 8 + Colors[i].Red = 192; + Colors[i].Green = 220; + Colors[i].Blue = 192; + i++; // 9 + Colors[i].Red = 166; + Colors[i].Green = 202; + Colors[i].Blue = 240; + + // overwrite colors 246 to 255 + i=246; + Colors[i].Red = 255; + Colors[i].Green = 251; + Colors[i].Blue = 240; + i++; // 247 + Colors[i].Red = 160; + Colors[i].Green = 160; + Colors[i].Blue = 164; + i++; // 248 + Colors[i].Red = 128; + Colors[i].Green = 128; + Colors[i].Blue = 128; + i++; // 249 + Colors[i].Red = 255; + Colors[i].Green = 0; + Colors[i].Blue = 0; + i++; // 250 + Colors[i].Red = 0; + Colors[i].Green = 255; + Colors[i].Blue = 0; + i++; // 251 + Colors[i].Red = 255; + Colors[i].Green = 255; + Colors[i].Blue = 0; + i++; // 252 + Colors[i].Red = 0; + Colors[i].Green = 0; + Colors[i].Blue = 255; + i++; // 253 + Colors[i].Red = 255; + Colors[i].Green = 0; + Colors[i].Blue = 255; + i++; // 254 + Colors[i].Red = 0; + Colors[i].Green = 255; + Colors[i].Blue = 255; + i++; // 255 + Colors[i].Red = 255; + Colors[i].Green = 255; + Colors[i].Blue = 255; + + return true; + } + return true; +} + +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; +} + +void BMP::SetDPI( int HorizontalDPI, int VerticalDPI ) +{ + XPelsPerMeter = (int) ( HorizontalDPI * 39.37007874015748 ); + YPelsPerMeter = (int) ( VerticalDPI * 39.37007874015748 ); +} + +// int BMP::TellVerticalDPI( void ) const +int BMP::TellVerticalDPI( void ) +{ + if( !YPelsPerMeter ) + { YPelsPerMeter = DefaultYPelsPerMeter; } + return (int) ( YPelsPerMeter / (double) 39.37007874015748 ); +} + +// int BMP::TellHorizontalDPI( void ) const +int BMP::TellHorizontalDPI( void ) +{ + if( !XPelsPerMeter ) + { XPelsPerMeter = DefaultXPelsPerMeter; } + return (int) ( XPelsPerMeter / (double) 39.37007874015748 ); +} + +/* These functions are defined in EasyBMP_VariousBMPutilities.h */ + +BMFH GetBMFH( const char* szFileNameIn ) +{ + using namespace std; + BMFH bmfh; + + FILE* fp; + fp = fopen( szFileNameIn,"rb"); + + if( !fp ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: Cannot initialize from file " + << szFileNameIn << "." << endl + << " File cannot be opened or does not exist." + << endl; + } + bmfh.bfType = 0; + return bmfh; + } + + SafeFread( (char*) &(bmfh.bfType) , sizeof(ebmpWORD) , 1 , fp ); + SafeFread( (char*) &(bmfh.bfSize) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmfh.bfReserved1) , sizeof(ebmpWORD) , 1 , fp ); + SafeFread( (char*) &(bmfh.bfReserved2) , sizeof(ebmpWORD) , 1 , fp ); + SafeFread( (char*) &(bmfh.bfOffBits) , sizeof(ebmpDWORD) , 1 , fp ); + + fclose( fp ); + + if( IsBigEndian() ) + { bmfh.SwitchEndianess(); } + + return bmfh; +} + +BMIH GetBMIH( const char* szFileNameIn ) +{ + using namespace std; + BMFH bmfh; + BMIH bmih; + + FILE* fp; + fp = fopen( szFileNameIn,"rb"); + + if( !fp ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: Cannot initialize from file " + << szFileNameIn << "." << endl + << " File cannot be opened or does not exist." + << endl; + } + return bmih; + } + + // read the bmfh, i.e., first 14 bytes (just to get it out of the way); + + ebmpBYTE TempBYTE; + int i; + for( i = 14 ; i > 0 ; i-- ) + { SafeFread( (char*) &TempBYTE , sizeof(ebmpBYTE) , 1, fp ); } + + // read the bmih + + SafeFread( (char*) &(bmih.biSize) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biWidth) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biHeight) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biPlanes) , sizeof(ebmpWORD) , 1 , fp ); + + SafeFread( (char*) &(bmih.biBitCount) , sizeof(ebmpWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biCompression) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biSizeImage) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biXPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp ); + + SafeFread( (char*) &(bmih.biYPelsPerMeter) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biClrUsed) , sizeof(ebmpDWORD) , 1 , fp ); + SafeFread( (char*) &(bmih.biClrImportant) , sizeof(ebmpDWORD) , 1 , fp ); + + fclose( fp ); + + if( IsBigEndian() ) + { bmih.SwitchEndianess(); } + + return bmih; +} + +void DisplayBitmapInfo( const char* szFileNameIn ) +{ + using namespace std; + FILE* fp; + fp = fopen( szFileNameIn,"rb"); + + if( !fp ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: Cannot initialize from file " + << szFileNameIn << "." << endl + << " File cannot be opened or does not exist." + << endl; + } + return; + } + fclose( fp ); + + // don't duplicate work! Just use the functions from above! + + BMFH bmfh = GetBMFH(szFileNameIn); + BMIH bmih = GetBMIH(szFileNameIn); + + cout << "File information for file " << szFileNameIn + << ":" << endl << endl; + + cout << "BITMAPFILEHEADER:" << endl + << "bfType: " << bmfh.bfType << endl + << "bfSize: " << bmfh.bfSize << endl + << "bfReserved1: " << bmfh.bfReserved1 << endl + << "bfReserved2: " << bmfh.bfReserved2 << endl + << "bfOffBits: " << bmfh.bfOffBits << endl << endl; + + cout << "BITMAPINFOHEADER:" << endl + << "biSize: " << bmih.biSize << endl + << "biWidth: " << bmih.biWidth << endl + << "biHeight: " << bmih.biHeight << endl + << "biPlanes: " << bmih.biPlanes << endl + << "biBitCount: " << bmih.biBitCount << endl + << "biCompression: " << bmih.biCompression << endl + << "biSizeImage: " << bmih.biSizeImage << endl + << "biXPelsPerMeter: " << bmih.biXPelsPerMeter << endl + << "biYPelsPerMeter: " << bmih.biYPelsPerMeter << endl + << "biClrUsed: " << bmih.biClrUsed << endl + << "biClrImportant: " << bmih.biClrImportant << endl << endl; + return; +} + +int GetBitmapColorDepth( const char* szFileNameIn ) +{ + BMIH bmih = GetBMIH( szFileNameIn ); + return (int) bmih.biBitCount; +} + +void PixelToPixelCopy( BMP& From, int FromX, int FromY, + BMP& To, int ToX, int ToY) +{ + *To(ToX,ToY) = *From(FromX,FromY); + return; +} + +void PixelToPixelCopyTransparent( BMP& From, int FromX, int FromY, + BMP& To, int ToX, int ToY, + RGBApixel& Transparent ) +{ + if( From(FromX,FromY)->Red != Transparent.Red || + From(FromX,FromY)->Green != Transparent.Green || + From(FromX,FromY)->Blue != Transparent.Blue ) + { *To(ToX,ToY) = *From(FromX,FromY); } + return; +} + +void RangedPixelToPixelCopy( BMP& From, int FromL , int FromR, int FromB, int FromT, + BMP& To, int ToX, int ToY ) +{ + // make sure the conventions are followed + if( FromB < FromT ) + { int Temp = FromT; FromT = FromB; FromB = Temp; } + + // make sure that the copied regions exist in both bitmaps + if( FromR >= From.TellWidth() ) + { FromR = From.TellWidth()-1; } + if( FromL < 0 ){ FromL = 0; } + + if( FromB >= From.TellHeight() ) + { FromB = From.TellHeight()-1; } + if( FromT < 0 ){ FromT = 0; } + + if( ToX+(FromR-FromL) >= To.TellWidth() ) + { FromR = To.TellWidth()-1+FromL-ToX; } + if( ToY+(FromB-FromT) >= To.TellHeight() ) + { FromB = To.TellHeight()-1+FromT-ToY; } + + int i,j; + for( j=FromT ; j <= FromB ; j++ ) + { + for( i=FromL ; i <= FromR ; i++ ) + { + PixelToPixelCopy( From, i,j, + To, ToX+(i-FromL), ToY+(j-FromT) ); + } + } + + return; +} + +void RangedPixelToPixelCopyTransparent( + BMP& From, int FromL , int FromR, int FromB, int FromT, + BMP& To, int ToX, int ToY , + RGBApixel& Transparent ) +{ + // make sure the conventions are followed + if( FromB < FromT ) + { int Temp = FromT; FromT = FromB; FromB = Temp; } + + // make sure that the copied regions exist in both bitmaps + if( FromR >= From.TellWidth() ) + { FromR = From.TellWidth()-1; } + if( FromL < 0 ){ FromL = 0; } + + if( FromB >= From.TellHeight() ) + { FromB = From.TellHeight()-1; } + if( FromT < 0 ){ FromT = 0; } + + if( ToX+(FromR-FromL) >= To.TellWidth() ) + { FromR = To.TellWidth()-1+FromL-ToX; } + if( ToY+(FromB-FromT) >= To.TellHeight() ) + { FromB = To.TellHeight()-1+FromT-ToY; } + + int i,j; + for( j=FromT ; j <= FromB ; j++ ) + { + for( i=FromL ; i <= FromR ; i++ ) + { + PixelToPixelCopyTransparent( From, i,j, + To, ToX+(i-FromL), ToY+(j-FromT) , + Transparent); + } + } + + return; +} + +bool CreateGrayscaleColorTable( BMP& InputImage ) +{ + using namespace std; + int BitDepth = InputImage.TellBitDepth(); + if( BitDepth != 1 && BitDepth != 4 && BitDepth != 8 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Warning: Attempted to create color table at a bit" << endl + << " depth that does not require a color table." << endl + << " Ignoring request." << endl; + } + return false; + } + int i; + int NumberOfColors = InputImage.TellNumberOfColors(); + + ebmpBYTE StepSize; + if( BitDepth != 1 ) + { StepSize = 255/(NumberOfColors-1); } + else + { StepSize = 255; } + + for( i=0 ; i < NumberOfColors ; i++ ) + { + ebmpBYTE TempBYTE = i*StepSize; + RGBApixel TempColor; + TempColor.Red = TempBYTE; + TempColor.Green = TempBYTE; + TempColor.Blue = TempBYTE; + TempColor.Alpha = 0; + InputImage.SetColor( i , TempColor ); + } + return true; +} + +bool BMP::Read32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int i; + if( Width*4 > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { memcpy( (char*) &(Pixels[i][Row]), (char*) Buffer+4*i, 4 ); } + return true; +} + +bool BMP::Read24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int i; + if( Width*3 > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { memcpy( (char*) &(Pixels[i][Row]), Buffer+3*i, 3 ); } + return true; +} + +bool BMP::Read8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int i; + if( Width > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { + int Index = Buffer[i]; + *( this->operator()(i,Row) )= GetColor(Index); + } + return true; +} + +bool BMP::Read4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + 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]); + *( this->operator()(i,Row) )= GetColor(Index); + i++; j++; + } + k++; + } + return true; +} +bool BMP::Read1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + 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]); + *( this->operator()(i,Row) )= GetColor(Index); + i++; j++; + } + k++; + } + return true; +} + +bool BMP::Write32bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int i; + if( Width*4 > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { memcpy( (char*) Buffer+4*i, (char*) &(Pixels[i][Row]), 4 ); } + return true; +} + +bool BMP::Write24bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int i; + if( Width*3 > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { memcpy( (char*) Buffer+3*i, (char*) &(Pixels[i][Row]), 3 ); } + return true; +} + +bool BMP::Write8bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int i; + if( Width > BufferSize ) + { return false; } + for( i=0 ; i < Width ; i++ ) + { Buffer[i] = FindClosestColor( Pixels[i][Row] ); } + return true; +} + +bool BMP::Write4bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int PositionWeights[2] = {16,1}; + + int i=0; + int j; + int k=0; + if( Width > 2*BufferSize ) + { return false; } + while( i < Width ) + { + j=0; + int Index = 0; + while( j < 2 && i < Width ) + { + Index += ( PositionWeights[j]* (int) FindClosestColor( Pixels[i][Row] ) ); + i++; j++; + } + Buffer[k] = (ebmpBYTE) Index; + k++; + } + return true; +} + +bool BMP::Write1bitRow( ebmpBYTE* Buffer, int BufferSize, int Row ) +{ + int PositionWeights[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; + int Index = 0; + while( j < 8 && i < Width ) + { + Index += ( PositionWeights[j]* (int) FindClosestColor( Pixels[i][Row] ) ); + i++; j++; + } + Buffer[k] = (ebmpBYTE) Index; + k++; + } + return true; +} + +ebmpBYTE BMP::FindClosestColor( RGBApixel& input ) +{ + using namespace std; + + int i=0; + int NumberOfColors = TellNumberOfColors(); + ebmpBYTE BestI = 0; + int BestMatch = 999999; + + while( i < NumberOfColors ) + { + RGBApixel Attempt = GetColor( i ); + int TempMatch = IntSquare( (int) Attempt.Red - (int) input.Red ) + + IntSquare( (int) Attempt.Green - (int) input.Green ) + + IntSquare( (int) Attempt.Blue - (int) input.Blue ); + if( TempMatch < BestMatch ) + { BestI = (ebmpBYTE) i; BestMatch = TempMatch; } + if( BestMatch < 1 ) + { i = NumberOfColors; } + i++; + } + return BestI; +} + +bool EasyBMPcheckDataSize( void ) +{ + using namespace std; + bool ReturnValue = true; + if( sizeof( ebmpBYTE ) != 1 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: ebmpBYTE has the wrong size (" + << sizeof( ebmpBYTE ) << " bytes)," << endl + << " Compared to the expected 1 byte value" << endl; + } + ReturnValue = false; + } + if( sizeof( ebmpWORD ) != 2 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: ebmpWORD has the wrong size (" + << sizeof( ebmpWORD ) << " bytes)," << endl + << " Compared to the expected 2 byte value" << endl; + } + ReturnValue = false; + } + if( sizeof( ebmpDWORD ) != 4 ) + { + if( EasyBMPwarnings ) + { + cout << "EasyBMP Error: ebmpDWORD has the wrong size (" + << sizeof( ebmpDWORD ) << " bytes)," << endl + << " Compared to the expected 4 byte value" << endl; + } + ReturnValue = false; + } + return ReturnValue; +} + +bool Rescale( BMP& InputImage , char mode, ScaleParam scale ) +{ + using namespace std; + int CapMode = toupper( mode ); + + BMP OldImage( InputImage ); + + if( CapMode != 'P' && + CapMode != 'W' && + CapMode != 'H' && + CapMode != 'F' && + CapMode != 'D' ) + { + if( EasyBMPwarnings ) + { + char ErrorMessage [1024]; + sprintf( ErrorMessage, "EasyBMP Error: Unknown rescale mode %c requested\n" , mode ); + cout << ErrorMessage; + } + return false; + } + + int NewWidth =0; + int NewHeight =0; + + int OldWidth = OldImage.TellWidth(); + int OldHeight= OldImage.TellHeight(); + + if( CapMode == 'P' ) + { + NewWidth = (int) floor( OldWidth * scale.ratio / 100.0 ); + NewHeight = (int) floor( OldHeight * scale.ratio / 100.0 ); + } + if( CapMode == 'F' ) + { + if( OldWidth > OldHeight ) + { CapMode = 'W'; } + else + { CapMode = 'H'; } + } + + if( CapMode == 'W' ) + { + double percent = (double) scale.keepsize / (double) OldWidth; + NewWidth = scale.keepsize; + NewHeight = (int) floor( OldHeight * percent ); + } + if( CapMode == 'H' ) + { + double percent = (double) scale.keepsize / (double) OldHeight; + NewHeight = scale.keepsize; + NewWidth = (int) floor( OldWidth * percent ); + } + + if( CapMode == 'D') + { + NewWidth = scale.dimension.width; + NewHeight = scale.dimension.height; + } + + if( NewWidth < 1 ) + { NewWidth = 1; } + if( NewHeight < 1 ) + { NewHeight = 1; } + + InputImage.SetSize( NewWidth, NewHeight ); + InputImage.SetBitDepth( 24 ); + + int I,J; + double ThetaI,ThetaJ; + + for( int j=0; j < NewHeight-1 ; j++ ) + { + ThetaJ = (double)(j*(OldHeight-1.0)) + /(double)(NewHeight-1.0); + J = (int) floor( ThetaJ ); + ThetaJ -= J; + + for( int i=0; i < NewWidth-1 ; i++ ) + { + ThetaI = (double)(i*(OldWidth-1.0)) + /(double)(NewWidth-1.0); + I = (int) floor( ThetaI ); + ThetaI -= I; + + InputImage(i,j)->Red = (ebmpBYTE) + ( (1.0-ThetaI-ThetaJ+ThetaI*ThetaJ)*(OldImage(I,J)->Red) + +(ThetaI-ThetaI*ThetaJ)*(OldImage(I+1,J)->Red) + +(ThetaJ-ThetaI*ThetaJ)*(OldImage(I,J+1)->Red) + +(ThetaI*ThetaJ)*(OldImage(I+1,J+1)->Red) ); + InputImage(i,j)->Green = (ebmpBYTE) + ( (1.0-ThetaI-ThetaJ+ThetaI*ThetaJ)*OldImage(I,J)->Green + +(ThetaI-ThetaI*ThetaJ)*OldImage(I+1,J)->Green + +(ThetaJ-ThetaI*ThetaJ)*OldImage(I,J+1)->Green + +(ThetaI*ThetaJ)*OldImage(I+1,J+1)->Green ); + InputImage(i,j)->Blue = (ebmpBYTE) + ( (1.0-ThetaI-ThetaJ+ThetaI*ThetaJ)*OldImage(I,J)->Blue + +(ThetaI-ThetaI*ThetaJ)*OldImage(I+1,J)->Blue + +(ThetaJ-ThetaI*ThetaJ)*OldImage(I,J+1)->Blue + +(ThetaI*ThetaJ)*OldImage(I+1,J+1)->Blue ); + } + InputImage(NewWidth-1,j)->Red = (ebmpBYTE) + ( (1.0-ThetaJ)*(OldImage(OldWidth-1,J)->Red) + + ThetaJ*(OldImage(OldWidth-1,J+1)->Red) ); + InputImage(NewWidth-1,j)->Green = (ebmpBYTE) + ( (1.0-ThetaJ)*(OldImage(OldWidth-1,J)->Green) + + ThetaJ*(OldImage(OldWidth-1,J+1)->Green) ); + InputImage(NewWidth-1,j)->Blue = (ebmpBYTE) + ( (1.0-ThetaJ)*(OldImage(OldWidth-1,J)->Blue) + + ThetaJ*(OldImage(OldWidth-1,J+1)->Blue) ); + } + + for( int i=0 ; i < NewWidth-1 ; i++ ) + { + ThetaI = (double)(i*(OldWidth-1.0)) + /(double)(NewWidth-1.0); + I = (int) floor( ThetaI ); + ThetaI -= I; + InputImage(i,NewHeight-1)->Red = (ebmpBYTE) + ( (1.0-ThetaI)*(OldImage(I,OldHeight-1)->Red) + + ThetaI*(OldImage(I,OldHeight-1)->Red) ); + InputImage(i,NewHeight-1)->Green = (ebmpBYTE) + ( (1.0-ThetaI)*(OldImage(I,OldHeight-1)->Green) + + ThetaI*(OldImage(I,OldHeight-1)->Green) ); + InputImage(i,NewHeight-1)->Blue = (ebmpBYTE) + ( (1.0-ThetaI)*(OldImage(I,OldHeight-1)->Blue) + + ThetaI*(OldImage(I,OldHeight-1)->Blue) ); + } + + *InputImage(NewWidth-1,NewHeight-1) = *OldImage(OldWidth-1,OldHeight-1); + return true; +} -- cgit v1.2.3