added CreateDDB() and CreatePalette()
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19720 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -35,26 +35,37 @@ public:
|
||||
wxDIB(int width, int height, int depth)
|
||||
{ Init(); (void)Create(width, height, depth); }
|
||||
|
||||
// same as ctor but with return value
|
||||
// load a DIB from file (any depth is supoprted here unlike above)
|
||||
//
|
||||
// as above, use IsOk() to see if the bitmap was loaded successfully
|
||||
wxDIB(const wxString& filename)
|
||||
{ Init(); (void)Load(filename); }
|
||||
|
||||
// same as the corresponding ctors but with return value
|
||||
bool Create(int width, int height, int depth);
|
||||
bool Load(const wxString& filename);
|
||||
|
||||
// dtor is not virtual, this class is not meant to be used polymorphically
|
||||
~wxDIB()
|
||||
{
|
||||
if ( m_handle && !::DeleteObject(m_handle) )
|
||||
{
|
||||
wxLogLastError(wxT("DeleteObject(hDIB)"));
|
||||
}
|
||||
}
|
||||
~wxDIB();
|
||||
|
||||
|
||||
// operations
|
||||
// ----------
|
||||
|
||||
// create a bitmap compatiblr with the given HDC (or screen by default) and
|
||||
// return its handle, the caller is responsible for freeing it (using
|
||||
// DeleteObject())
|
||||
HBITMAP CreateDDB(HDC hdc = NULL) const;
|
||||
|
||||
// get the handle from the DIB and reset it, i.e. this object won't destroy
|
||||
// the DIB after this (but the caller should do it)
|
||||
HBITMAP Detach() { HBITMAP hbmp = m_handle; m_handle = 0; return hbmp; }
|
||||
|
||||
#if wxUSE_PALETTE
|
||||
// create a palette for this DIB (always a trivial/default one for 24bpp)
|
||||
wxPalette *CreatePalette() const;
|
||||
#endif // wxUSE_PALETTE
|
||||
|
||||
|
||||
// accessors
|
||||
// ---------
|
||||
@@ -118,6 +129,20 @@ private:
|
||||
m_depth = 0;
|
||||
}
|
||||
|
||||
// free resources
|
||||
void Free()
|
||||
{
|
||||
if ( m_handle )
|
||||
{
|
||||
if ( !::DeleteObject(m_handle) )
|
||||
{
|
||||
wxLogLastError(wxT("DeleteObject(hDIB)"));
|
||||
}
|
||||
|
||||
Init();
|
||||
}
|
||||
}
|
||||
|
||||
// the DIB section handle, 0 if invalid
|
||||
HBITMAP m_handle;
|
||||
|
||||
@@ -146,6 +171,14 @@ private:
|
||||
wxDIB& operator=(const wxDIB&);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// inline functions implementation
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
inline wxDIB::~wxDIB()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Functions for working with DIBs
|
||||
|
204
src/msw/dib.cpp
204
src/msw/dib.cpp
@@ -110,6 +110,30 @@ bool wxDIB::Create(int width, int height, int depth)
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Loading/saving the DIBs
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxDIB::Load(const wxString& filename)
|
||||
{
|
||||
m_handle = (HBITMAP)::LoadImage
|
||||
(
|
||||
wxGetInstance(),
|
||||
filename,
|
||||
IMAGE_BITMAP,
|
||||
0, 0, // don't specify the size
|
||||
LR_CREATEDIBSECTION | LR_LOADFROMFILE
|
||||
);
|
||||
if ( !m_handle )
|
||||
{
|
||||
wxLogLastError(_T("LoadImage(LR_CREATEDIBSECTION | LR_LOADFROMFILE)"));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDIB accessors
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -129,7 +153,6 @@ void wxDIB::DoGetObject() const
|
||||
if ( !::GetObject(m_handle, sizeof(ds), &ds) )
|
||||
{
|
||||
wxLogLastError(_T("GetObject(hDIB)"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -142,6 +165,127 @@ void wxDIB::DoGetObject() const
|
||||
}
|
||||
}
|
||||
|
||||
HBITMAP wxDIB::CreateDDB(HDC hdc) const
|
||||
{
|
||||
wxCHECK_MSG( m_handle, 0, _T("wxDIB::CreateDDB(): invalid object") );
|
||||
|
||||
DIBSECTION ds;
|
||||
if ( !::GetObject(m_handle, sizeof(ds), &ds) )
|
||||
{
|
||||
wxLogLastError(_T("GetObject(hDIB)"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HBITMAP hbitmap = ::CreateCompatibleBitmap
|
||||
(
|
||||
hdc ? hdc : ScreenHDC(),
|
||||
ds.dsBm.bmWidth,
|
||||
ds.dsBm.bmHeight
|
||||
);
|
||||
if ( !hbitmap )
|
||||
{
|
||||
wxLogLastError(_T("CreateCompatibleBitmap()"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MemoryHDC hdcMem;
|
||||
SelectInHDC select(hdcMem, hbitmap);
|
||||
if ( !select )
|
||||
{
|
||||
wxLogLastError(_T("SelectObjct(hBitmap)"));
|
||||
}
|
||||
|
||||
if ( !::SetDIBits
|
||||
(
|
||||
hdcMem,
|
||||
hbitmap,
|
||||
0,
|
||||
ds.dsBm.bmHeight,
|
||||
ds.dsBm.bmBits,
|
||||
(BITMAPINFO *)&ds.dsBmih,
|
||||
DIB_RGB_COLORS
|
||||
) )
|
||||
{
|
||||
wxLogLastError(_T("SetDIBits"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hbitmap;
|
||||
}
|
||||
|
||||
#if wxUSE_PALETTE
|
||||
|
||||
wxPalette *wxDIB::CreatePalette() const
|
||||
{
|
||||
wxCHECK_MSG( m_handle, NULL, _T("wxDIB::CreatePalette(): invalid object") );
|
||||
|
||||
DIBSECTION ds;
|
||||
if ( !::GetObject(m_handle, sizeof(ds), &ds) )
|
||||
{
|
||||
wxLogLastError(_T("GetObject(hDIB)"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// how many colours are we going to have in the palette?
|
||||
DWORD biClrUsed = ds.dsBmih.biClrUsed;
|
||||
if ( !biClrUsed )
|
||||
{
|
||||
// biClrUsed field might not be set
|
||||
biClrUsed = 1 << ds.dsBmih.biBitCount;
|
||||
}
|
||||
|
||||
if ( biClrUsed > 256 )
|
||||
{
|
||||
// only 8bpp bitmaps (and less) have palettes, so we surely don't
|
||||
//
|
||||
// NB: another possibility would be to return
|
||||
// GetStockObject(DEFAULT_PALETTE) or even CreateHalftonePalette()?
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// LOGPALETTE struct has only 1 element in palPalEntry array, we're
|
||||
// going to have biClrUsed of them so add necessary space
|
||||
LOGPALETTE *pPalette = (LOGPALETTE *)
|
||||
malloc(sizeof(LOGPALETTE) + (biClrUsed - 1)*sizeof(PALETTEENTRY));
|
||||
wxCHECK_MSG( pPalette, NULL, _T("out of memory") );
|
||||
|
||||
// initialize the palette header
|
||||
pPalette->palVersion = 0x300; // magic number, not in docs but works
|
||||
pPalette->palNumEntries = biClrUsed;
|
||||
|
||||
// and the colour table (it starts right after the end of the header)
|
||||
const RGBQUAD *pRGB = (RGBQUAD *)((char *)&ds.dsBmih + ds.dsBmih.biSize);
|
||||
for ( DWORD i = 0; i < biClrUsed; i++, pRGB++ )
|
||||
{
|
||||
pPalette->palPalEntry[i].peRed = pRGB->rgbRed;
|
||||
pPalette->palPalEntry[i].peGreen = pRGB->rgbGreen;
|
||||
pPalette->palPalEntry[i].peBlue = pRGB->rgbBlue;
|
||||
pPalette->palPalEntry[i].peFlags = 0;
|
||||
}
|
||||
|
||||
HPALETTE hPalette = ::CreatePalette(pPalette);
|
||||
|
||||
free(pPalette);
|
||||
|
||||
if ( !hPalette )
|
||||
{
|
||||
wxLogLastError(_T("CreatePalette"));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wxPalette *palette = new wxPalette;
|
||||
palette->SetHPALETTE((WXHPALETTE)hPalette);
|
||||
|
||||
return palette;
|
||||
}
|
||||
|
||||
#endif // wxUSE_PALETTE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxImage support
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -675,64 +819,6 @@ HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
|
||||
return((HPALETTE) GetStockObject(DEFAULT_PALETTE));
|
||||
}
|
||||
|
||||
bool wxLoadIntoBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette **pal)
|
||||
{
|
||||
HBITMAP hBitmap = NULL;
|
||||
HPALETTE hPalette = NULL;
|
||||
|
||||
bool success = (wxReadDIB(filename, &hBitmap, &hPalette) != 0);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
if (hPalette)
|
||||
DeleteObject(hPalette);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (hPalette)
|
||||
{
|
||||
#if wxUSE_PALETTE
|
||||
if (pal)
|
||||
{
|
||||
*pal = new wxPalette;
|
||||
(*pal)->SetHPALETTE((WXHPALETTE) hPalette);
|
||||
}
|
||||
else
|
||||
#endif // wxUSE_PALETTE
|
||||
DeleteObject(hPalette);
|
||||
}
|
||||
else if (pal)
|
||||
*pal = NULL;
|
||||
|
||||
if (hBitmap)
|
||||
{
|
||||
BITMAP bm;
|
||||
GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);
|
||||
|
||||
bitmap->SetHBITMAP((WXHBITMAP) hBitmap);
|
||||
bitmap->SetWidth(bm.bmWidth);
|
||||
bitmap->SetHeight(bm.bmHeight);
|
||||
bitmap->SetDepth(bm.bmPlanes * bm.bmBitsPixel);
|
||||
#if WXWIN_COMPATIBILITY_2
|
||||
bitmap->SetOk(TRUE);
|
||||
#endif // WXWIN_COMPATIBILITY_2
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
|
||||
wxBitmap *wxLoadBitmap(wxChar *filename, wxPalette **pal)
|
||||
{
|
||||
wxBitmap *bitmap = new wxBitmap;
|
||||
if (wxLoadIntoBitmap(filename, bitmap, pal))
|
||||
return bitmap;
|
||||
else
|
||||
{
|
||||
delete bitmap;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Function: InitBitmapInfoHeader
|
||||
|
Reference in New Issue
Block a user