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