📄 image.cpp
字号:
unsigned int i;
unsigned char* ucpFile= m_ucpData;
//load in the file header
fileHeader= ( BMPFileHeader* )ucpFile;
//advance the buffer, and load in the file information header
ucpFile += sizeof( BMPFileHeader );
infoHeader= ( BMPInfoHeader* )ucpFile;
//advance the buffer to load int he actual image data
ucpFile += sizeof( BMPInfoHeader );
ucpFile += fileHeader->uiOffBits;
//initialize the image memory
iImageSize= fileHeader->uiSize - fileHeader->uiOffBits;
Create( infoHeader->lWidth, infoHeader->lWidth, infoHeader->usBitCount );
//copy the data to the class's data buffer
memcpy( m_ucpData, ucpFile, iImageSize );
//swap the R and B values to get RGB since the bitmap color format is in BGR
for( i=0; i<infoHeader->uiSizeImage; i+=3 )
{
uiTempRGB = m_ucpData[i];
m_ucpData[i] = m_ucpData[i+2];
m_ucpData[i+2]= uiTempRGB;
}
//the BMP has been successfully loaded
return true;
}
//--------------------------------------------------------------
// Name: CIMAGE::SaveBMP - private
// Description: The routine to save a windows bitmap (BMP)
// Arguments: -szFilename: Filename to save the image to
// Return Value: A boolean variable: -true: BMP was saved
// -false: BMP was not saved
//--------------------------------------------------------------
bool CIMAGE::SaveBMP( char* szFilename )
{
FILE* pFile;
BMPFileHeader bitmapFileHeader;
BMPInfoHeader bitmapInfoHeader;
unsigned char ucTempRGB;
unsigned int i;
//open a file that we can write to
pFile= fopen( szFilename, "wb" );
if( !pFile )
{
g_log.Write( LOG_FAILURE, "Could not open a file to save %s in", szFilename );
return false;
}
//define the BMP file header
bitmapFileHeader.uiSize = m_uiWidth*m_uiHeight*3+sizeof( BMPFileHeader )+sizeof( BMPInfoHeader );
bitmapFileHeader.usType = BITMAP_ID;
bitmapFileHeader.usReserved1= 0;
bitmapFileHeader.usReserved2= 0;
bitmapFileHeader.uiOffBits = sizeof( BMPFileHeader )+sizeof( BMPInfoHeader );
//write the .bmp file header to the file
fwrite( &bitmapFileHeader, 1, sizeof( BMPFileHeader ), pFile );
//define the BMP information header
bitmapInfoHeader.uiSize = sizeof( BMPInfoHeader );
bitmapInfoHeader.usPlanes = 1;
bitmapInfoHeader.usBitCount = 24;
bitmapInfoHeader.uiCompression = BI_RGB;
bitmapInfoHeader.uiSizeImage = m_uiWidth*m_uiHeight*3;
bitmapInfoHeader.lXPelsPerMeter= 0;
bitmapInfoHeader.lYPelsPerMeter= 0;
bitmapInfoHeader.uiClrUsed = 0;
bitmapInfoHeader.uiClrImportant= 0;
bitmapInfoHeader.lWidth = m_uiWidth;
bitmapInfoHeader.lHeight = m_uiHeight;
//write the .bmp file information header to the file
fwrite( &bitmapInfoHeader, 1, sizeof( BMPInfoHeader ), pFile );
//swap the image bit order (RGB to BGR)
for( i=0; i<bitmapInfoHeader.uiSizeImage; i+=3 )
{
ucTempRGB = m_ucpData[i];
m_ucpData[i] = m_ucpData[i+2];
m_ucpData[i+2]= ucTempRGB;
}
//now write the actual image data
fwrite( m_ucpData, 1, bitmapInfoHeader.uiSizeImage, pFile );
//the file has been successfully saved
fclose( pFile );
return true;
}
//--------------------------------------------------------------
// Name: CIMAGE::LoadCompressedTGA - private
// Description: Load a compressed targa (TGA)
// Arguments: None
// Return Value: A boolean variable: -true: TGA was loaded
// -false: TGA was not loaded
//--------------------------------------------------------------
bool CIMAGE::LoadCompressedTGA( void )
{
TGAInformationHeader pTGAinfo;
unsigned char* ucpFile;
unsigned char* ucpColorBuffer;
unsigned char ucChunkHeader;
unsigned int uiPixelCount;
unsigned int uiCurrentPixel;
unsigned int uiCurrentByte;
short i;
ucpFile= m_ucpData;
//skip past the image header
ucpFile+= 12;
memcpy( pTGAinfo.m_ucHeader, ucpFile, sizeof( unsigned char[6] ) );
//allocate memory for the image data buffer
Create( pTGAinfo.m_ucHeader[1] * 256 + pTGAinfo.m_ucHeader[0],
pTGAinfo.m_ucHeader[3] * 256 + pTGAinfo.m_ucHeader[2],
pTGAinfo.m_ucHeader[4] );
//set the class's member variables
pTGAinfo.m_uiBPP = m_uiBPP;
pTGAinfo.m_uiHeight= m_uiHeight;
pTGAinfo.m_uiWidth = m_uiWidth;
//advance the file buffer
ucpFile+= 6;
//make sure that the image's dimensions are supported by this loaded
if( ( m_uiWidth<=0 ) || ( m_uiHeight<=0 ) || ( ( m_uiBPP!=24 ) && ( m_uiBPP!=32 ) ) )
return false;
pTGAinfo.m_uiBytesPerPixel= pTGAinfo.m_uiBPP/8;
pTGAinfo.m_uiImageSize = ( pTGAinfo.m_uiBytesPerPixel*pTGAinfo.m_uiWidth*pTGAinfo.m_uiHeight );
uiPixelCount = pTGAinfo.m_uiHeight * pTGAinfo.m_uiWidth;
uiCurrentPixel= 0;
uiCurrentByte = 0;
ucpColorBuffer= new unsigned char [pTGAinfo.m_uiBytesPerPixel];
do
{
ucChunkHeader= 0;
ucChunkHeader= *( unsigned char* )ucpFile;
ucpFile++;
if( ucChunkHeader<128 )
{
ucChunkHeader++;
//read RAW color values
for( i=0; i<ucChunkHeader; i++ )
{
memcpy( ucpColorBuffer, ucpFile, pTGAinfo.m_uiBytesPerPixel );
ucpFile += pTGAinfo.m_uiBytesPerPixel;
//flip R and B color values around
m_ucpData[uiCurrentByte] = ucpColorBuffer[2];
m_ucpData[uiCurrentByte+1]= ucpColorBuffer[1];
m_ucpData[uiCurrentByte+2]= ucpColorBuffer[0];
if( pTGAinfo.m_uiBytesPerPixel==4 )
m_ucpData[uiCurrentByte+3]= ucpColorBuffer[3];
uiCurrentByte += pTGAinfo.m_uiBytesPerPixel;
uiCurrentPixel++;
//make sure too many pixels have not been read in
if( uiCurrentPixel>uiPixelCount )
{
if( ucpColorBuffer!=NULL )
delete[] ucpColorBuffer;
if( m_ucpData!=NULL )
delete[] m_ucpData;
return false;
}
}
}
//the chunk header is greater than 128 RLE data
else
{
ucChunkHeader-= 127;
memcpy( ucpColorBuffer, ucpFile, pTGAinfo.m_uiBytesPerPixel );
ucpFile+= pTGAinfo.m_uiBytesPerPixel;
//copy the color into the image data as many times as needed
for( i=0; i<ucChunkHeader; i++ )
{
//switch R and B bytes around while copying
m_ucpData[uiCurrentByte] = ucpColorBuffer[2];
m_ucpData[uiCurrentByte+1]= ucpColorBuffer[1];
m_ucpData[uiCurrentByte+2]= ucpColorBuffer[0];
if( pTGAinfo.m_uiBytesPerPixel==4 )
m_ucpData[uiCurrentByte+3]= ucpColorBuffer[3];
uiCurrentByte += pTGAinfo.m_uiBytesPerPixel;
uiCurrentPixel++;
//make sure that we have not written too many pixels
if( uiCurrentPixel>uiPixelCount )
{
if( ucpColorBuffer!=NULL )
delete[] ucpColorBuffer;
if( m_ucpData!=NULL )
delete[] m_ucpData;
return false;
}
}
}
}
//loop while there are still pixels left
while( uiCurrentPixel<uiPixelCount );
//the compressed TGA has been successfully loaded
return true;
}
//--------------------------------------------------------------
// Name: CIMAGE::LoadUncompressedTGA - private
// Description: Load an uncompressed targa (TGA)
// Arguments: None
// Return Value: A boolean variable: -true: TGA was loaded
// -false: TGA was not loaded
//--------------------------------------------------------------
bool CIMAGE::LoadUncompressedTGA( void )
{
TGAInformationHeader pTGAinfo;
unsigned int uiCSwap;
unsigned char* ucpFile= m_ucpData;
//skip past the TGA header in the data buffer
ucpFile+= 12;
//copy the header data
memcpy( pTGAinfo.m_ucHeader, ucpFile, sizeof( unsigned char[6] ) );
//allocate memory for the image's data buffer
Create( pTGAinfo.m_ucHeader[1]*256+pTGAinfo.m_ucHeader[0],
pTGAinfo.m_ucHeader[3]*256+pTGAinfo.m_ucHeader[2],
pTGAinfo.m_ucHeader[4] );
//set the class's member variables
pTGAinfo.m_uiBPP = m_uiBPP;
pTGAinfo.m_uiWidth = m_uiWidth;
pTGAinfo.m_uiHeight= m_uiHeight;
ucpFile+= 6;
if( ( m_uiWidth<=0 ) || ( m_uiHeight<=0 ) || ( ( m_uiBPP!=24 ) && ( m_uiBPP!=32 ) ) )
return false;
pTGAinfo.m_uiBytesPerPixel= m_uiBPP/8;
pTGAinfo.m_uiImageSize = ( pTGAinfo.m_uiBytesPerPixel*m_uiWidth*m_uiHeight );
//copy the image data
memcpy( m_ucpData, ucpFile, pTGAinfo.m_uiImageSize );
//byte swapping ( optimized by Steve Thomas )
for( uiCSwap=0; uiCSwap<( int )pTGAinfo.m_uiImageSize; uiCSwap+=pTGAinfo.m_uiBytesPerPixel )
{
m_ucpData[uiCSwap]^= m_ucpData[uiCSwap+2]^=
m_ucpData[uiCSwap]^= m_ucpData[uiCSwap+2];
}
//the uncompressed TGA has been successfully loaded
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -