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:
Vadim Zeitlin
2003-03-23 01:46:31 +00:00
parent b0ea5d9603
commit c11bf84234
2 changed files with 260 additions and 141 deletions

View File

@@ -35,26 +35,37 @@ public:
wxDIB(int width, int height, int depth) wxDIB(int width, int height, int depth)
{ Init(); (void)Create(width, height, 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 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 // dtor is not virtual, this class is not meant to be used polymorphically
~wxDIB() ~wxDIB();
{
if ( m_handle && !::DeleteObject(m_handle) )
{
wxLogLastError(wxT("DeleteObject(hDIB)"));
}
}
// operations // 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 // 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) // the DIB after this (but the caller should do it)
HBITMAP Detach() { HBITMAP hbmp = m_handle; m_handle = 0; return hbmp; } 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 // accessors
// --------- // ---------
@@ -118,6 +129,20 @@ private:
m_depth = 0; 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 // the DIB section handle, 0 if invalid
HBITMAP m_handle; HBITMAP m_handle;
@@ -146,6 +171,14 @@ private:
wxDIB& operator=(const wxDIB&); wxDIB& operator=(const wxDIB&);
}; };
// ----------------------------------------------------------------------------
// inline functions implementation
// ----------------------------------------------------------------------------
inline wxDIB::~wxDIB()
{
Free();
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Functions for working with DIBs // Functions for working with DIBs

View File

@@ -110,6 +110,30 @@ bool wxDIB::Create(int width, int height, int depth)
return true; 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 // wxDIB accessors
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -129,7 +153,6 @@ void wxDIB::DoGetObject() const
if ( !::GetObject(m_handle, sizeof(ds), &ds) ) if ( !::GetObject(m_handle, sizeof(ds), &ds) )
{ {
wxLogLastError(_T("GetObject(hDIB)")); wxLogLastError(_T("GetObject(hDIB)"));
return; 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 // wxImage support
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -267,14 +411,14 @@ static bool wxWriteDIB(LPTSTR szFile, HANDLE hdib)
LPBITMAPINFOHEADER lpbi; LPBITMAPINFOHEADER lpbi;
int fh; int fh;
OFSTRUCT of; OFSTRUCT of;
if (!hdib) if (!hdib)
return FALSE; return FALSE;
fh = OpenFile(wxConvertWX2MB(szFile), &of, OF_CREATE | OF_READWRITE); fh = OpenFile(wxConvertWX2MB(szFile), &of, OF_CREATE | OF_READWRITE);
if (fh == -1) if (fh == -1)
return FALSE; return FALSE;
lpbi = (LPBITMAPINFOHEADER) GlobalLock(hdib); lpbi = (LPBITMAPINFOHEADER) GlobalLock(hdib);
/* Fill in the fields of the file header */ /* Fill in the fields of the file header */
@@ -284,13 +428,13 @@ static bool wxWriteDIB(LPTSTR szFile, HANDLE hdib)
hdr.bfReserved2 = 0; hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + lpbi->biSize + hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + lpbi->biSize +
wxPaletteSize(lpbi); wxPaletteSize(lpbi);
/* Write the file header */ /* Write the file header */
_lwrite(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER)); _lwrite(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER));
/* Write the DIB header and the bits */ /* Write the DIB header and the bits */
lwrite(fh, (LPSTR) lpbi, GlobalSize(hdib)); lwrite(fh, (LPSTR) lpbi, GlobalSize(hdib));
GlobalUnlock(hdib); GlobalUnlock(hdib);
_lclose(fh); _lclose(fh);
return TRUE; return TRUE;
@@ -309,10 +453,10 @@ WORD wxPaletteSize(VOID FAR * pv)
{ {
LPBITMAPINFOHEADER lpbi; LPBITMAPINFOHEADER lpbi;
WORD NumColors; WORD NumColors;
lpbi = (LPBITMAPINFOHEADER) pv; lpbi = (LPBITMAPINFOHEADER) pv;
NumColors = wxDibNumColors(lpbi); NumColors = wxDibNumColors(lpbi);
if (lpbi->biSize == sizeof(BITMAPCOREHEADER)) if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
return (WORD)(NumColors * sizeof(RGBTRIPLE)); return (WORD)(NumColors * sizeof(RGBTRIPLE));
else else
@@ -331,10 +475,10 @@ static WORD wxDibNumColors(VOID FAR *pv)
int bits; int bits;
BITMAPINFOHEADER *lpbi; BITMAPINFOHEADER *lpbi;
BITMAPCOREHEADER *lpbc; BITMAPCOREHEADER *lpbc;
lpbi = ((BITMAPINFOHEADER*) pv); lpbi = ((BITMAPINFOHEADER*) pv);
lpbc = ((BITMAPCOREHEADER*) pv); lpbc = ((BITMAPCOREHEADER*) pv);
/* With the BITMAPINFO format headers, the size of the palette /* With the BITMAPINFO format headers, the size of the palette
* is in biClrUsed, whereas in the BITMAPCORE - style headers, it * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
* is dependent on the bits per pixel ( = 2 raised to the power of * is dependent on the bits per pixel ( = 2 raised to the power of
@@ -347,7 +491,7 @@ static WORD wxDibNumColors(VOID FAR *pv)
} }
else else
bits = lpbc->bcBitCount; bits = lpbc->bcBitCount;
switch (bits) { switch (bits) {
case 1: case 1:
return 2; return 2;
@@ -424,7 +568,7 @@ static DWORD lwrite(int fh, VOID FAR *pv, DWORD ul)
* filled with the appropriate handles. * filled with the appropriate handles.
* FALSE - otherwise * FALSE - otherwise
*/ */
bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette) bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
{ {
int fh; int fh;
@@ -437,32 +581,32 @@ bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
HDC hDC; HDC hDC;
bool bCoreHead = FALSE; bool bCoreHead = FALSE;
HANDLE hDIB = 0; HANDLE hDIB = 0;
/* Open the file and get a handle to it's BITMAPINFO */ /* Open the file and get a handle to it's BITMAPINFO */
fh = OpenFile (wxConvertWX2MB(lpFileName), &of, OF_READ); fh = OpenFile (wxConvertWX2MB(lpFileName), &of, OF_READ);
if (fh == -1) { if (fh == -1) {
wxLogError(_("Can't open file '%s'"), lpFileName); wxLogError(_("Can't open file '%s'"), lpFileName);
return (0); return (0);
} }
hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) + hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD))); 256 * sizeof(RGBQUAD)));
if (!hDIB) if (!hDIB)
return(0); return(0);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/* read the BITMAPFILEHEADER */ /* read the BITMAPFILEHEADER */
if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf))) if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
goto ErrExit; goto ErrExit;
if (bf.bfType != 0x4d42) /* 'BM' */ if (bf.bfType != 0x4d42) /* 'BM' */
goto ErrExit; goto ErrExit;
if (sizeof(BITMAPCOREHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER))) if (sizeof(BITMAPCOREHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
goto ErrExit; goto ErrExit;
if (lpbi->biSize == sizeof(BITMAPCOREHEADER)) if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
{ {
lpbi->biSize = sizeof(BITMAPINFOHEADER); lpbi->biSize = sizeof(BITMAPINFOHEADER);
@@ -479,7 +623,7 @@ bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER))) if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
goto ErrExit; goto ErrExit;
} }
nNumColors = (WORD)lpbi->biClrUsed; nNumColors = (WORD)lpbi->biClrUsed;
if ( nNumColors == 0 ) if ( nNumColors == 0 )
{ {
@@ -487,17 +631,17 @@ bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
if (lpbi->biBitCount != 24) if (lpbi->biBitCount != 24)
nNumColors = 1 << lpbi->biBitCount; /* standard size table */ nNumColors = 1 << lpbi->biBitCount; /* standard size table */
} }
/* fill in some default values if they are zero */ /* fill in some default values if they are zero */
if (lpbi->biClrUsed == 0) if (lpbi->biClrUsed == 0)
lpbi->biClrUsed = nNumColors; lpbi->biClrUsed = nNumColors;
if (lpbi->biSizeImage == 0) if (lpbi->biSizeImage == 0)
{ {
lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
* lpbi->biHeight; * lpbi->biHeight;
} }
/* get a proper-sized buffer for header, color table and bits */ /* get a proper-sized buffer for header, color table and bits */
GlobalUnlock(hDIB); GlobalUnlock(hDIB);
hDIB = GlobalReAlloc(hDIB, lpbi->biSize + hDIB = GlobalReAlloc(hDIB, lpbi->biSize +
@@ -505,9 +649,9 @@ bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
lpbi->biSizeImage, 0); lpbi->biSizeImage, 0);
if (!hDIB) /* can't resize buffer for loading */ if (!hDIB) /* can't resize buffer for loading */
goto ErrExit2; goto ErrExit2;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/* read the color table */ /* read the color table */
if (!bCoreHead) if (!bCoreHead)
_lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD)); _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
@@ -516,9 +660,9 @@ bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
signed int i; signed int i;
RGBQUAD FAR *pQuad; RGBQUAD FAR *pQuad;
RGBTRIPLE FAR *pTriple; RGBTRIPLE FAR *pTriple;
_lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE)); _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize); pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
pTriple = (RGBTRIPLE FAR *) pQuad; pTriple = (RGBTRIPLE FAR *) pQuad;
for (i = nNumColors - 1; i >= 0; i--) for (i = nNumColors - 1; i >= 0; i--)
@@ -529,19 +673,19 @@ bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
pQuad[i].rgbReserved = 0; pQuad[i].rgbReserved = 0;
} }
} }
/* offset to the bits from start of DIB header */ /* offset to the bits from start of DIB header */
offBits = (WORD)(lpbi->biSize + nNumColors * sizeof(RGBQUAD)); offBits = (WORD)(lpbi->biSize + nNumColors * sizeof(RGBQUAD));
if (bf.bfOffBits != 0L) if (bf.bfOffBits != 0L)
{ {
_llseek(fh,bf.bfOffBits,SEEK_SET); _llseek(fh,bf.bfOffBits,SEEK_SET);
} }
if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage)) if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
{ {
GlobalUnlock(hDIB); GlobalUnlock(hDIB);
hDC = GetDC(NULL); hDC = GetDC(NULL);
if (!wxMakeBitmapAndPalette(hDC, hDIB, palette, if (!wxMakeBitmapAndPalette(hDC, hDIB, palette,
bitmap)) bitmap))
@@ -563,7 +707,7 @@ ErrExit:
ErrExit2: ErrExit2:
GlobalFree(hDIB); GlobalFree(hDIB);
} }
_lclose(fh); _lclose(fh);
return(result); return(result);
} }
@@ -579,7 +723,7 @@ ErrExit2:
* FALSE --> unable to create objects. both pointer are * FALSE --> unable to create objects. both pointer are
* not valid * not valid
*/ */
static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB, static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
HPALETTE * phPal, HBITMAP * phBitmap) HPALETTE * phPal, HBITMAP * phBitmap)
{ {
@@ -588,24 +732,24 @@ static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
HBITMAP hBitmap; HBITMAP hBitmap;
HPALETTE hPalette, hOldPal; HPALETTE hPalette, hOldPal;
LPSTR lpBits; LPSTR lpBits;
lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB); lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
hPalette = wxMakeDIBPalette(lpInfo); hPalette = wxMakeDIBPalette(lpInfo);
if ( hPalette ) if ( hPalette )
{ {
// Need to realize palette for converting DIB to bitmap. // Need to realize palette for converting DIB to bitmap.
hOldPal = SelectPalette(hDC, hPalette, TRUE); hOldPal = SelectPalette(hDC, hPalette, TRUE);
RealizePalette(hDC); RealizePalette(hDC);
lpBits = (LPSTR)lpInfo + (WORD)lpInfo->biSize + lpBits = (LPSTR)lpInfo + (WORD)lpInfo->biSize +
(WORD)lpInfo->biClrUsed * sizeof(RGBQUAD); (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD);
hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits, hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
(LPBITMAPINFO)lpInfo, DIB_RGB_COLORS); (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
SelectPalette(hDC, hOldPal, TRUE); SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC); RealizePalette(hDC);
if (!hBitmap) if (!hBitmap)
DeleteObject(hPalette); DeleteObject(hPalette);
else else
@@ -615,9 +759,9 @@ static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
result = TRUE; result = TRUE;
} }
} }
GlobalUnlock (hDIB); // glt GlobalUnlock (hDIB); // glt
return(result); return(result);
} }
@@ -628,14 +772,14 @@ static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
* RETURNS : non-zero - handle of a corresponding palette * RETURNS : non-zero - handle of a corresponding palette
* zero - unable to create palette * zero - unable to create palette
*/ */
HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo) HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
{ {
LPLOGPALETTE npPal; LPLOGPALETTE npPal;
RGBQUAD far *lpRGB; RGBQUAD far *lpRGB;
HPALETTE hLogPal; HPALETTE hLogPal;
WORD i; WORD i;
/* since biClrUsed field was filled during the loading of the DIB, /* since biClrUsed field was filled during the loading of the DIB,
* we know it contains the number of colors in the color table. * we know it contains the number of colors in the color table.
*/ */
@@ -645,13 +789,13 @@ HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
(WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY)); (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
if (!npPal) if (!npPal)
return NULL; return NULL;
npPal->palVersion = 0x300; npPal->palVersion = 0x300;
npPal->palNumEntries = (WORD)lpInfo->biClrUsed; npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
/* get pointer to the color table */ /* get pointer to the color table */
lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize); lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);
/* copy colors from the color table to the LogPalette structure */ /* copy colors from the color table to the LogPalette structure */
for (i = 0; (DWORD)i < lpInfo->biClrUsed; i++, lpRGB++) for (i = 0; (DWORD)i < lpInfo->biClrUsed; i++, lpRGB++)
{ {
@@ -660,13 +804,13 @@ HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue; npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
npPal->palPalEntry[i].peFlags = 0; npPal->palPalEntry[i].peFlags = 0;
} }
hLogPal = CreatePalette((LPLOGPALETTE)npPal); hLogPal = CreatePalette((LPLOGPALETTE)npPal);
free(npPal); free(npPal);
return(hLogPal); return(hLogPal);
} }
/* 24-bit DIB with no color table. Return default palette. Another /* 24-bit DIB with no color table. Return default palette. Another
* option would be to create a 256 color "rainbow" palette to provide * option would be to create a 256 color "rainbow" palette to provide
* some good color choices. * some good color choices.
@@ -675,64 +819,6 @@ HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
return((HPALETTE) GetStockObject(DEFAULT_PALETTE)); 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 * Function: InitBitmapInfoHeader
@@ -768,12 +854,12 @@ static void InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
{ {
// _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER)); // _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER)); memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
lpBmInfoHdr->biSize = sizeof (BITMAPINFOHEADER); lpBmInfoHdr->biSize = sizeof (BITMAPINFOHEADER);
lpBmInfoHdr->biWidth = dwWidth; lpBmInfoHdr->biWidth = dwWidth;
lpBmInfoHdr->biHeight = dwHeight; lpBmInfoHdr->biHeight = dwHeight;
lpBmInfoHdr->biPlanes = 1; lpBmInfoHdr->biPlanes = 1;
if (nBPP <= 1) if (nBPP <= 1)
nBPP = 1; nBPP = 1;
else if (nBPP <= 4) else if (nBPP <= 4)
@@ -786,7 +872,7 @@ static void InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
*/ */
else else
nBPP = 24; nBPP = 24;
lpBmInfoHdr->biBitCount = nBPP; lpBmInfoHdr->biBitCount = nBPP;
lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight; lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
} }
@@ -818,52 +904,52 @@ HANDLE wxBitmapToDIB (HBITMAP hBitmap, HPALETTE hPal)
HDC hMemDC; HDC hMemDC;
HANDLE hDIB; HANDLE hDIB;
HPALETTE hOldPal = NULL; HPALETTE hOldPal = NULL;
// Do some setup -- make sure the Bitmap passed in is valid, // Do some setup -- make sure the Bitmap passed in is valid,
// get info on the bitmap (like its height, width, etc.), // get info on the bitmap (like its height, width, etc.),
// then setup a BITMAPINFOHEADER. // then setup a BITMAPINFOHEADER.
if (!hBitmap) if (!hBitmap)
return NULL; return NULL;
if (!GetObject (hBitmap, sizeof (Bitmap), (LPSTR) &Bitmap)) if (!GetObject (hBitmap, sizeof (Bitmap), (LPSTR) &Bitmap))
return NULL; return NULL;
InitBitmapInfoHeader (&bmInfoHdr, InitBitmapInfoHeader (&bmInfoHdr,
Bitmap.bmWidth, Bitmap.bmWidth,
Bitmap.bmHeight, Bitmap.bmHeight,
Bitmap.bmPlanes * Bitmap.bmBitsPixel); Bitmap.bmPlanes * Bitmap.bmBitsPixel);
// Now allocate memory for the DIB. Then, set the BITMAPINFOHEADER // Now allocate memory for the DIB. Then, set the BITMAPINFOHEADER
// into this memory, and find out where the bitmap bits go. // into this memory, and find out where the bitmap bits go.
hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) + hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) +
wxPaletteSize ((LPSTR) &bmInfoHdr) + bmInfoHdr.biSizeImage); wxPaletteSize ((LPSTR) &bmInfoHdr) + bmInfoHdr.biSizeImage);
if (!hDIB) if (!hDIB)
return NULL; return NULL;
lpbmInfoHdr = (LPBITMAPINFOHEADER) GlobalLock (hDIB); lpbmInfoHdr = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
*lpbmInfoHdr = bmInfoHdr; *lpbmInfoHdr = bmInfoHdr;
lpBits = wxFindDIBBits ((LPSTR) lpbmInfoHdr); lpBits = wxFindDIBBits ((LPSTR) lpbmInfoHdr);
// Now, we need a DC to hold our bitmap. If the app passed us // Now, we need a DC to hold our bitmap. If the app passed us
// a palette, it should be selected into the DC. // a palette, it should be selected into the DC.
hMemDC = GetDC (NULL); hMemDC = GetDC (NULL);
if (hPal) if (hPal)
{ {
hOldPal = SelectPalette (hMemDC, hPal, FALSE); hOldPal = SelectPalette (hMemDC, hPal, FALSE);
RealizePalette (hMemDC); RealizePalette (hMemDC);
} }
// We're finally ready to get the DIB. Call the driver and let // We're finally ready to get the DIB. Call the driver and let
// it party on our bitmap. It will fill in the color table, // it party on our bitmap. It will fill in the color table,
// and bitmap bits of our global memory block. // and bitmap bits of our global memory block.
if (!GetDIBits (hMemDC, hBitmap, 0, Bitmap.bmHeight, lpBits, if (!GetDIBits (hMemDC, hBitmap, 0, Bitmap.bmHeight, lpBits,
(LPBITMAPINFO) lpbmInfoHdr, DIB_RGB_COLORS)) (LPBITMAPINFO) lpbmInfoHdr, DIB_RGB_COLORS))
{ {
@@ -872,15 +958,15 @@ HANDLE wxBitmapToDIB (HBITMAP hBitmap, HPALETTE hPal)
hDIB = NULL; hDIB = NULL;
} }
else else
GlobalUnlock (hDIB); GlobalUnlock (hDIB);
// Finally, clean up and return. // Finally, clean up and return.
if (hOldPal) if (hOldPal)
SelectPalette (hMemDC, hOldPal, FALSE); SelectPalette (hMemDC, hOldPal, FALSE);
ReleaseDC (NULL, hMemDC); ReleaseDC (NULL, hMemDC);
return hDIB; return hDIB;
} }
@@ -891,7 +977,7 @@ bool wxSaveBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette *palette)
if (palette) if (palette)
hPalette = (HPALETTE) palette->GetHPALETTE(); hPalette = (HPALETTE) palette->GetHPALETTE();
#endif // wxUSE_PALETTE #endif // wxUSE_PALETTE
HANDLE dibHandle = wxBitmapToDIB((HBITMAP) bitmap->GetHBITMAP(), hPalette); HANDLE dibHandle = wxBitmapToDIB((HBITMAP) bitmap->GetHBITMAP(), hPalette);
if (dibHandle) if (dibHandle)
{ {