Converted more DbgPrints to DPRINT and allocate bitmaps from paged pool instead of...
[reactos.git] / reactos / subsys / win32k / objects / bitmaps.c
1
2
3 #undef WIN32_LEAN_AND_MEAN
4 #include <windows.h>
5 #include <stdlib.h>
6 #include <win32k/bitmaps.h>
7 //#include <win32k/debug.h>
8
9 #define NDEBUG
10 #include <debug.h>
11
12 BOOL STDCALL W32kBitBlt(HDC hDCDest,
13 INT XDest,
14 INT YDest,
15 INT Width,
16 INT Height,
17 HDC hDCSrc,
18 INT XSrc,
19 INT YSrc,
20 DWORD ROP)
21 {
22 PDC DCDest = DC_HandleToPtr(hDCDest);
23 PDC DCSrc = DC_HandleToPtr(hDCSrc);
24 PSURFOBJ SurfDest;
25 PSURFOBJ SurfSrc;
26 RECTL DestRect;
27 POINTL SourcePoint;
28 PBITMAPOBJ DestBitmapObj;
29 PBITMAPOBJ SrcBitmapObj;
30 BOOL Status, SurfDestAlloc, SurfSrcAlloc;
31
32 DestRect.left = XDest;
33 DestRect.top = YDest;
34 DestRect.right = XDest+Width;
35 DestRect.bottom = YDest+Height;
36
37 SourcePoint.x = XSrc;
38 SourcePoint.y = YSrc;
39
40 SurfDestAlloc = FALSE;
41 SurfSrcAlloc = FALSE;
42
43 DPRINT("Get surfdest.. ");
44
45 // Get the SurfDest
46 if(DCDest->Surface != NULL)
47 {
48 // Use the DC's surface if it has one
49 SurfDest = AccessUserObject(DCDest->Surface);
50 } else
51 return FALSE;
52
53 DPRINT("Get surfsrc.. ");
54
55 // Get the SurfSrc
56 if(DCSrc->Surface != NULL)
57 {
58 DPRINT("from DC's surface\n");
59
60 // Use the DC's surface if it has one
61 SurfSrc = AccessUserObject(DCSrc->Surface);
62 } else
63 return FALSE;
64
65
66 DPRINT("Go to EngBitBlt\n");
67 Status = EngBitBlt(SurfDest, SurfSrc, NULL, NULL, NULL,
68 &DestRect, &SourcePoint, NULL, NULL, NULL, NULL); // FIXME: Color translation (xlateobj)
69
70 if(SurfDestAlloc == TRUE) ExFreePool(SurfDest);
71 if(SurfSrcAlloc == TRUE) ExFreePool(SurfSrc);
72
73 return Status;
74 }
75
76 HBITMAP STDCALL W32kCreateBitmap(INT Width,
77 INT Height,
78 UINT Planes,
79 UINT BitsPerPel,
80 CONST VOID *Bits)
81 {
82 PBITMAPOBJ bmp;
83 HBITMAP hBitmap;
84
85 Planes = (BYTE) Planes;
86 BitsPerPel = (BYTE) BitsPerPel;
87
88 /* Check parameters */
89 if (!Height || !Width)
90 {
91 return 0;
92 }
93 if (Planes != 1)
94 {
95 UNIMPLEMENTED;
96 return 0;
97 }
98 if (Height < 0)
99 {
100 Height = -Height;
101 }
102 if (Width < 0)
103 {
104 Width = -Width;
105 }
106
107 /* Create the BITMAPOBJ */
108 bmp = BITMAPOBJ_AllocBitmap ();
109 if (!bmp)
110 {
111 return 0;
112 }
113
114 DPRINT("W32kCreateBitmap:%dx%d, %d (%d BPP) colors returning %08x\n", Width, Height,
115 1 << (Planes * BitsPerPel), BitsPerPel, bmp);
116
117 bmp->size.cx = 0;
118 bmp->size.cy = 0;
119 bmp->bitmap.bmType = 0;
120 bmp->bitmap.bmWidth = Width;
121 bmp->bitmap.bmHeight = Height;
122 bmp->bitmap.bmPlanes = Planes;
123 bmp->bitmap.bmBitsPixel = BitsPerPel;
124 bmp->bitmap.bmWidthBytes = BITMAPOBJ_GetWidthBytes (Width, BitsPerPel);
125 bmp->bitmap.bmBits = NULL;
126 bmp->DDBitmap = NULL;
127 bmp->dib = NULL;
128 hBitmap = BITMAPOBJ_PtrToHandle (bmp);
129
130 // Allocate memory for bitmap bits
131 bmp->bitmap.bmBits = ExAllocatePool(PagedPool, bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight);
132
133 if (Bits) /* Set bitmap bits */
134 {
135 W32kSetBitmapBits(hBitmap,
136 Height * bmp->bitmap.bmWidthBytes,
137 Bits);
138 }
139
140
141 return hBitmap;
142 }
143
144 HBITMAP STDCALL W32kCreateCompatibleBitmap(HDC hDC,
145 INT Width,
146 INT Height)
147 {
148 HBITMAP hbmpRet;
149 PDC dc;
150
151 hbmpRet = 0;
152 dc = DC_HandleToPtr (hDC);
153
154 DPRINT("W32kCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
155
156 if (!dc)
157 {
158 return 0;
159 }
160 if ((Width >= 0x10000) || (Height >= 0x10000))
161 {
162 DPRINT("got bad width %d or height %d, please look for reason\n",
163 Width, Height);
164 }
165 else
166 {
167 /* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
168 if (!Width || !Height)
169 {
170 hbmpRet = W32kCreateBitmap (1, 1, 1, 1, NULL);
171 }
172 else
173 {
174 hbmpRet = W32kCreateBitmap (Width,
175 Height,
176 1,
177 dc->w.bitsPerPixel,
178 NULL);
179 }
180 }
181 DPRINT ("\t\t%04x\n", hbmpRet);
182 DC_UnlockDC (hDC);
183
184 return hbmpRet;
185 }
186
187 HBITMAP STDCALL W32kCreateBitmapIndirect(CONST BITMAP *BM)
188 {
189 return W32kCreateBitmap (BM->bmWidth,
190 BM->bmHeight,
191 BM->bmPlanes,
192 BM->bmBitsPixel,
193 BM->bmBits);
194 }
195
196 HBITMAP STDCALL W32kCreateDIBitmap(HDC hDC,
197 CONST BITMAPINFOHEADER *bmih,
198 DWORD Init,
199 CONST VOID *bInit,
200 CONST BITMAPINFO *bmi,
201 UINT Usage)
202 {
203 UNIMPLEMENTED;
204 }
205
206 HBITMAP STDCALL W32kCreateDIBSection(HDC hDC,
207 CONST BITMAPINFO *bmi,
208 UINT Usage,
209 VOID *Bits,
210 HANDLE hSection,
211 DWORD dwOffset)
212 {
213 UNIMPLEMENTED;
214 }
215
216 HBITMAP STDCALL W32kCreateDiscardableBitmap(HDC hDC,
217 INT Width,
218 INT Height)
219 {
220 /* FIXME: this probably should do something else */
221 return W32kCreateCompatibleBitmap(hDC, Width, Height);
222 }
223
224 BOOL STDCALL W32kExtFloodFill(HDC hDC,
225 INT XStart,
226 INT YStart,
227 COLORREF Color,
228 UINT FillType)
229 {
230 UNIMPLEMENTED;
231 }
232
233 BOOL STDCALL W32kFloodFill(HDC hDC,
234 INT XStart,
235 INT YStart,
236 COLORREF Fill)
237 {
238 UNIMPLEMENTED;
239 }
240
241 LONG STDCALL W32kGetBitmapBits(HBITMAP hBitmap,
242 LONG Count,
243 LPVOID Bits)
244 {
245 PBITMAPOBJ bmp;
246 LONG height, ret;
247
248 bmp = BITMAPOBJ_HandleToPtr (hBitmap);
249 if (!bmp)
250 {
251 return 0;
252 }
253
254 /* If the bits vector is null, the function should return the read size */
255 if (Bits == NULL)
256 {
257 return bmp->bitmap.bmWidthBytes * bmp->bitmap.bmHeight;
258 }
259
260 if (Count < 0)
261 {
262 DPRINT ("(%ld): Negative number of bytes passed???\n", Count);
263 Count = -Count;
264 }
265
266 /* Only get entire lines */
267 height = Count / bmp->bitmap.bmWidthBytes;
268 if (height > bmp->bitmap.bmHeight)
269 {
270 height = bmp->bitmap.bmHeight;
271 }
272 Count = height * bmp->bitmap.bmWidthBytes;
273 if (Count == 0)
274 {
275 DPRINT("Less then one entire line requested\n");
276 BITMAPOBJ_UnlockBitmap (hBitmap);
277 return 0;
278 }
279
280 DPRINT("(%08x, %ld, %p) %dx%d %d colors fetched height: %ld\n",
281 hBitmap, Count, Bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
282 1 << bmp->bitmap.bmBitsPixel, height );
283 #if 0
284 /* FIXME: Call DDI CopyBits here if available */
285 if(bmp->DDBitmap)
286 {
287 DPRINT("Calling device specific BitmapBits\n");
288 if(bmp->DDBitmap->funcs->pBitmapBits)
289 {
290 ret = bmp->DDBitmap->funcs->pBitmapBits(hbitmap, bits, count,
291 DDB_GET);
292 }
293 else
294 {
295 ERR_(bitmap)("BitmapBits == NULL??\n");
296 ret = 0;
297 }
298 }
299 else
300 #endif
301 {
302 if(!bmp->bitmap.bmBits)
303 {
304 DPRINT ("Bitmap is empty\n");
305 ret = 0;
306 }
307 else
308 {
309 memcpy(Bits, bmp->bitmap.bmBits, Count);
310 ret = Count;
311 }
312 }
313 BITMAPOBJ_UnlockBitmap (hBitmap);
314
315 return ret;
316 }
317
318 BOOL STDCALL W32kGetBitmapDimensionEx(HBITMAP hBitmap,
319 LPSIZE Dimension)
320 {
321 PBITMAPOBJ bmp;
322
323 bmp = BITMAPOBJ_HandleToPtr (hBitmap);
324 if (bmp == NULL)
325 {
326 return FALSE;
327 }
328
329 *Dimension = bmp->size;
330 BITMAPOBJ_UnlockBitmap (hBitmap);
331
332 return TRUE;
333 }
334
335 UINT STDCALL W32kGetDIBColorTable(HDC hDC,
336 UINT StartIndex,
337 UINT Entries,
338 RGBQUAD *Colors)
339 {
340 UNIMPLEMENTED;
341 }
342
343 INT STDCALL W32kGetDIBits(HDC hDC,
344 HBITMAP hBitmap,
345 UINT StartScan,
346 UINT ScanLines,
347 LPVOID Bits,
348 LPBITMAPINFO bi,
349 UINT Usage)
350 {
351 UNIMPLEMENTED;
352 }
353
354 COLORREF STDCALL W32kGetPixel(HDC hDC,
355 INT XPos,
356 INT YPos)
357 {
358 UNIMPLEMENTED;
359 }
360
361 BOOL STDCALL W32kMaskBlt(HDC hDCDest,
362 INT XDest,
363 INT YDest,
364 INT Width,
365 INT Height,
366 HDC hDCSrc,
367 INT XSrc,
368 INT YSrc,
369 HBITMAP hMaskBitmap,
370 INT xMask,
371 INT yMask,
372 DWORD ROP)
373 {
374 UNIMPLEMENTED;
375 }
376
377 BOOL STDCALL W32kPlgBlt(HDC hDCDest,
378 CONST POINT *Point,
379 HDC hDCSrc,
380 INT XSrc,
381 INT YSrc,
382 INT Width,
383 INT Height,
384 HBITMAP hMaskBitmap,
385 INT xMask,
386 INT yMask)
387 {
388 UNIMPLEMENTED;
389 }
390
391 LONG STDCALL W32kSetBitmapBits(HBITMAP hBitmap,
392 DWORD Bytes,
393 CONST VOID *Bits)
394 {
395 DWORD height, ret;
396 PBITMAPOBJ bmp;
397
398 bmp = BITMAPOBJ_HandleToPtr (hBitmap);
399 if (bmp == NULL || Bits == NULL)
400 {
401 return 0;
402 }
403
404 if (Bytes < 0)
405 {
406 DPRINT ("(%ld): Negative number of bytes passed???\n", Bytes );
407 Bytes = -Bytes;
408 }
409
410 /* Only get entire lines */
411 height = Bytes / bmp->bitmap.bmWidthBytes;
412 if (height > bmp->bitmap.bmHeight)
413 {
414 height = bmp->bitmap.bmHeight;
415 }
416 Bytes = height * bmp->bitmap.bmWidthBytes;
417 DPRINT ("(%08x, bytes:%ld, bits:%p) %dx%d %d colors fetched height: %ld\n",
418 hBitmap,
419 Bytes,
420 Bits,
421 bmp->bitmap.bmWidth,
422 bmp->bitmap.bmHeight,
423 1 << bmp->bitmap.bmBitsPixel,
424 height);
425
426 #if 0
427 /* FIXME: call DDI specific function here if available */
428 if(bmp->DDBitmap)
429 {
430 DPRINT ("Calling device specific BitmapBits\n");
431 if (bmp->DDBitmap->funcs->pBitmapBits)
432 {
433 ret = bmp->DDBitmap->funcs->pBitmapBits(hBitmap,
434 (void *) Bits,
435 Bytes,
436 DDB_SET);
437 }
438 else
439 {
440 DPRINT ("BitmapBits == NULL??\n");
441 ret = 0;
442 }
443 }
444 else
445 #endif
446 {
447 /* FIXME: Alloc enough for entire bitmap */
448 if (bmp->bitmap.bmBits == NULL)
449 {
450 bmp->bitmap.bmBits = ExAllocatePool (PagedPool, Bytes);
451 }
452 if(!bmp->bitmap.bmBits)
453 {
454 DPRINT ("Unable to allocate bit buffer\n");
455 ret = 0;
456 }
457 else
458 {
459 memcpy(bmp->bitmap.bmBits, Bits, Bytes);
460 ret = Bytes;
461 }
462 }
463 BITMAPOBJ_UnlockBitmap (hBitmap);
464
465 return ret;
466 }
467
468 BOOL STDCALL W32kSetBitmapDimensionEx(HBITMAP hBitmap,
469 INT Width,
470 INT Height,
471 LPSIZE Size)
472 {
473 PBITMAPOBJ bmp;
474
475 bmp = BITMAPOBJ_HandleToPtr (hBitmap);
476 if (bmp == NULL)
477 {
478 return FALSE;
479 }
480
481 if (Size)
482 {
483 *Size = bmp->size;
484 }
485 bmp->size.cx = Width;
486 bmp->size.cy = Height;
487 BITMAPOBJ_UnlockBitmap (hBitmap);
488
489 return TRUE;
490 }
491
492 UINT STDCALL W32kSetDIBColorTable(HDC hDC,
493 UINT StartIndex,
494 UINT Entries,
495 CONST RGBQUAD *Colors)
496 {
497 UNIMPLEMENTED;
498 }
499
500 INT STDCALL W32kSetDIBits(HDC hDC,
501 HBITMAP hBitmap,
502 UINT StartScan,
503 UINT ScanLines,
504 CONST VOID *Bits,
505 CONST BITMAPINFO *bmi,
506 UINT ColorUse)
507 {
508 UNIMPLEMENTED;
509 }
510
511 INT STDCALL W32kSetDIBitsToDevice(HDC hDC,
512 INT XDest,
513 INT YDest,
514 DWORD Width,
515 DWORD Height,
516 INT XSrc,
517 INT YSrc,
518 UINT StartScan,
519 UINT ScanLines,
520 CONST VOID *Bits,
521 CONST BITMAPINFO *bmi,
522 UINT ColorUse)
523 {
524 UNIMPLEMENTED;
525 }
526
527 COLORREF STDCALL W32kSetPixel(HDC hDC,
528 INT X,
529 INT Y,
530 COLORREF Color)
531 {
532 UNIMPLEMENTED;
533 }
534
535 BOOL STDCALL W32kSetPixelV(HDC hDC,
536 INT X,
537 INT Y,
538 COLORREF Color)
539 {
540 UNIMPLEMENTED;
541 }
542
543 BOOL STDCALL W32kStretchBlt(HDC hDCDest,
544 INT XOriginDest,
545 INT YOriginDest,
546 INT WidthDest,
547 INT HeightDest,
548 HDC hDCSrc,
549 INT XOriginSrc,
550 INT YOriginSrc,
551 INT WidthSrc,
552 INT HeightSrc,
553 DWORD ROP)
554 {
555 UNIMPLEMENTED;
556 }
557
558 INT STDCALL W32kStretchDIBits(HDC hDC,
559 INT XDest,
560 INT YDest,
561 INT DestWidth,
562 INT DestHeight,
563 INT XSrc,
564 INT YSrc,
565 INT SrcWidth,
566 INT SrcHeight,
567 CONST VOID *Bits,
568 CONST BITMAPINFO *BitsInfo,
569 UINT Usage,
570 DWORD ROP)
571 {
572 UNIMPLEMENTED;
573 }
574
575 /* Internal Functions */
576
577 INT
578 BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
579 {
580 switch(bpp)
581 {
582 case 1:
583 return 2 * ((bmWidth+15) >> 4);
584
585 case 24:
586 bmWidth *= 3; /* fall through */
587 case 8:
588 return bmWidth + (bmWidth & 1);
589
590 case 32:
591 return bmWidth * 4;
592
593 case 16:
594 case 15:
595 return bmWidth * 2;
596
597 case 4:
598 return 2 * ((bmWidth+3) >> 2);
599
600 default:
601 DPRINT ("stub");
602 }
603
604 return -1;
605 }
606
607 HBITMAP BITMAPOBJ_CopyBitmap(HBITMAP hBitmap)
608 {
609 PBITMAPOBJ bmp;
610 HBITMAP res;
611 BITMAP bm;
612
613 bmp = BITMAPOBJ_HandleToPtr (hBitmap);
614 if (bmp == NULL)
615 {
616 return 0;
617 }
618 res = 0;
619
620 bm = bmp->bitmap;
621 bm.bmBits = NULL;
622 res = W32kCreateBitmapIndirect(&bm);
623 if(res)
624 {
625 char *buf;
626
627 buf = ExAllocatePool (NonPagedPool, bm.bmWidthBytes * bm.bmHeight);
628 W32kGetBitmapBits (hBitmap, bm.bmWidthBytes * bm.bmHeight, buf);
629 W32kSetBitmapBits (res, bm.bmWidthBytes * bm.bmHeight, buf);
630 ExFreePool (buf);
631 }
632 BITMAPOBJ_UnlockBitmap (hBitmap);
633
634 return res;
635 }
636
637 /***********************************************************************
638 * DIB_GetDIBWidthBytes
639 *
640 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
641 * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
642 * 11/16/1999 (RJJ) lifted from wine
643 */
644 int DIB_GetDIBWidthBytes(int width, int depth)
645 {
646 int words;
647
648 switch(depth)
649 {
650 case 1: words = (width + 31) / 32; break;
651 case 4: words = (width + 7) / 8; break;
652 case 8: words = (width + 3) / 4; break;
653 case 15:
654 case 16: words = (width + 1) / 2; break;
655 case 24: words = (width * 3 + 3)/4; break;
656
657 default:
658 DPRINT("(%d): Unsupported depth\n", depth );
659 /* fall through */
660 case 32:
661 words = width;
662 }
663 return 4 * words;
664 }
665
666 /***********************************************************************
667 * DIB_GetDIBImageBytes
668 *
669 * Return the number of bytes used to hold the image in a DIB bitmap.
670 * 11/16/1999 (RJJ) lifted from wine
671 */
672
673 int DIB_GetDIBImageBytes (int width, int height, int depth)
674 {
675 return DIB_GetDIBWidthBytes( width, depth ) * (height < 0 ? -height : height);
676 }
677
678 /***********************************************************************
679 * DIB_BitmapInfoSize
680 *
681 * Return the size of the bitmap info structure including color table.
682 * 11/16/1999 (RJJ) lifted from wine
683 */
684
685 int DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse)
686 {
687 int colors;
688
689 if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
690 {
691 BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info;
692 colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
693 return sizeof(BITMAPCOREHEADER) + colors *
694 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
695 }
696 else /* assume BITMAPINFOHEADER */
697 {
698 colors = info->bmiHeader.biClrUsed;
699 if (!colors && (info->bmiHeader.biBitCount <= 8))
700 colors = 1 << info->bmiHeader.biBitCount;
701 return sizeof(BITMAPINFOHEADER) + colors *
702 ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
703 }
704 }
705