4 * ReactOS W32 Subsystem
5 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #undef WIN32_LEAN_AND_MEAN
25 #include <win32k/bitmaps.h>
26 #include <win32k/debug.h>
27 #include "../eng/handle.h"
28 #include <ntos/minmax.h>
29 #include <include/error.h>
30 #include <include/inteng.h>
31 #include <include/eng.h>
32 #include <include/dib.h>
33 #include <internal/safe.h>
34 #include <include/surface.h>
35 #include <include/palette.h>
38 #include <win32k/debug1.h>
40 UINT STDCALL NtGdiSetDIBColorTable(HDC hDC,
43 CONST RGBQUAD *Colors)
46 PALETTEENTRY * palEntry;
50 if (!(dc = (PDC)AccessUserObject((ULONG)hDC))) return 0;
52 if (!(palette = (PPALOBJ)PALETTE_LockPalette((ULONG)dc->DevInfo->hpalDefault)))
54 // GDI_ReleaseObj( hdc );
58 // Transfer color info
60 if (dc->w.bitsPerPixel <= 8)
62 palEntry = palette->logpalette->palPalEntry + StartIndex;
63 if (StartIndex + Entries > (UINT) (1 << dc->w.bitsPerPixel))
64 Entries = (1 << dc->w.bitsPerPixel) - StartIndex;
66 if (StartIndex + Entries > palette->logpalette->palNumEntries)
67 Entries = palette->logpalette->palNumEntries - StartIndex;
69 for (end = Colors + Entries; Colors < end; palEntry++, Colors++)
71 palEntry->peRed = Colors->rgbRed;
72 palEntry->peGreen = Colors->rgbGreen;
73 palEntry->peBlue = Colors->rgbBlue;
81 PALETTE_UnlockPalette(dc->DevInfo->hpalDefault);
82 // GDI_ReleaseObj(hdc);
87 // Converts a DIB to a device-dependent bitmap
95 CONST BITMAPINFO *bmi,
100 HBITMAP SourceBitmap, DestBitmap;
103 PSURFOBJ DestSurf, SourceSurf;
111 HPALETTE DDB_Palette, DIB_Palette;
112 ULONG DDB_Palette_Type, DIB_Palette_Type;
113 const BYTE *vBits = (const BYTE*)Bits;
114 INT scanDirection = 1, DIBWidth;
117 if (!(dc = DC_LockDc(hDC)))
120 if (!(bitmap = BITMAPOBJ_LockBitmap(hBitmap)))
127 //if (ColorUse == DIB_PAL_COLORS)
128 // lpRGB = DIB_MapPaletteColors(hDC, bmi);
130 // lpRGB = &bmi->bmiColors[0];
132 // Create a temporary surface for the destination bitmap
133 DestBitmap = BitmapToSurf(bitmap);
135 DestSurf = (PSURFOBJ) AccessUserObject( (ULONG)DestBitmap );
136 DestGDI = (PSURFGDI) AccessInternalObject( (ULONG)DestBitmap );
138 // Create source surface
139 SourceSize.cx = bmi->bmiHeader.biWidth;
140 SourceSize.cy = abs(bmi->bmiHeader.biHeight);
142 // Determine width of DIB
143 DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
145 // Determine DIB Vertical Orientation
146 if(bmi->bmiHeader.biHeight > 0)
149 vBits += DIBWidth * bmi->bmiHeader.biHeight - DIBWidth;
152 SourceBitmap = EngCreateBitmap(SourceSize,
153 DIBWidth * scanDirection,
154 BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
157 SourceSurf = (PSURFOBJ)AccessUserObject((ULONG)SourceBitmap);
159 // Destination palette obtained from the hDC
160 hDCPalette = PALETTE_LockPalette(dc->DevInfo->hpalDefault);
161 DDB_Palette_Type = hDCPalette->Mode;
162 DDB_Palette = dc->DevInfo->hpalDefault;
163 PALETTE_UnlockPalette(dc->DevInfo->hpalDefault);
165 // Source palette obtained from the BITMAPINFO
166 DIB_Palette = BuildDIBPalette ( (PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type );
168 // Determine XLATEOBJ for color translation
169 XlateObj = IntEngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
175 // Determine destination rectangle
178 DestRect.right = SourceSize.cx;
179 DestRect.bottom = SourceSize.cy;
181 copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
183 // If it succeeded, return number of scanlines copies
184 if(copyBitsResult == TRUE)
186 result = SourceSize.cy - 1;
190 EngDeleteXlate(XlateObj);
191 PALETTE_FreePalette(DIB_Palette);
192 EngDeleteSurface(SourceBitmap);
193 EngDeleteSurface(DestBitmap);
195 // if (ColorUse == DIB_PAL_COLORS)
196 // WinFree((LPSTR)lpRGB);
198 BITMAPOBJ_UnlockBitmap(hBitmap);
205 NtGdiSetDIBitsToDevice(
216 CONST BITMAPINFO *bmi,
223 UINT STDCALL NtGdiGetDIBColorTable(HDC hDC,
231 // Converts a device-dependent bitmap to a DIB
232 INT STDCALL NtGdiGetDIBits(HDC hDC,
237 LPBITMAPINFO UnsafeInfo,
241 BITMAPCOREHEADER *Core;
242 PBITMAPOBJ BitmapObj;
255 BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
256 if (NULL == BitmapObj)
258 SetLastWin32Error(ERROR_INVALID_HANDLE);
262 RtlZeroMemory(&Info, sizeof(BITMAPINFO));
263 Status = MmCopyFromCaller(&(Info.bmiHeader.biSize),
264 &(UnsafeInfo->bmiHeader.biSize),
266 if (! NT_SUCCESS(Status))
268 SetLastNtError(Status);
269 BITMAPOBJ_UnlockBitmap(hBitmap);
273 /* If the bits are not requested, UnsafeInfo can point to either a
274 BITMAPINFOHEADER or a BITMAPCOREHEADER */
275 if (sizeof(BITMAPINFOHEADER) != Info.bmiHeader.biSize &&
276 (sizeof(BITMAPCOREHEADER) != Info.bmiHeader.biSize ||
279 SetLastWin32Error(ERROR_INVALID_PARAMETER);
280 BITMAPOBJ_UnlockBitmap(hBitmap);
284 Status = MmCopyFromCaller(&(Info.bmiHeader),
285 &(UnsafeInfo->bmiHeader),
286 Info.bmiHeader.biSize);
287 if (! NT_SUCCESS(Status))
289 SetLastNtError(Status);
290 BITMAPOBJ_UnlockBitmap(hBitmap);
296 if (sizeof(BITMAPINFOHEADER) == Info.bmiHeader.biSize)
298 if (0 != Info.bmiHeader.biBitCount)
303 Info.bmiHeader.biWidth = BitmapObj->bitmap.bmWidth;
304 Info.bmiHeader.biHeight = BitmapObj->bitmap.bmHeight;
305 Info.bmiHeader.biPlanes = BitmapObj->bitmap.bmPlanes;
306 Info.bmiHeader.biBitCount = BitmapObj->bitmap.bmBitsPixel;
307 Info.bmiHeader.biCompression = BI_RGB;
308 Info.bmiHeader.biSizeImage = BitmapObj->bitmap.bmHeight * BitmapObj->bitmap.bmWidthBytes;
312 Core = (BITMAPCOREHEADER *)(&Info.bmiHeader);
313 if (0 != Core->bcBitCount)
318 Core->bcWidth = BitmapObj->bitmap.bmWidth;
319 Core->bcHeight = BitmapObj->bitmap.bmHeight;
320 Core->bcPlanes = BitmapObj->bitmap.bmPlanes;
321 Core->bcBitCount = BitmapObj->bitmap.bmBitsPixel;
324 Status = MmCopyToCaller(UnsafeInfo, &Info, Info.bmiHeader.biSize);
325 if (! NT_SUCCESS(Status))
327 SetLastNtError(Status);
328 BITMAPOBJ_UnlockBitmap(hBitmap);
333 else if (0 == StartScan && Info.bmiHeader.biHeight == (LONG) (StartScan + ScanLines) &&
334 Info.bmiHeader.biWidth == BitmapObj->bitmap.bmWidth &&
335 Info.bmiHeader.biHeight == BitmapObj->bitmap.bmHeight &&
336 Info.bmiHeader.biPlanes == BitmapObj->bitmap.bmPlanes &&
337 Info.bmiHeader.biBitCount == BitmapObj->bitmap.bmBitsPixel &&
338 8 < Info.bmiHeader.biBitCount)
340 Info.bmiHeader.biSizeImage = BitmapObj->bitmap.bmHeight * BitmapObj->bitmap.bmWidthBytes;
341 Status = MmCopyToCaller(Bits, BitmapObj->bitmap.bmBits, Info.bmiHeader.biSizeImage);
342 if (! NT_SUCCESS(Status))
344 SetLastNtError(Status);
345 BITMAPOBJ_UnlockBitmap(hBitmap);
348 RtlZeroMemory(&InfoWithBitFields, sizeof(InfoWithBitFields));
349 RtlCopyMemory(&(InfoWithBitFields.Info), &Info, sizeof(BITMAPINFO));
350 if (BI_BITFIELDS == Info.bmiHeader.biCompression)
352 DCObj = DC_LockDc(hDC);
355 SetLastWin32Error(ERROR_INVALID_HANDLE);
356 BITMAPOBJ_UnlockBitmap(hBitmap);
359 PalGdi = PALETTE_LockPalette(DCObj->w.hPalette);
360 BitField = (DWORD *) ((char *) &InfoWithBitFields + InfoWithBitFields.Info.bmiHeader.biSize);
361 BitField[0] = PalGdi->RedMask;
362 BitField[1] = PalGdi->GreenMask;
363 BitField[2] = PalGdi->BlueMask;
364 PALETTE_UnlockPalette(DCObj->w.hPalette);
365 InfoSize = InfoWithBitFields.Info.bmiHeader.biSize + 3 * sizeof(DWORD);
370 InfoSize = Info.bmiHeader.biSize;
372 Status = MmCopyToCaller(UnsafeInfo, &InfoWithBitFields, InfoSize);
373 if (! NT_SUCCESS(Status))
375 SetLastNtError(Status);
376 BITMAPOBJ_UnlockBitmap(hBitmap);
385 BITMAPOBJ_UnlockBitmap(hBitmap);
390 INT STDCALL NtGdiStretchDIBits(HDC hDC,
400 CONST BITMAPINFO *BitsInfo,
407 LONG STDCALL NtGdiGetBitmapBits(HBITMAP hBitmap,
414 bmp = BITMAPOBJ_LockBitmap (hBitmap);
420 /* If the bits vector is null, the function should return the read size */
423 return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
428 DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
432 /* Only get entire lines */
433 height = Count / bmp->bitmap.bmWidthBytes;
434 if (height > bmp->bitmap.bmHeight)
436 height = bmp->bitmap.bmHeight;
438 Count = height * bmp->bitmap.bmWidthBytes;
441 DPRINT("Less then one entire line requested\n");
445 DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
446 hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
447 1 << bmp->bitmap.bmBitsPixel, height );
449 /* FIXME: Call DDI CopyBits here if available */
452 DPRINT("Calling device specific BitmapBits\n");
453 if(bmp->DDBitmap->funcs->pBitmapBits)
455 ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
460 ERR_(bitmap)("BitmapBits == NULL??\n");
467 if(!bmp->bitmap.bmBits)
469 DPRINT ("Bitmap is empty\n");
474 memcpy(Bits, bmp->bitmap.bmBits, Count);
482 // The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
483 // The DDB that is created will be whatever bit depth your reference DC is
484 HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header,
485 DWORD init, LPCVOID bits, const BITMAPINFO *data,
495 if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
496 if (height < 0) height = -height;
498 // Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
499 // colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
501 if (bpp != 1) fColor = TRUE;
502 else if ((coloruse != DIB_RGB_COLORS) ||
503 (init != CBM_INIT) || !data) fColor = FALSE;
506 if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
508 RGBQUAD *rgb = data->bmiColors;
509 DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
511 // Check if the first color of the colormap is black
512 if ((col == RGB(0, 0, 0)))
515 col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
517 // If the second color is white, create a monochrome bitmap
518 fColor = (col != RGB(0xff,0xff,0xff));
522 else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
524 RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
525 DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
527 if ((col == RGB(0,0,0)))
530 col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
531 fColor = (col != RGB(0xff,0xff,0xff));
537 DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize );
542 // Now create the bitmap
544 if (init == CBM_INIT)
546 handle = NtGdiCreateCompatibleBitmap(hdc, width, height);
550 handle = NtGdiCreateBitmap(width, height, 1, bpp, NULL);
553 if (!handle) return 0;
555 if (init == CBM_INIT)
557 NtGdiSetDIBits(hdc, handle, 0, height, bits, data, coloruse);
563 HBITMAP STDCALL NtGdiCreateDIBSection(HDC hDC,
564 CONST BITMAPINFO *bmi,
572 BOOL bDesktopDC = FALSE;
574 // If the reference hdc is null, take the desktop dc
577 hDC = NtGdiCreateCompatableDC(0);
581 if ((dc = DC_LockDc(hDC)))
583 hbitmap = DIB_CreateDIBSection ( dc, (BITMAPINFO*)bmi, Usage, Bits,
584 hSection, dwOffset, 0);
595 DIB_CreateDIBSection(
596 PDC dc, BITMAPINFO *bmi, UINT usage,
597 LPVOID *bits, HANDLE section,
598 DWORD offset, DWORD ovr_pitch)
601 BITMAPOBJ *bmp = NULL;
602 DIBSECTION *dib = NULL;
604 // Fill BITMAP32 structure with DIB data
605 BITMAPINFOHEADER *bi = &bmi->bmiHeader;
611 DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
612 bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
613 bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
615 effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
617 bm.bmWidth = bi->biWidth;
618 bm.bmHeight = effHeight;
619 bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
621 bm.bmPlanes = bi->biPlanes;
622 bm.bmBitsPixel = bi->biBitCount;
625 // Get storage location for DIB bits. Only use biSizeImage if it's valid and
626 // we're dealing with a compressed bitmap. Otherwise, use width * height.
627 totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
628 ? bi->biSizeImage : (ULONG) (bm.bmWidthBytes * effHeight);
631 /* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS,
632 0L, offset, totalSize); */
633 DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n");
634 else if (ovr_pitch && offset)
635 bm.bmBits = (LPVOID) offset;
638 bm.bmBits = EngAllocUserMem(totalSize, 0);
641 /* bm.bmBits = ExAllocatePool(NonPagedPool, totalSize); */
643 if(usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *));
645 // Allocate Memory for DIB and fill structure
648 dib = ExAllocatePool(PagedPool, sizeof(DIBSECTION));
649 RtlZeroMemory(dib, sizeof(DIBSECTION));
656 dib->dsBmih.biSizeImage = totalSize;
658 /* Set dsBitfields values */
659 if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
661 dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0;
663 else switch(bi->biBitCount)
666 dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
667 dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
668 dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
672 dib->dsBitfields[0] = 0xff;
673 dib->dsBitfields[1] = 0xff00;
674 dib->dsBitfields[2] = 0xff0000;
678 dib->dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff;
679 dib->dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0xff00;
680 dib->dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0xff0000;
683 dib->dshSection = section;
684 dib->dsOffset = offset;
687 // Create Device Dependent Bitmap and add DIB pointer
690 res = NtGdiCreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
695 bmp = BITMAPOBJ_LockBitmap(res);
698 NtGdiDeleteObject(bmp);
701 bmp->dib = (DIBSECTION *) dib;
702 /* Install user-mode bits instead of kernel-mode bits */
703 ExFreePool(bmp->bitmap.bmBits);
704 bmp->bitmap.bmBits = bm.bmBits;
706 /* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical
707 device. Obviously, this is left out of the ReactOS implementation. Instead, we call
708 NtGdiSetDIBColorTable. */
709 if(bi->biBitCount == 1) { Entries = 2; } else
710 if(bi->biBitCount == 4) { Entries = 16; } else
711 if(bi->biBitCount == 8) { Entries = 256; }
713 bmp->ColorMap = ExAllocatePool(NonPagedPool, sizeof(RGBQUAD)*Entries);
714 RtlCopyMemory(bmp->ColorMap, bmi->bmiColors, sizeof(RGBQUAD)*Entries);
717 // Clean up in case of errors
718 if (!res || !bmp || !dib || !bm.bmBits)
720 DPRINT("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits);
724 UnmapViewOfFile(bm.bmBits), bm.bmBits = NULL;
726 VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL;
729 if (dib) { ExFreePool(dib); dib = NULL; }
730 if (bmp) { bmp = NULL; }
731 if (res) { BITMAPOBJ_FreeBitmap(res); res = 0; }
736 BITMAPOBJ_UnlockBitmap(res);
739 // Return BITMAP handle and storage location
740 if (NULL != bm.bmBits && NULL != bits)
748 /***********************************************************************
749 * DIB_GetDIBWidthBytes
751 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
752 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
753 * 11/16/1999 (RJJ) lifted from wine
755 INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth)
761 case 1: words = (width + 31) / 32; break;
762 case 4: words = (width + 7) / 8; break;
763 case 8: words = (width + 3) / 4; break;
765 case 16: words = (width + 1) / 2; break;
766 case 24: words = (width * 3 + 3)/4; break;
769 DPRINT("(%d): Unsupported depth\n", depth );
777 /***********************************************************************
778 * DIB_GetDIBImageBytes
780 * Return the number of bytes used to hold the image in a DIB bitmap.
781 * 11/16/1999 (RJJ) lifted from wine
784 INT STDCALL DIB_GetDIBImageBytes (INT width, INT height, INT depth)
786 return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
789 /***********************************************************************
792 * Return the size of the bitmap info structure including color table.
793 * 11/16/1999 (RJJ) lifted from wine
796 INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
800 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
802 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
803 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
804 return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
806 else /* assume BITMAPINFOHEADER */
808 colors = info->bmiHeader.biClrUsed;
809 if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount;
810 return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
814 INT STDCALL DIB_GetBitmapInfo (const BITMAPINFOHEADER *header,
820 if (header->biSize == sizeof(BITMAPINFOHEADER))
822 *width = header->biWidth;
823 *height = header->biHeight;
824 *bpp = header->biBitCount;
825 *compr = header->biCompression;
828 if (header->biSize == sizeof(BITMAPCOREHEADER))
830 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
831 *width = core->bcWidth;
832 *height = core->bcHeight;
833 *bpp = core->bcBitCount;
837 DPRINT("(%ld): wrong size for header\n", header->biSize );
841 // Converts a Device Independent Bitmap (DIB) to a Device Dependant Bitmap (DDB)
842 // The specified Device Context (DC) defines what the DIB should be converted to
843 PBITMAPOBJ FASTCALL DIBtoDDB(HGLOBAL hPackedDIB, HDC hdc) // FIXME: This should be removed. All references to this function should
844 // change to NtGdiSetDIBits
847 PBITMAPOBJ pBmp = NULL;
851 // Get a pointer to the packed DIB's data
852 // pPackedDIB = (LPBYTE)GlobalLock(hPackedDIB);
855 pbits = (LPBYTE)(dib + DIB_BitmapInfoSize((BITMAPINFO*)&dib->dsBmih, DIB_RGB_COLORS));
857 // Create a DDB from the DIB
858 hBmp = NtGdiCreateDIBitmap ( hdc, &dib->dsBmih, CBM_INIT,
859 (LPVOID)pbits, (BITMAPINFO*)&dib->dsBmih, DIB_RGB_COLORS);
861 // GlobalUnlock(hPackedDIB);
863 // Retrieve the internal Pixmap from the DDB
864 pBmp = BITMAPOBJ_LockBitmap(hBmp);
870 DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
877 palObj = (PPALOBJ) PALETTE_LockPalette(dc->DevInfo->hpalDefault);
881 // RELEASEDCINFO(hDC);
885 nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
886 if (lpbmi->bmiHeader.biClrUsed)
888 nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
891 lpRGB = (RGBQUAD *)ExAllocatePool(NonPagedPool, sizeof(RGBQUAD) * nNumColors);
892 lpIndex = (DWORD *)&lpbmi->bmiColors[0];
894 for (i = 0; i < nNumColors; i++)
896 lpRGB[i].rgbRed = palObj->logpalette->palPalEntry[*lpIndex].peRed;
897 lpRGB[i].rgbGreen = palObj->logpalette->palPalEntry[*lpIndex].peGreen;
898 lpRGB[i].rgbBlue = palObj->logpalette->palPalEntry[*lpIndex].peBlue;
901 // RELEASEDCINFO(hDC);
902 PALETTE_UnlockPalette(dc->DevInfo->hpalDefault);
907 PPALETTEENTRY STDCALL
908 DIBColorTableToPaletteEntries (
909 PPALETTEENTRY palEntries,
910 const RGBQUAD *DIBColorTable,
916 for (i = 0; i < ColorCount; i++)
918 palEntries->peRed = DIBColorTable->rgbRed;
919 palEntries->peGreen = DIBColorTable->rgbGreen;
920 palEntries->peBlue = DIBColorTable->rgbBlue;
929 BuildDIBPalette (PBITMAPINFO bmi, PINT paletteType)
933 PALETTEENTRY *palEntries = NULL;
936 // Determine Bits Per Pixel
937 bits = bmi->bmiHeader.biBitCount;
939 // Determine paletteType from Bits Per Pixel
942 *paletteType = PAL_INDEXED;
946 *paletteType = PAL_BITFIELDS;
950 *paletteType = PAL_BGR;
953 if (bmi->bmiHeader.biClrUsed == 0)
955 ColorCount = 1 << bmi->bmiHeader.biBitCount;
959 ColorCount = bmi->bmiHeader.biClrUsed;
962 if (PAL_INDEXED == *paletteType)
964 palEntries = ExAllocatePool(NonPagedPool, sizeof(PALETTEENTRY)*ColorCount);
965 DIBColorTableToPaletteEntries(palEntries, bmi->bmiColors, ColorCount);
967 hPal = PALETTE_AllocPalette( *paletteType, ColorCount, (ULONG*)palEntries, 0, 0, 0 );
968 if (NULL != palEntries)
970 ExFreePool(palEntries);