Remove ugly hack for the current display DC
[reactos.git] / reactos / subsys / win32k / objects / dib.c
1 #undef WIN32_LEAN_AND_MEAN
2 #include <windows.h>
3 #include <stdlib.h>
4 #include <win32k/bitmaps.h>
5 #include <win32k/debug.h>
6 #include <debug.h>
7 #include "../eng/objects.h"
8 #include <ntos/minmax.h>
9
10 UINT STDCALL W32kSetDIBColorTable(HDC hDC,
11 UINT StartIndex,
12 UINT Entries,
13 CONST RGBQUAD *Colors)
14 {
15 PDC dc;
16 PALETTEENTRY * palEntry;
17 PPALOBJ palette;
18 RGBQUAD *end;
19
20 if (!(dc = (PDC)AccessUserObject(hDC))) return 0;
21
22 if (!(palette = (PPALOBJ)AccessUserObject(dc->DevInfo.hpalDefault)))
23 {
24 // GDI_ReleaseObj( hdc );
25 return 0;
26 }
27
28 // Transfer color info
29
30 if (dc->w.bitsPerPixel <= 8) {
31 palEntry = palette->logpalette->palPalEntry + StartIndex;
32 if (StartIndex + Entries > (1 << dc->w.bitsPerPixel))
33 Entries = (1 << dc->w.bitsPerPixel) - StartIndex;
34
35 if (StartIndex + Entries > palette->logpalette->palNumEntries)
36 Entries = palette->logpalette->palNumEntries - StartIndex;
37
38 for (end = Colors + Entries; Colors < end; palEntry++, Colors++)
39 {
40 palEntry->peRed = Colors->rgbRed;
41 palEntry->peGreen = Colors->rgbGreen;
42 palEntry->peBlue = Colors->rgbBlue;
43 }
44 } else {
45 Entries = 0;
46 }
47
48 // GDI_ReleaseObj(dc->DevInfo.hpalDefault);
49 // GDI_ReleaseObj(hdc);
50
51 return Entries;
52 }
53
54 // Converts a DIB to a device-dependent bitmap
55 INT STDCALL W32kSetDIBits(HDC hDC,
56 HBITMAP hBitmap,
57 UINT StartScan,
58 UINT ScanLines,
59 CONST VOID *Bits,
60 CONST BITMAPINFO *bmi,
61 UINT ColorUse)
62 {
63 DC *dc;
64 BITMAPOBJ *bitmap;
65 HBITMAP SourceBitmap, DestBitmap;
66 INT result;
67 BOOL copyBitsResult;
68 PSURFOBJ DestSurf, SourceSurf;
69 PSURFGDI DestGDI;
70 SIZEL SourceSize;
71 POINTL ZeroPoint;
72 RECTL DestRect;
73 PXLATEOBJ XlateObj;
74 PPALGDI hDCPalette;
75 RGBQUAD *lpRGB;
76 HPALETTE DDB_Palette, DIB_Palette;
77 USHORT DDB_Palette_Type, DIB_Palette_Type;
78
79
80 // Check parameters
81 if (!(dc = DC_HandleToPtr(hDC))) return 0;
82
83 if (!(bitmap = (BITMAPOBJ *)GDIOBJ_HandleToPtr(hBitmap, GO_BITMAP_MAGIC)))
84 {
85 // GDI_ReleaseObj(hDC);
86 return 0;
87 }
88
89 // Get RGB values
90 if (ColorUse == DIB_PAL_COLORS)
91 lpRGB = DIB_MapPaletteColors(hDC, bmi);
92 else
93 lpRGB = &bmi->bmiColors[0];
94
95 // Create a temporary surface for the destination bitmap
96 DestSurf = ExAllocatePool(PagedPool, sizeof(SURFOBJ));
97 DestGDI = ExAllocatePool(PagedPool, sizeof(SURFGDI));
98 DestBitmap = (HBITMAP)CreateGDIHandle(DestGDI, DestSurf);
99
100 BitmapToSurf(hDC, DestGDI, DestSurf, bitmap);
101
102 // Create source surface
103 SourceSize.cx = bmi->bmiHeader.biWidth;
104 SourceSize.cy = bmi->bmiHeader.biHeight;
105 SourceBitmap = EngCreateBitmap(SourceSize, DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount),
106 BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
107 0, Bits);
108 SourceSurf = (PSURFOBJ)AccessUserObject(SourceBitmap);
109
110 // Destination palette obtained from the hDC
111 hDCPalette = (PPALGDI)AccessInternalObject(dc->DevInfo.hpalDefault);
112 DDB_Palette_Type = hDCPalette->Mode;
113 DDB_Palette = dc->DevInfo.hpalDefault;
114
115 // Source palette obtained from the BITMAPINFO
116 DIB_Palette = BuildDIBPalette(bmi, &DIB_Palette_Type);
117
118 // Determine XLATEOBJ for color translation
119 XlateObj = EngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
120
121 // Determine destination rectangle and source point
122 ZeroPoint.x = 0;
123 ZeroPoint.y = 0;
124 DestRect.top = 0;
125 DestRect.left = 0;
126 DestRect.right = SourceSize.cx;
127 DestRect.bottom = SourceSize.cy;
128
129 copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
130
131 // Clean up
132 EngDeleteSurface(SourceBitmap);
133 EngDeleteSurface(DestBitmap);
134
135 // if (ColorUse == DIB_PAL_COLORS)
136 // WinFree((LPSTR)lpRGB);
137
138 // GDI_ReleaseObj(hBitmap); unlock?
139 // GDI_ReleaseObj(hDC);
140
141 return result;
142 }
143
144 INT STDCALL W32kSetDIBitsToDevice(HDC hDC,
145 INT XDest,
146 INT YDest,
147 DWORD Width,
148 DWORD Height,
149 INT XSrc,
150 INT YSrc,
151 UINT StartScan,
152 UINT ScanLines,
153 CONST VOID *Bits,
154 CONST BITMAPINFO *bmi,
155 UINT ColorUse)
156 {
157
158 }
159
160 UINT STDCALL W32kGetDIBColorTable(HDC hDC,
161 UINT StartIndex,
162 UINT Entries,
163 RGBQUAD *Colors)
164 {
165 UNIMPLEMENTED;
166 }
167
168 // Converts a device-dependent bitmap to a DIB
169 INT STDCALL W32kGetDIBits(HDC hDC,
170 HBITMAP hBitmap,
171 UINT StartScan,
172 UINT ScanLines,
173 LPVOID Bits,
174 LPBITMAPINFO bi,
175 UINT Usage)
176 {
177 UNIMPLEMENTED;
178 }
179
180 INT STDCALL W32kStretchDIBits(HDC hDC,
181 INT XDest,
182 INT YDest,
183 INT DestWidth,
184 INT DestHeight,
185 INT XSrc,
186 INT YSrc,
187 INT SrcWidth,
188 INT SrcHeight,
189 CONST VOID *Bits,
190 CONST BITMAPINFO *BitsInfo,
191 UINT Usage,
192 DWORD ROP)
193 {
194 UNIMPLEMENTED;
195 }
196
197 LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
198 LONG Count,
199 LPVOID Bits)
200 {
201 PBITMAPOBJ bmp;
202 LONG height, ret;
203
204 bmp = BITMAPOBJ_HandleToPtr (hBitmap);
205 if (!bmp)
206 {
207 return 0;
208 }
209
210 /* If the bits vector is null, the function should return the read size */
211 if (Bits == NULL)
212 {
213 return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
214 }
215
216 if (Count < 0)
217 {
218 DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
219 Count = -Count;
220 }
221
222 /* Only get entire lines */
223 height = Count / bmp->bitmap.bmWidthBytes;
224 if (height > bmp->bitmap.bmHeight)
225 {
226 height = bmp->bitmap.bmHeight;
227 }
228 Count = height * bmp->bitmap.bmWidthBytes;
229 if (Count == 0)
230 {
231 DPRINT("Less then one entire line requested\n");
232 BITMAPOBJ_UnlockBitmap (hBitmap);
233 return 0;
234 }
235
236 DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
237 hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
238 1 << bmp->bitmap.bmBitsPixel, height );
239 #if 0
240 /* FIXME: Call DDI CopyBits here if available */
241 if(bmp->DDBitmap)
242 {
243 DPRINT("Calling device specific BitmapBits\n");
244 if(bmp->DDBitmap->funcs->pBitmapBits)
245 {
246 ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
247 DDB_GET);
248 }
249 else
250 {
251 ERR_(bitmap)("BitmapBits == NULL??\n");
252 ret = 0;
253 }
254 }
255 else
256 #endif
257 {
258 if(!bmp->bitmap.bmBits)
259 {
260 DPRINT ("Bitmap is empty\n");
261 ret = 0;
262 }
263 else
264 {
265 memcpy(Bits, bmp->bitmap.bmBits, Count);
266 ret = Count;
267 }
268 }
269 BITMAPOBJ_UnlockBitmap (hBitmap);
270
271 return ret;
272 }
273
274 // The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
275 // The DDB that is created will be whatever bit depth your reference DC is
276 HBITMAP STDCALL W32kCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header,
277 DWORD init, LPCVOID bits, const BITMAPINFO *data,
278 UINT coloruse)
279 {
280 HBITMAP handle;
281 BOOL fColor;
282 DWORD width;
283 int height;
284 WORD bpp;
285 WORD compr;
286
287 if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
288 if (height < 0) height = -height;
289
290 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
291 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
292
293 if (bpp != 1) fColor = TRUE;
294 else if ((coloruse != DIB_RGB_COLORS) ||
295 (init != CBM_INIT) || !data) fColor = FALSE;
296 else
297 {
298 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
299 {
300 RGBQUAD *rgb = data->bmiColors;
301 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
302
303 // Check if the first color of the colormap is black
304 if ((col == RGB(0, 0, 0)))
305 {
306 rgb++;
307 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
308
309 // If the second color is white, create a monochrome bitmap
310 fColor = (col != RGB(0xff,0xff,0xff));
311 }
312 else fColor = TRUE;
313 }
314 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
315 {
316 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
317 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
318
319 if ((col == RGB(0,0,0)))
320 {
321 rgb++;
322 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
323 fColor = (col != RGB(0xff,0xff,0xff));
324 }
325 else fColor = TRUE;
326 }
327 else
328 {
329 DbgPrint("(%ld): wrong size for data\n", data->bmiHeader.biSize );
330 return 0;
331 }
332 }
333
334 // Now create the bitmap
335
336 if(fColor)
337 {
338 // If we are using indexed colors, then we need to create a bitmap that is compatible with the palette
339 if(coloruse == DIB_PAL_COLORS)
340 {
341 handle = W32kCreateCompatibleBitmap(hdc, width, height);
342 }
343 else if(coloruse == DIB_RGB_COLORS) {
344 handle = W32kCreateBitmap(width, height, 1, 24, NULL);
345 }
346 }
347 else handle = W32kCreateBitmap(width, height, 1, 1, NULL);
348
349 if (!handle) return 0;
350
351 if (init == CBM_INIT)
352 {
353 W32kSetDIBits(hdc, handle, 0, height, bits, data, coloruse);
354 }
355
356 return handle;
357 }
358
359 HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
360 CONST BITMAPINFO *bmi,
361 UINT Usage,
362 VOID *Bits,
363 HANDLE hSection,
364 DWORD dwOffset)
365 {
366 HBITMAP hbitmap = 0;
367 DC *dc;
368 BOOL bDesktopDC = FALSE;
369
370 // If the reference hdc is null, take the desktop dc
371 if (hDC == 0)
372 {
373 hDC = W32kCreateCompatableDC(0);
374 bDesktopDC = TRUE;
375 }
376
377 if ((dc = DC_HandleToPtr(hDC)))
378 {
379 hbitmap = DIB_CreateDIBSection(dc, bmi, Usage, Bits, hSection, dwOffset, 0);
380 DC_UnlockDC (hDC);
381 }
382
383 if (bDesktopDC)
384 W32kDeleteDC(hDC);
385
386 return hbitmap;
387 }
388
389 HBITMAP DIB_CreateDIBSection(
390 PDC dc, BITMAPINFO *bmi, UINT usage,
391 LPVOID *bits, HANDLE section,
392 DWORD offset, DWORD ovr_pitch)
393 {
394 HBITMAP res = 0;
395 BITMAPOBJ *bmp = NULL;
396 DIBSECTION *dib = NULL;
397 int *colorMap = NULL;
398 int nColorMap;
399
400 // Fill BITMAP32 structure with DIB data
401 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
402 INT effHeight, totalSize;
403 BITMAP bm;
404
405 DbgPrint("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
406 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
407 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
408
409 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
410 bm.bmType = 0;
411 bm.bmWidth = bi->biWidth;
412 bm.bmHeight = effHeight;
413 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
414
415 bm.bmPlanes = bi->biPlanes;
416 bm.bmBitsPixel = bi->biBitCount;
417 bm.bmBits = NULL;
418
419 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
420 // we're dealing with a compressed bitmap. Otherwise, use width * height.
421 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
422 ? bi->biSizeImage : bm.bmWidthBytes * effHeight;
423
424 /*
425 if (section)
426 bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
427 0L, offset, totalSize);
428 else if (ovr_pitch && offset)
429 bm.bmBits = (LPVOID) offset;
430 else { */
431 offset = 0;
432 /* bm.bmBits = VirtualAlloc(NULL, totalSize,
433 MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); */
434
435 bm.bmBits = ExAllocatePool(NonPagedPool, totalSize);
436
437 /* } */
438
439 if (usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *));
440
441 // Allocate Memory for DIB and fill structure
442 if (bm.bmBits)
443 dib = ExAllocatePool(PagedPool, sizeof(DIBSECTION));
444 RtlZeroMemory(dib, sizeof(DIBSECTION));
445
446 if (dib)
447 {
448 dib->dsBm = bm;
449 dib->dsBmih = *bi;
450 dib->dsBmih.biSizeImage = totalSize;
451
452 /* Set dsBitfields values */
453 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
454 {
455 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
456 }
457 else switch(bi->biBitCount)
458 {
459 case 16:
460 dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
461 dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
462 dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
463 break;
464
465 case 24:
466 dib->dsBitfields[0] = 0xff;
467 dib->dsBitfields[1] = 0xff00;
468 dib->dsBitfields[2] = 0xff0000;
469 break;
470
471 case 32:
472 dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
473 dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
474 dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
475 break;
476 }
477 dib->dshSection = section;
478 dib->dsOffset = offset;
479 }
480
481 // Create Device Dependent Bitmap and add DIB pointer
482 if (dib)
483 {
484 res = W32kCreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
485 if (res)
486 {
487 bmp = BITMAPOBJ_HandleToPtr (res);
488 if (bmp)
489 {
490 bmp->dib = (DIBSECTION *) dib;
491 }
492 }
493 }
494
495 // Clean up in case of errors
496 if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap))
497 {
498 DbgPrint("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits);
499 /* if (bm.bmBits)
500 {
501 if (section)
502 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
503 else if (!offset)
504 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
505 } */
506
507 if (colorMap) { ExFreePool(colorMap); colorMap = NULL; }
508 if (dib) { ExFreePool(dib); dib = NULL; }
509 if (bmp) { BITMAPOBJ_UnlockBitmap(res); bmp = NULL; }
510 if (res) { GDIOBJ_FreeObject(res, GO_BITMAP_MAGIC); res = 0; }
511 }
512
513 // Install fault handler, if possible
514 /* if (bm.bmBits)
515 {
516 if (VIRTUAL_SetFaultHandler(bm.bmBits, DIB_FaultHandler, (LPVOID)res))
517 {
518 if (section || offset)
519 {
520 DIB_DoProtectDIBSection( bmp, PAGE_READWRITE );
521 if (dib) dib->status = DIB_AppMod;
522 }
523 else
524 {
525 DIB_DoProtectDIBSection( bmp, PAGE_READONLY );
526 if (dib) dib->status = DIB_InSync;
527 }
528 }
529 } */
530
531 // Return BITMAP handle and storage location
532 if (bmp) BITMAPOBJ_UnlockBitmap(res);
533 if (bm.bmBits && bits) *bits = bm.bmBits;
534 return res;
535 }
536
537 /***********************************************************************
538 * DIB_GetDIBWidthBytes
539 *
540 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
541 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
542 * 11/16/1999 (RJJ) lifted from wine
543 */
544 int DIB_GetDIBWidthBytes(int width, int depth)
545 {
546 int words;
547
548 switch(depth)
549 {
550 case 1: words = (width + 31) / 32; break;
551 case 4: words = (width + 7) / 8; break;
552 case 8: words = (width + 3) / 4; break;
553 case 15:
554 case 16: words = (width + 1) / 2; break;
555 case 24: words = (width * 3 + 3)/4; break;
556
557 default:
558 DPRINT("(%d): Unsupported depth\n", depth );
559 /* fall through */
560 case 32:
561 words = width;
562 }
563 return 4 * words;
564 }
565
566 /***********************************************************************
567 * DIB_GetDIBImageBytes
568 *
569 * Return the number of bytes used to hold the image in a DIB bitmap.
570 * 11/16/1999 (RJJ) lifted from wine
571 */
572
573 int DIB_GetDIBImageBytes (int width, int height, int depth)
574 {
575 return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
576 }
577
578 /***********************************************************************
579 * DIB_BitmapInfoSize
580 *
581 * Return the size of the bitmap info structure including color table.
582 * 11/16/1999 (RJJ) lifted from wine
583 */
584
585 int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
586 {
587 int colors;
588
589 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
590 {
591 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
592 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
593 return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
594 }
595 else /* assume BITMAPINFOHEADER */
596 {
597 colors = info->bmiHeader.biClrUsed;
598 if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
599 return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
600 }
601 }
602
603 int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
604 int *height, WORD *bpp, WORD *compr )
605 {
606 if (header->biSize == sizeof(BITMAPINFOHEADER))
607 {
608 *width = header->biWidth;
609 *height = header->biHeight;
610 *bpp = header->biBitCount;
611 *compr = header->biCompression;
612 return 1;
613 }
614 if (header->biSize == sizeof(BITMAPCOREHEADER))
615 {
616 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
617 *width = core->bcWidth;
618 *height = core->bcHeight;
619 *bpp = core->bcBitCount;
620 *compr = 0;
621 return 0;
622 }
623 DbgPrint("(%ld): wrong size for header\n", header->biSize );
624 return -1;
625 }
626
627 // Converts a Device Independent Bitmap (DIB) to a Device Dependant Bitmap (DDB)
628 // The specified Device Context (DC) defines what the DIB should be converted to
629 PBITMAPOBJ DIBtoDDB(HGLOBAL hPackedDIB, HDC hdc) // FIXME: This should be removed. All references to this function should
630 // change to W32kSetDIBits
631 {
632 HBITMAP hBmp = 0;
633 PBITMAPOBJ pBmp = NULL;
634 DIBSECTION *dib;
635 LPBYTE pbits = NULL;
636
637 // Get a pointer to the packed DIB's data
638 // pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
639 dib = hPackedDIB;
640
641 pbits = (dib + DIB_BitmapInfoSize(&dib->dsBmih, DIB_RGB_COLORS));
642
643 // Create a DDB from the DIB
644 hBmp = W32kCreateDIBitmap(hdc, &dib->dsBmih, CBM_INIT, (LPVOID)pbits, &dib->dsBmih, DIB_RGB_COLORS);
645
646 // GlobalUnlock(hPackedDIB);
647
648 // Retrieve the internal Pixmap from the DDB
649 pBmp = (BITMAPOBJ *)GDIOBJ_HandleToPtr(hBmp, GO_BITMAP_MAGIC);
650
651 return pBmp;
652 }
653
654 RGBQUAD *DIB_MapPaletteColors(PDC dc, LPBITMAPINFO lpbmi)
655 {
656 RGBQUAD *lpRGB;
657 int nNumColors,i;
658 DWORD *lpIndex;
659 PPALOBJ palObj;
660
661 palObj = AccessUserObject(dc->DevInfo.hpalDefault);
662
663 if (palObj == NULL) {
664 // RELEASEDCINFO(hDC);
665 return NULL;
666 }
667
668 nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
669 if (lpbmi->bmiHeader.biClrUsed)
670 nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
671
672 lpRGB = (RGBQUAD *)ExAllocatePool(NonPagedPool, sizeof(RGBQUAD) * nNumColors);
673 lpIndex = (DWORD *)&lpbmi->bmiColors[0];
674
675 for (i=0; i<nNumColors; i++) {
676 lpRGB[i].rgbRed = palObj->logpalette->palPalEntry[*lpIndex].peRed;
677 lpRGB[i].rgbGreen = palObj->logpalette->palPalEntry[*lpIndex].peGreen;
678 lpRGB[i].rgbBlue = palObj->logpalette->palPalEntry[*lpIndex].peBlue;
679 lpIndex++;
680 }
681 // RELEASEDCINFO(hDC);
682 // RELEASEPALETTEINFO(hPalette);
683 return lpRGB;
684 }
685
686 HPALETTE BuildDIBPalette(BITMAPINFO *bmi, PINT paletteType)
687 {
688 BYTE bits;
689
690 // Determine Bits Per Pixel
691 bits = bmi->bmiHeader.biBitCount;
692
693 // Determine paletteType from Bits Per Pixel
694 if(bits <= 8)
695 {
696 *paletteType = PAL_INDEXED;
697 } else
698 if(bits < 24)
699 {
700 *paletteType = PAL_BITFIELDS;
701 } else {
702 *paletteType = PAL_RGB; // FIXME: This could be BGR, must still check
703 }
704
705 return EngCreatePalette(*paletteType, bmi->bmiHeader.biClrUsed, bmi->bmiColors, 0, 0, 0);
706 }