1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: GNU GPL, See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS kernel
4c2c66affSColin Finck * PURPOSE: Bitmap functions
5c2c66affSColin Finck * FILE: win32ss/gdi/ntgdi/bitmaps.c
60aa21c33SKatayama Hirofumi MZ * PROGRAMERS: Timo Kreuzer <timo.kreuzer@reactos.org>
70aa21c33SKatayama Hirofumi MZ * Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck #include <win32k.h>
11c2c66affSColin Finck
12c2c66affSColin Finck #define NDEBUG
13c2c66affSColin Finck #include <debug.h>
14c2c66affSColin Finck
15c2c66affSColin Finck BOOL
16c2c66affSColin Finck NTAPI
GreSetBitmapOwner(_In_ HBITMAP hbmp,_In_ ULONG ulOwner)17c2c66affSColin Finck GreSetBitmapOwner(
18c2c66affSColin Finck _In_ HBITMAP hbmp,
19c2c66affSColin Finck _In_ ULONG ulOwner)
20c2c66affSColin Finck {
21c2c66affSColin Finck /* Check if we have the correct object type */
22c2c66affSColin Finck if (GDI_HANDLE_GET_TYPE(hbmp) != GDILoObjType_LO_BITMAP_TYPE)
23c2c66affSColin Finck {
24c2c66affSColin Finck DPRINT1("Incorrect type for hbmp: %p\n", hbmp);
25c2c66affSColin Finck return FALSE;
26c2c66affSColin Finck }
27c2c66affSColin Finck
28c2c66affSColin Finck /// FIXME: this is a hack and doesn't handle a race condition properly.
29c2c66affSColin Finck /// It needs to be done in GDIOBJ_vSetObjectOwner atomically.
30c2c66affSColin Finck
31c2c66affSColin Finck /* Check if we set public or none */
32c2c66affSColin Finck if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) ||
33c2c66affSColin Finck (ulOwner == GDI_OBJ_HMGR_NONE))
34c2c66affSColin Finck {
35c2c66affSColin Finck /* Only allow this for owned objects */
36c2c66affSColin Finck if (GreGetObjectOwner(hbmp) != GDI_OBJ_HMGR_POWNED)
37c2c66affSColin Finck {
38c2c66affSColin Finck DPRINT1("Cannot change owner for non-powned hbmp\n");
39c2c66affSColin Finck return FALSE;
40c2c66affSColin Finck }
41c2c66affSColin Finck }
42c2c66affSColin Finck
43c2c66affSColin Finck return GreSetObjectOwner(hbmp, ulOwner);
44c2c66affSColin Finck }
45c2c66affSColin Finck
460aa21c33SKatayama Hirofumi MZ LONG
47c2c66affSColin Finck NTAPI
UnsafeSetBitmapBits(_Inout_ PSURFACE psurf,_In_ ULONG cjBits,_In_ const VOID * pvBits)48c2c66affSColin Finck UnsafeSetBitmapBits(
49c2c66affSColin Finck _Inout_ PSURFACE psurf,
50c2c66affSColin Finck _In_ ULONG cjBits,
51c2c66affSColin Finck _In_ const VOID *pvBits)
52c2c66affSColin Finck {
53c2c66affSColin Finck PUCHAR pjDst;
54c2c66affSColin Finck const UCHAR *pjSrc;
551cd2f543SKatayama Hirofumi MZ LONG lDeltaDst, lDeltaSrc, lDeltaDstAbs;
560aa21c33SKatayama Hirofumi MZ ULONG Y, iSrc, iDst, cbSrc, cbDst, nWidth, nHeight, cBitsPixel;
570aa21c33SKatayama Hirofumi MZ
58c2c66affSColin Finck NT_ASSERT(psurf->flags & API_BITMAP);
59c2c66affSColin Finck NT_ASSERT(psurf->SurfObj.iBitmapFormat <= BMF_32BPP);
60c2c66affSColin Finck
61c2c66affSColin Finck nWidth = psurf->SurfObj.sizlBitmap.cx;
6231d616ffSKatayama Hirofumi MZ nHeight = psurf->SurfObj.sizlBitmap.cy;
63c2c66affSColin Finck cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
64c2c66affSColin Finck
65c2c66affSColin Finck pjDst = psurf->SurfObj.pvScan0;
66c2c66affSColin Finck pjSrc = pvBits;
67c2c66affSColin Finck lDeltaDst = psurf->SurfObj.lDelta;
681cd2f543SKatayama Hirofumi MZ lDeltaDstAbs = labs(lDeltaDst);
69c2c66affSColin Finck lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
701cd2f543SKatayama Hirofumi MZ NT_ASSERT(lDeltaSrc <= lDeltaDstAbs);
71c2c66affSColin Finck
721cd2f543SKatayama Hirofumi MZ cbDst = lDeltaDstAbs * nHeight;
730aa21c33SKatayama Hirofumi MZ cbSrc = lDeltaSrc * nHeight;
740aa21c33SKatayama Hirofumi MZ cjBits = min(cjBits, cbSrc);
75c2c66affSColin Finck
760aa21c33SKatayama Hirofumi MZ iSrc = iDst = 0;
770aa21c33SKatayama Hirofumi MZ for (Y = 0; Y < nHeight; Y++)
78c2c66affSColin Finck {
791cd2f543SKatayama Hirofumi MZ if (iSrc + lDeltaSrc > cjBits || iDst + lDeltaDstAbs > cbDst)
800aa21c33SKatayama Hirofumi MZ {
810aa21c33SKatayama Hirofumi MZ LONG lDelta = min(cjBits - iSrc, cbDst - iDst);
820aa21c33SKatayama Hirofumi MZ NT_ASSERT(lDelta >= 0);
830aa21c33SKatayama Hirofumi MZ RtlCopyMemory(pjDst, pjSrc, lDelta);
840aa21c33SKatayama Hirofumi MZ iSrc += lDelta;
850aa21c33SKatayama Hirofumi MZ break;
86c2c66affSColin Finck }
87c2c66affSColin Finck
880aa21c33SKatayama Hirofumi MZ /* Copy one line */
890aa21c33SKatayama Hirofumi MZ RtlCopyMemory(pjDst, pjSrc, lDeltaSrc);
900aa21c33SKatayama Hirofumi MZ pjSrc += lDeltaSrc;
910aa21c33SKatayama Hirofumi MZ pjDst += lDeltaDst;
920aa21c33SKatayama Hirofumi MZ iSrc += lDeltaSrc;
931cd2f543SKatayama Hirofumi MZ iDst += lDeltaDstAbs;
940aa21c33SKatayama Hirofumi MZ }
950aa21c33SKatayama Hirofumi MZ
960aa21c33SKatayama Hirofumi MZ return iSrc;
97c2c66affSColin Finck }
98c2c66affSColin Finck
99c2c66affSColin Finck HBITMAP
100c2c66affSColin Finck NTAPI
GreCreateBitmapEx(_In_ ULONG nWidth,_In_ ULONG nHeight,_In_ ULONG cjWidthBytes,_In_ ULONG iFormat,_In_ USHORT fjBitmap,_In_ ULONG cjSizeImage,_In_opt_ PVOID pvBits,_In_ FLONG flags)101c2c66affSColin Finck GreCreateBitmapEx(
102c2c66affSColin Finck _In_ ULONG nWidth,
103c2c66affSColin Finck _In_ ULONG nHeight,
104c2c66affSColin Finck _In_ ULONG cjWidthBytes,
105c2c66affSColin Finck _In_ ULONG iFormat,
106c2c66affSColin Finck _In_ USHORT fjBitmap,
107c2c66affSColin Finck _In_ ULONG cjSizeImage,
108c2c66affSColin Finck _In_opt_ PVOID pvBits,
109c2c66affSColin Finck _In_ FLONG flags)
110c2c66affSColin Finck {
111c2c66affSColin Finck PSURFACE psurf;
112c2c66affSColin Finck HBITMAP hbmp;
113c2c66affSColin Finck PVOID pvCompressedBits = NULL;
114c2c66affSColin Finck
115c2c66affSColin Finck /* Verify format */
116c2c66affSColin Finck if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
117c2c66affSColin Finck
118c2c66affSColin Finck /* The infamous RLE hack */
119c2c66affSColin Finck if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
120c2c66affSColin Finck {
121c2c66affSColin Finck pvCompressedBits = pvBits;
122c2c66affSColin Finck pvBits = NULL;
123c2c66affSColin Finck iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
124c2c66affSColin Finck }
125c2c66affSColin Finck
126c2c66affSColin Finck /* Allocate a surface */
127c2c66affSColin Finck psurf = SURFACE_AllocSurface(STYPE_BITMAP,
128c2c66affSColin Finck nWidth,
129c2c66affSColin Finck nHeight,
130c2c66affSColin Finck iFormat,
131c2c66affSColin Finck fjBitmap,
132c2c66affSColin Finck cjWidthBytes,
133c2c66affSColin Finck pvCompressedBits ? 0 : cjSizeImage,
134c2c66affSColin Finck pvBits);
135c2c66affSColin Finck if (!psurf)
136c2c66affSColin Finck {
137c2c66affSColin Finck DPRINT1("SURFACE_AllocSurface failed.\n");
138c2c66affSColin Finck return NULL;
139c2c66affSColin Finck }
140c2c66affSColin Finck
141c2c66affSColin Finck /* The infamous RLE hack */
142c2c66affSColin Finck if (pvCompressedBits)
143c2c66affSColin Finck {
144c2c66affSColin Finck SIZEL sizl;
145c2c66affSColin Finck LONG lDelta;
146c2c66affSColin Finck
147c2c66affSColin Finck sizl.cx = nWidth;
148c2c66affSColin Finck sizl.cy = nHeight;
149c2c66affSColin Finck lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]);
150c2c66affSColin Finck
151c2c66affSColin Finck pvBits = psurf->SurfObj.pvBits;
152c2c66affSColin Finck DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat, cjSizeImage);
153c2c66affSColin Finck }
154c2c66affSColin Finck
155c2c66affSColin Finck /* Get the handle for the bitmap */
156c2c66affSColin Finck hbmp = (HBITMAP)psurf->SurfObj.hsurf;
157c2c66affSColin Finck
158c2c66affSColin Finck /* Mark as API bitmap */
159c2c66affSColin Finck psurf->flags |= (flags | API_BITMAP);
160c2c66affSColin Finck
161c2c66affSColin Finck /* Unlock the surface and return */
162c2c66affSColin Finck SURFACE_UnlockSurface(psurf);
163c2c66affSColin Finck return hbmp;
164c2c66affSColin Finck }
165c2c66affSColin Finck
166c2c66affSColin Finck /* Creates a DDB surface,
167c2c66affSColin Finck * as in CreateCompatibleBitmap or CreateBitmap.
168c2c66affSColin Finck * Note that each scanline must be 32bit aligned!
169c2c66affSColin Finck */
170c2c66affSColin Finck HBITMAP
171c2c66affSColin Finck NTAPI
GreCreateBitmap(_In_ ULONG nWidth,_In_ ULONG nHeight,_In_ ULONG cPlanes,_In_ ULONG cBitsPixel,_In_opt_ PVOID pvBits)172c2c66affSColin Finck GreCreateBitmap(
173c2c66affSColin Finck _In_ ULONG nWidth,
174c2c66affSColin Finck _In_ ULONG nHeight,
175c2c66affSColin Finck _In_ ULONG cPlanes,
176c2c66affSColin Finck _In_ ULONG cBitsPixel,
177c2c66affSColin Finck _In_opt_ PVOID pvBits)
178c2c66affSColin Finck {
179c2c66affSColin Finck /* Call the extended function */
180c2c66affSColin Finck return GreCreateBitmapEx(nWidth,
181c2c66affSColin Finck nHeight,
182c2c66affSColin Finck 0, /* Auto width */
183c2c66affSColin Finck BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
184c2c66affSColin Finck 0, /* No bitmap flags */
185c2c66affSColin Finck 0, /* Auto size */
186c2c66affSColin Finck pvBits,
187c2c66affSColin Finck DDB_SURFACE /* DDB */);
188c2c66affSColin Finck }
189c2c66affSColin Finck
190c2c66affSColin Finck HBITMAP
191c2c66affSColin Finck APIENTRY
NtGdiCreateBitmap(IN INT nWidth,IN INT nHeight,IN UINT cPlanes,IN UINT cBitsPixel,IN OPTIONAL LPBYTE pUnsafeBits)192c2c66affSColin Finck NtGdiCreateBitmap(
193c2c66affSColin Finck IN INT nWidth,
194c2c66affSColin Finck IN INT nHeight,
195c2c66affSColin Finck IN UINT cPlanes,
196c2c66affSColin Finck IN UINT cBitsPixel,
197c2c66affSColin Finck IN OPTIONAL LPBYTE pUnsafeBits)
198c2c66affSColin Finck {
199c2c66affSColin Finck HBITMAP hbmp;
200c2c66affSColin Finck ULONG cRealBpp, cjWidthBytes, iFormat;
201c2c66affSColin Finck ULONGLONG cjSize;
202c2c66affSColin Finck PSURFACE psurf;
203c2c66affSColin Finck
204c2c66affSColin Finck /* Calculate bitmap format and real bits per pixel. */
205c2c66affSColin Finck iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
206c2c66affSColin Finck cRealBpp = gajBitsPerFormat[iFormat];
207c2c66affSColin Finck
208c2c66affSColin Finck /* Calculate width and image size in bytes */
209c2c66affSColin Finck cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp);
210c2c66affSColin Finck cjSize = (ULONGLONG)cjWidthBytes * nHeight;
211c2c66affSColin Finck
212c2c66affSColin Finck /* Check parameters (possible overflow of cjSize!) */
213c2c66affSColin Finck if ((iFormat == 0) || (nWidth <= 0) || (nWidth >= 0x8000000) || (nHeight <= 0) ||
214c2c66affSColin Finck (cBitsPixel > 32) || (cPlanes > 32) || (cjSize >= 0x100000000ULL))
215c2c66affSColin Finck {
216c2c66affSColin Finck DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%u, Planes=%u\n",
217c2c66affSColin Finck nWidth, nHeight, cBitsPixel, cPlanes);
218c2c66affSColin Finck EngSetLastError(ERROR_INVALID_PARAMETER);
219c2c66affSColin Finck return NULL;
220c2c66affSColin Finck }
221c2c66affSColin Finck
222c2c66affSColin Finck /* Allocate the surface (but don't set the bits) */
223c2c66affSColin Finck psurf = SURFACE_AllocSurface(STYPE_BITMAP,
224c2c66affSColin Finck nWidth,
225c2c66affSColin Finck nHeight,
226c2c66affSColin Finck iFormat,
227c2c66affSColin Finck 0,
228c2c66affSColin Finck 0,
229c2c66affSColin Finck 0,
230c2c66affSColin Finck NULL);
231c2c66affSColin Finck if (!psurf)
232c2c66affSColin Finck {
233c2c66affSColin Finck DPRINT1("SURFACE_AllocSurface failed.\n");
234c2c66affSColin Finck return NULL;
235c2c66affSColin Finck }
236c2c66affSColin Finck
237c2c66affSColin Finck /* Mark as API and DDB bitmap */
238c2c66affSColin Finck psurf->flags |= (API_BITMAP | DDB_SURFACE);
239c2c66affSColin Finck
240c2c66affSColin Finck /* Check if we have bits to set */
241c2c66affSColin Finck if (pUnsafeBits)
242c2c66affSColin Finck {
243c2c66affSColin Finck /* Protect with SEH and copy the bits */
244c2c66affSColin Finck _SEH2_TRY
245c2c66affSColin Finck {
246c2c66affSColin Finck ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
247c2c66affSColin Finck UnsafeSetBitmapBits(psurf, cjSize, pUnsafeBits);
248c2c66affSColin Finck }
249c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
250c2c66affSColin Finck {
251c2c66affSColin Finck GDIOBJ_vDeleteObject(&psurf->BaseObject);
252c2c66affSColin Finck _SEH2_YIELD(return NULL;)
253c2c66affSColin Finck }
254c2c66affSColin Finck _SEH2_END
255c2c66affSColin Finck }
256c2c66affSColin Finck else
257c2c66affSColin Finck {
258c2c66affSColin Finck /* Zero the bits */
259c2c66affSColin Finck RtlZeroMemory(psurf->SurfObj.pvBits, psurf->SurfObj.cjBits);
260c2c66affSColin Finck }
261c2c66affSColin Finck
262c2c66affSColin Finck /* Get the handle for the bitmap */
263c2c66affSColin Finck hbmp = (HBITMAP)psurf->SurfObj.hsurf;
264c2c66affSColin Finck
265c2c66affSColin Finck /* Unlock the surface */
266c2c66affSColin Finck SURFACE_UnlockSurface(psurf);
267c2c66affSColin Finck
268c2c66affSColin Finck return hbmp;
269c2c66affSColin Finck }
270c2c66affSColin Finck
271c2c66affSColin Finck
272c2c66affSColin Finck HBITMAP FASTCALL
IntCreateCompatibleBitmap(PDC Dc,INT Width,INT Height,UINT Planes,UINT Bpp)273c2c66affSColin Finck IntCreateCompatibleBitmap(
274c2c66affSColin Finck PDC Dc,
275c2c66affSColin Finck INT Width,
276c2c66affSColin Finck INT Height,
277c2c66affSColin Finck UINT Planes,
278c2c66affSColin Finck UINT Bpp)
279c2c66affSColin Finck {
280c2c66affSColin Finck HBITMAP Bmp = NULL;
281c2c66affSColin Finck PPALETTE ppal;
282c2c66affSColin Finck
283c2c66affSColin Finck /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
284c2c66affSColin Finck if (0 == Width || 0 == Height)
285c2c66affSColin Finck {
286c2c66affSColin Finck return NtGdiGetStockObject(DEFAULT_BITMAP);
287c2c66affSColin Finck }
288c2c66affSColin Finck
2895e93daa9SHermès Bélusca-Maïto if (Dc->dctype != DCTYPE_MEMORY)
290c2c66affSColin Finck {
291c2c66affSColin Finck PSURFACE psurf;
292c2c66affSColin Finck
293c2c66affSColin Finck Bmp = GreCreateBitmap(abs(Width),
294c2c66affSColin Finck abs(Height),
295c2c66affSColin Finck Planes ? Planes : 1,
296c2c66affSColin Finck Bpp ? Bpp : Dc->ppdev->gdiinfo.cBitsPixel,
297c2c66affSColin Finck NULL);
298c2c66affSColin Finck if (Bmp == NULL)
299c2c66affSColin Finck {
300c2c66affSColin Finck DPRINT1("Failed to allocate a bitmap!\n");
301c2c66affSColin Finck return NULL;
302c2c66affSColin Finck }
303c2c66affSColin Finck
304c2c66affSColin Finck psurf = SURFACE_ShareLockSurface(Bmp);
305c2c66affSColin Finck ASSERT(psurf);
306c2c66affSColin Finck
307c2c66affSColin Finck /* Dereference old palette and set new palette */
308c2c66affSColin Finck ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
309c2c66affSColin Finck ASSERT(ppal);
310c2c66affSColin Finck SURFACE_vSetPalette(psurf, ppal);
311c2c66affSColin Finck PALETTE_ShareUnlockPalette(ppal);
312c2c66affSColin Finck
313c2c66affSColin Finck /* Set flags */
314c2c66affSColin Finck psurf->flags = API_BITMAP;
315c2c66affSColin Finck psurf->hdc = NULL; // FIXME:
316c2c66affSColin Finck psurf->SurfObj.hdev = (HDEV)Dc->ppdev;
317c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
318c2c66affSColin Finck }
319c2c66affSColin Finck else
320c2c66affSColin Finck {
321c2c66affSColin Finck DIBSECTION dibs;
322c2c66affSColin Finck INT Count;
323c2c66affSColin Finck PSURFACE psurf = Dc->dclevel.pSurface;
324c2c66affSColin Finck if(!psurf) psurf = psurfDefaultBitmap;
325c2c66affSColin Finck Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
326c2c66affSColin Finck
327c2c66affSColin Finck if (Count == sizeof(BITMAP))
328c2c66affSColin Finck {
329c2c66affSColin Finck PSURFACE psurfBmp;
330c2c66affSColin Finck
331c2c66affSColin Finck Bmp = GreCreateBitmap(abs(Width),
332c2c66affSColin Finck abs(Height),
333c2c66affSColin Finck Planes ? Planes : 1,
334c2c66affSColin Finck Bpp ? Bpp : dibs.dsBm.bmBitsPixel,
335c2c66affSColin Finck NULL);
336*090ccb3dSTimo Kreuzer if (Bmp == NULL)
337*090ccb3dSTimo Kreuzer {
338*090ccb3dSTimo Kreuzer DPRINT1("Failed to allocate a bitmap!\n");
339*090ccb3dSTimo Kreuzer return NULL;
340*090ccb3dSTimo Kreuzer }
341c2c66affSColin Finck psurfBmp = SURFACE_ShareLockSurface(Bmp);
342c2c66affSColin Finck ASSERT(psurfBmp);
343c2c66affSColin Finck
344c2c66affSColin Finck /* Dereference old palette and set new palette */
345c2c66affSColin Finck SURFACE_vSetPalette(psurfBmp, psurf->ppal);
346c2c66affSColin Finck
347c2c66affSColin Finck /* Set flags */
348c2c66affSColin Finck psurfBmp->flags = API_BITMAP;
349c2c66affSColin Finck psurfBmp->hdc = NULL; // FIXME:
350*090ccb3dSTimo Kreuzer psurfBmp->SurfObj.hdev = (HDEV)Dc->ppdev;
351c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurfBmp);
352c2c66affSColin Finck }
353c2c66affSColin Finck else if (Count == sizeof(DIBSECTION))
354c2c66affSColin Finck {
355c2c66affSColin Finck /* A DIB section is selected in the DC */
356c2c66affSColin Finck BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
357c2c66affSColin Finck PVOID Bits;
358c2c66affSColin Finck BITMAPINFO* bi = (BITMAPINFO*)buf;
359c2c66affSColin Finck
360c2c66affSColin Finck bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
361c2c66affSColin Finck bi->bmiHeader.biWidth = Width;
362c2c66affSColin Finck bi->bmiHeader.biHeight = Height;
363c2c66affSColin Finck bi->bmiHeader.biPlanes = Planes ? Planes : dibs.dsBmih.biPlanes;
364c2c66affSColin Finck bi->bmiHeader.biBitCount = Bpp ? Bpp : dibs.dsBmih.biBitCount;
365c2c66affSColin Finck bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
366c2c66affSColin Finck bi->bmiHeader.biSizeImage = 0;
367c2c66affSColin Finck bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
368c2c66affSColin Finck bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
369c2c66affSColin Finck bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
370c2c66affSColin Finck bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
371c2c66affSColin Finck
372c2c66affSColin Finck if (bi->bmiHeader.biCompression == BI_BITFIELDS)
373c2c66affSColin Finck {
374c2c66affSColin Finck /* Copy the color masks */
375c2c66affSColin Finck RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
376c2c66affSColin Finck }
377c2c66affSColin Finck else if (bi->bmiHeader.biBitCount <= 8)
378c2c66affSColin Finck {
379c2c66affSColin Finck /* Copy the color table */
380c2c66affSColin Finck UINT Index;
381c2c66affSColin Finck PPALETTE PalGDI;
382c2c66affSColin Finck
383c2c66affSColin Finck if (!psurf->ppal)
384c2c66affSColin Finck {
385c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
386c2c66affSColin Finck return 0;
387c2c66affSColin Finck }
388c2c66affSColin Finck
389c2c66affSColin Finck PalGDI = psurf->ppal;
390c2c66affSColin Finck
391c2c66affSColin Finck for (Index = 0;
392c2c66affSColin Finck Index < 256 && Index < PalGDI->NumColors;
393c2c66affSColin Finck Index++)
394c2c66affSColin Finck {
395c2c66affSColin Finck bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
396c2c66affSColin Finck bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
397c2c66affSColin Finck bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
398c2c66affSColin Finck bi->bmiColors[Index].rgbReserved = 0;
399c2c66affSColin Finck }
400c2c66affSColin Finck }
401c2c66affSColin Finck
402c2c66affSColin Finck Bmp = DIB_CreateDIBSection(Dc,
403c2c66affSColin Finck bi,
404c2c66affSColin Finck DIB_RGB_COLORS,
405c2c66affSColin Finck &Bits,
406c2c66affSColin Finck NULL,
407c2c66affSColin Finck 0,
408c2c66affSColin Finck 0);
409c2c66affSColin Finck return Bmp;
410c2c66affSColin Finck }
411c2c66affSColin Finck }
412c2c66affSColin Finck return Bmp;
413c2c66affSColin Finck }
414c2c66affSColin Finck
415c2c66affSColin Finck HBITMAP APIENTRY
NtGdiCreateCompatibleBitmap(HDC hDC,INT Width,INT Height)416c2c66affSColin Finck NtGdiCreateCompatibleBitmap(
417c2c66affSColin Finck HDC hDC,
418c2c66affSColin Finck INT Width,
419c2c66affSColin Finck INT Height)
420c2c66affSColin Finck {
421c2c66affSColin Finck HBITMAP Bmp;
422c2c66affSColin Finck PDC Dc;
423c2c66affSColin Finck
424c2c66affSColin Finck /* Check parameters */
425c2c66affSColin Finck if ((Width <= 0) || (Height <= 0) || ((Width * Height) > 0x3FFFFFFF))
426c2c66affSColin Finck {
427c2c66affSColin Finck EngSetLastError(ERROR_INVALID_PARAMETER);
428c2c66affSColin Finck return NULL;
429c2c66affSColin Finck }
430c2c66affSColin Finck
431c2c66affSColin Finck if (!hDC)
432c2c66affSColin Finck return GreCreateBitmap(Width, Height, 1, 1, 0);
433c2c66affSColin Finck
434c2c66affSColin Finck Dc = DC_LockDc(hDC);
435c2c66affSColin Finck
436c2c66affSColin Finck DPRINT("NtGdiCreateCompatibleBitmap(%p,%d,%d, bpp:%u) = \n",
437c2c66affSColin Finck hDC, Width, Height, Dc->ppdev->gdiinfo.cBitsPixel);
438c2c66affSColin Finck
439c2c66affSColin Finck if (NULL == Dc)
440c2c66affSColin Finck {
441c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
442c2c66affSColin Finck return NULL;
443c2c66affSColin Finck }
444c2c66affSColin Finck
445c2c66affSColin Finck Bmp = IntCreateCompatibleBitmap(Dc, Width, Height, 0, 0);
446c2c66affSColin Finck
447c2c66affSColin Finck DC_UnlockDc(Dc);
448c2c66affSColin Finck return Bmp;
449c2c66affSColin Finck }
450c2c66affSColin Finck
451c2c66affSColin Finck BOOL
452c2c66affSColin Finck NTAPI
GreGetBitmapDimension(_In_ HBITMAP hBitmap,_Out_ LPSIZE psizDim)453c2c66affSColin Finck GreGetBitmapDimension(
454c2c66affSColin Finck _In_ HBITMAP hBitmap,
455c2c66affSColin Finck _Out_ LPSIZE psizDim)
456c2c66affSColin Finck {
457c2c66affSColin Finck PSURFACE psurfBmp;
458c2c66affSColin Finck
459c2c66affSColin Finck if (hBitmap == NULL)
460c2c66affSColin Finck return FALSE;
461c2c66affSColin Finck
462c2c66affSColin Finck /* Lock the bitmap */
463c2c66affSColin Finck psurfBmp = SURFACE_ShareLockSurface(hBitmap);
464c2c66affSColin Finck if (psurfBmp == NULL)
465c2c66affSColin Finck {
466c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
467c2c66affSColin Finck return FALSE;
468c2c66affSColin Finck }
469c2c66affSColin Finck
470c2c66affSColin Finck *psizDim = psurfBmp->sizlDim;
471c2c66affSColin Finck
472c2c66affSColin Finck /* Unlock the bitmap */
473c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurfBmp);
474c2c66affSColin Finck
475c2c66affSColin Finck return TRUE;
476c2c66affSColin Finck }
477c2c66affSColin Finck
478c2c66affSColin Finck BOOL
479c2c66affSColin Finck APIENTRY
NtGdiGetBitmapDimension(HBITMAP hBitmap,LPSIZE psizDim)480c2c66affSColin Finck NtGdiGetBitmapDimension(
481c2c66affSColin Finck HBITMAP hBitmap,
482c2c66affSColin Finck LPSIZE psizDim)
483c2c66affSColin Finck {
484c2c66affSColin Finck SIZE dim;
485c2c66affSColin Finck
486c2c66affSColin Finck if (!GreGetBitmapDimension(hBitmap, &dim))
487c2c66affSColin Finck return FALSE;
488c2c66affSColin Finck
489c2c66affSColin Finck /* Use SEH to copy the data to the caller */
490c2c66affSColin Finck _SEH2_TRY
491c2c66affSColin Finck {
492c2c66affSColin Finck ProbeForWrite(psizDim, sizeof(*psizDim), 1);
493c2c66affSColin Finck *psizDim = dim;
494c2c66affSColin Finck }
495c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
496c2c66affSColin Finck {
497c2c66affSColin Finck _SEH2_YIELD(return FALSE);
498c2c66affSColin Finck }
499c2c66affSColin Finck _SEH2_END
500c2c66affSColin Finck
501c2c66affSColin Finck return TRUE;
502c2c66affSColin Finck }
503c2c66affSColin Finck
504c2c66affSColin Finck
50529795a2dSKatayama Hirofumi MZ LONG
506c2c66affSColin Finck FASTCALL
UnsafeGetBitmapBits(PSURFACE psurf,DWORD Bytes,OUT PBYTE pvBits)507c2c66affSColin Finck UnsafeGetBitmapBits(
508c2c66affSColin Finck PSURFACE psurf,
509c2c66affSColin Finck DWORD Bytes,
510c2c66affSColin Finck OUT PBYTE pvBits)
511c2c66affSColin Finck {
512c2c66affSColin Finck PUCHAR pjDst, pjSrc;
5131cd2f543SKatayama Hirofumi MZ LONG lDeltaDst, lDeltaSrc, lDeltaSrcAbs;
51429795a2dSKatayama Hirofumi MZ ULONG Y, iSrc, iDst, cbSrc, cbDst, nWidth, nHeight, cBitsPixel;
515c2c66affSColin Finck
516c2c66affSColin Finck nWidth = psurf->SurfObj.sizlBitmap.cx;
51731d616ffSKatayama Hirofumi MZ nHeight = psurf->SurfObj.sizlBitmap.cy;
518c2c66affSColin Finck cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
519c2c66affSColin Finck
520c2c66affSColin Finck /* Get pointers */
521c2c66affSColin Finck pjSrc = psurf->SurfObj.pvScan0;
522c2c66affSColin Finck pjDst = pvBits;
523c2c66affSColin Finck lDeltaSrc = psurf->SurfObj.lDelta;
5241cd2f543SKatayama Hirofumi MZ lDeltaSrcAbs = labs(lDeltaSrc);
525c2c66affSColin Finck lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
5261cd2f543SKatayama Hirofumi MZ NT_ASSERT(lDeltaSrcAbs >= lDeltaDst);
527c2c66affSColin Finck
5281cd2f543SKatayama Hirofumi MZ cbSrc = nHeight * lDeltaSrcAbs;
52929795a2dSKatayama Hirofumi MZ cbDst = nHeight * lDeltaDst;
53029795a2dSKatayama Hirofumi MZ Bytes = min(Bytes, cbDst);
53129795a2dSKatayama Hirofumi MZ
53229795a2dSKatayama Hirofumi MZ iSrc = iDst = 0;
53329795a2dSKatayama Hirofumi MZ for (Y = 0; Y < nHeight; Y++)
534c2c66affSColin Finck {
5351cd2f543SKatayama Hirofumi MZ if (iSrc + lDeltaSrcAbs > cbSrc || iDst + lDeltaDst > Bytes)
53629795a2dSKatayama Hirofumi MZ {
53729795a2dSKatayama Hirofumi MZ LONG lDelta = min(cbSrc - iSrc, Bytes - iDst);
53829795a2dSKatayama Hirofumi MZ NT_ASSERT(lDelta >= 0);
53929795a2dSKatayama Hirofumi MZ RtlCopyMemory(pjDst, pjSrc, lDelta);
54029795a2dSKatayama Hirofumi MZ iDst += lDelta;
54129795a2dSKatayama Hirofumi MZ break;
54229795a2dSKatayama Hirofumi MZ }
54329795a2dSKatayama Hirofumi MZ
544c2c66affSColin Finck /* Copy one line */
545c2c66affSColin Finck RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
546c2c66affSColin Finck pjSrc += lDeltaSrc;
547c2c66affSColin Finck pjDst += lDeltaDst;
5481cd2f543SKatayama Hirofumi MZ iSrc += lDeltaSrcAbs;
54929795a2dSKatayama Hirofumi MZ iDst += lDeltaDst;
550c2c66affSColin Finck }
55129795a2dSKatayama Hirofumi MZ
55229795a2dSKatayama Hirofumi MZ return iDst;
553c2c66affSColin Finck }
554c2c66affSColin Finck
555c2c66affSColin Finck LONG
556c2c66affSColin Finck APIENTRY
NtGdiGetBitmapBits(HBITMAP hBitmap,ULONG cjBuffer,OUT OPTIONAL PBYTE pUnsafeBits)557c2c66affSColin Finck NtGdiGetBitmapBits(
558c2c66affSColin Finck HBITMAP hBitmap,
559c2c66affSColin Finck ULONG cjBuffer,
560c2c66affSColin Finck OUT OPTIONAL PBYTE pUnsafeBits)
561c2c66affSColin Finck {
562c2c66affSColin Finck PSURFACE psurf;
563c2c66affSColin Finck ULONG cjSize;
564c2c66affSColin Finck LONG ret;
565c2c66affSColin Finck
566c2c66affSColin Finck /* Check parameters */
567c2c66affSColin Finck if (pUnsafeBits != NULL && cjBuffer == 0)
568c2c66affSColin Finck {
569c2c66affSColin Finck return 0;
570c2c66affSColin Finck }
571c2c66affSColin Finck
572c2c66affSColin Finck /* Lock the bitmap */
573c2c66affSColin Finck psurf = SURFACE_ShareLockSurface(hBitmap);
574c2c66affSColin Finck if (!psurf)
575c2c66affSColin Finck {
576c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
577c2c66affSColin Finck return 0;
578c2c66affSColin Finck }
579c2c66affSColin Finck
580c2c66affSColin Finck /* Calculate the size of the bitmap in bytes */
581c2c66affSColin Finck cjSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
582c2c66affSColin Finck BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
58331d616ffSKatayama Hirofumi MZ psurf->SurfObj.sizlBitmap.cy;
584c2c66affSColin Finck
585c2c66affSColin Finck /* If the bits vector is null, the function should return the read size */
586c2c66affSColin Finck if (pUnsafeBits == NULL)
587c2c66affSColin Finck {
588c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
589c2c66affSColin Finck return cjSize;
590c2c66affSColin Finck }
591c2c66affSColin Finck
592c2c66affSColin Finck /* Don't copy more bytes than the buffer has */
593c2c66affSColin Finck cjBuffer = min(cjBuffer, cjSize);
594c2c66affSColin Finck
595c2c66affSColin Finck // FIXME: Use MmSecureVirtualMemory
596c2c66affSColin Finck _SEH2_TRY
597c2c66affSColin Finck {
598c2c66affSColin Finck ProbeForWrite(pUnsafeBits, cjBuffer, 1);
59929795a2dSKatayama Hirofumi MZ ret = UnsafeGetBitmapBits(psurf, cjBuffer, pUnsafeBits);
600c2c66affSColin Finck }
601c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
602c2c66affSColin Finck {
603c2c66affSColin Finck ret = 0;
604c2c66affSColin Finck }
605c2c66affSColin Finck _SEH2_END
606c2c66affSColin Finck
607c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
608c2c66affSColin Finck
609c2c66affSColin Finck return ret;
610c2c66affSColin Finck }
611c2c66affSColin Finck
612c2c66affSColin Finck
613c2c66affSColin Finck LONG APIENTRY
NtGdiSetBitmapBits(HBITMAP hBitmap,DWORD Bytes,IN PBYTE pUnsafeBits)614c2c66affSColin Finck NtGdiSetBitmapBits(
615c2c66affSColin Finck HBITMAP hBitmap,
616c2c66affSColin Finck DWORD Bytes,
617c2c66affSColin Finck IN PBYTE pUnsafeBits)
618c2c66affSColin Finck {
619c2c66affSColin Finck LONG ret;
620c2c66affSColin Finck PSURFACE psurf;
621c2c66affSColin Finck
622c2c66affSColin Finck if (pUnsafeBits == NULL || Bytes == 0)
623c2c66affSColin Finck {
624c2c66affSColin Finck return 0;
625c2c66affSColin Finck }
626c2c66affSColin Finck
627c2c66affSColin Finck if (GDI_HANDLE_IS_STOCKOBJ(hBitmap))
628c2c66affSColin Finck {
629c2c66affSColin Finck return 0;
630c2c66affSColin Finck }
631c2c66affSColin Finck
632c2c66affSColin Finck psurf = SURFACE_ShareLockSurface(hBitmap);
633c2c66affSColin Finck if (psurf == NULL)
634c2c66affSColin Finck {
635c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
636c2c66affSColin Finck return 0;
637c2c66affSColin Finck }
638c2c66affSColin Finck
639c2c66affSColin Finck if (((psurf->flags & API_BITMAP) == 0) ||
640c2c66affSColin Finck (psurf->SurfObj.iBitmapFormat > BMF_32BPP))
641c2c66affSColin Finck {
642c2c66affSColin Finck DPRINT1("Invalid bitmap: iBitmapFormat = %lu, flags = 0x%lx\n",
643c2c66affSColin Finck psurf->SurfObj.iBitmapFormat,
644c2c66affSColin Finck psurf->flags);
645c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
646c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
647c2c66affSColin Finck return 0;
648c2c66affSColin Finck }
649c2c66affSColin Finck
650c2c66affSColin Finck _SEH2_TRY
651c2c66affSColin Finck {
6526b8f9c0cSKatayama Hirofumi MZ /* NOTE: Win2k3 doesn't check WORD alignment here. */
653bb336924SKatayama Hirofumi MZ ProbeForWrite(pUnsafeBits, Bytes, 1);
654c2c66affSColin Finck ret = UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
655c2c66affSColin Finck }
656c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
657c2c66affSColin Finck {
658c2c66affSColin Finck ret = 0;
659c2c66affSColin Finck }
660c2c66affSColin Finck _SEH2_END
661c2c66affSColin Finck
662c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
663c2c66affSColin Finck
664c2c66affSColin Finck return ret;
665c2c66affSColin Finck }
666c2c66affSColin Finck
667c2c66affSColin Finck BOOL APIENTRY
NtGdiSetBitmapDimension(HBITMAP hBitmap,INT Width,INT Height,LPSIZE Size)668c2c66affSColin Finck NtGdiSetBitmapDimension(
669c2c66affSColin Finck HBITMAP hBitmap,
670c2c66affSColin Finck INT Width,
671c2c66affSColin Finck INT Height,
672c2c66affSColin Finck LPSIZE Size)
673c2c66affSColin Finck {
674c2c66affSColin Finck PSURFACE psurf;
675c2c66affSColin Finck BOOL Ret = TRUE;
676c2c66affSColin Finck
677c2c66affSColin Finck if (hBitmap == NULL)
678c2c66affSColin Finck return FALSE;
679c2c66affSColin Finck
680c2c66affSColin Finck psurf = SURFACE_ShareLockSurface(hBitmap);
681c2c66affSColin Finck if (psurf == NULL)
682c2c66affSColin Finck {
683c2c66affSColin Finck EngSetLastError(ERROR_INVALID_HANDLE);
684c2c66affSColin Finck return FALSE;
685c2c66affSColin Finck }
686c2c66affSColin Finck
687c2c66affSColin Finck if (Size)
688c2c66affSColin Finck {
689c2c66affSColin Finck _SEH2_TRY
690c2c66affSColin Finck {
691c2c66affSColin Finck ProbeForWrite(Size, sizeof(SIZE), 1);
692c2c66affSColin Finck *Size = psurf->sizlDim;
693c2c66affSColin Finck }
694c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
695c2c66affSColin Finck {
696c2c66affSColin Finck Ret = FALSE;
697c2c66affSColin Finck }
698c2c66affSColin Finck _SEH2_END
699c2c66affSColin Finck }
700c2c66affSColin Finck
701c2c66affSColin Finck /* The dimension is changed even if writing the old value failed */
702c2c66affSColin Finck psurf->sizlDim.cx = Width;
703c2c66affSColin Finck psurf->sizlDim.cy = Height;
704c2c66affSColin Finck
705c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
706c2c66affSColin Finck
707c2c66affSColin Finck return Ret;
708c2c66affSColin Finck }
709c2c66affSColin Finck
710c2c66affSColin Finck /* Internal Functions */
711c2c66affSColin Finck
712c2c66affSColin Finck HBITMAP
713c2c66affSColin Finck FASTCALL
BITMAP_CopyBitmap(HBITMAP hBitmap)714c2c66affSColin Finck BITMAP_CopyBitmap(HBITMAP hBitmap)
715c2c66affSColin Finck {
716c2c66affSColin Finck HBITMAP hbmNew;
717c2c66affSColin Finck SURFACE *psurfSrc, *psurfNew;
718c2c66affSColin Finck
719c2c66affSColin Finck /* Fail, if no source bitmap is given */
720c2c66affSColin Finck if (hBitmap == NULL) return 0;
721c2c66affSColin Finck
722c2c66affSColin Finck /* Lock the source bitmap */
723c2c66affSColin Finck psurfSrc = SURFACE_ShareLockSurface(hBitmap);
724c2c66affSColin Finck if (psurfSrc == NULL)
725c2c66affSColin Finck {
726c2c66affSColin Finck return 0;
727c2c66affSColin Finck }
728c2c66affSColin Finck
729c2c66affSColin Finck /* Allocate a new bitmap with the same dimensions as the source bmp */
730c2c66affSColin Finck hbmNew = GreCreateBitmapEx(psurfSrc->SurfObj.sizlBitmap.cx,
731c2c66affSColin Finck psurfSrc->SurfObj.sizlBitmap.cy,
732c2c66affSColin Finck abs(psurfSrc->SurfObj.lDelta),
733c2c66affSColin Finck psurfSrc->SurfObj.iBitmapFormat,
734c2c66affSColin Finck psurfSrc->SurfObj.fjBitmap & BMF_TOPDOWN,
735c2c66affSColin Finck psurfSrc->SurfObj.cjBits,
736c2c66affSColin Finck NULL,
737c2c66affSColin Finck psurfSrc->flags);
738c2c66affSColin Finck
739c2c66affSColin Finck if (hbmNew)
740c2c66affSColin Finck {
741c2c66affSColin Finck /* Lock the new bitmap */
742c2c66affSColin Finck psurfNew = SURFACE_ShareLockSurface(hbmNew);
743c2c66affSColin Finck if (psurfNew)
744c2c66affSColin Finck {
745c2c66affSColin Finck /* Copy the bitmap bits to the new bitmap buffer */
746c2c66affSColin Finck RtlCopyMemory(psurfNew->SurfObj.pvBits,
747c2c66affSColin Finck psurfSrc->SurfObj.pvBits,
748c2c66affSColin Finck psurfNew->SurfObj.cjBits);
749c2c66affSColin Finck
750c2c66affSColin Finck
751c2c66affSColin Finck /* Reference the palette of the source bitmap and use it */
752c2c66affSColin Finck SURFACE_vSetPalette(psurfNew, psurfSrc->ppal);
753c2c66affSColin Finck
754c2c66affSColin Finck /* Unlock the new surface */
755c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurfNew);
756c2c66affSColin Finck }
757c2c66affSColin Finck else
758c2c66affSColin Finck {
759c2c66affSColin Finck /* Failed to lock the bitmap, shouldn't happen */
760c2c66affSColin Finck GreDeleteObject(hbmNew);
761c2c66affSColin Finck hbmNew = NULL;
762c2c66affSColin Finck }
763c2c66affSColin Finck }
764c2c66affSColin Finck
765c2c66affSColin Finck /* Unlock the source bitmap and return the handle of the new bitmap */
766c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurfSrc);
767c2c66affSColin Finck return hbmNew;
768c2c66affSColin Finck }
769c2c66affSColin Finck
770c2c66affSColin Finck INT APIENTRY
BITMAP_GetObject(SURFACE * psurf,INT Count,LPVOID buffer)771c2c66affSColin Finck BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
772c2c66affSColin Finck {
773c2c66affSColin Finck PBITMAP pBitmap;
774c2c66affSColin Finck
775c2c66affSColin Finck if (!buffer) return sizeof(BITMAP);
776c2c66affSColin Finck if ((UINT)Count < sizeof(BITMAP)) return 0;
777c2c66affSColin Finck
778c2c66affSColin Finck /* Always fill a basic BITMAP structure */
779c2c66affSColin Finck pBitmap = buffer;
780c2c66affSColin Finck pBitmap->bmType = 0;
781c2c66affSColin Finck pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
782c2c66affSColin Finck pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
783c2c66affSColin Finck pBitmap->bmPlanes = 1;
784c2c66affSColin Finck pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
785c2c66affSColin Finck pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
786c2c66affSColin Finck
787c2c66affSColin Finck /* Check for DIB section */
788c2c66affSColin Finck if (psurf->hSecure)
789c2c66affSColin Finck {
790c2c66affSColin Finck /* Set bmBits in this case */
791c2c66affSColin Finck pBitmap->bmBits = psurf->SurfObj.pvBits;
792c2c66affSColin Finck /* DIBs data are 32 bits aligned */
793c2c66affSColin Finck pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
794c2c66affSColin Finck
795c2c66affSColin Finck if (Count >= sizeof(DIBSECTION))
796c2c66affSColin Finck {
797c2c66affSColin Finck /* Fill rest of DIBSECTION */
798c2c66affSColin Finck PDIBSECTION pds = buffer;
799c2c66affSColin Finck
800c2c66affSColin Finck pds->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
801c2c66affSColin Finck pds->dsBmih.biWidth = pds->dsBm.bmWidth;
802c2c66affSColin Finck pds->dsBmih.biHeight = pds->dsBm.bmHeight;
803c2c66affSColin Finck pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
804c2c66affSColin Finck pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
805c2c66affSColin Finck
806c2c66affSColin Finck switch (psurf->SurfObj.iBitmapFormat)
807c2c66affSColin Finck {
808c2c66affSColin Finck case BMF_1BPP:
809c2c66affSColin Finck case BMF_4BPP:
810c2c66affSColin Finck case BMF_8BPP:
811c2c66affSColin Finck pds->dsBmih.biCompression = BI_RGB;
812c2c66affSColin Finck break;
813c2c66affSColin Finck
814c2c66affSColin Finck case BMF_16BPP:
815c2c66affSColin Finck if (psurf->ppal->flFlags & PAL_RGB16_555)
816c2c66affSColin Finck pds->dsBmih.biCompression = BI_RGB;
817c2c66affSColin Finck else
818c2c66affSColin Finck pds->dsBmih.biCompression = BI_BITFIELDS;
819c2c66affSColin Finck break;
820c2c66affSColin Finck
821c2c66affSColin Finck case BMF_24BPP:
822c2c66affSColin Finck case BMF_32BPP:
823c2c66affSColin Finck /* 24/32bpp BI_RGB is actually BGR format */
824c2c66affSColin Finck if (psurf->ppal->flFlags & PAL_BGR)
825c2c66affSColin Finck pds->dsBmih.biCompression = BI_RGB;
826c2c66affSColin Finck else
827c2c66affSColin Finck pds->dsBmih.biCompression = BI_BITFIELDS;
828c2c66affSColin Finck break;
829c2c66affSColin Finck
830c2c66affSColin Finck case BMF_4RLE:
831c2c66affSColin Finck pds->dsBmih.biCompression = BI_RLE4;
832c2c66affSColin Finck break;
833c2c66affSColin Finck case BMF_8RLE:
834c2c66affSColin Finck pds->dsBmih.biCompression = BI_RLE8;
835c2c66affSColin Finck break;
836c2c66affSColin Finck case BMF_JPEG:
837c2c66affSColin Finck pds->dsBmih.biCompression = BI_JPEG;
838c2c66affSColin Finck break;
839c2c66affSColin Finck case BMF_PNG:
840c2c66affSColin Finck pds->dsBmih.biCompression = BI_PNG;
841c2c66affSColin Finck break;
842c2c66affSColin Finck default:
843c2c66affSColin Finck ASSERT(FALSE); /* This shouldn't happen */
844c2c66affSColin Finck }
845c2c66affSColin Finck
846c2c66affSColin Finck pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
847c2c66affSColin Finck pds->dsBmih.biXPelsPerMeter = 0;
848c2c66affSColin Finck pds->dsBmih.biYPelsPerMeter = 0;
849c2c66affSColin Finck pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
850c2c66affSColin Finck pds->dsBmih.biClrImportant = psurf->biClrImportant;
851c2c66affSColin Finck pds->dsBitfields[0] = psurf->ppal->RedMask;
852c2c66affSColin Finck pds->dsBitfields[1] = psurf->ppal->GreenMask;
853c2c66affSColin Finck pds->dsBitfields[2] = psurf->ppal->BlueMask;
854c2c66affSColin Finck pds->dshSection = psurf->hDIBSection;
855c2c66affSColin Finck pds->dsOffset = psurf->dwOffset;
856c2c66affSColin Finck
857c2c66affSColin Finck return sizeof(DIBSECTION);
858c2c66affSColin Finck }
859c2c66affSColin Finck }
860c2c66affSColin Finck else
861c2c66affSColin Finck {
862c2c66affSColin Finck /* Not set according to wine test, confirmed in win2k */
863c2c66affSColin Finck pBitmap->bmBits = NULL;
864c2c66affSColin Finck }
865c2c66affSColin Finck
866c2c66affSColin Finck return sizeof(BITMAP);
867c2c66affSColin Finck }
868c2c66affSColin Finck
869c2c66affSColin Finck /*
870c2c66affSColin Finck * @implemented
871c2c66affSColin Finck */
872c2c66affSColin Finck HDC
873c2c66affSColin Finck APIENTRY
NtGdiGetDCforBitmap(IN HBITMAP hsurf)874c2c66affSColin Finck NtGdiGetDCforBitmap(
875c2c66affSColin Finck IN HBITMAP hsurf)
876c2c66affSColin Finck {
877c2c66affSColin Finck HDC hdc = NULL;
878c2c66affSColin Finck PSURFACE psurf = SURFACE_ShareLockSurface(hsurf);
879c2c66affSColin Finck if (psurf)
880c2c66affSColin Finck {
881c2c66affSColin Finck hdc = psurf->hdc;
882c2c66affSColin Finck SURFACE_ShareUnlockSurface(psurf);
883c2c66affSColin Finck }
884c2c66affSColin Finck return hdc;
885c2c66affSColin Finck }
886c2c66affSColin Finck
887c2c66affSColin Finck
888c2c66affSColin Finck /* EOF */
889