xref: /reactos/win32ss/gdi/dib/dib4bpp.c (revision 84ccccab)
1 /*
2  * PROJECT:         Win32 subsystem
3  * LICENSE:         See COPYING in the top level directory
4  * FILE:            win32ss/gdi/dib/dib4bpp.c
5  * PURPOSE:         Device Independant Bitmap functions, 4bpp
6  * PROGRAMMERS:     Jason Filby
7  */
8 
9 
10 #include <win32k.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 VOID
16 DIB_4BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
17 {
18    PBYTE addr = (PBYTE)SurfObj->pvScan0 + (x>>1) + y * SurfObj->lDelta;
19    *addr = (*addr & notmask[x&1]) | (BYTE)(c << ((1-(x&1))<<2));
20 }
21 
22 ULONG
23 DIB_4BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
24 {
25    PBYTE addr = (PBYTE)SurfObj->pvScan0 + (x>>1) + y * SurfObj->lDelta;
26    return (*addr >> ((1-(x&1))<<2)) & 0x0f;
27 }
28 
29 VOID
30 DIB_4BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
31 {
32   PBYTE  addr = (PBYTE)SurfObj->pvScan0 + (x1>>1) + y * SurfObj->lDelta;
33   LONG  cx = x1;
34 
35   while(cx < x2)
36   {
37     *addr = (*addr & notmask[x1&1]) | (BYTE)(c << ((1-(x1&1))<<2));
38     if((++x1 & 1) == 0)
39       ++addr;
40     ++cx;
41   }
42 }
43 
44 VOID
45 DIB_4BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
46 {
47   PBYTE  addr = SurfObj->pvScan0;
48   int  lDelta = SurfObj->lDelta;
49 
50   addr += (x>>1) + y1 * lDelta;
51   while(y1++ < y2)
52   {
53     *addr = (*addr & notmask[x&1]) | (BYTE)(c << ((1-(x&1))<<2));
54     addr += lDelta;
55   }
56 }
57 
58 #ifndef _USE_DIBLIB_
59 BOOLEAN
60 DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo)
61 {
62   LONG     i, j, sx, sy, f2, xColor;
63   PBYTE    SourceBits_24BPP, SourceLine_24BPP;
64   PBYTE    DestBits, DestLine, SourceBits_8BPP, SourceLine_8BPP;
65   PBYTE    SourceBits, SourceLine;
66 
67   DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 +
68              (BltInfo->DestRect.left >> 1) +
69              BltInfo->DestRect.top * BltInfo->DestSurface->lDelta;
70 
71   switch (BltInfo->SourceSurface->iBitmapFormat)
72   {
73     case BMF_1BPP:
74       sx = BltInfo->SourcePoint.x;
75       sy = BltInfo->SourcePoint.y;
76 
77       for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
78       {
79         sx = BltInfo->SourcePoint.x;
80         for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
81         {
82           if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
83           {
84             DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
85           }
86           else
87           {
88             DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
89           }
90           sx++;
91         }
92         sy++;
93       }
94       break;
95 
96     case BMF_4BPP:
97       sy = BltInfo->SourcePoint.y;
98 
99       for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
100       {
101         sx = BltInfo->SourcePoint.x;
102 
103         for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
104         {
105           if (NULL != BltInfo->XlateSourceToDest)
106           {
107             DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy)));
108           }
109           else
110           {
111             DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, DIB_4BPP_GetPixel(BltInfo->SourceSurface, sx, sy));
112           }
113           sx++;
114         }
115         sy++;
116       }
117       break;
118 
119     case BMF_8BPP:
120       SourceBits_8BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
121 
122       for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
123       {
124         SourceLine_8BPP = SourceBits_8BPP;
125         DestLine = DestBits;
126         f2 = BltInfo->DestRect.left & 1;
127 
128         for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
129         {
130           *DestLine = (*DestLine & notmask[f2]) |
131             (BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_8BPP)) << ((4 * (1 - f2))));
132           if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
133           SourceLine_8BPP++;
134         }
135 
136         SourceBits_8BPP += BltInfo->SourceSurface->lDelta;
137         DestBits += BltInfo->DestSurface->lDelta;
138       }
139       break;
140 
141     case BMF_16BPP:
142       SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
143       DestLine = DestBits;
144 
145       for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
146       {
147         SourceBits = SourceLine;
148         DestBits = DestLine;
149         f2 = BltInfo->DestRect.left & 1;
150 
151         for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
152         {
153           xColor = *((PWORD) SourceBits);
154           *DestBits = (*DestBits & notmask[f2]) |
155             (BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor)) << ((4 * (1 - f2))));
156           if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; }
157           SourceBits += 2;
158         }
159 
160         SourceLine += BltInfo->SourceSurface->lDelta;
161         DestLine += BltInfo->DestSurface->lDelta;
162       }
163       break;
164 
165     case BMF_24BPP:
166       SourceBits_24BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x * 3;
167 
168       for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
169       {
170         SourceLine_24BPP = SourceBits_24BPP;
171         DestLine = DestBits;
172         f2 = BltInfo->DestRect.left & 1;
173 
174         for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
175         {
176           xColor = (*(SourceLine_24BPP + 2) << 0x10) +
177              (*(SourceLine_24BPP + 1) << 0x08) +
178              (*(SourceLine_24BPP));
179           *DestLine = (*DestLine & notmask[f2]) |
180             (BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor)) << ((4 * (1 - f2))));
181           if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
182           SourceLine_24BPP+=3;
183         }
184 
185         SourceBits_24BPP += BltInfo->SourceSurface->lDelta;
186         DestBits += BltInfo->DestSurface->lDelta;
187       }
188       break;
189 
190     case BMF_32BPP:
191       SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
192       DestLine = DestBits;
193 
194       for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
195       {
196         SourceBits = SourceLine;
197         DestBits = DestLine;
198         f2 = BltInfo->DestRect.left & 1;
199 
200         for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
201         {
202           xColor = *((PDWORD) SourceBits);
203           *DestBits = (*DestBits & notmask[f2]) |
204             (BYTE)((XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor)) << ((4 * (1 - f2))));
205           if(f2 == 1) { DestBits++; f2 = 0; } else { f2 = 1; }
206           SourceBits += 4;
207         }
208 
209         SourceLine += BltInfo->SourceSurface->lDelta;
210         DestLine += BltInfo->DestSurface->lDelta;
211       }
212       break;
213 
214     default:
215       DbgPrint("DIB_4BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
216       return FALSE;
217   }
218   return(TRUE);
219 }
220 
221 BOOLEAN
222 DIB_4BPP_BitBlt(PBLTINFO BltInfo)
223 {
224   LONG DestX, DestY;
225   LONG SourceX, SourceY;
226   LONG PatternY = 0;
227   ULONG Dest, Source = 0, Pattern = 0;
228   BOOLEAN UsesSource;
229   BOOLEAN UsesPattern;
230   PULONG DestBits;
231   LONG RoundedRight;
232   static const ULONG ExpandSolidColor[16] =
233   {
234     0x00000000 /* 0 */,
235     0x11111111 /* 1 */,
236     0x22222222 /* 2 */,
237     0x33333333 /* 3 */,
238     0x44444444 /* 4 */,
239     0x55555555 /* 5 */,
240     0x66666666 /* 6 */,
241     0x77777777 /* 7 */,
242     0x88888888 /* 8 */,
243     0x99999999 /* 9 */,
244     0xAAAAAAAA /* 10 */,
245     0xBBBBBBBB /* 11 */,
246     0xCCCCCCCC /* 12 */,
247     0xDDDDDDDD /* 13 */,
248     0xEEEEEEEE /* 14 */,
249     0xFFFFFFFF /* 15 */,
250   };
251 
252   UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
253   UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
254 
255   SourceY = BltInfo->SourcePoint.y;
256   RoundedRight = BltInfo->DestRect.right -
257     ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 0x7);
258 
259   if (UsesPattern)
260   {
261     if (BltInfo->PatternSurface)
262     {
263       PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
264         BltInfo->PatternSurface->sizlBitmap.cy;
265     }
266     else
267     {
268       if (BltInfo->Brush)
269         Pattern = ExpandSolidColor[BltInfo->Brush->iSolidColor];
270     }
271   }
272 
273   for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
274   {
275     DestBits = (PULONG)(
276       (PBYTE)BltInfo->DestSurface->pvScan0 +
277       (BltInfo->DestRect.left >> 1) +
278       DestY * BltInfo->DestSurface->lDelta);
279     SourceX = BltInfo->SourcePoint.x;
280     DestX = BltInfo->DestRect.left;
281 
282     if (DestX & 0x1)
283     {
284       Dest = DIB_4BPP_GetPixel(BltInfo->DestSurface, DestX, DestY);
285 
286       if (UsesSource)
287       {
288         Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
289       }
290 
291       if (BltInfo->PatternSurface)
292       {
293         Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
294       }
295 
296       DIB_4BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
297 
298       DestX++;
299       SourceX++;
300       DestBits = (PULONG)((ULONG_PTR)DestBits + 1);
301     }
302 
303     for (; DestX < RoundedRight; DestX += 8, SourceX += 8, DestBits++)
304     {
305       Dest = *DestBits;
306       if (UsesSource)
307       {
308         Source =
309           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 1, SourceY, BltInfo->XlateSourceToDest)) |
310           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 0, SourceY, BltInfo->XlateSourceToDest) << 4) |
311           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 3, SourceY, BltInfo->XlateSourceToDest) << 8) |
312           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 2, SourceY, BltInfo->XlateSourceToDest) << 12) |
313           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 5, SourceY, BltInfo->XlateSourceToDest) << 16) |
314           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 4, SourceY, BltInfo->XlateSourceToDest) << 20) |
315           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 7, SourceY, BltInfo->XlateSourceToDest) << 24) |
316           (DIB_GetSource(BltInfo->SourceSurface, SourceX + 6, SourceY, BltInfo->XlateSourceToDest) << 28);
317       }
318       if (BltInfo->PatternSurface)
319       {
320         Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 1) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
321         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 0) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 4;
322         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 3) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 8;
323         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 2) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 12;
324         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 5) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 16;
325         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 4) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 20;
326         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 7) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 24;
327         Pattern |= DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 6) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY) << 28;
328       }
329       *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
330     }
331 
332     /* Process the rest of pixel on the line */
333     for (; DestX < BltInfo->DestRect.right; DestX++, SourceX++)
334     {
335       Dest = DIB_4BPP_GetPixel(BltInfo->DestSurface, DestX, DestY);
336       if (UsesSource)
337       {
338         Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
339       }
340       if (BltInfo->PatternSurface)
341       {
342         Pattern = DIB_GetSourceIndex(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY);
343       }
344       DIB_4BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xF);
345     }
346 
347     SourceY++;
348     if (BltInfo->PatternSurface)
349     {
350       PatternY++;
351       PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
352     }
353   }
354 
355   return TRUE;
356 }
357 
358 /* BitBlt Optimize */
359 BOOLEAN
360 DIB_4BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
361 {
362   LONG DestY;
363 
364   for (DestY = DestRect->top; DestY < DestRect->bottom; DestY++)
365   {
366     DIB_4BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
367   }
368   return TRUE;
369 }
370 #endif // !_USE_DIBLIB_
371 
372 BOOLEAN
373 DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
374                         RECTL*  DestRect,  RECTL *SourceRect,
375                         XLATEOBJ *ColorTranslation, ULONG iTransColor)
376 {
377   return FALSE;
378 }
379 
380 /* EOF */
381