source: trunk/src/gdi32/dibitmap.cpp@ 9359

Last change on this file since 9359 was 9359, checked in by sandervl, 23 years ago

Workaround added for WGSS GetDIBits bug

File size: 21.8 KB
Line 
1/* $Id: dibitmap.cpp,v 1.34 2002-10-28 13:24:44 sandervl Exp $ */
2
3/*
4 * GDI32 dib & bitmap code
5 *
6 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
7 * Copyright 1998 Patrick Haller
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <stdlib.h>
14#include <stdarg.h>
15#include <string.h>
16#include <misc.h>
17#include <cpuhlp.h>
18#include <winuser32.h>
19#include "dibsect.h"
20#include "rgbcvt.h"
21#include <stats.h>
22#include "oslibgpi.h"
23#include <objhandle.h>
24
25#define DBG_LOCALLOG DBG_dibitmap
26#include "dbglocal.h"
27
28ULONG CalcBitmapSize(ULONG cBits, LONG cx, LONG cy);
29
30//******************************************************************************
31//******************************************************************************
32HBITMAP WIN32API CreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *lpbmih,
33 DWORD fdwInit, const void *lpbInit,
34 const BITMAPINFO *lpbmi, UINT fuUsage)
35{
36 int iHeight;
37 HBITMAP rc;
38 DWORD bitfields[3];
39 WORD *newbits = NULL;
40
41 //SvL: Completely wrong result when creating a 1bpp bitmap here (converted
42 // to 8bpp by Open32)
43 if(lpbmih->biBitCount == 1) {
44 dprintf(("WARNING: CreateDIBitmap doesn't handle 1bpp bitmaps very well!!!!!"));
45 }
46
47 //TEMPORARY HACK TO PREVENT CRASH IN OPEN32 (WSeB GA)
48 iHeight = lpbmih->biHeight;
49 if(lpbmih->biHeight < 0)
50 {
51 dprintf(("GDI32: CreateDIBitmap negative height! (%d,%d)", lpbmih->biWidth, lpbmih->biHeight));
52 //TODO: doesn't work if memory is readonly!!
53 ((BITMAPINFOHEADER *)lpbmih)->biHeight = -lpbmih->biHeight;
54
55 if(lpbInit && fdwInit == CBM_INIT) {
56 // upside down
57 HBITMAP rc = 0;
58 long lLineByte = DIB_GetDIBWidthBytes(lpbmih->biWidth, lpbmih->biBitCount);
59 long lHeight = lpbmih->biHeight;
60
61 newbits = (WORD *)malloc( lLineByte * lHeight );
62 if(newbits) {
63 unsigned char *pbSrc = (unsigned char *)lpbInit + lLineByte * (lHeight - 1);
64 unsigned char *pbDst = (unsigned char *)newbits;
65 for(int y = 0; y < lHeight; y++) {
66 memcpy( pbDst, pbSrc, lLineByte );
67 pbDst += lLineByte;
68 pbSrc -= lLineByte;
69 }
70 rc = CreateDIBitmap(hdc, lpbmih, fdwInit, newbits, lpbmi, fuUsage);
71 free( newbits );
72 }
73
74 ((BITMAPINFOHEADER *)lpbmih)->biHeight = iHeight;
75 return rc;
76 }
77 }
78
79 // 2000/09/01 PH Netscape 4.7
80 // If color depth of lpbhmi is 16 bit and lpbmi is 8 bit,
81 // Open32 will crash since it won't allocate any palette color memory,
82 // however wants to copy it later on ...
83 int biBitCount = lpbmih->biBitCount;
84
85 if (lpbmih->biBitCount != lpbmi->bmiHeader.biBitCount)
86 {
87 dprintf(("GDI32: CreateDIBitmap: color depths of bitmaps differ! (%d,%d\n", lpbmih->biBitCount,
88 lpbmi->bmiHeader.biBitCount));
89
90 ((BITMAPINFOHEADER *)lpbmih)->biBitCount = lpbmi->bmiHeader.biBitCount;
91 }
92
93 switch(lpbmih->biBitCount) {
94 case 15:
95 case 16: //Default if BI_BITFIELDS not set is RGB 555
96 bitfields[0] = (lpbmih->biCompression == BI_BITFIELDS) ? *(DWORD *)lpbmi->bmiColors : DEFAULT_16BPP_RED_MASK;
97 bitfields[1] = (lpbmih->biCompression == BI_BITFIELDS) ? *((DWORD *)lpbmi->bmiColors + 1) : DEFAULT_16BPP_GREEN_MASK;
98 bitfields[2] = (lpbmih->biCompression == BI_BITFIELDS) ? *((DWORD *)lpbmi->bmiColors + 2) : DEFAULT_16BPP_BLUE_MASK;
99 break;
100 case 24:
101 case 32:
102 bitfields[0] = (lpbmih->biCompression == BI_BITFIELDS) ? *(DWORD *)lpbmi->bmiColors : DEFAULT_24BPP_RED_MASK;
103 bitfields[1] = (lpbmih->biCompression == BI_BITFIELDS) ? *((DWORD *)lpbmi->bmiColors + 1) : DEFAULT_24BPP_GREEN_MASK;
104 bitfields[2] = (lpbmih->biCompression == BI_BITFIELDS) ? *((DWORD *)lpbmi->bmiColors + 2) : DEFAULT_24BPP_BLUE_MASK;
105 break;
106 default:
107 bitfields[0] = 0;
108 bitfields[1] = 0;
109 bitfields[2] = 0;
110 break;
111 }
112 if(bitfields[1] == RGB555_GREEN_MASK && lpbInit && fdwInit == CBM_INIT)
113 {//RGB 555?
114 dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
115
116 int imgsize = CalcBitmapSize(lpbmih->biBitCount, lpbmih->biWidth, lpbmih->biHeight);
117
118 newbits = (WORD *)malloc(imgsize);
119 if(CPUFeatures & CPUID_MMX) {
120 RGB555to565MMX(newbits, (WORD *)lpbInit, imgsize/sizeof(WORD));
121 }
122 else RGB555to565(newbits, (WORD *)lpbInit, imgsize/sizeof(WORD));
123 lpbInit = newbits;
124 }
125
126 rc = O32_CreateDIBitmap(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
127
128 dprintf(("GDI32: CreateDIBitmap %x %x %x %x %x returned %x (%d,%d, bps %d)", hdc, lpbmih, fdwInit, lpbInit, fuUsage, rc, lpbmih->biWidth, lpbmih->biHeight, lpbmih->biBitCount));
129
130 if(newbits) free(newbits);
131
132 ((BITMAPINFOHEADER *)lpbmih)->biHeight = iHeight;
133 ((BITMAPINFOHEADER *)lpbmih)->biBitCount = biBitCount;
134
135 if(rc) {
136 STATS_CreateDIBitmap(rc, hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
137 if(bitfields[1] == RGB565_GREEN_MASK) {
138 //mark bitmap as RGB565
139 dprintf(("RGB565 bitmap"));
140 ObjSetHandleFlag(rc, OBJHANDLE_FLAG_BMP_RGB565, TRUE);
141 }
142 }
143
144 return rc;
145}
146//******************************************************************************
147//******************************************************************************
148HBITMAP WIN32API CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight)
149{
150 HBITMAP hBitmap;
151 pDCData pHps;
152
153 pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
154 if(!pHps)
155 {
156 SetLastError(ERROR_INVALID_HANDLE);
157 return 0;
158 }
159
160 hBitmap = O32_CreateCompatibleBitmap(hdc, nWidth, nHeight);
161 dprintf(("GDI32: CreateCompatibleBitmap %x (%d,%d) returned %x", hdc, nWidth, nHeight, hBitmap));
162 if(hBitmap) {
163 STATS_CreateCompatibleBitmap(hBitmap,hdc, nWidth, nHeight);
164 if(pHps->hwnd == 1) { //1 == HWND_DESKTOP
165 dprintf(("Screen compatible bitmap"));
166 ObjSetHandleFlag(hBitmap, OBJHANDLE_FLAG_BMP_SCREEN_COMPATIBLE, 1);
167 }
168 }
169
170 return hBitmap;
171}
172//******************************************************************************
173//CreateDisardableBitmap is obsolete and can be replaced by CreateCompatibleBitmap
174//******************************************************************************
175HBITMAP WIN32API CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
176{
177 dprintf(("GDI32: CreateDisardableBitmap"));
178 return CreateCompatibleBitmap(hDC, nWidth, nHeight);
179}
180//******************************************************************************
181//******************************************************************************
182HBITMAP WIN32API CreateBitmap(int nWidth, int nHeight, UINT cPlanes,
183 UINT cBitsPerPel, const void *lpvBits)
184{
185 HBITMAP hBitmap;
186
187 hBitmap = O32_CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, lpvBits);
188 dprintf(("GDI32: CreateBitmap (%d,%d) bps %d returned %x", nWidth, nHeight, cBitsPerPel, hBitmap));
189 if(hBitmap) STATS_CreateBitmap(hBitmap,nWidth, nHeight, cPlanes, cBitsPerPel, lpvBits);
190
191 return(hBitmap);
192}
193//******************************************************************************
194//******************************************************************************
195HBITMAP WIN32API CreateBitmapIndirect( const BITMAP *pBitmap)
196{
197 HBITMAP hBitmap;
198
199 dprintf(("GDI32: CreateBitmapIndirect (%d,%d) bpp %d bits %x", pBitmap->bmWidth, pBitmap->bmHeight, pBitmap->bmBitsPixel, pBitmap->bmBits));
200 hBitmap = O32_CreateBitmapIndirect(pBitmap);
201 if(hBitmap) STATS_CreateBitmapIndirect(hBitmap, pBitmap);
202
203 dprintf(("GDI32: CreateBitmapIndirect returned %x", hBitmap));
204 return hBitmap;
205}
206//******************************************************************************
207//*********************************************************************************
208HBITMAP WIN32API CreateDIBSection( HDC hdc, BITMAPINFO *pbmi, UINT iUsage,
209 VOID **ppvBits, HANDLE hSection, DWORD dwOffset)
210{
211 HBITMAP res = 0;
212 BOOL fFlip = 0;
213 int iHeight, iWidth;
214 BOOL fCreateDC = FALSE;
215
216 dprintf(("GDI32: CreateDIBSection %x %x %x %x %x %d", hdc, pbmi, iUsage, ppvBits, hSection, dwOffset));
217
218 //SvL: 13-9-98: StarCraft uses bitmap with negative height
219 iWidth = pbmi->bmiHeader.biWidth;
220 if(pbmi->bmiHeader.biWidth < 0)
221 {
222 dprintf(("CreateDIBSection: width %d", pbmi->bmiHeader.biWidth));
223 pbmi->bmiHeader.biWidth = -pbmi->bmiHeader.biWidth;
224 fFlip = FLIP_HOR;
225 }
226 iHeight = pbmi->bmiHeader.biHeight;
227 if(pbmi->bmiHeader.biHeight < 0)
228 {
229 dprintf(("CreateDIBSection: height %d", pbmi->bmiHeader.biHeight));
230 pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
231 fFlip |= FLIP_VERT;
232 }
233
234 //SvL: RP7 (update) calls this api with hdc == 0
235 if(hdc == 0) {
236 hdc = CreateCompatibleDC(0);
237 fCreateDC = TRUE;
238 }
239 res = O32_CreateDIBitmap(hdc, &pbmi->bmiHeader, 0, NULL, pbmi, iUsage);
240 if (res)
241 {
242 char PalSize;
243 DIBSection *dsect;
244
245 dsect = new DIBSection((BITMAPINFOHEADER_W *)&pbmi->bmiHeader, (char *)&pbmi->bmiColors, iUsage, hSection, dwOffset, (DWORD)res, fFlip);
246
247 if(dsect != NULL)
248 {
249 PalSize = dsect->GetBitCount();
250 if(PalSize <= 8)
251 {
252 ULONG Pal[256], nrcolors;
253 LOGPALETTE tmpPal = { 0x300,1,{0,0,0,0}};
254 HPALETTE hpalCur, hpalTmp;
255
256 // Now get the current Palette from the DC
257 hpalTmp = CreatePalette(&tmpPal);
258 hpalCur = SelectPalette(hdc, hpalTmp, FALSE);
259
260 // and use it to set the DIBColorTable
261 nrcolors = GetPaletteEntries( hpalCur, 0, 1<<PalSize, (LPPALETTEENTRY)&Pal);
262 dsect->SetDIBColorTable(0, nrcolors, (LPPALETTEENTRY)&Pal);
263
264 // Restore the DC Palette
265 SelectPalette(hdc,hpalCur,FALSE);
266 DeleteObject(hpalTmp);
267 }
268
269 if(ppvBits!=NULL)
270 *ppvBits = dsect->GetDIBObject();
271
272 pbmi->bmiHeader.biWidth = iWidth;
273 pbmi->bmiHeader.biHeight = iHeight;
274
275 if(fCreateDC) DeleteDC(hdc);
276
277 STATS_CreateDIBSection(res, hdc, pbmi, iUsage, ppvBits, hSection, dwOffset);
278
279 return(res);
280 }
281 }
282 if(fCreateDC) DeleteDC(hdc);
283
284 /* Error. */
285 if (res)
286 DeleteObject(res);
287 *ppvBits = NULL;
288
289#ifdef DEBUG
290 dprintf(("GDI32: CreateDIBSection, error!\n"));
291 dprintf(("pbmi->biWidth %d", pbmi->bmiHeader.biWidth));
292 dprintf(("pbmi->biHeight %d", pbmi->bmiHeader.biHeight));
293 dprintf(("pbmi->biBitCount %d", pbmi->bmiHeader.biBitCount));
294#endif
295
296 return 0;
297}
298//******************************************************************************
299//******************************************************************************
300UINT WIN32API GetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries,
301 RGBQUAD *pColors)
302{
303 DIBSection *dsect = DIBSection::findHDC(hdc);
304 UINT rc;
305 int i;
306
307 dprintf(("GetDIBColorTable %x %d->%d %x", hdc, uStartIndex, cEntries, pColors));
308
309 if(dsect)
310 {
311 return(dsect->GetDIBColorTable(uStartIndex, cEntries, pColors));
312 }
313 //TODO: Is this correct?????
314 // Wine returns 0 if bitmap selected into dc with bpp > 8
315 HPALETTE hpal = GetCurrentObject(hdc, OBJ_PAL);
316 rc = O32_GetPaletteEntries(hpal, uStartIndex, cEntries, (PALETTEENTRY *)pColors);
317 for(i=0;i<cEntries;i++)
318 {
319 BYTE tmp;
320 tmp = pColors[i].rgbBlue;
321 pColors[i].rgbBlue = pColors[i].rgbRed;
322 pColors[i].rgbRed = tmp;
323 pColors[i].rgbReserved = 0;
324 }
325 dprintf(("GDI32: GetDIBColorTable returns %d\n", rc));
326 return(rc);
327}
328//******************************************************************************
329//******************************************************************************
330UINT WIN32API SetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries,
331 RGBQUAD *pColors)
332{
333 DIBSection *dsect = DIBSection::findHDC(hdc);
334
335 dprintf(("GDI32: SetDIBColorTable %x %d,%d %x", hdc, uStartIndex, cEntries, pColors));
336 if(dsect)
337 {
338 return(dsect->SetDIBColorTable(uStartIndex, cEntries, pColors));
339 }
340 else return(0);
341}
342//******************************************************************************
343//******************************************************************************
344LONG WIN32API GetBitmapBits( HBITMAP hBitmap, LONG arg2, PVOID arg3)
345{
346 dprintf(("GDI32: GetBitmapBits %x", hBitmap));
347 return O32_GetBitmapBits(hBitmap, arg2, arg3);
348}
349//******************************************************************************
350//******************************************************************************
351LONG WIN32API SetBitmapBits( HBITMAP hBitmap, LONG arg2, const VOID * arg3)
352{
353 dprintf(("GDI32: SetBitmapBits %x", hBitmap));
354 return O32_SetBitmapBits(hBitmap, (DWORD)arg2, arg3);
355}
356//******************************************************************************
357//******************************************************************************
358BOOL WIN32API GetBitmapDimensionEx( HBITMAP hBitmap, PSIZE pSize)
359{
360 dprintf(("GDI32: GetBitmapDimensionEx %x (%d,%d)", hBitmap, pSize->cx, pSize->cy));
361 return O32_GetBitmapDimensionEx(hBitmap, pSize);
362}
363//******************************************************************************
364//******************************************************************************
365BOOL WIN32API SetBitmapDimensionEx( HBITMAP arg1, int arg2, int arg3, PSIZE arg4)
366{
367 dprintf(("GDI32: SetBitmapDimensionEx"));
368 return O32_SetBitmapDimensionEx(arg1, arg2, arg3, arg4);
369}
370//******************************************************************************
371//******************************************************************************
372int WIN32API GetDIBits(HDC hdc, HBITMAP hBitmap, UINT uStartScan, UINT cScanLines,
373 void *lpvBits, PBITMAPINFO lpbi, UINT uUsage)
374{
375 int nrlines;
376
377 dprintf(("GDI32: GetDIBits %x %x %d %d %x %x (biBitCount %d) %d", hdc, hBitmap, uStartScan, cScanLines, lpvBits, lpbi, lpbi->bmiHeader.biBitCount, uUsage));
378
379 //SvL: WGSS screws up the DC if it's a memory DC
380 // TODO: Fix in WGSS
381 HDC hdcMem = CreateCompatibleDC(0);
382
383 if(lpbi->bmiHeader.biHeight < 0) {
384 //NOTE: workaround for WGSS bug; remove when fixed
385 LONG height = lpbi->bmiHeader.biHeight;
386
387 nrlines = O32_GetDIBits(hdcMem, hBitmap, uStartScan, cScanLines, lpvBits, lpbi, uUsage);
388
389 //NOTE: workaround for WGSS bug; remove when fixed
390 lpbi->bmiHeader.biHeight = height;
391 }
392 else {
393 nrlines = O32_GetDIBits(hdcMem, hBitmap, uStartScan, cScanLines, lpvBits, lpbi, uUsage);
394 }
395
396 DeleteDC(hdcMem);
397
398 if(lpvBits) {
399 // set proper color masks (only if lpvBits not NULL)
400 switch(lpbi->bmiHeader.biBitCount) {
401 case 15:
402 case 16: //RGB 565
403 {
404 DWORD dwFlags;
405
406 dwFlags = ObjQueryHandleFlags(hBitmap);
407 if(dwFlags & (OBJHANDLE_FLAG_BMP_SCREEN_COMPATIBLE|OBJHANDLE_FLAG_BMP_RGB565)) {
408 ((DWORD*)(lpbi->bmiColors))[0] = RGB565_RED_MASK;
409 ((DWORD*)(lpbi->bmiColors))[1] = RGB565_GREEN_MASK;
410 ((DWORD*)(lpbi->bmiColors))[2] = RGB565_BLUE_MASK;
411 }
412 else {
413 ((DWORD*)(lpbi->bmiColors))[0] = RGB555_RED_MASK;
414 ((DWORD*)(lpbi->bmiColors))[1] = RGB555_GREEN_MASK;
415 ((DWORD*)(lpbi->bmiColors))[2] = RGB555_BLUE_MASK;
416 }
417 break;
418 }
419 case 24:
420 case 32:
421 ((DWORD*)(lpbi->bmiColors))[0] = DEFAULT_24BPP_RED_MASK;
422 ((DWORD*)(lpbi->bmiColors))[1] = DEFAULT_24BPP_GREEN_MASK;
423 ((DWORD*)(lpbi->bmiColors))[2] = DEFAULT_24BPP_BLUE_MASK;
424 break;
425 }
426 if(lpbi->bmiHeader.biCompression == BI_RGB && lpbi->bmiHeader.biBitCount > 8) {
427 lpbi->bmiHeader.biCompression = BI_BITFIELDS;
428 dprintf(("BI_BITFIELDS: %x %x %x", ((DWORD*)(lpbi->bmiColors))[0], ((DWORD*)(lpbi->bmiColors))[1], ((DWORD*)(lpbi->bmiColors))[2]));
429 }
430 }
431 if(nrlines && lpvBits && lpbi->bmiHeader.biBitCount == 16 && ((DWORD*)(lpbi->bmiColors))[1] == RGB555_GREEN_MASK)
432 {//RGB 555?
433 dprintf(("RGB 565->555 conversion required"));
434
435 int imgsize = CalcBitmapSize(lpbi->bmiHeader.biBitCount,
436 lpbi->bmiHeader.biWidth, nrlines);
437
438 if(CPUFeatures & CPUID_MMX) {
439 RGB565to555MMX((WORD *)lpvBits, (WORD *)lpvBits, imgsize/sizeof(WORD));
440 }
441 else RGB565to555((WORD *)lpvBits, (WORD *)lpvBits, imgsize/sizeof(WORD));
442 }
443
444 //WGSS/Open32 returns 0 when querying the bitmap info; must return nr of scanlines
445 //as 0 signals failure
446 if(lpvBits == NULL) {
447 nrlines = cScanLines;
448 }
449 dprintf(("GDI32: GetDIBits returned %d", nrlines));
450 return nrlines;
451}
452//******************************************************************************
453//******************************************************************************
454void WIN32API ConvertRGB555to565(LPVOID dest, LPVOID src, UINT imgsize)
455{
456 if(CPUFeatures & CPUID_MMX) {
457 RGB555to565MMX((WORD *)dest, (WORD *)src, imgsize/sizeof(WORD));
458 }
459 else RGB555to565((WORD *)dest, (WORD *)src, imgsize/sizeof(WORD));
460}
461//******************************************************************************
462//******************************************************************************
463int WIN32API SetDIBits(HDC hdc, HBITMAP hBitmap, UINT startscan, UINT numlines, const VOID *pBits,
464 const BITMAPINFO *pBitmapInfo, UINT usage)
465{
466 int ret;
467 DWORD bitfields[3];
468 WORD *newbits = NULL;
469
470 dprintf(("GDI32: SetDIBits %x %x %x %x %x %x %x", hdc, hBitmap, startscan, numlines, pBits, pBitmapInfo, usage));
471
472 //SvL: Open32's SetDIBits really messes things up for 1 bpp bitmaps, must use SetBitmapBits
473 if(pBitmapInfo->bmiHeader.biBitCount == 1 && startscan == 0 && numlines == pBitmapInfo->bmiHeader.biHeight)
474 {//WARNING: hack alert!
475 int dibwidth = DIB_GetDIBWidthBytes(pBitmapInfo->bmiHeader.biWidth, 1);
476 int bmpwidth = BITMAP_GetWidthBytes(pBitmapInfo->bmiHeader.biWidth, 1);
477 char *newpix = (char *)malloc(dibwidth*pBitmapInfo->bmiHeader.biHeight);
478 char *orgpix = (char *)pBits;
479 int ret;
480
481 dprintf(("Flipping 1bpp bitmap and calling SetBitmapBits (WORKAROUND) (%d -> %d)", dibwidth, bmpwidth));
482 newpix += ((pBitmapInfo->bmiHeader.biHeight-1)*bmpwidth);
483
484 //flip bitmap here; SetDIBits assumes origin is left bottom, SetBitmapBits left top
485 //SetDIBits assumes DWORD aligned data
486 //SetBitmapBits assumes WORD aligned data
487 for(int i=0;i<pBitmapInfo->bmiHeader.biHeight;i++) {
488 memcpy(newpix, orgpix, bmpwidth);
489
490 newpix -= bmpwidth;
491 orgpix += dibwidth;
492 }
493 newpix += bmpwidth;
494 ret = O32_SetBitmapBits(hBitmap, pBitmapInfo->bmiHeader.biSizeImage, newpix);
495
496 free(newpix);
497 return ret;
498 }
499#ifdef DEBUG
500 if(pBitmapInfo->bmiHeader.biBitCount == 1) {
501 dprintf(("ERROR: SetDIBits does NOT work well for 1 bpp bitmaps!!!!!"));
502 }
503#endif
504
505 switch(pBitmapInfo->bmiHeader.biBitCount) {
506 case 15:
507 case 16: //Default if BI_BITFIELDS not set is RGB 555
508 bitfields[0] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)pBitmapInfo->bmiColors : DEFAULT_16BPP_RED_MASK;
509 bitfields[1] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)pBitmapInfo->bmiColors + 1) : DEFAULT_16BPP_GREEN_MASK;
510 bitfields[2] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)pBitmapInfo->bmiColors + 2) : DEFAULT_16BPP_BLUE_MASK;
511 break;
512
513 case 24:
514 case 32:
515 bitfields[0] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *(DWORD *)pBitmapInfo->bmiColors : DEFAULT_24BPP_RED_MASK;
516 bitfields[1] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)pBitmapInfo->bmiColors + 1) : DEFAULT_24BPP_GREEN_MASK;
517 bitfields[2] = (pBitmapInfo->bmiHeader.biCompression == BI_BITFIELDS) ? *((DWORD *)pBitmapInfo->bmiColors + 2) : DEFAULT_24BPP_BLUE_MASK;
518 break;
519 default:
520 bitfields[0] = 0;
521 bitfields[1] = 0;
522 bitfields[2] = 0;
523 break;
524 }
525 if(pBits && bitfields[1] == RGB555_GREEN_MASK)
526 {//RGB 555?
527 dprintf(("RGB 555->565 conversion required %x %x %x", bitfields[0], bitfields[1], bitfields[2]));
528
529 int imgsize = CalcBitmapSize(pBitmapInfo->bmiHeader.biBitCount,
530 pBitmapInfo->bmiHeader.biWidth, numlines);
531
532 newbits = (WORD *)malloc(imgsize);
533 if(CPUFeatures & CPUID_MMX) {
534 RGB555to565MMX(newbits, (WORD *)pBits, imgsize/sizeof(WORD));
535 }
536 else RGB555to565(newbits, (WORD *)pBits, imgsize/sizeof(WORD));
537 pBits = newbits;
538 }
539
540 if(pBitmapInfo->bmiHeader.biHeight < 0) {
541 dprintf(("!WARNING! Negative height!!"));
542 }
543 ret = O32_SetDIBits(hdc, hBitmap, startscan, numlines, pBits, pBitmapInfo, usage);
544 if(newbits) free(newbits);
545
546 if(DIBSection::getSection() != NULL)
547 {
548 DIBSection *dsect;
549
550 dsect = DIBSection::findObj(hBitmap);
551 if(dsect) {
552 HBITMAP hBmpOld = SelectObject(hdc, hBitmap);
553 dsect->sync(hdc, 0, dsect->GetHeight());
554 SelectObject(hdc, hBmpOld);
555 }
556 }
557
558 return ret;
559}
560//******************************************************************************
561//******************************************************************************
Note: See TracBrowser for help on using the repository browser.