+///////////////////////////////////////////////////////////////////////////////
+// Name: src/msw/dib.cpp
+// Purpose: implements wxDIB class
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 03.03.03 (replaces the old file with the same name)
+// RCS-ID: $Id$
+// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
+// License: wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #include "wx/log.h"
+#endif //WX_PRECOMP
+
+#include "wx/image.h"
+
+#include "wx/msw/dib.h"
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxDIB creation
+// ----------------------------------------------------------------------------
+
+bool wxDIB::Create(int width, int height, int depth)
+{
+ // we don't handle the palette yet
+ wxASSERT_MSG( depth == 24 || depth == 32,
+ _T("unsupported image depth in wxDIB::Create()") );
+
+ static const int infosize = sizeof(BITMAPINFOHEADER);
+
+ BITMAPINFO *info = (BITMAPINFO *)malloc(infosize);
+ wxCHECK_MSG( info, NULL, _T("malloc(BITMAPINFO) failed") );
+
+ memset(info, 0, infosize);
+
+ info->bmiHeader.biSize = infosize;
+ info->bmiHeader.biWidth = width;
+ info->bmiHeader.biHeight = -height;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = depth;
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biSizeImage = GetLineSize(width, depth)*height;
+
+ // No need to report an error here. If it fails, we just won't use a
+ // file mapping and CreateDIBSection will just allocate memory for us.
+ m_handle = ::CreateDIBSection
+ (
+ 0, // hdc (unused with DIB_RGB_COLORS)
+ info, // bitmap description
+ DIB_RGB_COLORS, // use RGB, not palette
+ &m_data, // [out] DIB bits
+ NULL, // don't use file mapping
+ 0 // file mapping offset (not used here)
+ );
+
+ free(info);
+
+ if ( !m_handle )
+ {
+ wxLogLastError(wxT("CreateDIBSection"));
+
+ return false;
+ }
+
+ m_width = width;
+ m_height = height;
+ m_depth = depth;
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// wxDIB accessors
+// ----------------------------------------------------------------------------
+
+void wxDIB::DoGetObject() const
+{
+ // only do something if we have a valid DIB but we don't [yet] have valid
+ // data
+ if ( m_handle && !m_data )
+ {
+ // although all the info we need is in BITMAP and so we don't really
+ // need DIBSECTION we still ask for it as modifying the bit values only
+ // works for the real DIBs and not for the bitmaps and it's better to
+ // check for this now rather than trying to find out why it doesn't
+ // work later
+ DIBSECTION ds;
+ if ( !::GetObject(m_handle, sizeof(ds), &ds) )
+ {
+ wxLogLastError(_T("GetObject(hDIB)"));
+
+ return;
+ }
+
+ wxDIB *self = wxConstCast(this, wxDIB);
+
+ self->m_width = ds.dsBm.bmWidth;
+ self->m_height = ds.dsBm.bmHeight;
+ self->m_depth = ds.dsBm.bmBitsPixel;
+ self->m_data = ds.dsBm.bmBits;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxImage support
+// ----------------------------------------------------------------------------
+
+#if wxUSE_IMAGE
+
+bool wxDIB::Create(const wxImage& image)
+{
+ wxCHECK_MSG( image.Ok(), false, _T("invalid wxImage in wxDIB ctor") );
+
+ const int h = image.GetHeight();
+ const int w = image.GetWidth();
+
+ // if we have alpha channel, we need to create a 32bpp RGBA DIB, otherwise
+ // a 24bpp RGB is sufficient
+ const bool hasAlpha = image.HasAlpha();
+ const int bpp = hasAlpha ? 32 : 24;
+
+ if ( !Create(w, h, bpp) )
+ return false;
+
+ // DIBs are stored in bottom to top order so we need to copy bits line by
+ // line and starting from the end
+ const int srcBytesPerLine = w * 3;
+ const int dstBytesPerLine = GetLineSize(w, bpp);
+ const unsigned char *src = image.GetData() + ((h - 1) * srcBytesPerLine);
+ const unsigned char *alpha = hasAlpha ? image.GetAlpha() + (h - 1)*w : NULL;
+ unsigned char *dstLineStart = (unsigned char *)m_data;
+ for ( int y = 0; y < h; y++ )
+ {
+ // copy one DIB line
+ unsigned char *dst = dstLineStart;
+ for ( int x = 0; x < w; x++ )
+ {
+ // also, the order of RGB is inversed for DIBs
+ *dst++ = src[2];
+ *dst++ = src[1];
+ *dst++ = src[0];
+
+ src += 3;
+
+ if ( alpha )
+ *dst++ = *alpha++;
+ }
+
+ // pass to the previous line in the image
+ src -= 2*srcBytesPerLine;
+ if ( alpha )
+ alpha -= 2*w;
+
+ // and to the next one in the DIB
+ dstLineStart += dstBytesPerLine;
+ }
+
+ return true;
+}
+
+#endif // wxUSE_IMAGE
+
+// ============================================================================
+// old DIB code, to be integrated in wxDIB class
+// ============================================================================
+
/*******************************************************************************
* *
* MODULE : DIB.CC *
#endif
#ifndef WX_PRECOMP
-#include "wx/setup.h"
-#include "wx/defs.h"
#include "wx/bitmap.h"
+#include "wx/log.h"
+#include "wx/intl.h"
#endif
#include <windows.h>
#include "wx/msw/dib.h"
-#ifndef __TWIN32__
-#ifndef wxUSE_NORLANDER_HEADERS
-#ifdef __GNUWIN32__
-#include "wx/msw/gnuwin32/extra.h"
-#endif
-#endif
+#ifdef __GNUWIN32_OLD__
+ #include "wx/msw/gnuwin32/extra.h"
#endif
#ifndef SEEK_CUR
if (!hdib)
return FALSE;
- fh = OpenFile(wxFNCONV(szFile), &of, OF_CREATE | OF_READWRITE);
+ fh = OpenFile(wxConvertWX2MB(szFile), &of, OF_CREATE | OF_READWRITE);
if (fh == -1)
return FALSE;
NumColors = DibNumColors(lpbi);
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
- return NumColors * sizeof(RGBTRIPLE);
+ return (WORD)(NumColors * sizeof(RGBTRIPLE));
else
- return NumColors * sizeof(RGBQUAD);
+ return (WORD)(NumColors * sizeof(RGBQUAD));
}
/****************************************************************************
static DWORD PASCAL lread(int fh, void far *pv, DWORD ul)
{
DWORD ulT = ul;
-#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__) || defined(__WXWINE__)
+#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__)
BYTE *hp = (BYTE *) pv;
#else
BYTE huge *hp = (BYTE huge *) pv;
ul -= MAXREAD;
hp += MAXREAD;
}
- if (_lread(fh, (LPSTR) hp, (WORD) ul) != (WORD) ul)
+ if (_lread(fh, (LPSTR) hp, (WXUINT) ul) != (WXUINT) ul)
return 0;
return ulT;
}
static DWORD PASCAL lwrite(int fh, VOID FAR *pv, DWORD ul)
{
DWORD ulT = ul;
-#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__) || defined(__WXWINE__)
+#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__)
BYTE *hp = (BYTE *) pv;
#else
BYTE huge *hp = (BYTE huge *) pv;
ul -= MAXREAD;
hp += MAXREAD;
}
- if (_lwrite(fh, (LPSTR) hp, (WORD) ul) != (WORD) ul)
+ if (_lwrite(fh, (LPSTR) hp, (WXUINT) ul) != (WXUINT) ul)
return 0;
return ulT;
}
/* Open the file and get a handle to it's BITMAPINFO */
- fh = OpenFile (wxFNCONV(lpFileName), &of, OF_READ);
+ fh = OpenFile (wxConvertWX2MB(lpFileName), &of, OF_READ);
if (fh == -1) {
wxLogError(_("Can't open file '%s'"), lpFileName);
return (0);
}
/* 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)
{
result = TRUE;
}
}
+
+ GlobalUnlock (hDIB); // glt
+
return(result);
}
****************************************************************************/
HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
{
-#ifdef __WXWINE__
- return (FALSE);
-#else
LPLOGPALETTE npPal;
RGBQUAD far *lpRGB;
HPALETTE hLogPal;
npPal = (LPLOGPALETTE)malloc(sizeof(LOGPALETTE) +
(WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
if (!npPal)
- return(FALSE);
+ return NULL;
npPal->palVersion = 0x300;
npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);
/* copy colors from the color table to the LogPalette structure */
- for (i = 0; i < lpInfo->biClrUsed; i++, lpRGB++)
+ for (i = 0; (DWORD)i < lpInfo->biClrUsed; i++, lpRGB++)
{
npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
*/
else
return((HPALETTE) GetStockObject(DEFAULT_PALETTE));
-#endif
-
}
bool wxLoadIntoBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette **pal)
{
- HBITMAP hBitmap;
- HPALETTE hPalette;
+ HBITMAP hBitmap = NULL;
+ HPALETTE hPalette = NULL;
bool success = (wxReadDIB(filename, &hBitmap, &hPalette) != 0);
if (!success)
{
- DeleteObject(hPalette);
+ 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)
bool wxSaveBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette *colourmap)
{
HPALETTE hPalette = 0;
+#if wxUSE_PALETTE
if (colourmap)
hPalette = (HPALETTE) colourmap->GetHPALETTE();
+#endif // wxUSE_PALETTE
HANDLE dibHandle = wxBitmapToDIB((HBITMAP) bitmap->GetHBITMAP(), hPalette);
if (dibHandle)
else return FALSE;
}
-