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)
|
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
|
||||||
|
352
src/msw/dib.cpp
352
src/msw/dib.cpp
@@ -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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user