2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
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.
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.
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.
26 DIB_16BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
28 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
;
29 PWORD addr
= (PWORD
)byteaddr
+ x
;
35 DIB_16BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
37 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
;
38 PWORD addr
= (PWORD
)byteaddr
+ x
;
39 return (ULONG
)(*addr
);
43 DIB_16BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
45 PDWORD addr
= (PDWORD
)((PWORD
)((PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
) + x1
);
47 #if defined(_M_IX86) && !defined(_MSC_VER)
48 /* This is about 10% faster than the generic C code below */
51 __asm__
__volatile__ (
55 " andl $0xffff, %0\n" /* If the pixel value is "abcd", put "abcdabcd" in %eax */
58 " test $0x03, %%edi\n" /* Align to fullword boundary */
64 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */
66 " rep stosl\n" /* The actual fill */
67 " test $0x01, %1\n" /* One left to do at the right side? */
72 : "r"(c
), "r"(Count
), "m"(addr
)
73 : "%eax", "%ecx", "%edi");
82 addr
= (PDWORD
)((PWORD
)(addr
) + 1);
84 cc
= ((c
& 0xffff) << 16) | (c
& 0xffff);
99 DIB_16BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
101 #if defined(_M_IX86) && !defined(_MSC_VER)
103 " testl %2, %2" "\n\t"
105 " movl %2, %%ecx" "\n\t"
106 " shrl $2, %2" "\n\t"
107 " andl $3, %%ecx" "\n\t"
110 " movw %%ax, (%0)" "\n\t"
111 " addl %1, %0" "\n\t"
114 " testl %2, %2" "\n\t"
117 " movw %%ax, (%0)" "\n\t"
118 " addl %1, %0" "\n\t"
119 " movw %%ax, (%0)" "\n\t"
120 " addl %1, %0" "\n\t"
121 " movw %%ax, (%0)" "\n\t"
122 " addl %1, %0" "\n\t"
123 " movw %%ax, (%0)" "\n\t"
124 " addl %1, %0" "\n\t"
129 : "r"((PBYTE
)SurfObj
->pvScan0
+ (y1
* SurfObj
->lDelta
) + (x
* sizeof (WORD
))),
130 "r"(SurfObj
->lDelta
), "r"(y2
- y1
), "a"(c
)
131 : "cc", "memory", "%ecx");
133 PBYTE byteaddr
= (PBYTE
)(ULONG_PTR
)SurfObj
->pvScan0
+ y1
* SurfObj
->lDelta
;
134 PWORD addr
= (PWORD
)byteaddr
+ x
;
135 LONG lDelta
= SurfObj
->lDelta
;
137 byteaddr
= (PBYTE
)addr
;
143 addr
= (PWORD
)byteaddr
;
149 DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
151 LONG i
, j
, sx
, sy
, xColor
, f1
;
152 PBYTE SourceBits
, DestBits
, SourceLine
, DestLine
;
153 PBYTE SourceBits_4BPP
, SourceLine_4BPP
;
154 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ (BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
156 switch(BltInfo
->SourceSurface
->iBitmapFormat
)
159 sx
= BltInfo
->SourcePoint
.x
;
160 sy
= BltInfo
->SourcePoint
.y
;
161 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
163 sx
= BltInfo
->SourcePoint
.x
;
164 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
166 if(DIB_1BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
) == 0)
168 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
,
169 XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 0));
173 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
,
174 XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 1));
183 SourceBits_4BPP
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
184 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
185 (BltInfo
->SourcePoint
.x
>> 1);
187 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
189 SourceLine_4BPP
= SourceBits_4BPP
;
190 sx
= BltInfo
->SourcePoint
.x
;
193 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
195 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
,
196 (*SourceLine_4BPP
& altnotmask
[f1
]) >> (4 * (1 - f1
)));
197 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, xColor
);
209 SourceBits_4BPP
+= BltInfo
->SourceSurface
->lDelta
;
214 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
215 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
216 BltInfo
->SourcePoint
.x
;
219 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
221 SourceBits
= SourceLine
;
224 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
226 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
227 BltInfo
->XlateSourceToDest
, *SourceBits
);
232 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
233 DestLine
+= BltInfo
->DestSurface
->lDelta
;
238 if (NULL
== BltInfo
->XlateSourceToDest
|| 0 !=
239 (BltInfo
->XlateSourceToDest
->flXlate
& XO_TRIVIAL
))
241 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
243 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
244 (BltInfo
->SourcePoint
.y
*
245 BltInfo
->SourceSurface
->lDelta
) + 2 *
246 BltInfo
->SourcePoint
.x
;
248 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
250 RtlMoveMemory(DestBits
, SourceBits
,
251 2 * (BltInfo
->DestRect
.right
-
252 BltInfo
->DestRect
.left
));
254 SourceBits
+= BltInfo
->SourceSurface
->lDelta
;
255 DestBits
+= BltInfo
->DestSurface
->lDelta
;
260 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
261 ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
-
262 BltInfo
->DestRect
.top
- 1) *
263 BltInfo
->SourceSurface
->lDelta
) + 2 *
264 BltInfo
->SourcePoint
.x
;
266 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+
267 ((BltInfo
->DestRect
.bottom
- 1) *
268 BltInfo
->DestSurface
->lDelta
) + 2 *
269 BltInfo
->DestRect
.left
;
271 for (j
= BltInfo
->DestRect
.bottom
- 1;
272 BltInfo
->DestRect
.top
<= j
; j
--)
274 RtlMoveMemory(DestBits
, SourceBits
, 2 *
275 (BltInfo
->DestRect
.right
-
276 BltInfo
->DestRect
.left
));
278 SourceBits
-= BltInfo
->SourceSurface
->lDelta
;
279 DestBits
-= BltInfo
->DestSurface
->lDelta
;
285 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
287 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
288 (BltInfo
->SourcePoint
.y
*
289 BltInfo
->SourceSurface
->lDelta
) + 2 *
290 BltInfo
->SourcePoint
.x
;
293 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
295 SourceBits
= SourceLine
;
297 for (i
= BltInfo
->DestRect
.left
; i
<
298 BltInfo
->DestRect
.right
; i
++)
300 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
301 BltInfo
->XlateSourceToDest
,
302 *((WORD
*)SourceBits
));
306 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
307 DestLine
+= BltInfo
->DestSurface
->lDelta
;
312 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
313 ((BltInfo
->SourcePoint
.y
+
314 BltInfo
->DestRect
.bottom
-
315 BltInfo
->DestRect
.top
- 1) *
316 BltInfo
->SourceSurface
->lDelta
) + 2 *
317 BltInfo
->SourcePoint
.x
;
319 DestLine
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+
320 ((BltInfo
->DestRect
.bottom
- 1) *
321 BltInfo
->DestSurface
->lDelta
) + 2 *
322 BltInfo
->DestRect
.left
;
324 for (j
= BltInfo
->DestRect
.bottom
- 1;
325 BltInfo
->DestRect
.top
<= j
; j
--)
327 SourceBits
= SourceLine
;
329 for (i
= BltInfo
->DestRect
.left
; i
<
330 BltInfo
->DestRect
.right
; i
++)
332 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
333 BltInfo
->XlateSourceToDest
,
334 *((WORD
*)SourceBits
));
338 SourceLine
-= BltInfo
->SourceSurface
->lDelta
;
339 DestLine
-= BltInfo
->DestSurface
->lDelta
;
346 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
347 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
348 3 * BltInfo
->SourcePoint
.x
;
352 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
354 SourceBits
= SourceLine
;
357 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
359 xColor
= (*(SourceBits
+ 2) << 0x10) +
360 (*(SourceBits
+ 1) << 0x08) + (*(SourceBits
));
362 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
363 BltInfo
->XlateSourceToDest
, xColor
);
368 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
369 DestLine
+= BltInfo
->DestSurface
->lDelta
;
374 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
375 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
376 4 * BltInfo
->SourcePoint
.x
;
380 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
382 SourceBits
= SourceLine
;
385 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
387 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
388 BltInfo
->XlateSourceToDest
,
389 *((PDWORD
) SourceBits
));
394 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
395 DestLine
+= BltInfo
->DestSurface
->lDelta
;
400 DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n",
401 BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
408 /* Optimize for bitBlt */
410 DIB_16BPP_ColorFill(SURFOBJ
* DestSurface
, RECTL
* DestRect
, ULONG color
)
414 #if defined(_M_IX86) && !defined(_MSC_VER)
415 /* This is about 10% faster than the generic C code below */
416 ULONG delta
= DestSurface
->lDelta
;
417 ULONG width
= (DestRect
->right
- DestRect
->left
) ;
418 PULONG pos
= (PULONG
) ((PBYTE
)DestSurface
->pvScan0
+ DestRect
->top
* delta
+ (DestRect
->left
<<1));
419 color
= (color
&0xffff); /* If the color value is "abcd", put "abcdabcd" into color */
420 color
+= (color
<<16);
422 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
424 __asm__
__volatile__ (
428 " test $0x03, %%edi\n" /* Align to fullword boundary */
434 " mov %%ebx,%%ecx\n" /* Setup count of fullwords to fill */
436 " rep stosl\n" /* The actual fill */
437 " test $0x01, %%ebx\n" /* One left to do at the right side? */
442 : "a" (color
), "r" (width
), "m" (pos
)
443 : "%ecx", "%ebx", "%edi");
444 pos
=(PULONG
)((ULONG_PTR
)pos
+ delta
);
448 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
450 DIB_16BPP_HLine (DestSurface
, DestRect
->left
, DestRect
->right
, DestY
, color
);
456 =======================================
457 Stretching functions goes below
458 Some parts of code are based on an
459 article "Bresenhame image scaling"
460 Dr. Dobb Journal, May 2002
461 =======================================
464 typedef unsigned short PIXEL
;
466 /* 16-bit HiColor (565 format) */
467 __inline PIXEL
average16(PIXEL a
, PIXEL b
)
469 // This one should be correct, but it's too long
471 unsigned char r1, g1, b1, r2, g2, b2, rr, gr, br;
474 r1 = (a & 0xF800) >> 11;
475 g1 = (a & 0x7E0) >> 5;
478 r2 = (b & 0xF800) >> 11;
479 g2 = (b & 0x7E0) >> 5;
486 res = (rr << 11) + (gr << 5) + br;
490 // This one is the short form of the correct one, but does not work for QEMU (expects 555 format)
491 //return (((a ^ b) & 0xf7deU) >> 1) + (a & b);
493 //hack until short version works properly
497 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
498 void ScaleLineAvg16(PIXEL
*Target
, PIXEL
*Source
, int SrcWidth
, int TgtWidth
)
500 int NumPixels
= TgtWidth
;
501 int IntPart
= SrcWidth
/ TgtWidth
;
502 int FractPart
= SrcWidth
% TgtWidth
;
503 int Mid
= TgtWidth
>> 1;
508 skip
= (TgtWidth
< SrcWidth
) ? 0 : (TgtWidth
/ (2*SrcWidth
) + 1);
511 while (NumPixels
-- > 0)
516 p
= average16(p
, *(Source
+1));
534 FinalCopy16(PIXEL
*Target
, PIXEL
*Source
, PSPAN ClipSpans
, UINT ClipSpansCount
, UINT
*SpanIndex
,
535 UINT DestY
, RECTL
*DestRect
)
539 while ( ClipSpans
[*SpanIndex
].Y
< DestY
||
540 (ClipSpans
[*SpanIndex
].Y
== DestY
&&
541 ClipSpans
[*SpanIndex
].X
+ ClipSpans
[*SpanIndex
].Width
< DestRect
->left
))
544 if (ClipSpansCount
<= *SpanIndex
)
546 /* No more spans, everything else is clipped away, we're done */
550 while (ClipSpans
[*SpanIndex
].Y
== DestY
)
552 if (ClipSpans
[*SpanIndex
].X
< DestRect
->right
)
554 Left
= max(ClipSpans
[*SpanIndex
].X
, DestRect
->left
);
556 Right
= min(ClipSpans
[*SpanIndex
].X
+ ClipSpans
[*SpanIndex
].Width
,
559 memcpy(Target
+ Left
- DestRect
->left
, Source
+ Left
- DestRect
->left
,
560 (Right
- Left
) * sizeof(PIXEL
));
565 if (ClipSpansCount
<= *SpanIndex
)
567 /* No more spans, everything else is clipped away, we're done */
575 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
576 BOOLEAN
ScaleRectAvg16(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
577 RECTL
* DestRect
, RECTL
*SourceRect
,
578 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
579 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
582 int NumPixels
= DestRect
->bottom
- DestRect
->top
;
584 int IntPart
= (((SourceRect
->bottom
- SourceRect
->top
) /
585 (DestRect
->bottom
- DestRect
->top
)) * SourceSurf
->lDelta
) >> 1;
587 int FractPart
= (SourceRect
->bottom
- SourceRect
->top
) %
588 (DestRect
->bottom
- DestRect
->top
);
590 int Mid
= (DestRect
->bottom
- DestRect
->top
) >> 1;
593 PIXEL
*ScanLine
, *ScanLineAhead
;
594 PIXEL
*PrevSource
= NULL
;
595 PIXEL
*PrevSourceAhead
= NULL
;
597 PIXEL
*Target
= (PIXEL
*) ((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->top
*
598 DestSurf
->lDelta
) + 2 * DestRect
->left
);
600 PIXEL
*Source
= (PIXEL
*) ((PBYTE
)SourceSurf
->pvScan0
+ (SourceRect
->top
*
601 SourceSurf
->lDelta
) + 2 * SourceRect
->left
);
608 if (! ClipobjToSpans(&ClipSpans
, &ClipSpansCount
, ClipRegion
, DestRect
))
612 if (0 == ClipSpansCount
)
614 /* No clip spans == empty clipping region, everything clipped away */
615 ASSERT(NULL
== ClipSpans
);
618 skip
= (DestRect
->bottom
- DestRect
->top
< SourceRect
->bottom
- SourceRect
->top
)
619 ? 0 : ((DestRect
->bottom
- DestRect
->top
) /
620 (2 * (SourceRect
->bottom
- SourceRect
->top
)) + 1);
624 ScanLine
= (PIXEL
*)ExAllocatePool(PagedPool
, (DestRect
->right
- DestRect
->left
) *
627 ScanLineAhead
= (PIXEL
*)ExAllocatePool(PagedPool
, (DestRect
->right
-
628 DestRect
->left
) * sizeof(PIXEL
));
630 if (!ScanLine
|| !ScanLineAhead
)
632 if (ScanLine
) ExFreePool(ScanLine
);
633 if (ScanLineAhead
) ExFreePool(ScanLineAhead
);
637 DestY
= DestRect
->top
;
639 while (NumPixels
-- > 0)
641 if (Source
!= PrevSource
)
643 if (Source
== PrevSourceAhead
)
645 /* the next scan line has already been scaled and stored in
646 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
649 PIXEL
*tmp
= ScanLine
;
650 ScanLine
= ScanLineAhead
;
655 ScaleLineAvg16(ScanLine
, Source
, SourceRect
->right
- SourceRect
->left
,
656 DestRect
->right
- DestRect
->left
);
661 if (E
>= Mid
&& PrevSourceAhead
!= (PIXEL
*)((BYTE
*)Source
+
666 ScaleLineAvg16(ScanLineAhead
, (PIXEL
*)((BYTE
*)Source
+
667 SourceSurf
->lDelta
), SourceRect
->right
-
668 SourceRect
->left
, DestRect
->right
- DestRect
->left
);
670 for (x
= 0; x
< DestRect
->right
- DestRect
->left
; x
++)
672 ScanLine
[x
] = average16(ScanLine
[x
], ScanLineAhead
[x
]);
675 PrevSourceAhead
= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
);
678 if (! FinalCopy16(Target
, ScanLine
, ClipSpans
, ClipSpansCount
, &SpanIndex
, DestY
, DestRect
))
680 /* No more spans, everything else is clipped away, we're done */
681 ExFreePool(ClipSpans
);
682 ExFreePool(ScanLine
);
683 ExFreePool(ScanLineAhead
);
688 Target
= (PIXEL
*)((BYTE
*)Target
+ DestSurf
->lDelta
);
692 if (E
>= DestRect
->bottom
- DestRect
->top
)
694 E
-= DestRect
->bottom
- DestRect
->top
;
695 Source
= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
);
699 if (skip
> 0 && Source
!= PrevSource
)
701 ScaleLineAvg16(ScanLine
, Source
, SourceRect
->right
- SourceRect
->left
,
702 DestRect
->right
- DestRect
->left
);
707 if (! FinalCopy16(Target
, ScanLine
, ClipSpans
, ClipSpansCount
, &SpanIndex
,
710 /* No more spans, everything else is clipped away, we're done */
711 ExFreePool(ClipSpans
);
712 ExFreePool(ScanLine
);
713 ExFreePool(ScanLineAhead
);
717 Target
= (PIXEL
*)((BYTE
*)Target
+ DestSurf
->lDelta
);
720 ExFreePool(ClipSpans
);
721 ExFreePool(ScanLine
);
722 ExFreePool(ScanLineAhead
);
728 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
729 BOOLEAN
DIB_16BPP_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
730 RECTL
* DestRect
, RECTL
*SourceRect
,
731 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
732 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
757 DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
758 BitsPerFormat(SourceSurf
->iBitmapFormat
), SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
759 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
761 /* Calc the Zoom height of Source */
762 SrcSizeY
= SourceRect
->bottom
- SourceRect
->top
;
764 /* Calc the Zoom Width of Source */
765 SrcSizeX
= SourceRect
->right
- SourceRect
->left
;
767 /* Calc the Zoom height of Destions */
768 DesSizeY
= DestRect
->bottom
- DestRect
->top
;
770 /* Calc the Zoom width of Destions */
771 DesSizeX
= DestRect
->right
- DestRect
->left
;
773 /* Calc the zoom factor of soruce height */
774 SrcZoomYHight
= SrcSizeY
/ DesSizeY
;
775 SrcZoomYLow
= SrcSizeY
- (SrcZoomYHight
* DesSizeY
);
777 /* Calc the zoom factor of soruce width */
778 SrcZoomXHight
= SrcSizeX
/ DesSizeX
;
779 SrcZoomXLow
= SrcSizeX
- (SrcZoomXHight
* DesSizeX
);
783 sy
= SourceRect
->top
;
785 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
786 DestRect
->top
* DestSurf
->lDelta
);
788 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
790 switch(SourceSurf
->iBitmapFormat
)
794 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
795 /* This is a reference implementation, it hasn't been optimized for speed */
797 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
799 sx
= SourceRect
->left
;
802 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
804 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
,
805 DIB_1BPP_GetPixel(SourceSurf
, sx
, sy
));
807 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
810 sx_dec
+= SrcZoomXLow
;
811 if (sx_dec
>= sx_max
)
818 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
821 sy_dec
+= SrcZoomYLow
;
822 if (sy_dec
>= sy_max
)
831 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
832 /* This is a reference implementation, it hasn't been optimized for speed */
834 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
836 sx
= SourceRect
->left
;
839 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
841 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
,
842 DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
));
844 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
847 sx_dec
+= SrcZoomXLow
;
848 if (sx_dec
>= sx_max
)
855 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
858 sy_dec
+= SrcZoomYLow
;
859 if (sy_dec
>= sy_max
)
868 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
869 /* This is a reference implementation, it hasn't been optimized for speed */
871 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
873 sx
= SourceRect
->left
;
876 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
878 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
,
879 DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
));
881 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
884 sx_dec
+= SrcZoomXLow
;
885 if (sx_dec
>= sx_max
)
892 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
895 sy_dec
+= SrcZoomYLow
;
896 if (sy_dec
>= sy_max
)
906 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
907 /* This is a reference implementation, it hasn't been optimized for speed */
909 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
910 DestRect
->top
* DestSurf
->lDelta
);
912 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
914 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
916 sx
= SourceRect
->left
;
919 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
921 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
,
922 DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
));
924 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
927 sx_dec
+= SrcZoomXLow
;
928 if (sx_dec
>= sx_max
)
935 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
938 sy_dec
+= SrcZoomYLow
;
939 if (sy_dec
>= sy_max
)
948 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
949 /* This is a reference implementation, it hasn't been optimized for speed */
951 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
953 sx
= SourceRect
->left
;
956 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
958 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
,
959 DIB_32BPP_GetPixel(SourceSurf
, sx
, sy
));
961 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
964 sx_dec
+= SrcZoomXLow
;
965 if (sx_dec
>= sx_max
)
971 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
974 sy_dec
+= SrcZoomYLow
;
975 if (sy_dec
>= sy_max
)
984 return ScaleRectAvg16(DestSurf
, SourceSurf
, DestRect
, SourceRect
, MaskOrigin
, BrushOrigin
,
985 ClipRegion
, ColorTranslation
, Mode
);
989 DPRINT1("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf
->iBitmapFormat
));
999 DIB_16BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
1000 RECTL
* DestRect
, POINTL
*SourcePoint
,
1001 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
1003 ULONG RoundedRight
, X
, Y
, SourceX
, SourceY
, Source
, wd
, Dest
;
1006 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x1);
1007 SourceY
= SourcePoint
->y
;
1008 DestBits
= (ULONG
*)((PBYTE
)DestSurf
->pvScan0
+
1009 (DestRect
->left
<< 1) +
1010 DestRect
->top
* DestSurf
->lDelta
);
1011 wd
= DestSurf
->lDelta
- ((DestRect
->right
- DestRect
->left
) << 1);
1013 for(Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
1015 SourceX
= SourcePoint
->x
;
1016 for(X
= DestRect
->left
; X
< RoundedRight
; X
+= 2, DestBits
++, SourceX
+= 2)
1019 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
1021 if(Source
!= iTransColor
)
1024 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFFFF);
1027 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
+ 1, SourceY
);
1028 if(Source
!= iTransColor
)
1031 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) << 16);
1037 if(X
< DestRect
->right
)
1039 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
1040 if(Source
!= iTransColor
)
1042 *((USHORT
*)DestBits
) = (USHORT
)XLATEOBJ_iXlate(ColorTranslation
,
1046 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
1050 DestBits
= (ULONG
*)((ULONG_PTR
)DestBits
+ wd
);
1079 static __inline UCHAR
1082 return (val
> 31) ? 31 : val
;
1085 static __inline UCHAR
1088 return (val
> 63) ? 63 : val
;
1092 DIB_16BPP_AlphaBlend(SURFOBJ
* Dest
, SURFOBJ
* Source
, RECTL
* DestRect
,
1093 RECTL
* SourceRect
, CLIPOBJ
* ClipRegion
,
1094 XLATEOBJ
* ColorTranslation
, BLENDOBJ
* BlendObj
)
1096 INT Rows
, Cols
, SrcX
, SrcY
;
1097 register PUSHORT Dst
;
1099 BLENDFUNCTION BlendFunc
;
1100 register NICEPIXEL16 DstPixel
;
1101 register NICEPIXEL32 SrcPixel
;
1102 UCHAR Alpha
, SrcBpp
;
1104 DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
1105 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
1106 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
1108 ASSERT(DestRect
->bottom
- DestRect
->top
== SourceRect
->bottom
- SourceRect
->top
&&
1109 DestRect
->right
- DestRect
->left
== SourceRect
->right
- SourceRect
->left
);
1111 BlendFunc
= BlendObj
->BlendFunction
;
1112 if (BlendFunc
.BlendOp
!= AC_SRC_OVER
)
1114 DPRINT1("BlendOp != AC_SRC_OVER\n");
1117 if (BlendFunc
.BlendFlags
!= 0)
1119 DPRINT1("BlendFlags != 0\n");
1122 if ((BlendFunc
.AlphaFormat
& ~AC_SRC_ALPHA
) != 0)
1124 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc
.AlphaFormat
);
1127 if ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0 &&
1128 BitsPerFormat(Source
->iBitmapFormat
) != 32)
1130 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
1134 Dst
= (PUSHORT
)((ULONG_PTR
)Dest
->pvScan0
+ (DestRect
->top
* Dest
->lDelta
) +
1135 (DestRect
->left
<< 1));
1136 DstDelta
= Dest
->lDelta
- ((DestRect
->right
- DestRect
->left
) << 1);
1137 SrcBpp
= BitsPerFormat(Source
->iBitmapFormat
);
1139 Rows
= DestRect
->bottom
- DestRect
->top
;
1140 SrcY
= SourceRect
->top
;
1143 Cols
= DestRect
->right
- DestRect
->left
;
1144 SrcX
= SourceRect
->left
;
1149 DstPixel
.us
= DIB_GetSource(Source
, SrcX
++, SrcY
, ColorTranslation
);
1150 SrcPixel
.col
.red
= (DstPixel
.col
.red
<< 3) | (DstPixel
.col
.red
>> 2);
1152 SrcPixel
.col
.green
= (DstPixel
.col
.green
<< 2) |
1153 (DstPixel
.col
.green
>> 4);
1155 SrcPixel
.col
.blue
= (DstPixel
.col
.blue
<< 3) | (DstPixel
.col
.blue
>> 2);
1159 SrcPixel
.ul
= DIB_GetSourceIndex(Source
, SrcX
++, SrcY
);
1161 SrcPixel
.col
.red
= SrcPixel
.col
.red
*
1162 BlendFunc
.SourceConstantAlpha
/ 255;
1164 SrcPixel
.col
.green
= SrcPixel
.col
.green
*
1165 BlendFunc
.SourceConstantAlpha
/ 255;
1167 SrcPixel
.col
.blue
= SrcPixel
.col
.blue
*
1168 BlendFunc
.SourceConstantAlpha
/ 255;
1170 SrcPixel
.col
.alpha
= (SrcBpp
== 32) ?
1171 (SrcPixel
.col
.alpha
*
1172 BlendFunc
.SourceConstantAlpha
/ 255) :
1173 BlendFunc
.SourceConstantAlpha
;
1175 Alpha
= ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0) ?
1176 SrcPixel
.col
.alpha
: BlendFunc
.SourceConstantAlpha
;
1179 DstPixel
.col
.red
= Clamp5(DstPixel
.col
.red
* (255 - Alpha
) / 255 +
1180 (SrcPixel
.col
.red
>> 3));
1182 DstPixel
.col
.green
= Clamp6(DstPixel
.col
.green
* (255 - Alpha
) / 255 +
1183 (SrcPixel
.col
.green
>> 2));
1185 DstPixel
.col
.blue
= Clamp5(DstPixel
.col
.blue
* (255 - Alpha
) / 255 +
1186 (SrcPixel
.col
.blue
>> 3));
1188 *Dst
++ = DstPixel
.us
;
1191 Dst
= (PUSHORT
)((ULONG_PTR
)Dst
+ DstDelta
);