added wxDIB::Save() and wxDIB to/from wxBitmap) conversions, use them instead of the old C functions (the latter were removed, there is no old code left any more)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19744 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
		@@ -35,6 +35,10 @@ public:
 | 
			
		||||
    wxDIB(int width, int height, int depth)
 | 
			
		||||
        { Init(); (void)Create(width, height, depth); }
 | 
			
		||||
 | 
			
		||||
    // create a DIB from the DDB
 | 
			
		||||
    wxDIB(const wxBitmap& bmp)
 | 
			
		||||
        { Init(); (void)Create(bmp); }
 | 
			
		||||
 | 
			
		||||
    // load a DIB from file (any depth is supoprted here unlike above)
 | 
			
		||||
    //
 | 
			
		||||
    // as above, use IsOk() to see if the bitmap was loaded successfully
 | 
			
		||||
@@ -43,6 +47,7 @@ public:
 | 
			
		||||
 | 
			
		||||
    // same as the corresponding ctors but with return value
 | 
			
		||||
    bool Create(int width, int height, int depth);
 | 
			
		||||
    bool Create(const wxBitmap& bmp);
 | 
			
		||||
    bool Load(const wxString& filename);
 | 
			
		||||
 | 
			
		||||
    // dtor is not virtual, this class is not meant to be used polymorphically
 | 
			
		||||
@@ -66,6 +71,9 @@ public:
 | 
			
		||||
    wxPalette *CreatePalette() const;
 | 
			
		||||
#endif // wxUSE_PALETTE
 | 
			
		||||
 | 
			
		||||
    // save the DIB as a .BMP file to the file with the given name
 | 
			
		||||
    bool Save(const wxString& filename);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // accessors
 | 
			
		||||
    // ---------
 | 
			
		||||
@@ -92,8 +100,8 @@ public:
 | 
			
		||||
    // HBITMAP conversion
 | 
			
		||||
    // ------------------
 | 
			
		||||
 | 
			
		||||
    // these functions are only used by wxBitmapDataObject implementation in
 | 
			
		||||
    // src/msw/ole/dataobj.cpp, don't use them directly if possible
 | 
			
		||||
    // these functions are only used by wxWindows internally right now, please
 | 
			
		||||
    // don't use them directly if possible as they're subject to change
 | 
			
		||||
 | 
			
		||||
    // creates a DDB compatible with the given (or screen) DC from either
 | 
			
		||||
    // a plain DIB or a DIB section (in which case the last parameter must be
 | 
			
		||||
@@ -102,12 +110,18 @@ public:
 | 
			
		||||
                                   HDC hdc = 0,
 | 
			
		||||
                                   void *bits = NULL);
 | 
			
		||||
 | 
			
		||||
    // create a plain DIB (not a DIB section) from a DDB, the caller is
 | 
			
		||||
    // responsable for freeing it using ::GlobalFree()
 | 
			
		||||
    static HGLOBAL ConvertFromBitmap(HBITMAP hbmp);
 | 
			
		||||
 | 
			
		||||
    // creates a DIB from the given DDB or calculates the space needed by it:
 | 
			
		||||
    // if pbi is NULL, only the space is calculated, otherwise pbi is supposed
 | 
			
		||||
    // to point at BITMAPINFO of the correct size which is filled by this
 | 
			
		||||
    // function
 | 
			
		||||
    // function (this overload is needed for wxBitmapDataObject code in
 | 
			
		||||
    // src/msw/ole/dataobj.cpp)
 | 
			
		||||
    static size_t ConvertFromBitmap(BITMAPINFO *pbi, HBITMAP hbmp);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // wxImage conversion
 | 
			
		||||
    // ------------------
 | 
			
		||||
 | 
			
		||||
@@ -199,16 +213,5 @@ inline wxDIB::~wxDIB()
 | 
			
		||||
    Free();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// the rest is defined in dib.cpp
 | 
			
		||||
 | 
			
		||||
// Save (device dependent) wxBitmap as a DIB
 | 
			
		||||
bool wxSaveBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette *palette = NULL);
 | 
			
		||||
 | 
			
		||||
HANDLE wxBitmapToDIB (HBITMAP hBitmap, HPALETTE hPal);
 | 
			
		||||
bool   wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette);
 | 
			
		||||
HANDLE wxReadDIB2(LPTSTR lpFileName);
 | 
			
		||||
LPSTR wxFindDIBBits (LPSTR lpbi);
 | 
			
		||||
HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo);
 | 
			
		||||
 | 
			
		||||
