X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2b254edf9cb508b48bfd3f9cf76d46f7cf1e1f5b..f7f78039d2e18114efdec0abe46dc4ed2d4529a8:/src/msw/dib.cpp diff --git a/src/msw/dib.cpp b/src/msw/dib.cpp index fe4136e2a3..ef71fc3f51 100644 --- a/src/msw/dib.cpp +++ b/src/msw/dib.cpp @@ -84,7 +84,7 @@ bool wxDIB::Create(int width, int height, int depth) static const int infosize = sizeof(BITMAPINFOHEADER); BITMAPINFO *info = (BITMAPINFO *)malloc(infosize); - wxCHECK_MSG( info, NULL, _T("malloc(BITMAPINFO) failed") ); + wxCHECK_MSG( info, false, _T("malloc(BITMAPINFO) failed") ); memset(info, 0, infosize); @@ -132,26 +132,48 @@ bool wxDIB::Create(const wxBitmap& bmp) { wxCHECK_MSG( bmp.Ok(), false, _T("wxDIB::Create(): invalid bitmap") ); - const int w = bmp.GetWidth(); - const int h = bmp.GetHeight(); - int d = bmp.GetDepth(); - if ( d == -1 ) - d = wxDisplayDepth(); + // this bitmap could already be a DIB section in which case we don't need + // to convert it to DIB + HBITMAP hbmp = GetHbitmapOf(bmp); - if ( !Create(w, h, d) ) - return false; + DIBSECTION ds; + if ( ::GetObject(hbmp, sizeof(ds), &ds) == sizeof(ds) ) + { + m_handle = hbmp; - // we could have used GetDIBits() too but GetBitmapBits() is simpler - if ( !::GetBitmapBits - ( - GetHbitmapOf(bmp), // the source DDB - GetLineSize(w, d)*h, // the number of bytes to copy - m_data // the pixels will be copied here - ) ) + // wxBitmap will free it, not we + m_ownsHandle = false; + + // copy all the bitmap parameters too as we have them now anyhow + m_width = ds.dsBm.bmWidth; + m_height = ds.dsBm.bmHeight; + m_depth = ds.dsBm.bmBitsPixel; + + m_data = ds.dsBm.bmBits; + } + else // no, it's a DDB -- convert it to DIB { - wxLogLastError(wxT("GetDIBits()")); + const int w = bmp.GetWidth(); + const int h = bmp.GetHeight(); + int d = bmp.GetDepth(); + if ( d == -1 ) + d = wxDisplayDepth(); + + if ( !Create(w, h, d) ) + return false; + + // we could have used GetDIBits() too but GetBitmapBits() is simpler + if ( !::GetBitmapBits + ( + GetHbitmapOf(bmp), // the source DDB + GetLineSize(w, d)*h, // the number of bytes to copy + m_data // the pixels will be copied here + ) ) + { + wxLogLastError(wxT("GetDIBits()")); - return 0; + return 0; + } } return true; @@ -288,13 +310,31 @@ HBITMAP wxDIB::ConvertToBitmap(const BITMAPINFO *pbmi, HDC hdc, void *bits) if ( !bits ) { // we must skip over the colour table to get to the image data - - // biClrUsed has the number of colors but it may be not initialized at - // all - int numColors = pbmih->biClrUsed; - if ( !numColors ) + // + // colour table either has the real colour data in which case its + // number of entries is given by biClrUsed or is used for masks to be + // used for extracting colour information from true colour bitmaps in + // which case it always have exactly 3 DWORDs + int numColors; + switch ( pbmih->biCompression ) { - numColors = wxGetNumOfBitmapColors(pbmih->biBitCount); + case BI_BITFIELDS: + numColors = 3; + break; + + case BI_RGB: + // biClrUsed has the number of colors but it may be not initialized at + // all + numColors = pbmih->biClrUsed; + if ( !numColors ) + { + numColors = wxGetNumOfBitmapColors(pbmih->biBitCount); + } + break; + + default: + // no idea how it should be calculated for the other cases + numColors = 0; } bits = (char *)pbmih + sizeof(*pbmih) + numColors*sizeof(RGBQUAD); @@ -303,7 +343,7 @@ HBITMAP wxDIB::ConvertToBitmap(const BITMAPINFO *pbmi, HDC hdc, void *bits) HBITMAP hbmp = ::CreateDIBitmap ( hdc ? hdc // create bitmap compatible - : ScreenHDC(), // with this DC + : (HDC) ScreenHDC(), // with this DC pbmih, // used to get size &c CBM_INIT, // initialize bitmap bits too bits, // ... using this data