]> git.saurik.com Git - wxWidgets.git/blame - src/msw/dibutils.cpp
Only send two EVT_BUTTON events when double clicking a button, not three
[wxWidgets.git] / src / msw / dibutils.cpp
CommitLineData
2bda0e17
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: dibutils.cpp
3// Purpose: Utilities for DIBs
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
8// Copyright: (c) Microsoft, Julian Smart and Markus Holzem
3f4a0c5b 9// Licence: wxWindows license
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "dibutils.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
2bda0e17
KB
24#include "wx/setup.h"
25#include "wx/defs.h"
2662e49e 26#include "wx/string.h"
2bda0e17
KB
27#endif
28
29#include <windows.h>
30#include <windowsx.h>
31#include <stdio.h>
3f4a0c5b
VZ
32
33#include "wx/msw/dibutils.h"
2bda0e17
KB
34
35#if defined(__WIN32__)
ce3ed50d 36#if !defined(__MWERKS__) && !defined(__SALFORDC__)
2bda0e17 37 #include <memory.h> // for _fmemcpy()
17dff81c 38#endif
3f4a0c5b 39 #define _huge
2bda0e17
KB
40#ifndef hmemcpy
41 #define hmemcpy memcpy
42#endif
43#endif
44
45#define BFT_ICON 0x4349 /* 'IC' */
46#define BFT_BITMAP 0x4d42 /* 'BM' */
e90c1d2a 47#define BFT_CURSOR 0x5450 /* 'PT(' */
2bda0e17 48
2662e49e 49#ifndef SEEK_CUR
2bda0e17
KB
50/* flags for _lseek */
51#define SEEK_CUR 1
52#define SEEK_END 2
53#define SEEK_SET 0
2662e49e
RR
54#endif
55
56/* Copied from PNGhandler for coompilation with MingW32, RR */
57
58#ifndef GlobalAllocPtr
59#define GlobalPtrHandle(lp) \
60 ((HGLOBAL)GlobalHandle(lp))
61
62#define GlobalLockPtr(lp) \
63 ((BOOL)GlobalLock(GlobalPtrHandle(lp)))
64#define GlobalUnlockPtr(lp) \
65 GlobalUnlock(GlobalPtrHandle(lp))
66
67#define GlobalAllocPtr(flags, cb) \
68 (GlobalLock(GlobalAlloc((flags), (cb))))
69#define GlobalReAllocPtr(lp, cbNew, flags) \
70 (GlobalUnlockPtr(lp), GlobalLock(GlobalReAlloc(GlobalPtrHandle(lp) , (cbNew), (flags))))
71#define GlobalFreePtr(lp) \
72 (GlobalUnlockPtr(lp), (BOOL)GlobalFree(GlobalPtrHandle(lp)))
73#endif
2bda0e17
KB
74
75
76/*
a0c3c734 77 * Clear the System Palette so that we can ensure an identity palette
2bda0e17
KB
78 * mapping for fast performance.
79 */
80
ef3ab009 81void wxClearSystemPalette(void)
2bda0e17
KB
82{
83 //*** A dummy palette setup
84 struct
85 {
86 WORD Version;
87 WORD NumberOfEntries;
88 PALETTEENTRY aEntries[256];
89 } Palette =
90 {
91 0x300,
92 256
93 };
94
95 HPALETTE ScreenPalette = 0;
96 HDC ScreenDC;
97 int Counter;
98 UINT nMapped = 0;
99 BOOL bOK = FALSE;
100 int nOK = 0;
a0c3c734 101
c455ab93 102 // *** Reset everything in the system palette to black
2bda0e17
KB
103 for(Counter = 0; Counter < 256; Counter++)
104 {
105 Palette.aEntries[Counter].peRed = 0;
3f4a0c5b 106 Palette.aEntries[Counter].peGreen = 0;
2bda0e17
KB
107 Palette.aEntries[Counter].peBlue = 0;
108 Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
109 }
110
c455ab93 111 // *** Create, select, realize, deselect, and delete the palette
2bda0e17
KB
112 ScreenDC = GetDC(NULL);
113 ScreenPalette = CreatePalette((LOGPALETTE *)&Palette);
114
115 if (ScreenPalette)
116 {
3f4a0c5b
VZ
117 ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
118 nMapped = RealizePalette(ScreenDC);
2bda0e17
KB
119 ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
120 bOK = DeleteObject(ScreenPalette);
121 }
122
123 nOK = ReleaseDC(NULL, ScreenDC);
124
125 return;
126}
127
128
129/*
130 * Open a DIB file and return a MEMORY DIB, a memory handle containing..
131 *
132 * BITMAP INFO bi
133 * palette data
134 * bits....
135 */
136
ef3ab009 137int wxDibWriteFile(LPTSTR szFile, LPBITMAPINFOHEADER lpbi)
2bda0e17 138{
3f4a0c5b
VZ
139 HFILE fh;
140 OFSTRUCT of;
2bda0e17 141
837e5743 142 fh = OpenFile(wxConvFile.cWX2MB(szFile), &of, OF_WRITE | OF_CREATE);
2bda0e17
KB
143
144 if (!fh) {
3f4a0c5b
VZ
145// printf("la regamos0");
146 return 0;
2bda0e17
KB
147 }
148
ef3ab009 149 long size = wxDibSize(lpbi);
2bda0e17
KB
150
151 // write file header
152 BITMAPFILEHEADER bmf;
a0c3c734 153 bmf.bfType = BFT_BITMAP;
2bda0e17
KB
154 bmf.bfSize = sizeof(bmf) + size;
155 bmf.bfReserved1 = 0;
156 bmf.bfReserved2 = 0;
ef3ab009 157 bmf.bfOffBits = sizeof(bmf) + (char FAR*)(wxDibPtr(lpbi)) - (char FAR*)lpbi;
b64f0a5f 158#if 1 // defined( __WATCOMC__) || defined(__VISUALC__) || defined(__SC__) || defined(__SALFORDC__) || defined(__MWERKS__) || wxUSE_NORLANDER_HEADERS
a0c3c734
VZ
159 #define HWRITE_2ND_ARG_TYPE LPCSTR
160#else // don't know who needs this...
161 #define HWRITE_2ND_ARG_TYPE LPBYTE
162#endif
163
164 if ( _hwrite(fh, (HWRITE_2ND_ARG_TYPE)(&bmf), sizeof(bmf)) < 0 ||
165 _hwrite(fh, (HWRITE_2ND_ARG_TYPE)lpbi, size) < 0 )
166 {
3f4a0c5b 167 _lclose(fh);
3f4a0c5b 168 return 0;
2bda0e17 169 }
a0c3c734
VZ
170
171#undef HWRITE_2ND_ARG_TYPE
2bda0e17
KB
172
173 _lclose(fh);
174 return 1;
175}
176
ef3ab009 177PDIB wxDibOpenFile(LPTSTR szFile)
2bda0e17 178{
3f4a0c5b
VZ
179 HFILE fh;
180 DWORD dwLen;
181 DWORD dwBits;
182 PDIB pdib;
183 LPVOID p;
184 OFSTRUCT of;
2bda0e17 185
d66dcb60 186#if defined(__WIN32__)
3f4a0c5b 187 #define GetCurrentInstance() GetModuleHandle(NULL)
2bda0e17 188#else
3f4a0c5b 189 #define GetCurrentInstance() (HINSTANCE)SELECTOROF((LPVOID)&of)
2bda0e17
KB
190#endif
191
837e5743 192 fh = OpenFile(wxConvFile.cWX2MB(szFile), &of, OF_READ);
2bda0e17 193
3f4a0c5b
VZ
194 if (fh == -1)
195 {
196 HRSRC h;
2bda0e17
KB
197
198 // TODO: Unicode version
62448488 199#ifdef __WIN16__
3f4a0c5b 200 h = FindResource(GetCurrentInstance(), szFile, RT_BITMAP);
837e5743
OK
201#elif wxUSE_UNICODE
202 h = FindResourceW(GetCurrentInstance(), szFile, RT_BITMAP);
62448488 203#else
3f4a0c5b 204 h = FindResourceA(GetCurrentInstance(), szFile, RT_BITMAP);
62448488 205#endif
2bda0e17 206
62448488 207#if defined(__WIN32__)
3f4a0c5b
VZ
208 //!!! can we call GlobalFree() on this? is it the right format.
209 //!!! can we write to this resource?
210 if (h)
211 return (PDIB)LockResource(LoadResource(GetCurrentInstance(), h));
2bda0e17 212#else
3f4a0c5b
VZ
213 if (h)
214 fh = AccessResource(GetCurrentInstance(), h);
2bda0e17 215#endif
3f4a0c5b 216 }
2bda0e17 217
3f4a0c5b
VZ
218 if (fh == -1)
219 return NULL;
2bda0e17 220
ef3ab009 221 pdib = wxDibReadBitmapInfo(fh);
2bda0e17 222
3f4a0c5b
VZ
223 if (!pdib)
224 return NULL;
2bda0e17
KB
225
226 /* How much memory do we need to hold the DIB */
227
228 dwBits = pdib->biSizeImage;
ef3ab009 229 dwLen = pdib->biSize + wxDibPaletteSize(pdib) + dwBits;
2bda0e17
KB
230
231 /* Can we get more memory? */
232
3f4a0c5b 233 p = GlobalReAllocPtr(pdib,dwLen,0);
2bda0e17
KB
234
235 if (!p)
236 {
3f4a0c5b 237 GlobalFreePtr(pdib);
2bda0e17
KB
238 pdib = NULL;
239 }
240 else
241 {
242 pdib = (PDIB)p;
243 }
244
245 if (pdib)
246 {
3f4a0c5b 247 /* read in the bits */
ef3ab009 248 _hread(fh, (LPBYTE)pdib + (UINT)pdib->biSize + wxDibPaletteSize(pdib), dwBits);
2bda0e17
KB
249 }
250
251 _lclose(fh);
252
253 return pdib;
254}
255
256
257/*
258 * ReadDibBitmapInfo()
259 *
260 * Will read a file in DIB format and return a global HANDLE to its
261 * BITMAPINFO. This function will work with both "old" and "new"
262 * bitmap formats, but will always return a "new" BITMAPINFO.
263 */
264
ef3ab009 265PDIB wxDibReadBitmapInfo(HFILE fh)
2bda0e17
KB
266{
267 DWORD off;
2bda0e17
KB
268 int size;
269 int i;
270 int nNumColors;
271
272 RGBQUAD FAR *pRgb;
273 BITMAPINFOHEADER bi;
274 BITMAPCOREHEADER bc;
275 BITMAPFILEHEADER bf;
276 PDIB pdib;
277
278 if (fh == -1)
279 return NULL;
280
281 off = _llseek(fh,0L,SEEK_CUR);
282
283 if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf)))
f7f50f49 284 return NULL;
2bda0e17
KB
285
286 /*
287 * do we have a RC HEADER?
288 */
289 if (bf.bfType != BFT_BITMAP)
290 {
291 bf.bfOffBits = 0L;
292 _llseek(fh,off,SEEK_SET);
293 }
294
295 if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi)))
6703082e 296 return NULL;
2bda0e17
KB
297
298 /*
299 * what type of bitmap info is this?
300 */
301 switch (size = (int)bi.biSize)
302 {
303 default:
304 case sizeof(BITMAPINFOHEADER):
305 break;
306
307 case sizeof(BITMAPCOREHEADER):
308 bc = *(BITMAPCOREHEADER*)&bi;
309 bi.biSize = sizeof(BITMAPINFOHEADER);
310 bi.biWidth = (DWORD)bc.bcWidth;
311 bi.biHeight = (DWORD)bc.bcHeight;
33ac7e6f
KB
312 bi.biPlanes = (WORD)bc.bcPlanes;
313 bi.biBitCount = (WORD)bc.bcBitCount;
2bda0e17
KB
314 bi.biCompression = BI_RGB;
315 bi.biSizeImage = 0;
316 bi.biXPelsPerMeter = 0;
317 bi.biYPelsPerMeter = 0;
318 bi.biClrUsed = 0;
319 bi.biClrImportant = 0;
320
321 _llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
322
323 break;
324 }
325
ef3ab009 326 nNumColors = wxDibNumColors(&bi);
2bda0e17
KB
327
328#if 0
329 if (bi.biSizeImage == 0)
330 bi.biSizeImage = DibSizeImage(&bi);
331
332 if (bi.biClrUsed == 0)
ef3ab009 333 bi.biClrUsed = wxDibNumColors(&bi);
2bda0e17 334#else
ef3ab009 335 wxFixBitmapInfo(&bi);
2bda0e17
KB
336#endif
337
338 pdib = (PDIB)GlobalAllocPtr(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
339
340 if (!pdib)
341 return NULL;
342
343 *pdib = bi;
344
ef3ab009 345 pRgb = wxDibColors(pdib);
2bda0e17
KB
346
347 if (nNumColors)
348 {
349 if (size == sizeof(BITMAPCOREHEADER))
350 {
351 /*
352 * convert a old color table (3 byte entries) to a new
353 * color table (4 byte entries)
354 */
355 _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
356
357 for (i=nNumColors-1; i>=0; i--)
358 {
359 RGBQUAD rgb;
360
361 rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
362 rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
363 rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
364 rgb.rgbReserved = (BYTE)0;
365
366 pRgb[i] = rgb;
367 }
368 }
369 else
370 {
371 _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
372 }
373 }
374
375 if (bf.bfOffBits != 0L)
376 _llseek(fh,off + bf.bfOffBits,SEEK_SET);
377
378 return pdib;
379}
380
381/*
382 * DibSetUsage(hdib,hpal,wUsage)
383 *
384 * Modifies the color table of the passed DIB for use with the wUsage
385 * parameter specifed.
386 *
387 * if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256
388 * if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values
389 * in the passed palette
390 */
391
ef3ab009 392BOOL wxDibSetUsage(PDIB pdib, HPALETTE hpal,UINT wUsage)
2bda0e17
KB
393{
394 PALETTEENTRY ape[256];
395 RGBQUAD FAR * pRgb;
396 WORD FAR * pw;
397 int nColors;
398 int n;
399
400 if (hpal == NULL)
401 hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
402
403 if (!pdib)
404 return FALSE;
405
ef3ab009 406 nColors = wxDibNumColors(pdib);
a0c3c734 407
ef3ab009 408 if (nColors == 3 && wxDibCompression(pdib) == BI_BITFIELDS)
2bda0e17
KB
409 nColors = 0;
410
411 if (nColors > 0)
412 {
ef3ab009 413 pRgb = wxDibColors(pdib);
2bda0e17
KB
414
415 switch (wUsage)
416 {
417 //
418 // Set the DIB color table to palette indexes
419 //
420 case DIB_PAL_COLORS:
421 for (pw = (WORD FAR*)pRgb,n=0; n<nColors; n++,pw++)
422 *pw = n;
423 break;
424
425 //
426 // Set the DIB color table to RGBQUADS
427 //
428 default:
429 case DIB_RGB_COLORS:
430 nColors = (nColors < 256) ? nColors: 256;
431
432 GetPaletteEntries(hpal,0,nColors,ape);
433
434 for (n=0; n<nColors; n++)
435 {
436 pRgb[n].rgbRed = ape[n].peRed;
437 pRgb[n].rgbGreen = ape[n].peGreen;
438 pRgb[n].rgbBlue = ape[n].peBlue;
439 pRgb[n].rgbReserved = 0;
440 }
441 break;
442 }
443 }
444 return TRUE;
445}
446
447/*
448 * DibCreate(bits, dx, dy)
449 *
450 * Creates a new packed DIB with the given dimensions and the
451 * given number of bits per pixel
452 */
453
ef3ab009 454PDIB wxDibCreate(int bits, int dx, int dy)
2bda0e17
KB
455{
456 LPBITMAPINFOHEADER lpbi ;
457 DWORD dwSizeImage;
458 int i;
459 DWORD FAR *pdw;
460
461 dwSizeImage = dy*(DWORD)((dx*bits/8+3)&~3);
462
463 lpbi = (PDIB)GlobalAllocPtr(GHND,sizeof(BITMAPINFOHEADER)+dwSizeImage + 1024);
464
465 if (lpbi == NULL)
466 return NULL;
467
468 lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
469 lpbi->biWidth = dx;
470 lpbi->biHeight = dy;
471 lpbi->biPlanes = 1;
472 lpbi->biBitCount = bits ;
473 lpbi->biCompression = BI_RGB ;
474 lpbi->biSizeImage = dwSizeImage;
475 lpbi->biXPelsPerMeter = 0 ;
476 lpbi->biYPelsPerMeter = 0 ;
477 lpbi->biClrUsed = 0 ;
478 lpbi->biClrImportant = 0 ;
479
480 if (bits == 4)
481 lpbi->biClrUsed = 16;
482
483 else if (bits == 8)
484 lpbi->biClrUsed = 256;
485
486 pdw = (DWORD FAR *)((LPBYTE)lpbi+(int)lpbi->biSize);
487
488 for (i=0; i<(int)lpbi->biClrUsed/16; i++)
489 {
490 *pdw++ = 0x00000000; // 0000 black
491 *pdw++ = 0x00800000; // 0001 dark red
492 *pdw++ = 0x00008000; // 0010 dark green
3f4a0c5b 493 *pdw++ = 0x00808000; // 0011 mustard
2bda0e17
KB
494 *pdw++ = 0x00000080; // 0100 dark blue
495 *pdw++ = 0x00800080; // 0101 purple
496 *pdw++ = 0x00008080; // 0110 dark turquoise
497 *pdw++ = 0x00C0C0C0; // 1000 gray
498 *pdw++ = 0x00808080; // 0111 dark gray
499 *pdw++ = 0x00FF0000; // 1001 red
500 *pdw++ = 0x0000FF00; // 1010 green
3f4a0c5b 501 *pdw++ = 0x00FFFF00; // 1011 yellow
2bda0e17
KB
502 *pdw++ = 0x000000FF; // 1100 blue
503 *pdw++ = 0x00FF00FF; // 1101 pink (magenta)
504 *pdw++ = 0x0000FFFF; // 1110 cyan
505 *pdw++ = 0x00FFFFFF; // 1111 white
506 }
507
508 return (PDIB)lpbi;
509}
510
511static void xlatClut8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
512{
513 DWORD dw;
514
515#ifdef __cplusplus
516 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
517#else
518 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
519#endif
520 *pb = xlat[*pb];
521}
522
523static void xlatClut4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
524{
525 DWORD dw;
526
527#ifdef __cplusplus
528 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
529#else
530 for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
531#endif
532 *pb = (BYTE)(xlat[*pb & 0x0F] | (xlat[(*pb >> 4) & 0x0F] << 4));
533}
534
535#define RLE_ESCAPE 0
536#define RLE_EOL 0
537#define RLE_EOF 1
538#define RLE_JMP 2
539
33ac7e6f 540static void xlatRle8(BYTE FAR *pb, DWORD WXUNUSED(dwSize), BYTE FAR *xlat)
2bda0e17
KB
541{
542 BYTE cnt;
543 BYTE b;
544 BYTE _huge *prle = pb;
545
546 for(;;)
547 {
548 cnt = *prle++;
549 b = *prle;
550
551 if (cnt == RLE_ESCAPE)
552 {
553 prle++;
554
555 switch (b)
556 {
557 case RLE_EOF:
558 return;
559
560 case RLE_EOL:
561 break;
562
563 case RLE_JMP:
564 prle++; // skip dX
565 prle++; // skip dY
566 break;
567
568 default:
569 cnt = b;
570 for (b=0; b<cnt; b++,prle++)
571 *prle = xlat[*prle];
572
573 if (cnt & 1)
574 prle++;
575
576 break;
577 }
578 }
579 else
580 {
581 *prle++ = xlat[b];
582 }
583 }
584}
585
33ac7e6f 586static void xlatRle4(BYTE FAR *WXUNUSED(pb), DWORD WXUNUSED(dwSize), BYTE FAR *WXUNUSED(xlat))
2bda0e17
KB
587{
588}
589
590static void hmemmove(BYTE _huge *d, BYTE _huge *s, LONG len)
591{
592 d += len-1;
593 s += len-1;
594
595 while (len--)
596 *d-- = *s--;
597}
598
599/*
600 * DibMapToPalette(pdib, hpal)
601 *
602 * Map the colors of the DIB, using GetNearestPaletteIndex, to
603 * the colors of the given palette.
604 */
605
ef3ab009 606BOOL wxDibMapToPalette(PDIB pdib, HPALETTE hpal)
2bda0e17 607{
3f4a0c5b
VZ
608 LPBITMAPINFOHEADER lpbi;
609 PALETTEENTRY pe;
610 int n;
611 int nDibColors;
612 int nPalColors=0;
613 BYTE FAR * lpBits;
614 RGBQUAD FAR * lpRgb;
615 BYTE xlat[256];
616 DWORD SizeImage;
617
618 if (!hpal || !pdib)
619 return FALSE;
620
621 lpbi = (LPBITMAPINFOHEADER)pdib;
ef3ab009 622 lpRgb = wxDibColors(pdib);
3f4a0c5b
VZ
623
624 GetObject(hpal,sizeof(int),(LPSTR)&nPalColors);
ef3ab009 625 nDibColors = wxDibNumColors(pdib);
3f4a0c5b
VZ
626
627 if ((SizeImage = lpbi->biSizeImage) == 0)
ef3ab009 628 SizeImage = wxDibSizeImage(lpbi);
3f4a0c5b
VZ
629
630 //
631 // build a xlat table. from the current DIB colors to the given
632 // palette.
633 //
634 for (n=0; n<nDibColors; n++)
635 xlat[n] = (BYTE)GetNearestPaletteIndex(hpal,RGB(lpRgb[n].rgbRed,lpRgb[n].rgbGreen,lpRgb[n].rgbBlue));
636
ef3ab009 637 lpBits = (LPBYTE)wxDibPtr(lpbi);
3f4a0c5b
VZ
638 lpbi->biClrUsed = nPalColors;
639
640 //
641 // re-size the DIB
642 //
643 if (nPalColors > nDibColors)
644 {
645 GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
ef3ab009
UJ
646 hmemmove((BYTE _huge *)wxDibPtr(lpbi), (BYTE _huge *)lpBits, SizeImage);
647 lpBits = (LPBYTE)wxDibPtr(lpbi);
3f4a0c5b
VZ
648 }
649 else if (nPalColors < nDibColors)
650 {
ef3ab009 651 hmemcpy(wxDibPtr(lpbi), lpBits, SizeImage);
3f4a0c5b 652 GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
ef3ab009 653 lpBits = (LPBYTE)wxDibPtr(lpbi);
3f4a0c5b
VZ
654 }
655
656 //
657 // translate the DIB bits
658 //
659 switch (lpbi->biCompression)
660 {
661 case BI_RLE8:
662 xlatRle8(lpBits, SizeImage, xlat);
663 break;
664
665 case BI_RLE4:
666 xlatRle4(lpBits, SizeImage, xlat);
667 break;
2bda0e17
KB
668
669 case BI_RGB:
3f4a0c5b 670 if (lpbi->biBitCount == 8)
2bda0e17
KB
671 xlatClut8(lpBits, SizeImage, xlat);
672 else
673 xlatClut4(lpBits, SizeImage, xlat);
674 break;
675 }
676
677 //
678 // Now copy the RGBs in the logical palette to the dib color table
679 //
680 for (n=0; n<nPalColors; n++)
681 {
682 GetPaletteEntries(hpal,n,1,&pe);
683
684 lpRgb[n].rgbRed = pe.peRed;
3f4a0c5b
VZ
685 lpRgb[n].rgbGreen = pe.peGreen;
686 lpRgb[n].rgbBlue = pe.peBlue;
687 lpRgb[n].rgbReserved = (BYTE)0;
688 }
2bda0e17 689
3f4a0c5b 690 return TRUE;
2bda0e17
KB
691}
692
693
ef3ab009 694HPALETTE wxMakePalette(const BITMAPINFO FAR* Info, UINT flags)
2bda0e17
KB
695{
696 HPALETTE hPalette;
2662e49e 697 const RGBQUAD FAR* rgb = Info->bmiColors;
2bda0e17 698
33ac7e6f 699 WORD nColors = (WORD)Info->bmiHeader.biClrUsed;
2bda0e17 700 if (nColors) {
3f4a0c5b
VZ
701 LOGPALETTE* logPal = (LOGPALETTE*)
702 new BYTE[sizeof(LOGPALETTE) + (nColors-1)*sizeof(PALETTEENTRY)];
703
704 logPal->palVersion = 0x300; // Windows 3.0 version
705 logPal->palNumEntries = nColors;
48c12cb1 706 for (WORD n = 0; n < nColors; n++) {
3f4a0c5b
VZ
707 logPal->palPalEntry[n].peRed = rgb[n].rgbRed;
708 logPal->palPalEntry[n].peGreen = rgb[n].rgbGreen;
709 logPal->palPalEntry[n].peBlue = rgb[n].rgbBlue;
710 logPal->palPalEntry[n].peFlags = (BYTE)flags;
711 }
712 hPalette = ::CreatePalette(logPal);
713 delete logPal;
2bda0e17 714 } else
3f4a0c5b 715 hPalette = 0;
2bda0e17
KB
716
717 return hPalette;
718}
719