Copy msimg32
[reactos.git] / reactos / subsys / win32k / dib / dib24bpp.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$ */
20 #include <w32k.h>
21
22 VOID
23 DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
24 {
25 PBYTE addr = SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
26 *(PUSHORT)(addr) = c & 0xFFFF;
27 *(addr + 2) = (c >> 16) & 0xFF;
28 }
29
30 ULONG
31 DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
32 {
33 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
34 return *(PUSHORT)(addr) + (*(addr + 2) << 16);
35 }
36
37 VOID
38 DIB_24BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
39 {
40 PBYTE addr = SurfObj->pvScan0 + y * SurfObj->lDelta + (x1 << 1) + x1;
41 LONG cx = x1;
42
43 c &= 0xFFFFFF;
44 while(cx < x2) {
45 *(PUSHORT)(addr) = c & 0xFFFF;
46 addr += 2;
47 *(addr) = c >> 16;
48 addr += 1;
49 ++cx;
50 }
51 }
52
53 VOID
54 DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
55 {
56 PBYTE addr = SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
57 LONG lDelta = SurfObj->lDelta;
58
59 c &= 0xFFFFFF;
60 while(y1++ < y2) {
61 *(PUSHORT)(addr) = c & 0xFFFF;
62 *(addr + 2) = c >> 16;
63
64 addr += lDelta;
65 }
66 }
67
68 BOOLEAN
69 DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
70 {
71 LONG i, j, sx, sy, xColor, f1;
72 PBYTE SourceBits, DestBits, SourceLine, DestLine;
73 PBYTE SourceBits_4BPP, SourceLine_4BPP;
74 PWORD SourceBits_16BPP, SourceLine_16BPP;
75
76 DestBits = BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
77
78 switch(BltInfo->SourceSurface->iBitmapFormat)
79 {
80 case BMF_1BPP:
81 sx = BltInfo->SourcePoint.x;
82 sy = BltInfo->SourcePoint.y;
83
84 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
85 {
86 sx = BltInfo->SourcePoint.x;
87 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
88 {
89 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
90 {
91 DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
92 } else {
93 DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
94 }
95 sx++;
96 }
97 sy++;
98 }
99 break;
100
101 case BMF_4BPP:
102 SourceBits_4BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
103
104 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
105 {
106 SourceLine_4BPP = SourceBits_4BPP;
107 DestLine = DestBits;
108 sx = BltInfo->SourcePoint.x;
109 f1 = sx & 1;
110
111 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
112 {
113 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
114 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
115 *DestLine++ = xColor & 0xff;
116 *(PWORD)DestLine = xColor >> 8;
117 DestLine += 2;
118 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
119 sx++;
120 }
121
122 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
123 DestBits += BltInfo->DestSurface->lDelta;
124 }
125 break;
126
127 case BMF_8BPP:
128 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
129 DestLine = DestBits;
130
131 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
132 {
133 SourceBits = SourceLine;
134 DestBits = DestLine;
135
136 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
137 {
138 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
139 *DestBits = xColor & 0xff;
140 *(PWORD)(DestBits + 1) = xColor >> 8;
141 SourceBits += 1;
142 DestBits += 3;
143 }
144
145 SourceLine += BltInfo->SourceSurface->lDelta;
146 DestLine += BltInfo->DestSurface->lDelta;
147 }
148 break;
149
150 case BMF_16BPP:
151 SourceBits_16BPP = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
152
153 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
154 {
155 SourceLine_16BPP = SourceBits_16BPP;
156 DestLine = DestBits;
157
158 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
159 {
160 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_16BPP);
161 *DestLine++ = xColor & 0xff;
162 *(PWORD)DestLine = xColor >> 8;
163 DestLine += 2;
164 SourceLine_16BPP++;
165 }
166
167 SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
168 DestBits += BltInfo->DestSurface->lDelta;
169 }
170 break;
171
172 case BMF_24BPP:
173 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
174 {
175 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
176 {
177 SourceBits = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
178 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
179 {
180 RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
181 SourceBits += BltInfo->SourceSurface->lDelta;
182 DestBits += BltInfo->DestSurface->lDelta;
183 }
184 }
185 else
186 {
187 SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
188 DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
189 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
190 {
191 RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
192 SourceBits -= BltInfo->SourceSurface->lDelta;
193 DestBits -= BltInfo->DestSurface->lDelta;
194 }
195 }
196 }
197 else
198 {
199 /* FIXME */
200 DPRINT1("DIB_24BPP_Bitblt: Unhandled BltInfo->XlateSourceToDest for 16 -> 16 copy\n");
201 return FALSE;
202 }
203 break;
204
205 case BMF_32BPP:
206 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
207 DestLine = DestBits;
208
209 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
210 {
211 SourceBits = SourceLine;
212 DestBits = DestLine;
213
214 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
215 {
216 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
217 *DestBits = xColor & 0xff;
218 *(PWORD)(DestBits + 1) = xColor >> 8;
219 SourceBits += 4;
220 DestBits += 3;
221 }
222
223 SourceLine += BltInfo->SourceSurface->lDelta;
224 DestLine += BltInfo->DestSurface->lDelta;
225 }
226 break;
227
228 default:
229 DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
230 return FALSE;
231 }
232
233 return TRUE;
234 }
235
236 BOOLEAN
237 DIB_24BPP_BitBlt(PBLTINFO BltInfo)
238 {
239 ULONG DestX, DestY;
240 ULONG SourceX, SourceY;
241 ULONG PatternY = 0;
242 ULONG Dest, Source = 0, Pattern = 0;
243 BOOL UsesSource;
244 BOOL UsesPattern;
245 PBYTE DestBits;
246
247 UsesSource = ROP_USES_SOURCE(BltInfo->Rop4);
248 UsesPattern = ROP_USES_PATTERN(BltInfo->Rop4);
249
250 SourceY = BltInfo->SourcePoint.y;
251 DestBits = (PBYTE)(
252 BltInfo->DestSurface->pvScan0 +
253 (BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
254 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
255
256 if (UsesPattern)
257 {
258 if (BltInfo->PatternSurface)
259 {
260 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
261 BltInfo->PatternSurface->sizlBitmap.cy;
262 }
263 else
264 {
265 Pattern = BltInfo->Brush->iSolidColor;
266 }
267 }
268
269 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
270 {
271 SourceX = BltInfo->SourcePoint.x;
272
273 for (DestX = BltInfo->DestRect.left; DestX < BltInfo->DestRect.right; DestX++, DestBits += 3, SourceX++)
274 {
275 Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
276
277 if (UsesSource)
278 {
279 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
280 }
281
282 if (BltInfo->PatternSurface)
283 {
284 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
285 }
286
287 Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFFFF;
288 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
289 *(DestBits + 2) = Dest >> 16;
290 }
291
292 SourceY++;
293 if (BltInfo->PatternSurface)
294 {
295 PatternY++;
296 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
297 }
298 DestBits -= (BltInfo->DestRect.right - BltInfo->DestRect.left) * 3;
299 DestBits += BltInfo->DestSurface->lDelta;
300 }
301
302 return TRUE;
303 }
304
305 BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
306 RECTL* DestRect, RECTL *SourceRect,
307 POINTL* MaskOrigin, POINTL BrushOrigin,
308 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
309 ULONG Mode)
310 {
311 DbgPrint("DIB_24BPP_StretchBlt: Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
312 return FALSE;
313 }
314
315 BOOLEAN
316 DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
317 RECTL* DestRect, POINTL *SourcePoint,
318 XLATEOBJ *ColorTranslation, ULONG iTransColor)
319 {
320 ULONG X, Y, SourceX, SourceY, Source, wd, Dest;
321 BYTE *DestBits;
322
323 SourceY = SourcePoint->y;
324 DestBits = (BYTE*)(DestSurf->pvScan0 +
325 (DestRect->left << 2) +
326 DestRect->top * DestSurf->lDelta);
327 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
328
329 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
330 {
331 SourceX = SourcePoint->x;
332 for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
333 {
334 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
335 if(Source != iTransColor)
336 {
337 Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
338 *(PUSHORT)(DestBits) = Dest & 0xFFFF;
339 *(DestBits + 2) = Dest >> 16;
340 }
341 }
342
343 SourceY++;
344 DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
345 }
346
347 return TRUE;
348 }
349
350 /* EOF */