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