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