]> git.saurik.com Git - wxWidgets.git/blob - src/msw/bitmap.cpp
Updated wxvc_dll.dsp and memory.h to make VC++ compile in DLL mode again
[wxWidgets.git] / src / msw / bitmap.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: bitmap.cpp
3 // Purpose: wxBitmap
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "bitmap.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include <stdio.h>
33
34 #include "wx/list.h"
35 #include "wx/utils.h"
36 #include "wx/app.h"
37 #include "wx/palette.h"
38 #include "wx/dcmemory.h"
39 #include "wx/bitmap.h"
40 #include "wx/icon.h"
41 #endif
42
43 #include "wx/msw/private.h"
44 #include "wx/log.h"
45
46 #include "wx/msw/dib.h"
47 #include "wx/image.h"
48
49 // ----------------------------------------------------------------------------
50 // macros
51 // ----------------------------------------------------------------------------
52
53 IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
54 IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
55
56 IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject)
57
58 // ============================================================================
59 // implementation
60 // ============================================================================
61
62 // ----------------------------------------------------------------------------
63 // wxBitmapRefData
64 // ----------------------------------------------------------------------------
65
66 wxBitmapRefData::wxBitmapRefData()
67 {
68 m_quality = 0;
69 m_selectedInto = NULL;
70 m_numColors = 0;
71 m_bitmapMask = NULL;
72 m_hBitmap = (WXHBITMAP) NULL;
73 }
74
75 void wxBitmapRefData::Free()
76 {
77 wxASSERT_MSG( !m_selectedInto,
78 wxT("deleting bitmap still selected into wxMemoryDC") );
79
80 if ( m_hBitmap)
81 {
82 if ( !::DeleteObject((HBITMAP)m_hBitmap) )
83 {
84 wxLogLastError("DeleteObject(hbitmap)");
85 }
86 }
87
88 delete m_bitmapMask;
89 m_bitmapMask = NULL;
90 }
91
92 // ----------------------------------------------------------------------------
93 // wxBitmap creation
94 // ----------------------------------------------------------------------------
95
96 // this function should be called from all wxBitmap ctors
97 void wxBitmap::Init()
98 {
99 // m_refData = NULL; done in the base class ctor
100
101 if ( wxTheBitmapList )
102 wxTheBitmapList->AddBitmap(this);
103 }
104
105 #ifdef __WIN32__
106
107 bool wxBitmap::CopyFromIconOrCursor(const wxGDIImage& icon)
108 {
109 // it may be either HICON or HCURSOR
110 HICON hicon = (HICON)icon.GetHandle();
111
112 ICONINFO iconInfo;
113 if ( !::GetIconInfo(hicon, &iconInfo) )
114 {
115 wxLogLastError("GetIconInfo");
116
117 return FALSE;
118 }
119
120 wxBitmapRefData *refData = new wxBitmapRefData;
121 m_refData = refData;
122
123 int w = icon.GetWidth(),
124 h = icon.GetHeight();
125
126 refData->m_width = w;
127 refData->m_height = h;
128 refData->m_depth = wxDisplayDepth();
129
130 refData->m_hBitmap = (WXHBITMAP)iconInfo.hbmColor;
131
132 // the mask returned by GetIconInfo() is inversed compared to the usual
133 // wxWin convention
134 HBITMAP hbmpMask = ::CreateBitmap(w, h, 1, 1, 0);
135
136 // the icons mask is opposite to the usual wxWin convention
137 HDC dcSrc = ::CreateCompatibleDC(NULL);
138 HDC dcDst = ::CreateCompatibleDC(NULL);
139 (void)SelectObject(dcSrc, iconInfo.hbmMask);
140 (void)SelectObject(dcDst, hbmpMask);
141
142 HBRUSH brush = ::CreateSolidBrush(RGB(255, 255, 255));
143 RECT rect = { 0, 0, w, h };
144 FillRect(dcDst, &rect, brush);
145
146 BitBlt(dcDst, 0, 0, w, h, dcSrc, 0, 0, SRCINVERT);
147
148 SelectObject(dcDst, NULL);
149 SelectObject(dcSrc, NULL);
150 DeleteDC(dcDst);
151 DeleteDC(dcSrc);
152
153 refData->m_bitmapMask = new wxMask((WXHBITMAP)hbmpMask);
154
155 #if WXWIN_COMPATIBILITY_2
156 refData->m_ok = TRUE;
157 #endif // WXWIN_COMPATIBILITY_2
158
159 return TRUE;
160 }
161
162 #endif // Win32
163
164 bool wxBitmap::CopyFromCursor(const wxCursor& cursor)
165 {
166 UnRef();
167
168 if ( !cursor.Ok() )
169 return FALSE;
170
171 #ifdef __WIN16__
172 wxFAIL_MSG( _T("don't know how to convert cursor to bitmap") );
173
174 return FALSE;
175 #else
176 return CopyFromIconOrCursor(cursor);
177 #endif // Win16
178 }
179
180 bool wxBitmap::CopyFromIcon(const wxIcon& icon)
181 {
182 UnRef();
183
184 if ( !icon.Ok() )
185 return FALSE;
186
187 // GetIconInfo() doesn't exist under Win16 and I don't know any other way
188 // to create a bitmap from icon there - but using this way we won't have
189 // the mask (FIXME)
190 #ifdef __WIN16__
191 int width = icon.GetWidth(),
192 height = icon.GetHeight();
193
194 // copy the icon to the bitmap
195 ScreenHDC hdcScreen;
196 HDC hdc = ::CreateCompatibleDC(hdcScreen);
197 HBITMAP hbitmap = ::CreateCompatibleBitmap(hdcScreen, width, height);
198 HBITMAP hbmpOld = (HBITMAP)::SelectObject(hdc, hbitmap);
199
200 ::DrawIcon(hdc, 0, 0, GetHiconOf(icon));
201
202 ::SelectObject(hdc, hbmpOld);
203 ::DeleteDC(hdc);
204
205 wxBitmapRefData *refData = new wxBitmapRefData;
206 m_refData = refData;
207
208 refData->m_width = width;
209 refData->m_height = height;
210 refData->m_depth = wxDisplayDepth();
211
212 refData->m_hBitmap = (WXHBITMAP)hbitmap;
213
214 #if WXWIN_COMPATIBILITY_2
215 refData->m_ok = TRUE;
216 #endif // WXWIN_COMPATIBILITY_2
217
218 return TRUE;
219 #else // Win32
220 return CopyFromIconOrCursor(icon);
221 #endif // Win16/Win32
222 }
223
224 wxBitmap::~wxBitmap()
225 {
226 if (wxTheBitmapList)
227 wxTheBitmapList->DeleteObject(this);
228 }
229
230 wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
231 {
232 Init();
233
234 wxBitmapRefData *refData = new wxBitmapRefData;
235 m_refData = refData;
236
237 refData->m_width = the_width;
238 refData->m_height = the_height;
239 refData->m_depth = no_bits;
240 refData->m_numColors = 0;
241 refData->m_selectedInto = NULL;
242
243 HBITMAP hbmp = ::CreateBitmap(the_width, the_height, 1, no_bits, bits);
244 if ( !hbmp )
245 {
246 wxLogLastError("CreateBitmap");
247 }
248
249 SetHBITMAP((WXHBITMAP)hbmp);
250 }
251
252 // GRG, Dic/99
253 wxBitmap wxBitmap::GetSubBitmap( const wxRect& rect) const
254 {
255 wxCHECK_MSG( Ok() &&
256 (rect.x >= 0) && (rect.y >= 0) &&
257 (rect.x+rect.width <= GetWidth()) &&
258 (rect.y+rect.height <= GetHeight()),
259 wxNullBitmap, wxT("Invalid bitmap or bitmap region") );
260
261 wxBitmap ret( rect.width, rect.height, GetDepth() );
262 wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
263
264 // copy bitmap data
265 HDC dcSrc = ::CreateCompatibleDC(NULL);
266 HDC dcDst = ::CreateCompatibleDC(NULL);
267 SelectObject(dcSrc, (HBITMAP) GetHBITMAP());
268 SelectObject(dcDst, (HBITMAP) ret.GetHBITMAP());
269 BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
270
271 // copy mask if there is one
272 if (GetMask())
273 {
274 HBITMAP hbmpMask = ::CreateBitmap(rect.width, rect.height, 1, 1, 0);
275
276 SelectObject(dcSrc, (HBITMAP) GetMask()->GetMaskBitmap());
277 SelectObject(dcDst, (HBITMAP) hbmpMask);
278 BitBlt(dcDst, 0, 0, rect.width, rect.height, dcSrc, rect.x, rect.y, SRCCOPY);
279
280 wxMask *mask = new wxMask((WXHBITMAP) hbmpMask);
281 ret.SetMask(mask);
282 }
283
284 SelectObject(dcDst, NULL);
285 SelectObject(dcSrc, NULL);
286 DeleteDC(dcDst);
287 DeleteDC(dcSrc);
288
289 return ret;
290 }
291
292 // Create from XPM data
293 wxBitmap::wxBitmap(char **data, wxControl *WXUNUSED(anItem))
294 {
295 Init();
296
297 (void)Create((void *)data, wxBITMAP_TYPE_XPM_DATA, 0, 0, 0);
298 }
299
300 wxBitmap::wxBitmap(int w, int h, int d)
301 {
302 Init();
303
304 (void)Create(w, h, d);
305 }
306
307 wxBitmap::wxBitmap(void *data, long type, int width, int height, int depth)
308 {
309 Init();
310
311 (void)Create(data, type, width, height, depth);
312 }
313
314 wxBitmap::wxBitmap(const wxString& filename, long type)
315 {
316 Init();
317
318 LoadFile(filename, (int)type);
319 }
320
321 bool wxBitmap::Create(int w, int h, int d)
322 {
323 UnRef();
324
325 m_refData = new wxBitmapRefData;
326
327 GetBitmapData()->m_width = w;
328 GetBitmapData()->m_height = h;
329 GetBitmapData()->m_depth = d;
330
331 HBITMAP hbmp;
332
333 if ( d > 0 )
334 {
335 hbmp = ::CreateBitmap(w, h, 1, d, NULL);
336 if ( !hbmp )
337 {
338 wxLogLastError("CreateBitmap");
339 }
340 }
341 else
342 {
343 ScreenHDC dc;
344 hbmp = ::CreateCompatibleBitmap(dc, w, h);
345 if ( !hbmp )
346 {
347 wxLogLastError("CreateCompatibleBitmap");
348 }
349
350 GetBitmapData()->m_depth = wxDisplayDepth();
351 }
352
353 SetHBITMAP((WXHBITMAP)hbmp);
354
355 #if WXWIN_COMPATIBILITY_2
356 GetBitmapData()->m_ok = hbmp != 0;
357 #endif // WXWIN_COMPATIBILITY_2
358
359 return Ok();
360 }
361
362 bool wxBitmap::LoadFile(const wxString& filename, long type)
363 {
364 UnRef();
365
366 wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler);
367
368 if ( handler )
369 {
370 m_refData = new wxBitmapRefData;
371
372 return handler->LoadFile(this, filename, type, -1, -1);
373 }
374 else
375 {
376 wxImage image;
377 if ( !image.LoadFile( filename, type ) || !image.Ok() )
378 return FALSE;
379
380 *this = image.ConvertToBitmap();
381
382 return TRUE;
383 }
384 }
385
386 bool wxBitmap::Create(void *data, long type, int width, int height, int depth)
387 {
388 UnRef();
389
390 wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler);
391
392 if ( !handler )
393 {
394 wxLogDebug(wxT("Failed to create bitmap: no bitmap handler for "
395 "type %d defined."), type);
396
397 return FALSE;
398 }
399
400 m_refData = new wxBitmapRefData;
401
402 return handler->Create(this, data, type, width, height, depth);
403 }
404
405 bool wxBitmap::SaveFile(const wxString& filename, int type, const wxPalette *palette)
406 {
407 wxBitmapHandler *handler = wxDynamicCast(FindHandler(type), wxBitmapHandler);
408
409 if ( handler )
410 {
411 return handler->SaveFile(this, filename, type, palette);
412 }
413 else
414 {
415 // FIXME what about palette? shouldn't we use it?
416 wxImage image( *this );
417 if (!image.Ok())
418 return FALSE;
419
420 return image.SaveFile( filename, type );
421 }
422 }
423
424 // ----------------------------------------------------------------------------
425 // wxBitmap accessors
426 // ----------------------------------------------------------------------------
427
428 void wxBitmap::SetQuality(int q)
429 {
430 EnsureHasData();
431
432 GetBitmapData()->m_quality = q;
433 }
434
435 #if WXWIN_COMPATIBILITY_2
436 void wxBitmap::SetOk(bool isOk)
437 {
438 EnsureHasData();
439
440 GetBitmapData()->m_ok = isOk;
441 }
442 #endif // WXWIN_COMPATIBILITY_2
443
444 void wxBitmap::SetPalette(const wxPalette& palette)
445 {
446 EnsureHasData();
447
448 GetBitmapData()->m_bitmapPalette = palette;
449 }
450
451 void wxBitmap::SetMask(wxMask *mask)
452 {
453 EnsureHasData();
454
455 GetBitmapData()->m_bitmapMask = mask;
456 }
457
458 // Creates a bitmap that matches the device context, from
459 // an arbitray bitmap. At present, the original bitmap must have an
460 // associated palette. TODO: use a default palette if no palette exists.
461 // Contributed by Frederic Villeneuve <frederic.villeneuve@natinst.com>
462 wxBitmap wxBitmap::GetBitmapForDC(wxDC& dc) const
463 {
464 wxMemoryDC memDC;
465 wxBitmap tmpBitmap(this->GetWidth(), this->GetHeight(), dc.GetDepth());
466 HPALETTE hPal = (HPALETTE) NULL;
467 LPBITMAPINFO lpDib;
468 void *lpBits = (void*) NULL;
469
470 if( GetPalette() && GetPalette()->Ok() )
471 {
472 tmpBitmap.SetPalette(*GetPalette());
473 memDC.SelectObject(tmpBitmap);
474 memDC.SetPalette(*GetPalette());
475 hPal = (HPALETTE)GetPalette()->GetHPALETTE();
476 }
477 else
478 {
479 hPal = (HPALETTE) ::GetStockObject(DEFAULT_PALETTE);
480 wxPalette palette;
481 palette.SetHPALETTE( (WXHPALETTE)hPal );
482 tmpBitmap.SetPalette( palette );
483 memDC.SelectObject(tmpBitmap);
484 memDC.SetPalette( palette );
485 }
486
487 // set the height negative because in a DIB the order of the lines is
488 // reversed
489 if ( !wxCreateDIB(GetWidth(), -GetHeight(), GetDepth(), hPal, &lpDib) )
490 {
491 return wxNullBitmap;
492 }
493
494 lpBits = malloc(lpDib->bmiHeader.biSizeImage);
495
496 ::GetBitmapBits(GetHbitmap(), lpDib->bmiHeader.biSizeImage, lpBits);
497
498 ::SetDIBitsToDevice(GetHdcOf(memDC), 0, 0,
499 GetWidth(), GetHeight(),
500 0, 0, 0, GetHeight(),
501 lpBits, lpDib, DIB_RGB_COLORS);
502
503 free(lpBits);
504
505 wxFreeDIB(lpDib);
506
507 return tmpBitmap;
508 }
509
510 // ----------------------------------------------------------------------------
511 // wxMask
512 // ----------------------------------------------------------------------------
513
514 wxMask::wxMask()
515 {
516 m_maskBitmap = 0;
517 }
518
519 // Construct a mask from a bitmap and a colour indicating
520 // the transparent area
521 wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
522 {
523 m_maskBitmap = 0;
524 Create(bitmap, colour);
525 }
526
527 // Construct a mask from a bitmap and a palette index indicating
528 // the transparent area
529 wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
530 {
531 m_maskBitmap = 0;
532 Create(bitmap, paletteIndex);
533 }
534
535 // Construct a mask from a mono bitmap (copies the bitmap).
536 wxMask::wxMask(const wxBitmap& bitmap)
537 {
538 m_maskBitmap = 0;
539 Create(bitmap);
540 }
541
542 wxMask::~wxMask()
543 {
544 if ( m_maskBitmap )
545 ::DeleteObject((HBITMAP) m_maskBitmap);
546 }
547
548 // Create a mask from a mono bitmap (copies the bitmap).
549 bool wxMask::Create(const wxBitmap& bitmap)
550 {
551 if ( m_maskBitmap )
552 {
553 ::DeleteObject((HBITMAP) m_maskBitmap);
554 m_maskBitmap = 0;
555 }
556 if (!bitmap.Ok() || bitmap.GetDepth() != 1)
557 {
558 return FALSE;
559 }
560 m_maskBitmap = (WXHBITMAP) CreateBitmap(
561 bitmap.GetWidth(),
562 bitmap.GetHeight(),
563 1, 1, 0
564 );
565 HDC srcDC = CreateCompatibleDC(0);
566 SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
567 HDC destDC = CreateCompatibleDC(0);
568 SelectObject(destDC, (HBITMAP) m_maskBitmap);
569 BitBlt(destDC, 0, 0, bitmap.GetWidth(), bitmap.GetHeight(), srcDC, 0, 0, SRCCOPY);
570 SelectObject(srcDC, 0);
571 DeleteDC(srcDC);
572 SelectObject(destDC, 0);
573 DeleteDC(destDC);
574 return TRUE;
575 }
576
577 // Create a mask from a bitmap and a palette index indicating
578 // the transparent area
579 bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
580 {
581 if ( m_maskBitmap )
582 {
583 ::DeleteObject((HBITMAP) m_maskBitmap);
584 m_maskBitmap = 0;
585 }
586 if (bitmap.Ok() && bitmap.GetPalette()->Ok())
587 {
588 unsigned char red, green, blue;
589 if (bitmap.GetPalette()->GetRGB(paletteIndex, &red, &green, &blue))
590 {
591 wxColour transparentColour(red, green, blue);
592 return Create(bitmap, transparentColour);
593 }
594 }
595 return FALSE;
596 }
597
598 // Create a mask from a bitmap and a colour indicating
599 // the transparent area
600 bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
601 {
602 if ( m_maskBitmap )
603 {
604 ::DeleteObject((HBITMAP) m_maskBitmap);
605 m_maskBitmap = 0;
606 }
607 if (!bitmap.Ok())
608 {
609 return FALSE;
610 }
611
612 // scan the bitmap for the transparent colour and set
613 // the corresponding pixels in the mask to BLACK and
614 // the rest to WHITE
615 COLORREF maskColour = RGB(colour.Red(), colour.Green(), colour.Blue());
616 m_maskBitmap = (WXHBITMAP) ::CreateBitmap(
617 bitmap.GetWidth(),
618 bitmap.GetHeight(),
619 1, 1, 0
620 );
621 HDC srcDC = ::CreateCompatibleDC(0);
622 ::SelectObject(srcDC, (HBITMAP) bitmap.GetHBITMAP());
623 HDC destDC = ::CreateCompatibleDC(0);
624 ::SelectObject(destDC, (HBITMAP) m_maskBitmap);
625
626 // this is not very efficient, but I can't think
627 // of a better way of doing it
628 for (int w = 0; w < bitmap.GetWidth(); w++)
629 {
630 for (int h = 0; h < bitmap.GetHeight(); h++)
631 {
632 COLORREF col = GetPixel(srcDC, w, h);
633 if (col == maskColour)
634 {
635 ::SetPixel(destDC, w, h, RGB(0, 0, 0));
636 }
637 else
638 {
639 ::SetPixel(destDC, w, h, RGB(255, 255, 255));
640 }
641 }
642 }
643 ::SelectObject(srcDC, 0);
644 ::DeleteDC(srcDC);
645 ::SelectObject(destDC, 0);
646 ::DeleteDC(destDC);
647 return TRUE;
648 }
649
650 // ----------------------------------------------------------------------------
651 // wxBitmapHandler
652 // ----------------------------------------------------------------------------
653
654 bool wxBitmapHandler::Create(wxGDIImage *image,
655 void *data,
656 long flags,
657 int width, int height, int depth)
658 {
659 wxBitmap *bitmap = wxDynamicCast(image, wxBitmap);
660
661 return bitmap ? Create(bitmap, data, width, height, depth) : FALSE;
662 }
663
664 bool wxBitmapHandler::Load(wxGDIImage *image,
665 const wxString& name,
666 long flags,
667 int width, int height)
668 {
669 wxBitmap *bitmap = wxDynamicCast(image, wxBitmap);
670
671 return bitmap ? LoadFile(bitmap, name, flags, width, height) : FALSE;
672 }
673
674 bool wxBitmapHandler::Save(wxGDIImage *image,
675 const wxString& name,
676 int type)
677 {
678 wxBitmap *bitmap = wxDynamicCast(image, wxBitmap);
679
680 return bitmap ? SaveFile(bitmap, name, type) : FALSE;
681 }
682
683 bool wxBitmapHandler::Create(wxBitmap *WXUNUSED(bitmap),
684 void *WXUNUSED(data),
685 long WXUNUSED(type),
686 int WXUNUSED(width),
687 int WXUNUSED(height),
688 int WXUNUSED(depth))
689 {
690 return FALSE;
691 }
692
693 bool wxBitmapHandler::LoadFile(wxBitmap *WXUNUSED(bitmap),
694 const wxString& WXUNUSED(name),
695 long WXUNUSED(type),
696 int WXUNUSED(desiredWidth),
697 int WXUNUSED(desiredHeight))
698 {
699 return FALSE;
700 }
701
702 bool wxBitmapHandler::SaveFile(wxBitmap *WXUNUSED(bitmap),
703 const wxString& WXUNUSED(name),
704 int WXUNUSED(type),
705 const wxPalette *WXUNUSED(palette))
706 {
707 return FALSE;
708 }
709
710 // ----------------------------------------------------------------------------
711 // DIB functions
712 // ----------------------------------------------------------------------------
713
714 bool wxCreateDIB(long xSize, long ySize, long bitsPerPixel,
715 HPALETTE hPal, LPBITMAPINFO* lpDIBHeader)
716 {
717 unsigned long i, headerSize;
718 LPBITMAPINFO lpDIBheader = NULL;
719 LPPALETTEENTRY lpPe = NULL;
720
721
722 // Allocate space for a DIB header
723 headerSize = (sizeof(BITMAPINFOHEADER) + (256 * sizeof(PALETTEENTRY)));
724 lpDIBheader = (BITMAPINFO *) malloc(headerSize);
725 lpPe = (PALETTEENTRY *)((BYTE*)lpDIBheader + sizeof(BITMAPINFOHEADER));
726
727 GetPaletteEntries(hPal, 0, 256, lpPe);
728
729 memset(lpDIBheader, 0x00, sizeof(BITMAPINFOHEADER));
730
731 // Fill in the static parts of the DIB header
732 lpDIBheader->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
733 lpDIBheader->bmiHeader.biWidth = xSize;
734 lpDIBheader->bmiHeader.biHeight = ySize;
735 lpDIBheader->bmiHeader.biPlanes = 1;
736
737 // this value must be 1, 4, 8 or 24 so PixelDepth can only be
738 lpDIBheader->bmiHeader.biBitCount = (WORD)(bitsPerPixel);
739 lpDIBheader->bmiHeader.biCompression = BI_RGB;
740 lpDIBheader->bmiHeader.biSizeImage = xSize * abs(ySize) * bitsPerPixel >> 3;
741 lpDIBheader->bmiHeader.biClrUsed = 256;
742
743
744 // Initialize the DIB palette
745 for (i = 0; i < 256; i++) {
746 lpDIBheader->bmiColors[i].rgbReserved = lpPe[i].peFlags;
747 lpDIBheader->bmiColors[i].rgbRed = lpPe[i].peRed;
748 lpDIBheader->bmiColors[i].rgbGreen = lpPe[i].peGreen;
749 lpDIBheader->bmiColors[i].rgbBlue = lpPe[i].peBlue;
750 }
751
752 *lpDIBHeader = lpDIBheader;
753
754 return TRUE;
755 }
756
757 void wxFreeDIB(LPBITMAPINFO lpDIBHeader)
758 {
759 free(lpDIBHeader);
760 }
761
762