#endif // _WX_MSW_DIB_H_
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -487,7 +487,6 @@ bool wxBitmap::DoCreate(int w, int h, int d, WXHDC hdc)
 | 
			
		||||
        hbmp = dib.Detach();
 | 
			
		||||
 | 
			
		||||
        GetBitmapData()->m_depth = d;
 | 
			
		||||
        GetBitmapData()->m_hasAlpha = d == 32; // 32bpp DIBs have alpha channel
 | 
			
		||||
    }
 | 
			
		||||
    else // create a DDB
 | 
			
		||||
    {
 | 
			
		||||
 
 | 
			
		||||
@@ -220,13 +220,13 @@ bool wxSetClipboardData(wxDataFormat dataFormat,
 | 
			
		||||
 | 
			
		||||
        case wxDF_DIB:
 | 
			
		||||
            {
 | 
			
		||||
#if wxUSE_IMAGE_LOADING_IN_MSW
 | 
			
		||||
                wxBitmap *bitmap = (wxBitmap *)data;
 | 
			
		||||
                HBITMAP hBitmap = (HBITMAP)bitmap->GetHBITMAP();
 | 
			
		||||
                // NULL palette means to use the system one
 | 
			
		||||
                HANDLE hDIB = wxBitmapToDIB(hBitmap, (HPALETTE)NULL);
 | 
			
		||||
                handle = SetClipboardData(CF_DIB, hDIB);
 | 
			
		||||
#endif // wxUSE_IMAGE_LOADING_IN_MSW
 | 
			
		||||
 | 
			
		||||
                HGLOBAL hDIB = wxDIB::ConvertFromBitmap(GetHbitmapOf(*bitmap));
 | 
			
		||||
                if ( hDIB )
 | 
			
		||||
                {
 | 
			
		||||
                    handle = ::SetClipboardData(CF_DIB, hDIB);
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										802
									
								
								src/msw/dib.cpp
									
									
									
									
									
								
							
							
						
						
									
										802
									
								
								src/msw/dib.cpp
									
									
									
									
									
								
							@@ -9,6 +9,13 @@
 | 
			
		||||
// License:     wxWindows licence
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
    TODO: support for palettes is very incomplete, several functions simply
 | 
			
		||||
          ignore them (we should select and realize the palette, if any, before
 | 
			
		||||
          caling GetDIBits() in the DC we use with it and we shouldn't use
 | 
			
		||||
          GetBitmapBits() at all because we can't do it with it)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
// declarations
 | 
			
		||||
// ============================================================================
 | 
			
		||||
@@ -31,6 +38,7 @@
 | 
			
		||||
 | 
			
		||||
#include "wx/bitmap.h"
 | 
			
		||||
#include "wx/intl.h"
 | 
			
		||||
#include "wx/file.h"
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
@@ -120,6 +128,35 @@ bool wxDIB::Create(int width, int height, int depth)
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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();
 | 
			
		||||
 | 
			
		||||
    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 true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// Loading/saving the DIBs
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
@@ -144,6 +181,48 @@ bool wxDIB::Load(const wxString& filename)
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool wxDIB::Save(const wxString& filename)
 | 
			
		||||
{
 | 
			
		||||
    wxCHECK_MSG( m_handle, false, _T("wxDIB::Save(): invalid object") );
 | 
			
		||||
 | 
			
		||||
    wxFile file(filename, wxFile::write);
 | 
			
		||||
    bool ok = file.IsOpened();
 | 
			
		||||
    if ( ok )
 | 
			
		||||
    {
 | 
			
		||||
        DIBSECTION ds;
 | 
			
		||||
        if ( !::GetObject(m_handle, sizeof(ds), &ds) )
 | 
			
		||||
        {
 | 
			
		||||
            wxLogLastError(_T("GetObject(hDIB)"));
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            BITMAPFILEHEADER bmpHdr;
 | 
			
		||||
            wxZeroMemory(bmpHdr);
 | 
			
		||||
 | 
			
		||||
            const size_t sizeHdr = ds.dsBmih.biSize;
 | 
			
		||||
            const size_t sizeImage = ds.dsBmih.biSizeImage;
 | 
			
		||||
 | 
			
		||||
            bmpHdr.bfType = 0x4d42;    // 'BM' in little endian
 | 
			
		||||
            bmpHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + ds.dsBmih.biSize;
 | 
			
		||||
            bmpHdr.bfSize = bmpHdr.bfOffBits + sizeImage;
 | 
			
		||||
 | 
			
		||||
            // first write the file header, then the bitmap header and finally the
 | 
			
		||||
            // bitmap data itself
 | 
			
		||||
            ok = file.Write(&bmpHdr, sizeof(bmpHdr)) == sizeof(bmpHdr) &&
 | 
			
		||||
                    file.Write(&ds.dsBmih, sizeHdr) == sizeHdr &&
 | 
			
		||||
                        file.Write(ds.dsBm.bmBits, sizeImage) == sizeImage;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( !ok )
 | 
			
		||||
    {
 | 
			
		||||
        wxLogError(_("Failed to save the bitmap image to file \"%s\"."),
 | 
			
		||||
                   filename.c_str());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ok;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// wxDIB accessors
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
@@ -254,16 +333,11 @@ size_t wxDIB::ConvertFromBitmap(BITMAPINFO *pbi, HBITMAP hbmp)
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // calculate the number of bits per pixel and the number of items in
 | 
			
		||||
    // bmiColors array (whose meaning depends on the bitmap format)
 | 
			
		||||
    WORD biBits = bm.bmPlanes * bm.bmBitsPixel;
 | 
			
		||||
    WORD biColors = wxGetNumOfBitmapColors(biBits);
 | 
			
		||||
 | 
			
		||||
    // we need a BITMAPINFO anyhow and if we're not given a pointer to it we
 | 
			
		||||
    // use this one
 | 
			
		||||
    BITMAPINFO bi2;
 | 
			
		||||
 | 
			
		||||
    bool wantSizeOnly = pbi == NULL;
 | 
			
		||||
    const bool wantSizeOnly = pbi == NULL;
 | 
			
		||||
    if ( wantSizeOnly )
 | 
			
		||||
        pbi = &bi2;
 | 
			
		||||
 | 
			
		||||
@@ -277,36 +351,67 @@ size_t wxDIB::ConvertFromBitmap(BITMAPINFO *pbi, HBITMAP hbmp)
 | 
			
		||||
    bi.biWidth = bm.bmWidth;
 | 
			
		||||
    bi.biHeight = h;
 | 
			
		||||
    bi.biPlanes = 1;
 | 
			
		||||
    bi.biBitCount = biBits;
 | 
			
		||||
    bi.biBitCount = bm.bmBitsPixel;
 | 
			
		||||
 | 
			
		||||
    // memory we need for BITMAPINFO only
 | 
			
		||||
    DWORD dwLen = bi.biSize + biColors * sizeof(RGBQUAD);
 | 
			
		||||
    DWORD dwLen = bi.biSize + wxGetNumOfBitmapColors(bm.bmBitsPixel) * sizeof(RGBQUAD);
 | 
			
		||||
 | 
			
		||||
    // first get the image size
 | 
			
		||||
    ScreenHDC hdc;
 | 
			
		||||
    if ( !::GetDIBits(hdc, hbmp, 0, h, NULL, pbi, DIB_RGB_COLORS) )
 | 
			
		||||
    // get either just the image size or the image bits
 | 
			
		||||
    if ( !::GetDIBits
 | 
			
		||||
            (
 | 
			
		||||
                ScreenHDC(),                        // the DC to use
 | 
			
		||||
                hbmp,                               // the source DDB
 | 
			
		||||
                0,                                  // first scan line
 | 
			
		||||
                h,                                  // number of lines to copy
 | 
			
		||||
                wantSizeOnly ? NULL                 // pointer to the buffer or
 | 
			
		||||
                             : (char *)pbi + dwLen, // NULL if we don't have it
 | 
			
		||||
                pbi,                                // bitmap header
 | 
			
		||||
                DIB_RGB_COLORS                      // or DIB_PAL_COLORS
 | 
			
		||||
            ) )
 | 
			
		||||
    {
 | 
			
		||||
        wxLogLastError(wxT("GetDIBits(NULL)"));
 | 
			
		||||
        wxLogLastError(wxT("GetDIBits()"));
 | 
			
		||||
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( !wantSizeOnly )
 | 
			
		||||
    {
 | 
			
		||||
        // and now copy the bits
 | 
			
		||||
        void *image = (char *)pbi + dwLen;
 | 
			
		||||
        if ( !::GetDIBits(hdc, hbmp, 0, h, image, pbi, DIB_RGB_COLORS) )
 | 
			
		||||
        {
 | 
			
		||||
            wxLogLastError(wxT("GetDIBits"));
 | 
			
		||||
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // return the total size
 | 
			
		||||
    return dwLen + bi.biSizeImage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* static */
 | 
			
		||||
HGLOBAL wxDIB::ConvertFromBitmap(HBITMAP hbmp)
 | 
			
		||||
{
 | 
			
		||||
    // first calculate the size needed
 | 
			
		||||
    const size_t size = ConvertFromBitmap(NULL, hbmp);
 | 
			
		||||
    if ( !size )
 | 
			
		||||
    {
 | 
			
		||||
        // conversion to DDB failed?
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    HGLOBAL hDIB = ::GlobalAlloc(GMEM_MOVEABLE, size);
 | 
			
		||||
    if ( !hDIB )
 | 
			
		||||
    {
 | 
			
		||||
        // this is an error which does risk to happen especially under Win9x
 | 
			
		||||
        // and which the user may understand so let him know about it
 | 
			
		||||
        wxLogError(_("Failed to allocated %luKb of memory for bitmap data."),
 | 
			
		||||
                   (unsigned long)(size / 1024));
 | 
			
		||||
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( !ConvertFromBitmap((BITMAPINFO *)GlobalHandle(hDIB), hbmp) )
 | 
			
		||||
    {
 | 
			
		||||
        // this really shouldn't happen... it worked the first time, why not
 | 
			
		||||
        // now?
 | 
			
		||||
        wxFAIL_MSG( _T("wxDIB::ConvertFromBitmap() unexpectedly failed") );
 | 
			
		||||
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return hDIB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
// palette support
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
@@ -330,12 +435,12 @@ wxPalette *wxDIB::CreatePalette() const
 | 
			
		||||
    if ( !biClrUsed )
 | 
			
		||||
    {
 | 
			
		||||
        // biClrUsed field might not be set
 | 
			
		||||
        biClrUsed = 1 << ds.dsBmih.biBitCount;
 | 
			
		||||
        biClrUsed = wxGetNumOfBitmapColors(ds.dsBmih.biBitCount);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ( biClrUsed > 256 )
 | 
			
		||||
    if ( !biClrUsed )
 | 
			
		||||
    {
 | 
			
		||||
        // only 8bpp bitmaps (and less) have palettes, so we surely don't
 | 
			
		||||
        // bitmaps of this depth don't have palettes at all
 | 
			
		||||
        //
 | 
			
		||||
        // NB: another possibility would be to return
 | 
			
		||||
        //     GetStockObject(DEFAULT_PALETTE) or even CreateHalftonePalette()?
 | 
			
		||||
@@ -440,646 +545,3 @@ bool wxDIB::Create(const wxImage& image)
 | 
			
		||||
 | 
			
		||||
#endif // wxUSE_IMAGE
 | 
			
		||||
 | 
			
		||||
// ============================================================================
 | 
			
		||||
// old DIB code, to be integrated in wxDIB class
 | 
			
		||||
// ============================================================================
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  Routines for dealing with Device Independent Bitmaps.
 | 
			
		||||
 *
 | 
			
		||||
 *                  wxReadDIB()           - Reads a DIB
 | 
			
		||||
 *                  wxWriteDIB()            - Writes a global handle in CF_DIB format
 | 
			
		||||
 *                                          to a file.
 | 
			
		||||
 *                  wxPaletteSize()       - Calculates the palette size in bytes
 | 
			
		||||
 *                                          of given DIB
 | 
			
		||||
 *                  wxDibNumColors()        - Determines the number of colors in DIB
 | 
			
		||||
 *                  wxDibFromBitmap()       - Creates a DIB repr. the DDB passed in.
 | 
			
		||||
 *                  lread()               - Private routine to read more than 64k
 | 
			
		||||
 *                  lwrite()              - Private routine to write more than 64k
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef SEEK_CUR
 | 
			
		||||
/* flags for _lseek */
 | 
			
		||||
#define        SEEK_CUR 1
 | 
			
		||||
#define        SEEK_END 2
 | 
			
		||||
#define        SEEK_SET 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MAXREAD  32768                                 /* Number of bytes to be read during */
 | 
			
		||||
                                                 /* each read operation.                         */
 | 
			
		||||
 | 
			
		||||
/* Header signatutes for various resources */
 | 
			
		||||
#define BFT_ICON         0x4349         /* 'IC' */
 | 
			
		||||
#define BFT_BITMAP 0x4d42         /* 'BM' */
 | 
			
		||||
#define BFT_CURSOR 0x5450         /* 'PT(' */
 | 
			
		||||
 | 
			
		||||
/* macro to determine if resource is a DIB */
 | 
			
		||||
#define ISDIB(bft) ((bft) == BFT_BITMAP)
 | 
			
		||||
 | 
			
		||||
/* Macro to align given value to the closest DWORD (unsigned long ) */
 | 
			
		||||
#define ALIGNULONG(i)        ((i+3)/4*4)
 | 
			
		||||
 | 
			
		||||
/* Macro to determine to round off the given value to the closest byte */
 | 
			
		||||
#define WIDTHBYTES(i)        ((i+31)/32*4)
 | 
			
		||||
 | 
			
		||||
#define PALVERSION                0x300
 | 
			
		||||
#define MAXPALETTE        256          /* max. # supported palette entries */
 | 
			
		||||
 | 
			
		||||
static DWORD lread(int fh, VOID FAR *pv, DWORD ul);
 | 
			
		||||
static DWORD lwrite(int fh, VOID FAR *pv, DWORD ul);
 | 
			
		||||
 | 
			
		||||
static bool wxWriteDIB (LPTSTR szFile,HANDLE hdib);
 | 
			
		||||
WORD        wxPaletteSize (VOID FAR * pv); // This is non-static as some apps use it externally
 | 
			
		||||
static WORD wxDibNumColors (VOID FAR * pv);
 | 
			
		||||
static bool wxMakeBitmapAndPalette(HDC,HANDLE,HPALETTE *,HBITMAP *);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : wxWriteDIB(LPSTR szFile,HANDLE hdib)
 | 
			
		||||
 *  PURPOSE    : Write a global handle in CF_DIB format to a file.
 | 
			
		||||
 *  RETURNS    : TRUE  - if successful.
 | 
			
		||||
 *               FALSE - otherwise
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static bool wxWriteDIB(LPTSTR szFile, HANDLE hdib)
 | 
			
		||||
{
 | 
			
		||||
    BITMAPFILEHEADER        hdr;
 | 
			
		||||
    LPBITMAPINFOHEADER  lpbi;
 | 
			
		||||
    int                 fh;
 | 
			
		||||
    OFSTRUCT            of;
 | 
			
		||||
 | 
			
		||||
    if (!hdib)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    fh = OpenFile(wxConvertWX2MB(szFile), &of, OF_CREATE | OF_READWRITE);
 | 
			
		||||
    if (fh == -1)
 | 
			
		||||
        return FALSE;
 | 
			
		||||
 | 
			
		||||
    lpbi = (LPBITMAPINFOHEADER) GlobalLock(hdib);
 | 
			
		||||
 | 
			
		||||
    /* Fill in the fields of the file header */
 | 
			
		||||
    hdr.bfType = BFT_BITMAP;
 | 
			
		||||
    hdr.bfSize = GlobalSize(hdib) + sizeof(BITMAPFILEHEADER);
 | 
			
		||||
    hdr.bfReserved1 = 0;
 | 
			
		||||
    hdr.bfReserved2 = 0;
 | 
			
		||||
    hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + lpbi->biSize +
 | 
			
		||||
        wxPaletteSize(lpbi);
 | 
			
		||||
 | 
			
		||||
    /* Write the file header */
 | 
			
		||||
    _lwrite(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER));
 | 
			
		||||
 | 
			
		||||
    /* Write the DIB header and the bits */
 | 
			
		||||
    lwrite(fh, (LPSTR) lpbi, GlobalSize(hdib));
 | 
			
		||||
 | 
			
		||||
    GlobalUnlock(hdib);
 | 
			
		||||
    _lclose(fh);
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   :  wxPaletteSize(VOID FAR * pv)
 | 
			
		||||
 *  PURPOSE    :  Calculates the palette size in bytes. If the info. block
 | 
			
		||||
 *                is of the BITMAPCOREHEADER type, the number of colors is
 | 
			
		||||
 *                multiplied by 3 to give the palette size, otherwise the
 | 
			
		||||
 *                number of colors is multiplied by 4.
 | 
			
		||||
 *  RETURNS    :  Palette size in number of bytes.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
WORD wxPaletteSize(VOID FAR * pv)
 | 
			
		||||
{
 | 
			
		||||
    LPBITMAPINFOHEADER lpbi;
 | 
			
		||||
    WORD               NumColors;
 | 
			
		||||
 | 
			
		||||
    lpbi = (LPBITMAPINFOHEADER) pv;
 | 
			
		||||
    NumColors = wxDibNumColors(lpbi);
 | 
			
		||||
 | 
			
		||||
    if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
 | 
			
		||||
        return (WORD)(NumColors * sizeof(RGBTRIPLE));
 | 
			
		||||
    else
 | 
			
		||||
        return (WORD)(NumColors * sizeof(RGBQUAD));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : wxDibNumColors(VOID FAR * pv)
 | 
			
		||||
 *  PURPOSE    : Determines the number of colors in the DIB by looking at
 | 
			
		||||
 *               the BitCount filed in the info block.
 | 
			
		||||
 *  RETURNS    : The number of colors in the DIB.                            *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static WORD wxDibNumColors(VOID FAR *pv)
 | 
			
		||||
{
 | 
			
		||||
    int                 bits;
 | 
			
		||||
    BITMAPINFOHEADER        *lpbi;
 | 
			
		||||
    BITMAPCOREHEADER        *lpbc;
 | 
			
		||||
 | 
			
		||||
    lpbi = ((BITMAPINFOHEADER*) pv);
 | 
			
		||||
    lpbc = ((BITMAPCOREHEADER*) pv);
 | 
			
		||||
 | 
			
		||||
    /*        With the BITMAPINFO format headers, the size of the palette
 | 
			
		||||
     *        is in biClrUsed, whereas in the BITMAPCORE - style headers, it
 | 
			
		||||
     *        is dependent on the bits per pixel ( = 2 raised to the power of
 | 
			
		||||
     *        bits/pixel).
 | 
			
		||||
     */
 | 
			
		||||
    if (lpbi->biSize != sizeof(BITMAPCOREHEADER)) {
 | 
			
		||||
        if (lpbi->biClrUsed != 0)
 | 
			
		||||
            return (WORD) lpbi->biClrUsed;
 | 
			
		||||
        bits = lpbi->biBitCount;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        bits = lpbc->bcBitCount;
 | 
			
		||||
 | 
			
		||||
    switch (bits) {
 | 
			
		||||
    case 1:
 | 
			
		||||
        return 2;
 | 
			
		||||
    case 4:
 | 
			
		||||
        return 16;
 | 
			
		||||
    case 8:
 | 
			
		||||
        return 256;
 | 
			
		||||
    default:
 | 
			
		||||
        /* A 24 bitcount DIB has no color table */
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : lread(int fh, VOID FAR *pv, DWORD ul)
 | 
			
		||||
 *  PURPOSE    : Reads data in steps of 32k till all the data has been read.
 | 
			
		||||
 *  RETURNS    : 0 - If read did not proceed correctly.
 | 
			
		||||
 *               number of bytes read otherwise.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static DWORD lread(int fh, void far *pv, DWORD ul)
 | 
			
		||||
{
 | 
			
		||||
    DWORD     ulT = ul;
 | 
			
		||||
#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__)
 | 
			
		||||
    BYTE *hp = (BYTE *) pv;
 | 
			
		||||
#else
 | 
			
		||||
    BYTE huge *hp = (BYTE huge *) pv;
 | 
			
		||||
#endif
 | 
			
		||||
    while (ul > (DWORD) MAXREAD) {
 | 
			
		||||
        if (_lread(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
 | 
			
		||||
            return 0;
 | 
			
		||||
        ul -= MAXREAD;
 | 
			
		||||
        hp += MAXREAD;
 | 
			
		||||
    }
 | 
			
		||||
    if (_lread(fh, (LPSTR) hp, (WXUINT) ul) != (WXUINT) ul)
 | 
			
		||||
        return 0;
 | 
			
		||||
    return ulT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : lwrite(int fh, VOID FAR *pv, DWORD ul)
 | 
			
		||||
 *  PURPOSE    : Writes data in steps of 32k till all the data is written.
 | 
			
		||||
 *  RETURNS    : 0 - If write did not proceed correctly.
 | 
			
		||||
 *               number of bytes written otherwise.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static DWORD lwrite(int fh, VOID FAR *pv, DWORD ul)
 | 
			
		||||
{
 | 
			
		||||
    DWORD     ulT = ul;
 | 
			
		||||
#if defined(WINNT) || defined(__WIN32__) || defined(__WIN32__)
 | 
			
		||||
    BYTE *hp = (BYTE *) pv;
 | 
			
		||||
#else
 | 
			
		||||
    BYTE huge *hp = (BYTE huge *) pv;
 | 
			
		||||
#endif
 | 
			
		||||
    while (ul > MAXREAD) {
 | 
			
		||||
        if (_lwrite(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
 | 
			
		||||
            return 0;
 | 
			
		||||
        ul -= MAXREAD;
 | 
			
		||||
        hp += MAXREAD;
 | 
			
		||||
    }
 | 
			
		||||
    if (_lwrite(fh, (LPSTR) hp, (WXUINT) ul) != (WXUINT) ul)
 | 
			
		||||
        return 0;
 | 
			
		||||
    return ulT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : wxReadDIB(hWnd)
 | 
			
		||||
 *  PURPOSE    : Reads a DIB from a file, obtains a handle to its
 | 
			
		||||
 *               BITMAPINFO struct. and loads the DIB.  Once the DIB
 | 
			
		||||
 *               is loaded, the function also creates a bitmap and
 | 
			
		||||
 *               palette out of the DIB for a device-dependent form.
 | 
			
		||||
 *  RETURNS    : TRUE  - DIB loaded and bitmap/palette created
 | 
			
		||||
 *                       The DIBINIT structure pointed to by pInfo is
 | 
			
		||||
 *                       filled with the appropriate handles.
 | 
			
		||||
 *               FALSE - otherwise
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
bool wxReadDIB(LPTSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
 | 
			
		||||
{
 | 
			
		||||
    int fh;
 | 
			
		||||
    LPBITMAPINFOHEADER lpbi;
 | 
			
		||||
    OFSTRUCT               of;
 | 
			
		||||
    BITMAPFILEHEADER   bf;
 | 
			
		||||
    WORD                nNumColors;
 | 
			
		||||
    bool result = FALSE;
 | 
			
		||||
    WORD offBits;
 | 
			
		||||
    HDC hDC;
 | 
			
		||||
    bool bCoreHead = FALSE;
 | 
			
		||||
    HANDLE hDIB = 0;
 | 
			
		||||
 | 
			
		||||
    /* Open the file and get a handle to it's BITMAPINFO */
 | 
			
		||||
 | 
			
		||||
    fh = OpenFile (wxConvertWX2MB(lpFileName), &of, OF_READ);
 | 
			
		||||
    if (fh == -1) {
 | 
			
		||||
        wxLogError(_("Can't open file '%s'"), lpFileName);
 | 
			
		||||
        return (0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
 | 
			
		||||
        256 * sizeof(RGBQUAD)));
 | 
			
		||||
    if (!hDIB)
 | 
			
		||||
        return(0);
 | 
			
		||||
 | 
			
		||||
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
 | 
			
		||||
 | 
			
		||||
    /* read the BITMAPFILEHEADER */
 | 
			
		||||
    if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
 | 
			
		||||
        goto ErrExit;
 | 
			
		||||
 | 
			
		||||
    if (bf.bfType != 0x4d42)        /* 'BM' */
 | 
			
		||||
        goto ErrExit;
 | 
			
		||||
 | 
			
		||||
    if (sizeof(BITMAPCOREHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
 | 
			
		||||
        goto ErrExit;
 | 
			
		||||
 | 
			
		||||
    if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
 | 
			
		||||
    {
 | 
			
		||||
        lpbi->biSize = sizeof(BITMAPINFOHEADER);
 | 
			
		||||
        lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
 | 
			
		||||
        lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
 | 
			
		||||
        lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
 | 
			
		||||
        lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
 | 
			
		||||
        bCoreHead = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // get to the start of the header and read INFOHEADER
 | 
			
		||||
        _llseek(fh,sizeof(BITMAPFILEHEADER),SEEK_SET);
 | 
			
		||||
        if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
 | 
			
		||||
            goto ErrExit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    nNumColors = (WORD)lpbi->biClrUsed;
 | 
			
		||||
    if ( nNumColors == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        /* no color table for 24-bit, default size otherwise */
 | 
			
		||||
        if (lpbi->biBitCount != 24)
 | 
			
		||||
            nNumColors = 1 << lpbi->biBitCount;        /* standard size table */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* fill in some default values if they are zero */
 | 
			
		||||
    if (lpbi->biClrUsed == 0)
 | 
			
		||||
        lpbi->biClrUsed = nNumColors;
 | 
			
		||||
 | 
			
		||||
    if (lpbi->biSizeImage == 0)
 | 
			
		||||
    {
 | 
			
		||||
        lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
 | 
			
		||||
            * lpbi->biHeight;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* get a proper-sized buffer for header, color table and bits */
 | 
			
		||||
    GlobalUnlock(hDIB);
 | 
			
		||||
    hDIB = GlobalReAlloc(hDIB, lpbi->biSize +
 | 
			
		||||
        nNumColors * sizeof(RGBQUAD) +
 | 
			
		||||
        lpbi->biSizeImage, 0);
 | 
			
		||||
    if (!hDIB)        /* can't resize buffer for loading */
 | 
			
		||||
        goto ErrExit2;
 | 
			
		||||
 | 
			
		||||
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
 | 
			
		||||
 | 
			
		||||
    /* read the color table */
 | 
			
		||||
    if (!bCoreHead)
 | 
			
		||||
        _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        signed int i;
 | 
			
		||||
        RGBQUAD FAR *pQuad;
 | 
			
		||||
        RGBTRIPLE FAR *pTriple;
 | 
			
		||||
 | 
			
		||||
        _lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
 | 
			
		||||
 | 
			
		||||
        pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
 | 
			
		||||
        pTriple = (RGBTRIPLE FAR *) pQuad;
 | 
			
		||||
        for (i = nNumColors - 1; i >= 0; i--)
 | 
			
		||||
        {
 | 
			
		||||
            pQuad[i].rgbRed = pTriple[i].rgbtRed;
 | 
			
		||||
            pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
 | 
			
		||||
            pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
 | 
			
		||||
            pQuad[i].rgbReserved = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* offset to the bits from start of DIB header */
 | 
			
		||||
    offBits = (WORD)(lpbi->biSize + nNumColors * sizeof(RGBQUAD));
 | 
			
		||||
 | 
			
		||||
    if (bf.bfOffBits != 0L)
 | 
			
		||||
    {
 | 
			
		||||
        _llseek(fh,bf.bfOffBits,SEEK_SET);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
 | 
			
		||||
    {
 | 
			
		||||
        GlobalUnlock(hDIB);
 | 
			
		||||
 | 
			
		||||
        hDC = GetDC(NULL);
 | 
			
		||||
        if (!wxMakeBitmapAndPalette(hDC, hDIB, palette,
 | 
			
		||||
            bitmap))
 | 
			
		||||
        {
 | 
			
		||||
            ReleaseDC(NULL,hDC);
 | 
			
		||||
            goto ErrExit2;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            ReleaseDC(NULL,hDC);
 | 
			
		||||
            GlobalFree(hDIB);
 | 
			
		||||
            result = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
ErrExit:
 | 
			
		||||
    GlobalUnlock(hDIB);
 | 
			
		||||
ErrExit2:
 | 
			
		||||
    GlobalFree(hDIB);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _lclose(fh);
 | 
			
		||||
    return(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : wxMakeBitmapAndPalette
 | 
			
		||||
 *  PURPOSE    : Given a DIB, creates a bitmap and corresponding palette
 | 
			
		||||
 *               to be used for a device-dependent representation of
 | 
			
		||||
 *               of the image.
 | 
			
		||||
 *  RETURNS    : TRUE  --> success. phPal and phBitmap are filled with
 | 
			
		||||
 *                         appropriate handles.  Caller is responsible
 | 
			
		||||
 *                         for freeing objects.
 | 
			
		||||
 *               FALSE --> unable to create objects.  both pointer are
 | 
			
		||||
 *                         not valid
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static bool wxMakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
 | 
			
		||||
                        HPALETTE * phPal, HBITMAP * phBitmap)
 | 
			
		||||
{
 | 
			
		||||
    LPBITMAPINFOHEADER lpInfo;
 | 
			
		||||
    bool result = FALSE;
 | 
			
		||||
    HBITMAP hBitmap;
 | 
			
		||||
    HPALETTE hPalette, hOldPal;
 | 
			
		||||
    LPSTR lpBits;
 | 
			
		||||
 | 
			
		||||
    lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
 | 
			
		||||
 | 
			
		||||
    hPalette = wxMakeDIBPalette(lpInfo);
 | 
			
		||||
    if ( hPalette )
 | 
			
		||||
    {
 | 
			
		||||
        // Need to realize palette for converting DIB to bitmap.
 | 
			
		||||
        hOldPal = SelectPalette(hDC, hPalette, TRUE);
 | 
			
		||||
        RealizePalette(hDC);
 | 
			
		||||
 | 
			
		||||
        lpBits = (LPSTR)lpInfo + (WORD)lpInfo->biSize +
 | 
			
		||||
            (WORD)lpInfo->biClrUsed * sizeof(RGBQUAD);
 | 
			
		||||
        hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits,
 | 
			
		||||
            (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
 | 
			
		||||
 | 
			
		||||
        SelectPalette(hDC, hOldPal, TRUE);
 | 
			
		||||
        RealizePalette(hDC);
 | 
			
		||||
 | 
			
		||||
        if (!hBitmap)
 | 
			
		||||
            DeleteObject(hPalette);
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            *phBitmap = hBitmap;
 | 
			
		||||
            *phPal = hPalette;
 | 
			
		||||
            result = TRUE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    GlobalUnlock (hDIB);  // glt
 | 
			
		||||
 | 
			
		||||
    return(result);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *  FUNCTION   : wxMakeDIBPalette(lpInfo)
 | 
			
		||||
 *  PURPOSE    : Given a BITMAPINFOHEADER, create a palette based on
 | 
			
		||||
 *               the color table.
 | 
			
		||||
 *  RETURNS    : non-zero - handle of a corresponding palette
 | 
			
		||||
 *               zero - unable to create palette
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
HPALETTE wxMakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
 | 
			
		||||
{
 | 
			
		||||
    LPLOGPALETTE npPal;
 | 
			
		||||
    RGBQUAD far *lpRGB;
 | 
			
		||||
    HPALETTE hLogPal;
 | 
			
		||||
    WORD i;
 | 
			
		||||
 | 
			
		||||
    /* since biClrUsed field was filled during the loading of the DIB,
 | 
			
		||||
     * we know it contains the number of colors in the color table.
 | 
			
		||||
     */
 | 
			
		||||
    if (lpInfo->biClrUsed)
 | 
			
		||||
    {
 | 
			
		||||
        npPal = (LPLOGPALETTE)malloc(sizeof(LOGPALETTE) +
 | 
			
		||||
            (WORD)lpInfo->biClrUsed * sizeof(PALETTEENTRY));
 | 
			
		||||
        if (!npPal)
 | 
			
		||||
            return NULL;
 | 
			
		||||
 | 
			
		||||
        npPal->palVersion = 0x300;
 | 
			
		||||
        npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
 | 
			
		||||
 | 
			
		||||
        /* get pointer to the color table */
 | 
			
		||||
        lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);
 | 
			
		||||
 | 
			
		||||
        /* copy colors from the color table to the LogPalette structure */
 | 
			
		||||
        for (i = 0; (DWORD)i < lpInfo->biClrUsed; i++, lpRGB++)
 | 
			
		||||
        {
 | 
			
		||||
            npPal->palPalEntry[i].peRed = lpRGB->rgbRed;
 | 
			
		||||
            npPal->palPalEntry[i].peGreen = lpRGB->rgbGreen;
 | 
			
		||||
            npPal->palPalEntry[i].peBlue = lpRGB->rgbBlue;
 | 
			
		||||
            npPal->palPalEntry[i].peFlags = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        hLogPal = CreatePalette((LPLOGPALETTE)npPal);
 | 
			
		||||
        free(npPal);
 | 
			
		||||
 | 
			
		||||
        return(hLogPal);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 24-bit DIB with no color table. Return default palette. Another
 | 
			
		||||
     * option would be to create a 256 color "rainbow" palette to provide
 | 
			
		||||
     * some good color choices.
 | 
			
		||||
     */
 | 
			
		||||
    else
 | 
			
		||||
        return((HPALETTE) GetStockObject(DEFAULT_PALETTE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *
 | 
			
		||||
 * Function:   InitBitmapInfoHeader
 | 
			
		||||
 *
 | 
			
		||||
 * Purpose:    Does a "standard" initialization of a BITMAPINFOHEADER,
 | 
			
		||||
 *             given the Width, Height, and Bits per Pixel for the
 | 
			
		||||
 *             DIB.
 | 
			
		||||
 *
 | 
			
		||||
 *             By standard, I mean that all the relevant fields are set
 | 
			
		||||
 *             to the specified values.  biSizeImage is computed, the
 | 
			
		||||
 *             biCompression field is set to "no compression," and all
 | 
			
		||||
 *             other fields are 0.
 | 
			
		||||
 *
 | 
			
		||||
 *             Note that DIBs only allow BitsPixel values of 1, 4, 8, or
 | 
			
		||||
 *             24.  This routine makes sure that one of these values is
 | 
			
		||||
 *             used (whichever is most appropriate for the specified
 | 
			
		||||
 *             nBPP).
 | 
			
		||||
 *
 | 
			
		||||
 * Parms:      lpBmInfoHdr == Far pointer to a BITMAPINFOHEADER structure
 | 
			
		||||
 *                            to be filled in.
 | 
			
		||||
 *             dwWidth     == Width of DIB (not in Win 3.0 & 3.1, high
 | 
			
		||||
 *                            word MUST be 0).
 | 
			
		||||
 *             dwHeight    == Height of DIB (not in Win 3.0 & 3.1, high
 | 
			
		||||
 *                            word MUST be 0).
 | 
			
		||||
 *             nBPP        == Bits per Pixel for the DIB.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static void InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
 | 
			
		||||
                                        DWORD dwWidth,
 | 
			
		||||
                                        DWORD dwHeight,
 | 
			
		||||
                                          int nBPP)
 | 
			
		||||
{
 | 
			
		||||
    //   _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
 | 
			
		||||
    memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
 | 
			
		||||
 | 
			
		||||
    lpBmInfoHdr->biSize      = sizeof (BITMAPINFOHEADER);
 | 
			
		||||
    lpBmInfoHdr->biWidth     = dwWidth;
 | 
			
		||||
    lpBmInfoHdr->biHeight    = dwHeight;
 | 
			
		||||
    lpBmInfoHdr->biPlanes    = 1;
 | 
			
		||||
 | 
			
		||||
    if (nBPP <= 1)
 | 
			
		||||
        nBPP = 1;
 | 
			
		||||
    else if (nBPP <= 4)
 | 
			
		||||
        nBPP = 4;
 | 
			
		||||
    else if (nBPP <= 8)
 | 
			
		||||
        nBPP = 8;
 | 
			
		||||
   /* Doesn't work
 | 
			
		||||
        else if (nBPP <= 16)
 | 
			
		||||
        nBPP = 16;
 | 
			
		||||
    */
 | 
			
		||||
    else
 | 
			
		||||
        nBPP = 24;
 | 
			
		||||
 | 
			
		||||
    lpBmInfoHdr->biBitCount  = nBPP;
 | 
			
		||||
    lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LPSTR wxFindDIBBits (LPSTR lpbi)
 | 
			
		||||
{
 | 
			
		||||
    return (lpbi + *(LPDWORD)lpbi + wxPaletteSize (lpbi));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Function:   BitmapToDIB
 | 
			
		||||
 *
 | 
			
		||||
 * Purpose:    Given a device dependent bitmap and a palette, returns
 | 
			
		||||
 *             a handle to global memory with a DIB spec in it.  The
 | 
			
		||||
 *             DIB is rendered using the colors of the palette passed in.
 | 
			
		||||
 *
 | 
			
		||||
 * Parms:      hBitmap == Handle to device dependent bitmap compatible
 | 
			
		||||
 *                        with default screen display device.
 | 
			
		||||
 *             hPal    == Palette to render the DDB with.  If it's NULL,
 | 
			
		||||
 *                        use the default palette.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
HANDLE wxBitmapToDIB (HBITMAP hBitmap, HPALETTE hPal)
 | 
			
		||||
{
 | 
			
		||||
    BITMAP             Bitmap;
 | 
			
		||||
    BITMAPINFOHEADER   bmInfoHdr;
 | 
			
		||||
    LPBITMAPINFOHEADER lpbmInfoHdr;
 | 
			
		||||
    LPSTR              lpBits;
 | 
			
		||||
    HDC                hMemDC;
 | 
			
		||||
    HANDLE             hDIB;
 | 
			
		||||
    HPALETTE           hOldPal = NULL;
 | 
			
		||||
 | 
			
		||||
    // Do some setup -- make sure the Bitmap passed in is valid,
 | 
			
		||||
    //  get info on the bitmap (like its height, width, etc.),
 | 
			
		||||
    //  then setup a BITMAPINFOHEADER.
 | 
			
		||||
 | 
			
		||||
    if (!hBitmap)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    if (!GetObject (hBitmap, sizeof (Bitmap), (LPSTR) &Bitmap))
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    InitBitmapInfoHeader (&bmInfoHdr,
 | 
			
		||||
        Bitmap.bmWidth,
 | 
			
		||||
        Bitmap.bmHeight,
 | 
			
		||||
        Bitmap.bmPlanes * Bitmap.bmBitsPixel);
 | 
			
		||||
 | 
			
		||||
    // Now allocate memory for the DIB.  Then, set the BITMAPINFOHEADER
 | 
			
		||||
    //  into this memory, and find out where the bitmap bits go.
 | 
			
		||||
 | 
			
		||||
    hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) +
 | 
			
		||||
        wxPaletteSize ((LPSTR) &bmInfoHdr) + bmInfoHdr.biSizeImage);
 | 
			
		||||
 | 
			
		||||
    if (!hDIB)
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    lpbmInfoHdr  = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
 | 
			
		||||
 | 
			
		||||
    *lpbmInfoHdr = bmInfoHdr;
 | 
			
		||||
    lpBits       = wxFindDIBBits ((LPSTR) lpbmInfoHdr);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Now, we need a DC to hold our bitmap.  If the app passed us
 | 
			
		||||
    //  a palette, it should be selected into the DC.
 | 
			
		||||
 | 
			
		||||
    hMemDC = GetDC (NULL);
 | 
			
		||||
 | 
			
		||||
    if (hPal)
 | 
			
		||||
    {
 | 
			
		||||
        hOldPal = SelectPalette (hMemDC, hPal, FALSE);
 | 
			
		||||
        RealizePalette (hMemDC);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 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,
 | 
			
		||||
    // and bitmap bits of our global memory block.
 | 
			
		||||
 | 
			
		||||
    if (!GetDIBits (hMemDC, hBitmap, 0, Bitmap.bmHeight, lpBits,
 | 
			
		||||
            (LPBITMAPINFO) lpbmInfoHdr, DIB_RGB_COLORS))
 | 
			
		||||
    {
 | 
			
		||||
        GlobalUnlock (hDIB);
 | 
			
		||||
        GlobalFree (hDIB);
 | 
			
		||||
        hDIB = NULL;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
        GlobalUnlock (hDIB);
 | 
			
		||||
 | 
			
		||||
    // Finally, clean up and return.
 | 
			
		||||
 | 
			
		||||
    if (hOldPal)
 | 
			
		||||
        SelectPalette (hMemDC, hOldPal, FALSE);
 | 
			
		||||
 | 
			
		||||
    ReleaseDC (NULL, hMemDC);
 | 
			
		||||
 | 
			
		||||
    return hDIB;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool wxSaveBitmap(wxChar *filename, wxBitmap *bitmap, wxPalette *palette)
 | 
			
		||||
{
 | 
			
		||||
    HPALETTE hPalette = 0;
 | 
			
		||||
#if wxUSE_PALETTE
 | 
			
		||||
    if (palette)
 | 
			
		||||
        hPalette = (HPALETTE) palette->GetHPALETTE();
 | 
			
		||||
#endif // wxUSE_PALETTE
 | 
			
		||||
 | 
			
		||||
    HANDLE dibHandle = wxBitmapToDIB((HBITMAP) bitmap->GetHBITMAP(), hPalette);
 | 
			
		||||
    if (dibHandle)
 | 
			
		||||
    {
 | 
			
		||||
        bool success = (wxWriteDIB(filename, dibHandle) != 0);
 | 
			
		||||
        GlobalFree(dibHandle);
 | 
			
		||||
        return success;
 | 
			
		||||
    }
 | 
			
		||||
    else return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -355,22 +355,13 @@ bool wxBMPFileHandler::LoadFile(wxBitmap *bitmap,
 | 
			
		||||
bool wxBMPFileHandler::SaveFile(wxBitmap *bitmap,
 | 
			
		||||
                                const wxString& name,
 | 
			
		||||
                                int WXUNUSED(type),
 | 
			
		||||
                                const wxPalette *pal)
 | 
			
		||||
                                const wxPalette * WXUNUSED(pal))
 | 
			
		||||
{
 | 
			
		||||
#if wxUSE_IMAGE_LOADING_IN_MSW
 | 
			
		||||
    wxCHECK_MSG( bitmap, false, _T("NULL bitmap in SaveFile") );
 | 
			
		||||
 | 
			
		||||
#if wxUSE_PALETTE
 | 
			
		||||
    wxPalette *actualPalette = (wxPalette *)pal;
 | 
			
		||||
    if ( !actualPalette )
 | 
			
		||||
        actualPalette = bitmap->GetPalette();
 | 
			
		||||
#else
 | 
			
		||||
    wxPalette *actualPalette = NULL;
 | 
			
		||||
#endif // wxUSE_PALETTE
 | 
			
		||||
    wxDIB dib(*bitmap);
 | 
			
		||||
 | 
			
		||||
    return wxSaveBitmap(WXSTRINGCAST name, bitmap, actualPalette) != 0;
 | 
			
		||||
#else
 | 
			
		||||
    return false;
 | 
			
		||||
#endif
 | 
			
		||||
    return dib.Save(name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -1103,20 +1103,16 @@ WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE WXUNUSED(hInstance), void *i
 | 
			
		||||
 | 
			
		||||
WXHBITMAP wxToolBar::CreateMappedBitmap(WXHINSTANCE hInstance, WXHBITMAP hBitmap)
 | 
			
		||||
{
 | 
			
		||||
  HANDLE hDIB = wxBitmapToDIB((HBITMAP) hBitmap, 0);
 | 
			
		||||
  if (hDIB)
 | 
			
		||||
  {
 | 
			
		||||
#ifdef __WINDOWS_386__
 | 
			
		||||
    LPBITMAPINFOHEADER lpbmInfoHdr = (LPBITMAPINFOHEADER)MK_FP32(GlobalLock(hDIB));
 | 
			
		||||
#else
 | 
			
		||||
    LPBITMAPINFOHEADER lpbmInfoHdr = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
 | 
			
		||||
#endif
 | 
			
		||||
    HBITMAP newBitmap = (HBITMAP) CreateMappedBitmap((WXHINSTANCE) wxGetInstance(), lpbmInfoHdr);
 | 
			
		||||
    GlobalUnlock(hDIB);
 | 
			
		||||
    HANDLE hDIB = wxDIB::ConvertFromBitmap((HBITMAP) hBitmap);
 | 
			
		||||
    if ( !hDIB )
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    WXHBITMAP newBitmap = CreateMappedBitmap(hInstance, GlobalHandle(hDIB));
 | 
			
		||||
 | 
			
		||||
    GlobalFree(hDIB);
 | 
			
		||||
    return (WXHBITMAP) newBitmap;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
 | 
			
		||||
    return newBitmap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif // wxUSE_TOOLBAR
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user