windows-nt/Source/XPSP1/NT/shell/ext/sshow/imgs.cpp
2020-09-26 16:20:57 +08:00

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);
}