173 lines
4.6 KiB
C++
173 lines
4.6 KiB
C++
#include "precomp.h"
|
|
#include "imgs.h"
|
|
#include "gphelper.h"
|
|
#include "ssutil.h"
|
|
#include "psutil.h"
|
|
|
|
CBitmapImage::CBitmapImage(void)
|
|
: m_hBitmap(NULL),
|
|
m_hPalette(NULL)
|
|
{
|
|
}
|
|
|
|
CBitmapImage::~CBitmapImage(void)
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void CBitmapImage::Destroy(void)
|
|
{
|
|
if (m_hBitmap)
|
|
{
|
|
DeleteObject(m_hBitmap);
|
|
m_hBitmap = NULL;
|
|
}
|
|
if (m_hPalette)
|
|
{
|
|
DeleteObject(m_hPalette);
|
|
m_hPalette = NULL;
|
|
}
|
|
}
|
|
|
|
bool CBitmapImage::IsValid(void) const
|
|
{
|
|
return(m_hBitmap != NULL);
|
|
}
|
|
|
|
HPALETTE CBitmapImage::Palette(void) const
|
|
{
|
|
return(m_hPalette);
|
|
}
|
|
|
|
HBITMAP CBitmapImage::GetBitmap(void) const
|
|
{
|
|
return(m_hBitmap);
|
|
}
|
|
|
|
// Create a palette for the image
|
|
HPALETTE CBitmapImage::PreparePalette( CSimpleDC &dc, HBITMAP hBitmap )
|
|
{
|
|
HPALETTE hPalette = NULL;
|
|
if (GetDeviceCaps(dc,RASTERCAPS) & RC_PALETTE)
|
|
{
|
|
if (hBitmap)
|
|
{
|
|
DIBSECTION ds = {0};
|
|
GetObject(hBitmap, sizeof (DIBSECTION), &ds);
|
|
|
|
int nColors;
|
|
if (ds.dsBmih.biClrUsed != 0)
|
|
{
|
|
nColors = ds.dsBmih.biClrUsed;
|
|
}
|
|
else
|
|
{
|
|
// Handle the special case of an image that claims to be
|
|
// a 32bit DIB as a 24bit DIB
|
|
if (ds.dsBmih.biBitCount == 32)
|
|
{
|
|
nColors = 1 << 24;
|
|
}
|
|
else
|
|
{
|
|
nColors = 1 << ds.dsBmih.biBitCount;
|
|
}
|
|
}
|
|
|
|
// Create a halftone palette if the DIB section contains more
|
|
// than 256 colors
|
|
if (nColors > 256)
|
|
{
|
|
hPalette = CreateHalftonePalette(dc);
|
|
}
|
|
|
|
// Create a custom palette from the DIB section's color table
|
|
// if the number of colors is 256 or less
|
|
else
|
|
{
|
|
RGBQUAD* pRGB = new RGBQUAD[nColors];
|
|
if (pRGB)
|
|
{
|
|
CSimpleDC MemDC;
|
|
MemDC.CreateCompatibleDC(dc);
|
|
SelectObject( MemDC, hBitmap );
|
|
GetDIBColorTable( MemDC, 0, nColors, pRGB );
|
|
|
|
UINT nSize = sizeof (LOGPALETTE) + (sizeof (PALETTEENTRY) * (nColors - 1));
|
|
|
|
LOGPALETTE* pLP = (LOGPALETTE*) new BYTE[nSize];
|
|
if (pLP)
|
|
{
|
|
pLP->palVersion = 0x300;
|
|
pLP->palNumEntries = (WORD)nColors;
|
|
|
|
for (int i=0; i<nColors; i++)
|
|
{
|
|
pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
|
|
pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
|
|
pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
|
|
pLP->palPalEntry[i].peFlags = 0;
|
|
}
|
|
|
|
hPalette = CreatePalette(pLP);
|
|
delete[] pLP;
|
|
}
|
|
delete[] pRGB;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hPalette = CreateHalftonePalette(dc);
|
|
}
|
|
return hPalette;
|
|
}
|
|
|
|
SIZE CBitmapImage::ImageSize(void) const
|
|
{
|
|
SIZE sizeImage = {0,0};
|
|
if (IsValid())
|
|
{
|
|
BITMAP bm = {0};
|
|
if (GetObject( m_hBitmap, sizeof(bm), &bm ))
|
|
{
|
|
sizeImage.cx = bm.bmWidth;
|
|
sizeImage.cy = bm.bmHeight;
|
|
}
|
|
}
|
|
return(sizeImage);
|
|
}
|
|
|
|
bool CBitmapImage::Load( CSimpleDC &dc,
|
|
LPCTSTR pszFilename,
|
|
const RECT &rcScreen,
|
|
int nMaxScreenPercent,
|
|
bool bAllowStretching,
|
|
bool bDisplayFilename
|
|
)
|
|
{
|
|
// Clean up, if necessary
|
|
Destroy();
|
|
|
|
// Validate the arguments
|
|
if (!pszFilename || !lstrlen(pszFilename))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Try to load and scale the image using GDI plus
|
|
CGdiPlusHelper GdiPlusHelper;
|
|
if (SUCCEEDED(GdiPlusHelper.LoadAndScale( m_hBitmap,
|
|
pszFilename,
|
|
PrintScanUtil::MulDivNoRound(rcScreen.right - rcScreen.left,nMaxScreenPercent,100),
|
|
PrintScanUtil::MulDivNoRound(rcScreen.bottom - rcScreen.top,nMaxScreenPercent,100),
|
|
bAllowStretching )) && m_hBitmap)
|
|
{
|
|
// Prepare the image's palette, if it has one
|
|
m_hPalette = PreparePalette( dc, m_hBitmap );
|
|
}
|
|
return (m_hBitmap != NULL);
|
|
}
|
|
|