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