📄 dibobject.cpp
字号:
if( m_pLogPal != NULL ) delete [] m_pLogPal;
m_pLogPal = CreatePaletteFromBitmap( nNumNewColors, pOldBits, m_nBits, m_nWidth, m_nHeight );
}
HGLOBAL hGlobal;
DWORD dwSize;
dwSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ) + m_nHeight * nNewWidthBytes;
hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize );
if( hGlobal == NULL ){
::GlobalUnlock( m_hDib );
return( FALSE );
}
pBuffer = (char *) ::GlobalLock( hGlobal );
if( pBuffer == NULL ){
::GlobalFree( hGlobal );
::GlobalUnlock( m_hDib );
return( FALSE );
}
pNewBFH = (BITMAPFILEHEADER *) pBuffer;
pNewBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
pNewRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
*pNewBFH = *pOldBFH;
*pNewBIH = *pOldBIH;
int i, j = nNumNewColors;
if( m_nBits < 16 && nNewBitsPerPixel < 16 ){
for( i=0; i<j; i++ ) pNewRGBPalette[i] = pOldRGBPalette[i];
}
else if( m_nBits >= 16 ){
for( i=0; i<j; i++ ){
pNewRGBPalette[i].rgbRed = m_pLogPal->palPalEntry[i].peRed;
pNewRGBPalette[i].rgbGreen = m_pLogPal->palPalEntry[i].peGreen;
pNewRGBPalette[i].rgbBlue = m_pLogPal->palPalEntry[i].peBlue;
}
}
pNewBIH->biBitCount = nNewBitsPerPixel;
pNewBIH->biSizeImage = nNewWidthBytes * m_nHeight;
pNewBIH->biClrUsed = nNumNewColors;
pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD ) + pNewBIH->biSizeImage;
pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + nNumNewColors * sizeof( RGBQUAD );
pNewBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumNewColors*sizeof(RGBQUAD)];
m_nPaletteBytes = nNumNewColors * sizeof( RGBQUAD );
for( int y=0; y<m_nHeight; y++ ){
unsigned char ucRed, ucGreen, ucBlue;
unsigned char *pSrc, *pDest;
pSrc = pOldBits;
pSrc += ( nOldWidthBytes * y );
pDest = pNewBits;
pDest += ( nNewWidthBytes * y );
for( int x=0; x<m_nWidth; x++ ){
switch( m_nBits ){
case 1:
if( pSrc[x/8] & ( 0x80 >> ( x & 7 ) ) )
ucRed = ucGreen = ucBlue = 0xff;
else
ucRed = ucGreen = ucBlue = 0x00;
break;
case 4:
if( !( x & 1 ) ){
ucRed = pOldRGBPalette[pSrc[x/2]>>4].rgbRed;
ucGreen = pOldRGBPalette[pSrc[x/2]>>4].rgbGreen;
ucBlue = pOldRGBPalette[pSrc[x/2]>>4].rgbBlue;
}
else{
ucRed = pOldRGBPalette[pSrc[x/2]&15].rgbRed;
ucGreen = pOldRGBPalette[pSrc[x/2]&15].rgbGreen;
ucBlue = pOldRGBPalette[pSrc[x/2]&15].rgbBlue;
}
break;
case 8:
ucRed = pOldRGBPalette[pSrc[x]].rgbRed;
ucGreen = pOldRGBPalette[pSrc[x]].rgbGreen;
ucBlue = pOldRGBPalette[pSrc[x]].rgbBlue;
break;
case 16:
GETRGB555( ucRed, ucGreen, ucBlue, &pSrc[x*2] );
break;
case 24:
ucRed = pSrc[x*3+2];
ucGreen = pSrc[x*3+1];
ucBlue = pSrc[x*3];
break;
case 32:
GETRGB888( ucRed, ucGreen, ucBlue, &pSrc[x*4] );
break;
}
switch( nNewBitsPerPixel ){
case 1:
if( !( x & 7 ) ) pDest[x/8] = 0;
pDest[x/8] |= (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ) << ( x & 7 );
break;
case 4:
if( !( x & 1 ) )
pDest[x/2] = (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors ) << 4;
else
pDest[x/2] |= (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors );
break;
case 8:
pDest[x] = (unsigned char) GetNearestIndex( ucRed, ucGreen, ucBlue, pNewRGBPalette, nNumNewColors );
break;
case 16:
PUTRGB555( ucRed, ucGreen, ucBlue, &pDest[x*2] );
break;
case 24:
pDest[x*3+2] = ucRed;
pDest[x*3+1] = ucGreen;
pDest[x*3] = ucBlue;
break;
case 32:
PUTRGB888( ucRed, ucGreen, ucBlue, &pDest[x*4] );
break;
}
}
}
::GlobalUnlock( m_hDib );
::GlobalFree( m_hDib );
::GlobalUnlock( hGlobal );
m_hDib = hGlobal;
ProcessImageHeader();
return( TRUE );
}
////////////////////////////////////////////////////////////////////////
//LOGPALETTE CreatePaletteFromBitmap()
//----------------------------------------------------------------------
//基本功能:从当前CDibObject位图对象中创建逻辑调色板。
//----------------------------------------------------------------------
//参数说明:int nNumColors 颜色数
// unsigned char *pBits 位图数据指针
// int nBits 颜色位数
// int nWidth 图像宽度
// int nHeight 图像高度
//----------------------------------------------------------------------
//返 回 值:LOGPALETTE 逻辑调色板指针
////////////////////////////////////////////////////////////////////////
LOGPALETTE *CDibObject::CreatePaletteFromBitmap(int nNumColors,
unsigned char *pBits, int nBits,
int nWidth, int nHeight )
{
RGBQUAD *pRGBPalette;
if( nBits != 8 && m_nPaletteCreationType == POPULARITY_PALETTE ) pRGBPalette = MakePopularityPalette( nNumColors, pBits, nBits, nWidth, nHeight );
else if( nBits != 8 && m_nPaletteCreationType == MEDIAN_CUT_PALETTE ) pRGBPalette = MakeMedianCutPalette( nNumColors, pBits, nBits, nWidth, nHeight );
else if( m_nPaletteCreationType == FIXED_PALETTE ) pRGBPalette = MakeFixedPalette( nNumColors );
if( pRGBPalette == NULL ) return( NULL );
LOGPALETTE *pLogPal = CreateLogPalette( pRGBPalette, nNumColors );
delete [] pRGBPalette;
return( pLogPal );
}
////////////////////////////////////////////////////////////////////////
//void SetPaletteCreationType( int nType )
//----------------------------------------------------------------------
//基本功能:当希望通过颜色还原得到一幅具有调色板的图像时,本函数负责设置
// 调色板的创建类型。可以设置如下:
// #define POPULARITY_PALETTE 0
// #define MEDIAN_CUT_PALETTE 1
// #define FIXED_PALETTE 2
//----------------------------------------------------------------------
//参数说明:int nType
//----------------------------------------------------------------------
//返 回 值:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CDibObject::SetPaletteCreationType( int nType )
{
m_nPaletteCreationType = nType;
}
////////////////////////////////////////////////////////////////////////
//int GetPaletteCreationType( void )
//----------------------------------------------------------------------
//基本功能:本函数返回用于下一次颜色还原操作的调色板类型。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:int nPaletteCreationType
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
int CDibObject::GetPaletteCreationType( void )
{
return( m_nPaletteCreationType );
}
RGBQUAD *CDibObject::MakePopularityPalette( int nNumColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors];
if( pRGBQuad == NULL ) return( MakeFixedPalette( nNumColors ) );
memset( pRGBQuad, 0, nNumColors * sizeof( RGBQUAD ) );
BYTE ColMap[256][3];
if( !Popularity( pBits, nBits, nWidth, nHeight, ColMap ) ){
delete [] pRGBQuad;
return( MakeFixedPalette( nNumColors ) );
}
for( int i=0; i<nNumColors; i++ ){
pRGBQuad[i].rgbRed = ColMap[i][0];
pRGBQuad[i].rgbGreen = ColMap[i][1];
pRGBQuad[i].rgbBlue = ColMap[i][2];
}
return( pRGBQuad );
}
RGBQUAD *CDibObject::MakeMedianCutPalette( int nNumColors, unsigned char *pBits, int nBits, int nWidth, int nHeight )
{
RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors];
if( pRGBQuad == NULL ) return( MakeFixedPalette( nNumColors ) );
memset( pRGBQuad, 0, nNumColors * sizeof( RGBQUAD ) );
BYTE ColMap[256][3];
WORD *Hist = new WORD[32768];
if( Hist == NULL ){
delete [] pRGBQuad;
return( MakeFixedPalette( nNumColors ) );
}
memset( Hist, 0, 32768 * sizeof( WORD ) );
int nWidthBytes = WidthBytes( nBits, nWidth );
for( int y=0; y<nHeight; y++ ){
unsigned char *pData = pBits;
unsigned char ucRed, ucGreen, ucBlue;
WORD color;
pData += ( y * nWidthBytes );
for( int x=0; x<nWidth; x++ ){
switch( nBits ){
case 16:
GETRGB555( ucRed, ucGreen, ucBlue, &pData[x*2] );
break;
case 24:
ucRed = pData[x*3+2];
ucGreen = pData[x*3+1];
ucBlue = pData[x*3];
break;
case 32:
GETRGB888( ucRed, ucGreen, ucBlue, &pData[x*4] );
break;
}
color = _RGB( ucRed, ucGreen, ucBlue );
if( Hist[color] < 65535 ) Hist[color]++;
}
}
MedianCut( Hist, ColMap, (int) 256 );
for( int i=0; i<nNumColors; i++ ){
pRGBQuad[i].rgbRed = ColMap[i][0];
pRGBQuad[i].rgbGreen = ColMap[i][1];
pRGBQuad[i].rgbBlue = ColMap[i][2];
}
delete [] Hist;
return( pRGBQuad );
}
RGBQUAD *CDibObject::MakeFixedPalette( int nNumColors )
{
RGBQUAD *pRGBQuad = new RGBQUAD[nNumColors];
if( pRGBQuad == NULL ) return( NULL );
static int colors[] = {
255, 255, 255,
0, 0, 0,
255, 0, 0,
0, 0, 255,
0, 255, 0,
150, 150, 150,
255, 255, 0,
0, 150, 150,
150, 0, 150,
150, 150, 0,
0, 255, 255,
255, 0, 255,
255, 120, 120,
120, 255, 120,
120, 120, 255,
90, 90, 90 };
int nSteps = ( ( nNumColors + 15 ) / 16 );
for( int i=0; i<nSteps; i++ ){
for( int j=0; j<16; j++ ){
if( i * 16 + j < nNumColors ){
int r, g, b;
r = colors[j*3];
g = colors[j*3+1];
b = colors[j*3+2];
r = ( ( nSteps - i ) * r ) / nSteps;
g = ( ( nSteps - i ) * g ) / nSteps;
b = ( ( nSteps - i ) * b ) / nSteps;
pRGBQuad[i*16+j].rgbRed = (unsigned char) r;
pRGBQuad[i*16+j].rgbGreen = (unsigned char) g;
pRGBQuad[i*16+j].rgbBlue = (unsigned char) b;
}
}
}
return( pRGBQuad );
}
//得到调色板字节数
int CDibObject::GetPaletteBytes( void )
{
return( m_nPaletteBytes );
}
////////////////////////////////////////////////////////////////////////
//HGLOBALBOOL GetDib( void )
//----------------------------------------------------------------------
//基本功能:本函数返回当前载入的图像Dib句柄。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:HGLOBALBOOL hDib
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
HGLOBAL CDibObject::GetDib( void )
{
return( m_hDib );
}
////////////////////////////////////////////////////////////////////////
//CPalette GetPalette( void )
//----------------------------------------------------------------------
//基本功能:本函数返回一个指向CPalette对象的指针。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返 回 值:CPalette *Palette
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CPalette *CDibObject::GetPalette( void )
{
return( &m_Palette );
}
//得到逻辑调色板
LOGPALETTE *CDibObject::GetLogPal( void )
{
return( m_pLogPal );
}
void CDibObject::ProcImgHead()
{
ProcessImageHeader();
}
char * CDibObject::GetImageName()
{
return( m_pszFilename );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -