ReactOS  0.4.15-dev-3187-ge372f2b
dib24bpp.c
Go to the documentation of this file.
1 /*
2  * PROJECT: Win32 subsystem
3  * LICENSE: See COPYING in the top level directory
4  * FILE: win32ss/gdi/dib/dib24bpp.c
5  * PURPOSE: Device Independant Bitmap functions, 24bpp
6  * PROGRAMMERS: Jason Filby
7  * Thomas Bluemel
8  * Gregor Anich
9  * Doug Lyons
10  */
11 
12 #include <win32k.h>
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 #define DEC_OR_INC(var, decTrue, amount) \
18  ((var) = (decTrue) ? ((var) - (amount)) : ((var) + (amount)))
19 
20 VOID
22 {
23  PBYTE addr = (PBYTE)SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
24  *(PUSHORT)(addr) = c & 0xFFFF;
25  *(addr + 2) = (c >> 16) & 0xFF;
26 }
27 
28 ULONG
30 {
31  PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
32  return *(PUSHORT)(addr) + (*(addr + 2) << 16);
33 }
34 
35 
36 
37 VOID
39 {
40  PBYTE addr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
41  LONG lDelta = SurfObj->lDelta;
42 
43  c &= 0xFFFFFF;
44  while(y1++ < y2)
45  {
46  *(PUSHORT)(addr) = c & 0xFFFF;
47  *(addr + 2) = (BYTE)(c >> 16);
48 
49  addr += lDelta;
50  }
51 }
52 
53 BOOLEAN
55 {
56  LONG i, j, sx, sy, xColor, f1;
57  PBYTE SourceBits, DestBits, SourceLine, DestLine;
58  PBYTE SourceBits_4BPP, SourceLine_4BPP;
59  PWORD SourceBits_16BPP, SourceLine_16BPP;
60  BOOLEAN bTopToBottom, bLeftToRight;
61 
62  DPRINT("DIB_24BPP_BitBltSrcCopy: SrcSurf cx/cy (%d/%d), DestSuft cx/cy (%d/%d) dstRect: (%d,%d)-(%d,%d)\n",
64  BltInfo->DestSurface->sizlBitmap.cx, BltInfo->DestSurface->sizlBitmap.cy,
65  BltInfo->DestRect.left, BltInfo->DestRect.top, BltInfo->DestRect.right, BltInfo->DestRect.bottom);
66 
67  /* Get back left to right flip here */
68  bLeftToRight = (BltInfo->DestRect.left > BltInfo->DestRect.right);
69 
70  /* Check for top to bottom flip needed. */
71  bTopToBottom = BltInfo->DestRect.top > BltInfo->DestRect.bottom;
72 
73  DPRINT("BltInfo->SourcePoint.x is '%d' and BltInfo->SourcePoint.y is '%d'.\n",
74  BltInfo->SourcePoint.x, BltInfo->SourcePoint.y);
75 
76  /* Make WellOrdered by making top < bottom and left < right */
78 
79  DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
80 
81  switch(BltInfo->SourceSurface->iBitmapFormat)
82  {
83  case BMF_1BPP:
84  sx = BltInfo->SourcePoint.x;
85 
86  /* This sets sy to the top line */
87  sy = BltInfo->SourcePoint.y;
88 
89  if (bTopToBottom)
90  {
91  /* This sets sy to the bottom line */
92  sy += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
93  }
94 
95  for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
96  {
97  sx = BltInfo->SourcePoint.x;
98 
99  if (bLeftToRight)
100  {
101  /* This sets sx to the rightmost pixel */
102  sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
103  }
104 
105  for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
106  {
107  if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
108  {
110  } else {
112  }
113  DEC_OR_INC(sx, bLeftToRight, 1);
114  }
115  DEC_OR_INC(sy, bTopToBottom, 1);
116  }
117  break;
118 
119  case BMF_4BPP:
120  DPRINT("4BPP Case Selected with DestRect Width of '%d'.\n",
121  BltInfo->DestRect.right - BltInfo->DestRect.left);
122 
123  /* This sets SourceBits_4BPP to the top line */
124  SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
125 
126  if (bTopToBottom)
127  {
128  /* This sets SourceBits_4BPP to the bottom line */
129  SourceBits_4BPP += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
130  }
131 
132  for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
133  {
134  SourceLine_4BPP = SourceBits_4BPP;
135  DestLine = DestBits;
136  sx = BltInfo->SourcePoint.x;
137 
138  if (bLeftToRight)
139  {
140  /* This sets sx to the rightmost pixel */
141  sx += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
142  }
143 
144  f1 = sx & 1;
145 
146  for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
147  {
148  xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
149  (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
150  *DestLine++ = xColor & 0xff;
151  *(PWORD)DestLine = (WORD)(xColor >> 8);
152  DestLine += 2;
153  if(f1 == 1) {
154  DEC_OR_INC(SourceLine_4BPP, bLeftToRight, 1);
155  f1 = 0;
156  }
157  else
158  {
159  f1 = 1;
160  }
161  DEC_OR_INC(sx, bLeftToRight, 1);
162  }
163  DEC_OR_INC(SourceBits_4BPP, bTopToBottom, BltInfo->SourceSurface->lDelta);
164  DestBits += BltInfo->DestSurface->lDelta;
165  }
166  break;
167 
168  case BMF_8BPP:
169  DPRINT("8BPP Case Selected with DestRect Width of '%d'.\n",
170  BltInfo->DestRect.right - BltInfo->DestRect.left);
171 
172  /* This sets SourceLine to the top line */
173  SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
174 
175  if (bTopToBottom)
176  {
177  /* This sets SourceLine to the bottom line */
178  SourceLine += BltInfo->SourceSurface->lDelta * (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
179  }
180  DestLine = DestBits;
181 
182  for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
183  {
184  SourceBits = SourceLine;
185  DestBits = DestLine;
186 
187  if (bLeftToRight)
188  {
189  /* This sets the SourceBits to the rightmost pixel */
190  SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
191  }
192 
193  for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
194  {
195  xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
196  *DestBits = xColor & 0xff;
197  *(PWORD)(DestBits + 1) = (WORD)(xColor >> 8);
198  DEC_OR_INC(SourceBits, bLeftToRight, 1);
199  DestBits += 3;
200  }
201 
202  DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
203  DestLine += BltInfo->DestSurface->lDelta;
204  }
205  break;
206 
207  case BMF_16BPP:
208  DPRINT("16BPP Case Selected with DestRect Width of '%d'.\n",
209  BltInfo->DestRect.right - BltInfo->DestRect.left);
210 
211  /* This sets SourceBits_16BPP to the top line */
212  SourceBits_16BPP = (PWORD)((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x);
213 
214  if (bTopToBottom)
215  {
216  /* This sets SourceBits_16BPP to the bottom line */
217  SourceBits_16BPP += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta;
218  }
219 
220  for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
221  {
222  SourceLine_16BPP = SourceBits_16BPP;
223  DestLine = DestBits;
224 
225  if (bLeftToRight)
226  {
227  /* This sets the SourceLine_16BPP to the rightmost pixel */
228  SourceLine_16BPP += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
229  }
230 
231  for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
232  {
233  xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_16BPP);
234  *DestLine++ = xColor & 0xff;
235  *(PWORD)DestLine = (WORD)(xColor >> 8);
236  DestLine += 2;
237  DEC_OR_INC(SourceLine_16BPP, bLeftToRight, 1);
238  }
239  if (bTopToBottom)
240  {
241  SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP - BltInfo->SourceSurface->lDelta);
242  }
243  else
244  {
245  SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
246  }
247  DestBits += BltInfo->DestSurface->lDelta;
248  }
249  break;
250 
251  case BMF_24BPP:
252  DPRINT("24BPP Case Selected with DestRect Width of '%d'.\n",
253  BltInfo->DestRect.right - BltInfo->DestRect.left);
254 
255  /* Check for no flips here because we are about to use RtlMoveMemory and it can only do increasing src & dst */
256  if ((BltInfo->XlateSourceToDest == NULL ||
257  (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL) != 0) &&
258  (!bTopToBottom && !bLeftToRight))
259  {
260  DPRINT("XO_TRIVIAL is TRUE.\n");
261  if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
262  {
263  /* This sets SourceBits to the top line */
264  SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
265  for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
266  {
267  RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
268  SourceBits += BltInfo->SourceSurface->lDelta;
269  DestBits += BltInfo->DestSurface->lDelta;
270  }
271  }
272  else
273  {
274  SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
275  DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
276  for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
277  {
278  RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
279  SourceBits -= BltInfo->SourceSurface->lDelta;
280  DestBits -= BltInfo->DestSurface->lDelta;
281  }
282  }
283  }
284  else
285  {
286  DPRINT("XO_TRIVIAL is NOT TRUE.\n");
287 
288  if (!bTopToBottom && !bLeftToRight)
289  /* **Note: Indent is purposefully less than desired to keep reviewable differences to a minimum for PR** */
290  {
291  sx = BltInfo->SourcePoint.x;
292  sy = BltInfo->SourcePoint.y;
293 
294  for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
295  {
296  sx = BltInfo->SourcePoint.x;
297  for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
298  {
299  DWORD pixel = DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy);
300  DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, pixel));
301  sx++;
302  }
303  sy++;
304  }
305  }
306  else
307  {
308  /* Buffering for source and destination flip overlaps. Fixes KHMZ MirrorTest CORE-16642 */
309  BOOL TopToBottomDone = FALSE;
310 
311  if (bLeftToRight)
312  {
313  DPRINT("Flip is bLeftToRight.\n");
314  DWORD Index;
315 
316  /* Allocate enough pixels for a row in DWORD's */
318  (BltInfo->DestRect.right - BltInfo->DestRect.left + 1) * 4, TAG_DIB);
319  if (store == NULL)
320  {
321  DPRINT1("Storage Allocation Failed.\n");
322  return FALSE;
323  }
324 
325  sx = BltInfo->SourcePoint.x;
326  /* This sets sy to the top line */
327  sy = BltInfo->SourcePoint.y;
328 
329  /* This sets sx to the rightmost pixel */
330  sx = BltInfo->SourcePoint.x + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
331 
332  for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
333  {
334 
335  /* This sets sx to the rightmost pixel */
336  sx = BltInfo->SourcePoint.x + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1);
337 
338  Index = 0;
339 
340  // Read right to left and store
341  for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
342  {
343  store[Index] = DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy);
344  Index++;
345  sx--;
346  }
347 
348  Index = 0;
349 
350  // Write left to right to pixel
351  for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
352  {
354  Index++;
355  }
356  sy++;
357  }
358  ExFreePoolWithTag(store, TAG_DIB);
359  TopToBottomDone = TRUE;
360  }
361 
362  if (bTopToBottom)
363  {
364  DPRINT("Flip is bTopToBottom.\n");
365  DWORD Index;
366 
367  /* Allocate enough pixels for a column in DWORD's */
369  (BltInfo->DestRect.bottom - BltInfo->DestRect.top + 1) * 4, TAG_DIB);
370  if (store == NULL)
371  {
372  DPRINT1("Storage Allocation Failed.\n");
373  return FALSE;
374  }
375 
376  /* The TopToBottomDone flag indicates that we are flipping for bTopToBottom and bLeftToRight
377  * and have already completed the bLeftToRight. So we will lose our first flip output
378  * unless we work with its output which is at the destination site. So in this case
379  * our new Source becomes the previous outputs Destination.
380  */
381 
382  if (TopToBottomDone)
383  {
384  sx = BltInfo->DestRect.left;
385  sy = BltInfo->DestRect.top;
386 
387  /* This sets sy to the bottom line */
388  sy += (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
389  }
390  else
391  {
392  sx = BltInfo->SourcePoint.x;
393 
394  /* This sets sy to the top line */
395  sy = BltInfo->SourcePoint.y;
396 
397  /* This sets sy to the bottom line */
398  sy = BltInfo->SourcePoint.y + (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
399  }
400 
401  for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
402  {
403 
404  /* This sets sy to the bottom line */
405  sy = BltInfo->SourcePoint.y + (BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1);
406  Index = 0;
407 
408  /* Read bottom to top and store */
409  for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
410  {
411  if (TopToBottomDone)
412  {
413  store[Index] = DIB_24BPP_GetPixel(BltInfo->DestSurface, sx, sy);
414  }
415  else
416  {
417  store[Index] = DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy);
418  }
419  Index++;
420  sy--;
421  }
422 
423  Index = 0;
424 
425  for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
426  {
428  Index++;
429  }
430  sx++;
431  }
432  ExFreePoolWithTag(store, TAG_DIB);
433  }
434 
435  }
436  }
437  break;
438 
439  case BMF_32BPP:
440  DPRINT("32BPP Case Selected with DestRect Width of '%d'.\n",
441  BltInfo->DestRect.right - BltInfo->DestRect.left);
442 
443  SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
444 
445  if (bTopToBottom)
446  {
447  /* This sets SourceLine to the bottom line */
448  SourceLine += BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1;
449  }
450  DestLine = DestBits;
451 
452  for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
453  {
454  SourceBits = SourceLine;
455  DestBits = DestLine;
456 
457  if (bLeftToRight)
458  {
459  /* This sets SourceBits to the rightmost pixel */
460  SourceBits += (BltInfo->DestRect.right - BltInfo->DestRect.left - 1) * 4;
461  }
462  for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
463  {
464  xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
465  *DestBits = xColor & 0xff;
466  *(PWORD)(DestBits + 1) = (WORD)(xColor >> 8);
467  DEC_OR_INC(SourceBits, bLeftToRight, 4);
468  DestBits += 3;
469  }
470 
471  DEC_OR_INC(SourceLine, bTopToBottom, BltInfo->SourceSurface->lDelta);
472  DestLine += BltInfo->DestSurface->lDelta;
473  }
474  break;
475 
476  default:
477  DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
478  return FALSE;
479  }
480 
481  return TRUE;
482 }
483 
484 BOOLEAN
486 {
487  LONG DestX, DestY;
488  LONG SourceX, SourceY;
489  LONG PatternY = 0;
490  ULONG Dest, Source = 0, Pattern = 0;
491  BOOL UsesSource;
492  BOOL UsesPattern;
493  PBYTE DestBits;
494 
495  UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
496  UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
497 
498  SourceY = BltInfo->SourcePoint.y;
499  DestBits = (PBYTE)(
500  (PBYTE)BltInfo->DestSurface->pvScan0 +
501  (BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
502  BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
503 
504  if (UsesPattern)
505  {
506  if (BltInfo->PatternSurface)
507  {
508  PatternY = (BltInfo->DestRect.top - BltInfo->BrushOrigin.y) %
509  BltInfo->PatternSurface->sizlBitmap.cy;
510  }
511  else
512  {
513  if (BltInfo->Brush)
514  {
515  Pattern = BltInfo->Brush->iSolidColor;
516  }
517  }
518  }
519 
520  for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
521  {
522  SourceX = BltInfo->SourcePoint.x;
523 
524  for (DestX = BltInfo->DestRect.left; DestX < BltInfo->DestRect.right; DestX++, DestBits += 3, SourceX++)
525  {
526  Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
527 
528  if (UsesSource)
529  {
530  Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
531  }
532 
533  if (BltInfo->PatternSurface)
534  {
535  Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX - BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
536  }
537 
538  Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFFFF;
539  *(PUSHORT)(DestBits) = Dest & 0xFFFF;
540  *(DestBits + 2) = (BYTE)(Dest >> 16);
541  }
542 
543  SourceY++;
544  if (BltInfo->PatternSurface)
545  {
546  PatternY++;
547  PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
548  }
549  DestBits -= (BltInfo->DestRect.right - BltInfo->DestRect.left) * 3;
550  DestBits += BltInfo->DestSurface->lDelta;
551  }
552 
553  return TRUE;
554 }
555 
556 /* BitBlt Optimize */
557 BOOLEAN
558 DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
559 {
560  LONG DestY;
561 
562  /* Make WellOrdered by making top < bottom and left < right */
563  RECTL_vMakeWellOrdered(DestRect);
564 
565 #if defined(_M_IX86) && !defined(_MSC_VER)
566  PBYTE xaddr = (PBYTE)DestSurface->pvScan0 + DestRect->top * DestSurface->lDelta + (DestRect->left << 1) + DestRect->left;
567  PBYTE addr;
568  ULONG Count;
569  ULONG xCount=DestRect->right - DestRect->left;
570 
571  for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
572  {
573  Count = xCount;
574  addr = xaddr;
575  xaddr = (PBYTE)((ULONG_PTR)addr + DestSurface->lDelta);
576 
577  if (Count < 8)
578  {
579  /* For small fills, don't bother doing anything fancy */
580  while (Count--)
581  {
582  *(PUSHORT)(addr) = color;
583  addr += 2;
584  *(addr) = color >> 16;
585  addr += 1;
586  }
587  }
588  else
589  {
590  /* Align to 4-byte address */
591  while (0 != ((ULONG_PTR) addr & 0x3))
592  {
593  *(PUSHORT)(addr) = color;
594  addr += 2;
595  *(addr) = color >> 16;
596  addr += 1;
597  Count--;
598  }
599  /* If the color we need to fill with is 0ABC, then the final mem pattern
600  * (note little-endianness) would be:
601  *
602  * |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
603  * |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
604  *
605  * So, taking endianness into account again, we need to fill with these
606  * ULONGs: CABC BCAB ABCA */
607 
608  /* This is about 30% faster than the generic C code below */
609  __asm__ __volatile__ (
610  "movl %1, %%ecx\n\t"
611  "andl $0xffffff, %%ecx\n\t" /* 0ABC */
612  "movl %%ecx, %%ebx\n\t" /* Construct BCAB in ebx */
613  "shrl $8, %%ebx\n\t"
614  "movl %%ecx, %%eax\n\t"
615  "shll $16, %%eax\n\t"
616  "orl %%eax, %%ebx\n\t"
617  "movl %%ecx, %%edx\n\t" /* Construct ABCA in edx */
618  "shll $8, %%edx\n\t"
619  "movl %%ecx, %%eax\n\t"
620  "shrl $16, %%eax\n\t"
621  "orl %%eax, %%edx\n\t"
622  "movl %%ecx, %%eax\n\t" /* Construct CABC in eax */
623  "shll $24, %%eax\n\t"
624  "orl %%ecx, %%eax\n\t"
625  "movl %2, %%ecx\n\t" /* Load count */
626  "shr $2, %%ecx\n\t"
627  "movl %3, %%edi\n" /* Load dest */
628  "1:\n\t"
629  "movl %%eax, (%%edi)\n\t" /* Store 4 pixels, 12 bytes */
630  "movl %%ebx, 4(%%edi)\n\t"
631  "movl %%edx, 8(%%edi)\n\t"
632  "addl $12, %%edi\n\t"
633  "dec %%ecx\n\t"
634  "jnz 1b\n\t"
635  "movl %%edi, %0"
636  : "=m"(addr)
637  : "m"(color), "m"(Count), "m"(addr)
638  : "%eax", "%ebx", "%ecx", "%edx", "%edi");
639  Count = Count & 0x03;
640  while (0 != Count--)
641  {
642  *(PUSHORT)(addr) = color;
643  addr += 2;
644  *(addr) = color >> 16;
645  addr += 1;
646  }
647  }
648  }
649 #else
650 
651  for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
652  {
653  DIB_24BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
654  }
655 #endif
656  return TRUE;
657 }
658 
659 BOOLEAN
660 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
661  RECTL* DestRect, RECTL *SourceRect,
662  XLATEOBJ *ColorTranslation, ULONG iTransColor)
663 {
664  LONG X, Y, SourceX, SourceY = 0, wd;
665  ULONG Source = 0, Dest;
666  BYTE *DestBits;
667 
668  LONG DstHeight;
669  LONG DstWidth;
670  LONG SrcHeight;
671  LONG SrcWidth;
672 
673  DstHeight = DestRect->bottom - DestRect->top;
674  DstWidth = DestRect->right - DestRect->left;
675  SrcHeight = SourceRect->bottom - SourceRect->top;
676  SrcWidth = SourceRect->right - SourceRect->left;
677 
678  DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 +
679  (DestRect->left * 3) +
680  DestRect->top * DestSurf->lDelta);
681  wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) * 3);
682 
683  for(Y = DestRect->top; Y < DestRect->bottom; Y++)
684  {
685  SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight;
686  for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3)
687  {
688  SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth;
689  if (SourceX >= 0 && SourceY >= 0 &&
690  SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY)
691  {
692  Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
693  if(Source != iTransColor)
694  {
695  Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
696  *(PUSHORT)(DestBits) = Dest & 0xFFFF;
697  *(DestBits + 2) = (BYTE)(Dest >> 16);
698  }
699  }
700  }
701 
702  DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
703  }
704 
705  return TRUE;
706 }
707 
708 typedef union {
709  ULONG ul;
710  struct {
711  UCHAR red;
712  UCHAR green;
713  UCHAR blue;
714  UCHAR alpha;
715  } col;
716 } NICEPIXEL32;
717 
718 static __inline UCHAR
720 {
721  return (val > 255) ? 255 : (UCHAR)val;
722 }
723 
724 BOOLEAN
726  RECTL* SourceRect, CLIPOBJ* ClipRegion,
727  XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
728 {
729  INT Rows, Cols, SrcX, SrcY;
730  register PUCHAR Dst;
732  register NICEPIXEL32 DstPixel, SrcPixel;
733  UCHAR Alpha;
734  //UCHAR SrcBpp;
735 
736  DPRINT("DIB_24BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
737  SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
738  DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
739 
740  BlendFunc = BlendObj->BlendFunction;
742  {
743  DPRINT1("BlendOp != AC_SRC_OVER\n");
744  return FALSE;
745  }
746  if (BlendFunc.BlendFlags != 0)
747  {
748  DPRINT1("BlendFlags != 0\n");
749  return FALSE;
750  }
751  if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
752  {
753  DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
754  return FALSE;
755  }
756  if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
757  BitsPerFormat(Source->iBitmapFormat) != 32)
758  {
759  DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
760  return FALSE;
761  }
762 
763  Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
764  (DestRect->left * 3));
765  //SrcBpp = BitsPerFormat(Source->iBitmapFormat);
766 
767  Rows = 0;
768  SrcY = SourceRect->top;
769  while (++Rows <= DestRect->bottom - DestRect->top)
770  {
771  Cols = 0;
772  SrcX = SourceRect->left;
773  while (++Cols <= DestRect->right - DestRect->left)
774  {
775  SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation);
776  SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255;
777  SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255;
778  SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255;
780  {
782  }
783  else
784  {
785  Alpha = (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255;
786  }
787 
788  DstPixel.col.red = Clamp8((*Dst * (255 - Alpha)) / 255 + SrcPixel.col.red) ;
789  DstPixel.col.green = Clamp8((*(Dst+1) * (255 - Alpha) / 255 + SrcPixel.col.green)) ;
790  DstPixel.col.blue = Clamp8((*(Dst+2) * (255 - Alpha)) / 255 + SrcPixel.col.blue) ;
791  *Dst++ = DstPixel.col.red;
792  *Dst++ = DstPixel.col.green;
793  *Dst++ = DstPixel.col.blue;
794  SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left);
795  }
796  Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) +
797  (DestRect->left*3));
798  SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top);
799  }
800 
801  return TRUE;
802 }
803 
804 /* EOF */
POINTL BrushOrigin
Definition: dib.h:29
ROP4 Rop4
Definition: dib.h:30
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3706
#define BMF_24BPP
Definition: winddi.h:359
FLONG flXlate
Definition: winddi.h:1256
Definition: xlate.c:8
SIZEL sizlBitmap
Definition: winddi.h:1209
LONG lDelta
Definition: winddi.h:1213
#define BMF_32BPP
Definition: winddi.h:360
#define DbgPrint
Definition: hal.h:12
#define Y(I)
BOOLEAN DIB_24BPP_BitBlt(PBLTINFO BltInfo)
Definition: dib24bpp.c:485
XLATEOBJ * XlateSourceToDest
Definition: dib.h:25
VOID DIB_24BPP_HLine(SURFOBJ *, LONG, LONG, LONG, ULONG)
Definition: dib24bppc.c:16
#define TRUE
Definition: types.h:120
unsigned char altnotmask[2]
Definition: dib.c:18
#define BitsPerFormat(Format)
Definition: surface.h:109
unsigned char * PUCHAR
Definition: retypes.h:3
long bottom
Definition: polytest.cpp:53
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
__asm__("\n\t \ NewInt3Handler:\n\t \ pushl $" STR(REASON_INT3) "\n\t \ // call debugger loop\n\t \ jmp NewInt31Handler\n\t \ ")
ULONG iBitmapFormat
Definition: winddi.h:1215
#define AC_SRC_ALPHA
Definition: alphablend.c:9
_In_ SURFOBJ _In_ CLIPOBJ _In_opt_ XLATEOBJ _In_ RECTL _In_ RECTL _In_ ULONG iTransColor
Definition: winddi.h:4190
int32_t INT
Definition: typedefs.h:58
BYTE BlendOp
Definition: wingdi.h:2758
SURFOBJ * PatternSurface
Definition: dib.h:24
struct NICEPIXEL32::@4834 col
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
LONG y
Definition: windef.h:330
uint32_t ULONG_PTR
Definition: typedefs.h:65
long right
Definition: polytest.cpp:53
BOOLEAN DIB_24BPP_AlphaBlend(SURFOBJ *Dest, SURFOBJ *Source, RECTL *DestRect, RECTL *SourceRect, CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation, BLENDOBJ *BlendObj)
Definition: dib24bpp.c:725
#define DIB_GetSource(SourceSurf, sx, sy, ColorTranslation)
Definition: dib.h:136
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
#define DIB_GetSourceIndex(SourceSurf, sx, sy)
Definition: dib.h:141
long top
Definition: polytest.cpp:53
BOOLEAN DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
Definition: dib24bpp.c:54
unsigned char BOOLEAN
VOID DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
Definition: dib24bpp.c:21
_In_ ULONG Rows
Definition: haltypes.h:7
LONG cx
Definition: windef.h:334
GLint GLint bottom
Definition: glext.h:7726
static const BLENDFUNCTION BlendFunc
Definition: general.c:32
#define ROP4_USES_SOURCE(Rop4)
Definition: inteng.h:45
ULONG DIB_DoRop(ULONG Rop, ULONG Dest, ULONG Source, ULONG Pattern)
Definition: dib.c:92
GLclampf GLclampf blue
Definition: gl.h:1740
long left
Definition: polytest.cpp:53
#define BMF_16BPP
Definition: winddi.h:358
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
SURFOBJ * SourceSurface
Definition: dib.h:23
WORD * PWORD
Definition: pedump.c:67
RECTL DestRect
Definition: dib.h:26
int Count
Definition: noreturn.cpp:7
SURFOBJ * DestSurface
Definition: dib.h:22
_In_ WDFCOLLECTION _In_ ULONG Index
ULONG DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
Definition: dib24bpp.c:29
BYTE SourceConstantAlpha
Definition: wingdi.h:2760
const GLubyte * c
Definition: glext.h:8905
unsigned short WORD
Definition: ntddk_ex.h:93
GLclampf green
Definition: gl.h:1740
unsigned long DWORD
Definition: ntddk_ex.h:95
LONG x
Definition: windef.h:329
#define red
Definition: linetest.c:67
GLdouble GLdouble right
Definition: glext.h:10859
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
GLenum const GLvoid * addr
Definition: glext.h:9621
ULONG iSolidColor
Definition: winddi.h:234
BYTE BlendFlags
Definition: wingdi.h:2759
BRUSHOBJ * Brush
Definition: dib.h:28
#define AC_SRC_OVER
Definition: wingdi.h:1368
ULONG DIB_1BPP_GetPixel(SURFOBJ *, LONG, LONG)
Definition: dib1bpp.c:30
BOOLEAN DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, RECTL *DestRect, RECTL *SourceRect, XLATEOBJ *ColorTranslation, ULONG iTransColor)
Definition: dib24bpp.c:660
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3706
unsigned char BYTE
Definition: xxhash.c:193
#define XO_TRIVIAL
Definition: winddi.h:1247
Definition: xlate.c:9
#define Dst
Definition: mesh.h:153
#define f1(x, y, z)
Definition: sha1.c:30
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ROP4_USES_PATTERN(Rop4)
Definition: inteng.h:46
#define NULL
Definition: types.h:112
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
DWORD * PDWORD
Definition: pedump.c:68
#define DPRINT1
Definition: precomp.h:8
POINTL SourcePoint
Definition: dib.h:27
Definition: xlate.c:10
BOOLEAN DIB_24BPP_ColorFill(SURFOBJ *DestSurface, RECTL *DestRect, ULONG color)
Definition: dib24bpp.c:558
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
unsigned int ULONG
Definition: retypes.h:1
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
ENGAPI ULONG APIENTRY XLATEOBJ_iXlate(_In_ XLATEOBJ *pxlo, _In_ ULONG iColor)
Definition: xlateobj.c:664
static __inline UCHAR Clamp8(ULONG val)
Definition: dib24bpp.c:719
#define DPRINT
Definition: sndvol32.h:71
#define DEC_OR_INC(var, decTrue, amount)
Definition: dib24bpp.c:17
BYTE AlphaFormat
Definition: wingdi.h:2761
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
Definition: dib24bpp.c:38
LONG cy
Definition: windef.h:335
BYTE * PBYTE
Definition: pedump.c:66
ULONG ul
Definition: alphablend.c:16
VOID FASTCALL RECTL_vMakeWellOrdered(_Inout_ RECTL *prcl)
Definition: rect.c:81
Definition: dib.h:20
unsigned short * PUSHORT
Definition: retypes.h:2
BLENDFUNCTION BlendFunction
Definition: winddi.h:224
#define X(b, s)
PVOID pvScan0
Definition: winddi.h:1212
#define TAG_DIB
Definition: tags.h:17