Branch setupapi
[reactos.git] / reactos / subsys / win32k / dib / dib16bpp.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_16BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
24 {
25 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
26 PWORD addr = (PWORD)byteaddr + x;
27
28 *addr = (WORD)c;
29 }
30
31 ULONG
32 DIB_16BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
33 {
34 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
35 PWORD addr = (PWORD)byteaddr + x;
36
37 return (ULONG)(*addr);
38 }
39
40 VOID
41 DIB_16BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c)
42 {
43 PBYTE byteaddr = SurfObj->pvScan0 + y * SurfObj->lDelta;
44 PWORD addr = (PWORD)byteaddr + x1;
45 LONG cx = x1;
46
47 while(cx < x2) {
48 *addr = (WORD)c;
49 ++addr;
50 ++cx;
51 }
52 }
53
54 VOID
55 DIB_16BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
56 {
57 PBYTE byteaddr = SurfObj->pvScan0 + y1 * SurfObj->lDelta;
58 PWORD addr = (PWORD)byteaddr + x;
59 LONG lDelta = SurfObj->lDelta;
60
61 byteaddr = (PBYTE)addr;
62 while(y1++ < y2) {
63 *addr = (WORD)c;
64
65 byteaddr += lDelta;
66 addr = (PWORD)byteaddr;
67 }
68 }
69
70 BOOLEAN
71 DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo)
72 {
73 LONG i, j, sx, sy, xColor, f1;
74 PBYTE SourceBits, DestBits, SourceLine, DestLine;
75 PBYTE SourceBits_4BPP, SourceLine_4BPP;
76 DestBits = BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 2 * BltInfo->DestRect.left;
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_16BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
92 } else {
93 DIB_16BPP_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 sx = BltInfo->SourcePoint.x;
108 f1 = sx & 1;
109
110 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
111 {
112 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
113 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
114 DIB_16BPP_PutPixel(BltInfo->DestSurface, i, j, xColor);
115 if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
116 sx++;
117 }
118
119 SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
120 }
121 break;
122
123 case BMF_8BPP:
124 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
125 DestLine = DestBits;
126
127 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
128 {
129 SourceBits = SourceLine;
130 DestBits = DestLine;
131
132 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
133 {
134 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
135 SourceBits += 1;
136 DestBits += 2;
137 }
138
139 SourceLine += BltInfo->SourceSurface->lDelta;
140 DestLine += BltInfo->DestSurface->lDelta;
141 }
142 break;
143
144 case BMF_16BPP:
145 if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
146 {
147 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
148 {
149 SourceBits = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
150 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
151 {
152 RtlMoveMemory(DestBits, SourceBits, 2 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
153 SourceBits += BltInfo->SourceSurface->lDelta;
154 DestBits += BltInfo->DestSurface->lDelta;
155 }
156 }
157 else
158 {
159 SourceBits = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
160 DestBits = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 2 * BltInfo->DestRect.left;
161 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
162 {
163 RtlMoveMemory(DestBits, SourceBits, 2 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
164 SourceBits -= BltInfo->SourceSurface->lDelta;
165 DestBits -= BltInfo->DestSurface->lDelta;
166 }
167 }
168 }
169 else
170 {
171 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
172 {
173 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
174 DestLine = DestBits;
175 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
176 {
177 SourceBits = SourceLine;
178 DestBits = DestLine;
179 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
180 {
181 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((WORD *)SourceBits));
182 SourceBits += 2;
183 DestBits += 2;
184 }
185 SourceLine += BltInfo->SourceSurface->lDelta;
186 DestLine += BltInfo->DestSurface->lDelta;
187 }
188 }
189 else
190 {
191 SourceLine = BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x;
192 DestLine = BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 2 * BltInfo->DestRect.left;
193 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
194 {
195 SourceBits = SourceLine;
196 DestBits = DestLine;
197 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
198 {
199 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((WORD *)SourceBits));
200 SourceBits += 2;
201 DestBits += 2;
202 }
203 SourceLine -= BltInfo->SourceSurface->lDelta;
204 DestLine -= BltInfo->DestSurface->lDelta;
205 }
206 }
207 }
208 break;
209
210 case BMF_24BPP:
211 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
212 DestLine = DestBits;
213
214 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
215 {
216 SourceBits = SourceLine;
217 DestBits = DestLine;
218
219 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
220 {
221 xColor = (*(SourceBits + 2) << 0x10) +
222 (*(SourceBits + 1) << 0x08) +
223 (*(SourceBits));
224 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor);
225 SourceBits += 3;
226 DestBits += 2;
227 }
228
229 SourceLine += BltInfo->SourceSurface->lDelta;
230 DestLine += BltInfo->DestSurface->lDelta;
231 }
232 break;
233
234 case BMF_32BPP:
235 SourceLine = BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
236 DestLine = DestBits;
237
238 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
239 {
240 SourceBits = SourceLine;
241 DestBits = DestLine;
242
243 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
244 {
245 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
246 SourceBits += 4;
247 DestBits += 2;
248 }
249
250 SourceLine += BltInfo->SourceSurface->lDelta;
251 DestLine += BltInfo->DestSurface->lDelta;
252 }
253 break;
254
255 default:
256 DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
257 return FALSE;
258 }
259
260 return TRUE;
261 }
262
263 BOOLEAN
264 DIB_16BPP_BitBlt(PBLTINFO BltInfo)
265 {
266 ULONG DestX, DestY;
267 ULONG SourceX, SourceY;
268 ULONG PatternY = 0;
269 ULONG Dest, Source = 0, Pattern = 0;
270 BOOL UsesSource;
271 BOOL UsesPattern;
272 PULONG DestBits;
273 ULONG RoundedRight;
274
275 UsesSource = ROP_USES_SOURCE(BltInfo->Rop4);
276 UsesPattern = ROP_USES_PATTERN(BltInfo->Rop4);
277
278 RoundedRight = BltInfo->DestRect.right -
279 ((BltInfo->DestRect.right - BltInfo->DestRect.left) & 0x1);
280 SourceY = BltInfo->SourcePoint.y;
281 DestBits = (PULONG)(
282 BltInfo->DestSurface->pvScan0 +
283 (BltInfo->DestRect.left << 1) +
284 BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
285
286 if (UsesPattern)
287 {
288 if (BltInfo->PatternSurface)
289 {
290 PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
291 BltInfo->PatternSurface->sizlBitmap.cy;
292 }
293 else
294 {
295 Pattern = BltInfo->Brush->iSolidColor |
296 (BltInfo->Brush->iSolidColor << 16);
297 }
298 }
299
300 for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
301 {
302 SourceX = BltInfo->SourcePoint.x;
303
304 for (DestX = BltInfo->DestRect.left; DestX < RoundedRight; DestX += 2, DestBits++, SourceX += 2)
305 {
306 Dest = *DestBits;
307
308 if (UsesSource)
309 {
310 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
311 Source |= DIB_GetSource(BltInfo->SourceSurface, SourceX + 1, SourceY, BltInfo->XlateSourceToDest) << 16;
312 }
313
314 if (BltInfo->PatternSurface)
315 {
316 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
317 Pattern |= DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x + 1) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest) << 16;
318 }
319
320 *DestBits = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern);
321 }
322
323 if (DestX < BltInfo->DestRect.right)
324 {
325 Dest = *((PUSHORT)DestBits);
326
327 if (UsesSource)
328 {
329 Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
330 }
331
332 if (BltInfo->PatternSurface)
333 {
334 Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
335 }
336
337 DIB_16BPP_PutPixel(BltInfo->DestSurface, DestX, DestY, DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFF);
338 DestBits = (PULONG)((ULONG_PTR)DestBits + 2);
339 }
340
341 SourceY++;
342 if (BltInfo->PatternSurface)
343 {
344 PatternY++;
345 PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
346 }
347 DestBits = (PULONG)(
348 (ULONG_PTR)DestBits -
349 ((BltInfo->DestRect.right - BltInfo->DestRect.left) << 1) +
350 BltInfo->DestSurface->lDelta);
351 }
352
353 return TRUE;
354 }
355
356
357 /*
358 =======================================
359 Stretching functions goes below
360 Some parts of code are based on an
361 article "Bresenhame image scaling"
362 Dr. Dobb Journal, May 2002
363 =======================================
364 */
365
366 typedef unsigned short PIXEL;
367
368 /* 16-bit HiColor (565 format) */
369 inline PIXEL average16(PIXEL a, PIXEL b)
370 {
371 // This one doesn't work
372 /*
373 if (a == b) {
374 return a;
375 } else {
376 unsigned short mask = ~ (((a | b) & 0x0410) << 1);
377 return ((a & mask) + (b & mask)) >> 1;
378 }*/ /* if */
379
380 // This one should be correct, but it's too long
381 /*
382 unsigned char r1, g1, b1, r2, g2, b2, rr, gr, br;
383 unsigned short res;
384
385 r1 = (a & 0xF800) >> 11;
386 g1 = (a & 0x7E0) >> 5;
387 b1 = (a & 0x1F);
388
389 r2 = (b & 0xF800) >> 11;
390 g2 = (b & 0x7E0) >> 5;
391 b2 = (b & 0x1F);
392
393 rr = (r1+r2) / 2;
394 gr = (g1+g2) / 2;
395 br = (b1+b2) / 2;
396
397 res = (rr << 11) + (gr << 5) + br;
398
399 return res;
400 */
401 return a; // FIXME: Depend on SetStretchMode
402 }
403
404 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
405 void ScaleLineAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth)
406 {
407 int NumPixels = TgtWidth;
408 int IntPart = SrcWidth / TgtWidth;
409 int FractPart = SrcWidth % TgtWidth;
410 int Mid = TgtWidth >> 1;
411 int E = 0;
412 int skip;
413 PIXEL p;
414
415 skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1);
416 NumPixels -= skip;
417
418 while (NumPixels-- > 0) {
419 p = *Source;
420 if (E >= Mid)
421 p = average16(p, *(Source+1));
422 *Target++ = p;
423 Source += IntPart;
424 E += FractPart;
425 if (E >= TgtWidth) {
426 E -= TgtWidth;
427 Source++;
428 } /* if */
429 } /* while */
430 while (skip-- > 0)
431 *Target++ = *Source;
432 }
433
434 static BOOLEAN
435 FinalCopy16(PIXEL *Target, PIXEL *Source, PSPAN ClipSpans, UINT ClipSpansCount, UINT *SpanIndex,
436 UINT DestY, RECTL *DestRect)
437 {
438 LONG Left, Right;
439
440 while (ClipSpans[*SpanIndex].Y < DestY
441 || (ClipSpans[*SpanIndex].Y == DestY
442 && ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width < DestRect->left))
443 {
444 (*SpanIndex)++;
445 if (ClipSpansCount <= *SpanIndex)
446 {
447 /* No more spans, everything else is clipped away, we're done */
448 return FALSE;
449 }
450 }
451 while (ClipSpans[*SpanIndex].Y == DestY)
452 {
453 if (ClipSpans[*SpanIndex].X < DestRect->right)
454 {
455 Left = max(ClipSpans[*SpanIndex].X, DestRect->left);
456 Right = min(ClipSpans[*SpanIndex].X + ClipSpans[*SpanIndex].Width, DestRect->right);
457 memcpy(Target + Left - DestRect->left, Source + Left - DestRect->left,
458 (Right - Left) * sizeof(PIXEL));
459 }
460 (*SpanIndex)++;
461 if (ClipSpansCount <= *SpanIndex)
462 {
463 /* No more spans, everything else is clipped away, we're done */
464 return FALSE;
465 }
466 }
467
468 return TRUE;
469 }
470
471 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
472 BOOLEAN ScaleRectAvg16(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
473 RECTL* DestRect, RECTL *SourceRect,
474 POINTL* MaskOrigin, POINTL BrushOrigin,
475 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
476 ULONG Mode)
477 {
478 int NumPixels = DestRect->bottom - DestRect->top;
479 int IntPart = (((SourceRect->bottom - SourceRect->top) / (DestRect->bottom - DestRect->top)) * SourceSurf->lDelta) >> 1;
480 int FractPart = (SourceRect->bottom - SourceRect->top) % (DestRect->bottom - DestRect->top);
481 int Mid = (DestRect->bottom - DestRect->top) >> 1;
482 int E = 0;
483 int skip;
484 PIXEL *ScanLine, *ScanLineAhead;
485 PIXEL *PrevSource = NULL;
486 PIXEL *PrevSourceAhead = NULL;
487 PIXEL *Target = (PIXEL *) (DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left);
488 PIXEL *Source = (PIXEL *) (SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 2 * SourceRect->left);
489 PSPAN ClipSpans;
490 UINT ClipSpansCount;
491 UINT SpanIndex;
492 LONG DestY;
493
494 if (! ClipobjToSpans(&ClipSpans, &ClipSpansCount, ClipRegion, DestRect))
495 {
496 return FALSE;
497 }
498 if (0 == ClipSpansCount)
499 {
500 /* No clip spans == empty clipping region, everything clipped away */
501 ASSERT(NULL == ClipSpans);
502 return TRUE;
503 }
504 skip = (DestRect->bottom - DestRect->top < SourceRect->bottom - SourceRect->top) ? 0 : ((DestRect->bottom - DestRect->top) / (2 * (SourceRect->bottom - SourceRect->top)) + 1);
505 NumPixels -= skip;
506
507 ScanLine = (PIXEL*)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
508 ScanLineAhead = (PIXEL *)ExAllocatePool(PagedPool, (DestRect->right - DestRect->left) * sizeof(PIXEL));
509
510 DestY = DestRect->top;
511 SpanIndex = 0;
512 while (NumPixels-- > 0) {
513 if (Source != PrevSource) {
514 if (Source == PrevSourceAhead) {
515 /* the next scan line has already been scaled and stored in
516 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
517 * point to
518 */
519 PIXEL *tmp = ScanLine;
520 ScanLine = ScanLineAhead;
521 ScanLineAhead = tmp;
522 } else {
523 ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
524 } /* if */
525 PrevSource = Source;
526 } /* if */
527
528 if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + SourceSurf->lDelta)) {
529 int x;
530 ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + SourceSurf->lDelta), SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
531 for (x = 0; x < DestRect->right - DestRect->left; x++)
532 ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]);
533 PrevSourceAhead = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
534 } /* if */
535
536 if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
537 {
538 /* No more spans, everything else is clipped away, we're done */
539 ExFreePool(ClipSpans);
540 ExFreePool(ScanLine);
541 ExFreePool(ScanLineAhead);
542 return TRUE;
543 }
544 DestY++;
545 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
546 Source += IntPart;
547 E += FractPart;
548 if (E >= DestRect->bottom - DestRect->top) {
549 E -= DestRect->bottom - DestRect->top;
550 Source = (PIXEL *)((BYTE *)Source + SourceSurf->lDelta);
551 } /* if */
552 } /* while */
553
554 if (skip > 0 && Source != PrevSource)
555 ScaleLineAvg16(ScanLine, Source, SourceRect->right - SourceRect->left, DestRect->right - DestRect->left);
556 while (skip-- > 0) {
557 if (! FinalCopy16(Target, ScanLine, ClipSpans, ClipSpansCount, &SpanIndex, DestY, DestRect))
558 {
559 /* No more spans, everything else is clipped away, we're done */
560 ExFreePool(ClipSpans);
561 ExFreePool(ScanLine);
562 ExFreePool(ScanLineAhead);
563 return TRUE;
564 }
565 DestY++;
566 Target = (PIXEL *)((BYTE *)Target + DestSurf->lDelta);
567 } /* while */
568
569 ExFreePool(ClipSpans);
570 ExFreePool(ScanLine);
571 ExFreePool(ScanLineAhead);
572
573 return TRUE;
574 }
575
576 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
577 BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
578 RECTL* DestRect, RECTL *SourceRect,
579 POINTL* MaskOrigin, POINTL BrushOrigin,
580 CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
581 ULONG Mode)
582 {
583 DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
584 BitsPerFormat(SourceSurf->iBitmapFormat), SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
585 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
586
587 switch(SourceSurf->iBitmapFormat)
588 {
589 case BMF_1BPP:
590 case BMF_4BPP:
591 case BMF_8BPP:
592 case BMF_24BPP:
593 case BMF_32BPP:
594 /* Not implemented yet. */
595 return FALSE;
596 break;
597
598 case BMF_16BPP:
599 return ScaleRectAvg16(DestSurf, SourceSurf, DestRect, SourceRect, MaskOrigin, BrushOrigin,
600 ClipRegion, ColorTranslation, Mode);
601 break;
602
603 default:
604 DPRINT1("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
605 return FALSE;
606 }
607
608
609
610 return TRUE;
611 }
612
613 BOOLEAN
614 DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
615 RECTL* DestRect, POINTL *SourcePoint,
616 XLATEOBJ *ColorTranslation, ULONG iTransColor)
617 {
618 ULONG RoundedRight, X, Y, SourceX, SourceY, Source, wd, Dest;
619 ULONG *DestBits;
620
621 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x1);
622 SourceY = SourcePoint->y;
623 DestBits = (ULONG*)(DestSurf->pvScan0 +
624 (DestRect->left << 1) +
625 DestRect->top * DestSurf->lDelta);
626 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 1);
627
628 for(Y = DestRect->top; Y < DestRect->bottom; Y++)
629 {
630 SourceX = SourcePoint->x;
631 for(X = DestRect->left; X < RoundedRight; X += 2, DestBits++, SourceX += 2)
632 {
633 Dest = *DestBits;
634
635 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
636 if(Source != iTransColor)
637 {
638 Dest &= 0xFFFF0000;
639 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF);
640 }
641
642 Source = DIB_GetSourceIndex(SourceSurf, SourceX + 1, SourceY);
643 if(Source != iTransColor)
644 {
645 Dest &= 0xFFFF;
646 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16);
647 }
648
649 *DestBits = Dest;
650 }
651
652 if(X < DestRect->right)
653 {
654 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
655 if(Source != iTransColor)
656 {
657 *((USHORT*)DestBits) = (USHORT)XLATEOBJ_iXlate(ColorTranslation, Source);
658 }
659
660 DestBits = (PULONG)((ULONG_PTR)DestBits + 2);
661 }
662 SourceY++;
663 DestBits = (ULONG*)((ULONG_PTR)DestBits + wd);
664 }
665
666 return TRUE;
667 }
668
669 /* EOF */