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

Last change on this file since 4574 was 4574, checked in by sandervl, 25 years ago

DeleteDC + CreateDIBSection fixes

File size: 11.3 KB
Line 
1/* $Id: dibitmap.cpp,v 1.11 2000-11-09 18:16:56 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 "dibsect.h"
18
19#define DBG_LOCALLOG DBG_dibitmap
20#include "dbglocal.h"
21
22//******************************************************************************
23//******************************************************************************
24HBITMAP WIN32API CreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *lpbmih,
25 DWORD fdwInit, const void *lpbInit,
26 const BITMAPINFO *lpbmi, UINT fuUsage)
27{
28 int iHeight;
29 HBITMAP rc;
30
31 //SvL: Completely wrong result when creating a 1bpp bitmap here (converted
32 // to 8bpp by Open32)
33 if(lpbmih->biBitCount == 1) {
34 dprintf(("WARNING: CreateDIBitmap doesn't handle 1bpp bitmaps very well!!!!!"));
35 }
36
37 //TEMPORARY HACK TO PREVENT CRASH IN OPEN32 (WSeB GA)
38
39 iHeight = lpbmih->biHeight;
40 if(lpbmih->biHeight < 0)
41 {
42 dprintf(("GDI32: CreateDIBitmap negative height! (%d,%d)", lpbmih->biWidth, lpbmih->biHeight));
43 ((BITMAPINFOHEADER *)lpbmih)->biHeight = -lpbmih->biHeight;
44 }
45
46 // 2000/09/01 PH Netscape 4.7
47 // If color depth of lpbhmi is 16 bit and lpbmi is 8 bit,
48 // Open32 will crash since it won't allocate any palette color memory,
49 // however wants to copy it later on ...
50 int biBitCount = lpbmih->biBitCount;
51
52 if (lpbmih->biBitCount != lpbmi->bmiHeader.biBitCount)
53 {
54 dprintf(("GDI32: CreateDIBitmap: color depths of bitmaps differ! (%d,%d\n",
55 lpbmih->biBitCount,
56 lpbmi->bmiHeader.biBitCount));
57
58 ((BITMAPINFOHEADER *)lpbmih)->biBitCount = lpbmi->bmiHeader.biBitCount;
59 }
60
61 rc = O32_CreateDIBitmap(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
62
63 dprintf(("GDI32: CreateDIBitmap %x %x %x %x returned %x", hdc, fdwInit, lpbInit, fuUsage, rc));
64
65 ((BITMAPINFOHEADER *)lpbmih)->biHeight = iHeight;
66 ((BITMAPINFOHEADER *)lpbmih)->biBitCount = biBitCount;
67
68 return rc;
69}
70//******************************************************************************
71//******************************************************************************
72HBITMAP WIN32API CreateCompatibleBitmap( HDC hdc, int nWidth, int nHeight)
73{
74 HBITMAP hBitmap;
75
76 hBitmap = O32_CreateCompatibleBitmap(hdc, nWidth, nHeight);
77 dprintf(("GDI32: CreateCompatibleBitmap %x (%d,%d) returned %x", hdc, nWidth, nHeight, hBitmap));
78 return hBitmap;
79}
80//******************************************************************************
81//CreateDisardableBitmap is obsolete and can be replaced by CreateCompatibleBitmap
82//******************************************************************************
83HBITMAP WIN32API CreateDiscardableBitmap(HDC hDC, int nWidth, int nHeight)
84{
85 dprintf(("GDI32: CreateDisardableBitmap\n"));
86 return CreateCompatibleBitmap(hDC, nWidth, nHeight);
87}
88//******************************************************************************
89//******************************************************************************
90HBITMAP WIN32API CreateBitmap(int nWidth, int nHeight, UINT cPlanes,
91 UINT cBitsPerPel, const void *lpvBits)
92{
93 HBITMAP hBitmap;
94
95 hBitmap = O32_CreateBitmap(nWidth, nHeight, cPlanes, cBitsPerPel, lpvBits);
96 dprintf(("GDI32: CreateBitmap (%d,%d) bps %d returned %x", nWidth, nHeight, cBitsPerPel, hBitmap));
97 return(hBitmap);
98}
99//******************************************************************************
100//******************************************************************************
101HBITMAP WIN32API CreateBitmapIndirect( const BITMAP * arg1)
102{
103 dprintf(("GDI32: CreateBitmapIndirect"));
104 return O32_CreateBitmapIndirect(arg1);
105}
106//******************************************************************************
107//*********************************************************************************
108HBITMAP WIN32API CreateDIBSection( HDC hdc, BITMAPINFO *pbmi, UINT iUsage,
109 VOID **ppvBits, HANDLE hSection, DWORD dwOffset)
110{
111 HBITMAP res = 0;
112 BOOL fFlip = 0;
113 int iHeight, iWidth;
114 BOOL fCreateDC = FALSE;
115
116 dprintf(("GDI32: CreateDIBSection %x %x %x %x %x %d", hdc, pbmi, iUsage, ppvBits, hSection, dwOffset));
117
118 //SvL: 13-9-98: StarCraft uses bitmap with negative height
119 iWidth = pbmi->bmiHeader.biWidth;
120 if(pbmi->bmiHeader.biWidth < 0)
121 {
122 dprintf(("CreateDIBSection: width %d", pbmi->bmiHeader.biWidth));
123 pbmi->bmiHeader.biWidth = -pbmi->bmiHeader.biWidth;
124 fFlip = FLIP_HOR;
125 }
126 iHeight = pbmi->bmiHeader.biHeight;
127 if(pbmi->bmiHeader.biHeight < 0)
128 {
129 dprintf(("CreateDIBSection: height %d", pbmi->bmiHeader.biHeight));
130 pbmi->bmiHeader.biHeight = -pbmi->bmiHeader.biHeight;
131 fFlip |= FLIP_VERT;
132 }
133
134 //SvL: RP7 (update) calls this api with hdc == 0
135 if(hdc == 0) {
136 hdc = GetWindowDC(GetDesktopWindow());
137 fCreateDC = TRUE;
138 }
139 res = O32_CreateDIBitmap(hdc, &pbmi->bmiHeader, 0, NULL, pbmi, iUsage);
140 if (res)
141 {
142 char PalSize;
143 DIBSection *dsect;
144
145 dsect = new DIBSection((BITMAPINFOHEADER_W *)&pbmi->bmiHeader, (char *)&pbmi->bmiColors, iUsage, hSection, dwOffset, (DWORD)res, fFlip);
146
147 if(dsect != NULL)
148 {
149 PalSize = dsect->GetBitCount();
150 if(PalSize <= 8)
151 {
152 ULONG Pal[256], nrcolors;
153 LOGPALETTE tmpPal = { 0x300,1,{0,0,0,0}};
154 HPALETTE hpalCur, hpalTmp;
155
156 // Now get the current Palette from the DC
157 hpalTmp = CreatePalette(&tmpPal);
158 hpalCur = SelectPalette(hdc, hpalTmp, FALSE);
159
160 // and use it to set the DIBColorTable
161 nrcolors = GetPaletteEntries( hpalCur, 0, 1<<PalSize, (LPPALETTEENTRY)&Pal);
162 dsect->SetDIBColorTable(0, nrcolors, (LPPALETTEENTRY)&Pal);
163
164 // Restore the DC Palette
165 SelectPalette(hdc,hpalCur,FALSE);
166 DeleteObject(hpalTmp);
167 }
168//SvL: Shouldn't an app explicitely select the dib section into the hdc?
169// (RealPlayer does this)
170#if 0
171 // Set the hdc in the DIBSection so we can update the palete if a new
172 // Palette etc. gets selected into the DC.
173
174 dsect->SelectDIBObject(hdc);
175#endif
176
177 if(ppvBits!=NULL)
178 *ppvBits = dsect->GetDIBObject();
179
180 pbmi->bmiHeader.biWidth = iWidth;
181 pbmi->bmiHeader.biHeight = iHeight;
182
183 if(fCreateDC) ReleaseDC(GetDesktopWindow(), hdc);
184 return(res);
185 }
186 }
187 if(fCreateDC) ReleaseDC(GetDesktopWindow(), hdc);
188
189 /* Error. */
190 if (res)
191 DeleteObject(res);
192 *ppvBits = NULL;
193#ifdef DEBUG
194 dprintf(("GDI32: CreateDIBSection, error!\n"));
195 dprintf(("pbmi->biWidth %d", pbmi->bmiHeader.biWidth));
196 dprintf(("pbmi->biHeight %d", pbmi->bmiHeader.biHeight));
197 dprintf(("pbmi->biBitCount %d", pbmi->bmiHeader.biBitCount));
198#endif
199
200 return 0;
201}
202//******************************************************************************
203//******************************************************************************
204UINT WIN32API GetDIBColorTable( HDC hdc, UINT uStartIndex, UINT cEntries,
205 RGBQUAD *pColors)
206{
207 HPALETTE hpal = GetCurrentObject(hdc, OBJ_PAL);
208 UINT rc;
209 int i;
210
211 rc = O32_GetPaletteEntries(hpal,
212 uStartIndex,
213 cEntries,
214 (PALETTEENTRY *)pColors);
215 for(i=0;
216 i<cEntries;
217 i++)
218 {
219 BYTE tmp;
220 tmp = pColors[i].rgbBlue;
221 pColors[i].rgbBlue = pColors[i].rgbRed;
222 pColors[i].rgbRed = tmp;
223 pColors[i].rgbReserved = 0;
224 }
225 dprintf(("GDI32: GetDIBColorTable returns %d\n", rc));
226 return(rc);
227}
228//******************************************************************************
229//******************************************************************************
230UINT WIN32API SetDIBColorTable(HDC hdc, UINT uStartIndex, UINT cEntries,
231 RGBQUAD *pColors)
232{
233 DIBSection *dsect = DIBSection::findHDC(hdc);
234
235 dprintf(("GDI32: SetDIBColorTable\n"));
236 if(dsect)
237 {
238 return(dsect->SetDIBColorTable(uStartIndex, cEntries, pColors));
239 }
240 else
241 return(0);
242}
243//******************************************************************************
244//******************************************************************************
245LONG WIN32API GetBitmapBits( HBITMAP hBitmap, LONG arg2, PVOID arg3)
246{
247 dprintf(("GDI32: GetBitmapBits %x", hBitmap));
248 return O32_GetBitmapBits(hBitmap, arg2, arg3);
249}
250//******************************************************************************
251//******************************************************************************
252LONG WIN32API SetBitmapBits( HBITMAP hBitmap, LONG arg2, const VOID * arg3)
253{
254 dprintf(("GDI32: SetBitmapBits %x", hBitmap));
255 return O32_SetBitmapBits(hBitmap, (DWORD)arg2, arg3);
256}
257//******************************************************************************
258//******************************************************************************
259BOOL WIN32API GetBitmapDimensionEx( HBITMAP hBitmap, PSIZE pSize)
260{
261 dprintf(("GDI32: GetBitmapDimensionEx %x (%d,%d)", hBitmap, pSize->cx, pSize->cy));
262 return O32_GetBitmapDimensionEx(hBitmap, pSize);
263}
264//******************************************************************************
265//******************************************************************************
266BOOL WIN32API SetBitmapDimensionEx( HBITMAP arg1, int arg2, int arg3, PSIZE arg4)
267{
268 dprintf(("GDI32: SetBitmapDimensionEx"));
269 return O32_SetBitmapDimensionEx(arg1, arg2, arg3, arg4);
270}
271//******************************************************************************
272//******************************************************************************
273int WIN32API GetDIBits(HDC hdc, HBITMAP hBitmap, UINT uStartScan, UINT cScanLines,
274 void *lpvBits, PBITMAPINFO lpbi, UINT uUsage)
275{
276 int rc;
277
278 rc = O32_GetDIBits(hdc, hBitmap, uStartScan, cScanLines, lpvBits, lpbi, uUsage);
279 // set proper color masks!
280 switch(lpbi->bmiHeader.biBitCount) {
281 case 16: //RGB 565
282 ((DWORD*)(lpbi->bmiColors))[0] = 0xF800;
283 ((DWORD*)(lpbi->bmiColors))[1] = 0x07E0;
284 ((DWORD*)(lpbi->bmiColors))[2] = 0x001F;
285 break;
286 case 24:
287 case 32:
288 ((DWORD*)(lpbi->bmiColors))[0] = 0x0000FF;
289 ((DWORD*)(lpbi->bmiColors))[1] = 0x00FF00;
290 ((DWORD*)(lpbi->bmiColors))[2] = 0xFF0000;
291 break;
292 }
293
294 dprintf(("GDI32: GetDIBits %x %x %d %d %x %x %d returned %d", hdc, hBitmap, uStartScan, cScanLines, lpvBits, lpbi, uUsage, rc));
295 return rc;
296}
297//******************************************************************************
298//******************************************************************************
299int WIN32API SetDIBits( HDC arg1, HBITMAP arg2, UINT arg3, UINT arg4, const VOID * arg5, const BITMAPINFO * arg6, UINT arg7)
300{
301 dprintf(("GDI32: SetDIBits %x %x %x %x %x %x %x\n", arg1, arg2, arg3, arg4, arg5, arg6, arg7));
302
303 if(DIBSection::getSection() != NULL)
304 {
305 DIBSection *dsect;
306
307 dsect = DIBSection::find((DWORD)arg2);
308 if(dsect) {
309 return dsect->SetDIBits(arg1, arg2, arg3, arg4, arg5, (BITMAPINFOHEADER_W *)&arg6->bmiHeader, arg7);
310 }
311 }
312 return O32_SetDIBits(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
313}
314//******************************************************************************
315//******************************************************************************
Note: See TracBrowser for help on using the repository browser.