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
;
40 return (ULONG
)(*addr
);
44 DIB_16BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
46 PDWORD addr
= (PDWORD
)((PWORD
)((PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
) + x1
);
48 #if defined(_M_IX86) && !defined(_MSC_VER)
49 /* This is about 10% faster than the generic C code below */
52 __asm__
__volatile__ (
56 " andl $0xffff, %0\n" /* If the pixel value is "abcd", put "abcdabcd" in %eax */
59 " test $0x03, %%edi\n" /* Align to fullword boundary */
65 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */
67 " rep stosl\n" /* The actual fill */
68 " test $0x01, %1\n" /* One left to do at the right side? */
73 : "r"(c
), "r"(Count
), "m"(addr
)
74 : "%eax", "%ecx", "%edi");
79 if (0 != (cx
& 0x01)) {
82 addr
= (PDWORD
)((PWORD
)(addr
) + 1);
84 cc
= ((c
& 0xffff) << 16) | (c
& 0xffff);
97 DIB_16BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
99 #if defined(_M_IX86) && !defined(_MSC_VER)
101 " testl %2, %2" "\n\t"
103 " movl %2, %%ecx" "\n\t"
104 " shrl $2, %2" "\n\t"
105 " andl $3, %%ecx" "\n\t"
108 " movw %%ax, (%0)" "\n\t"
109 " addl %1, %0" "\n\t"
112 " testl %2, %2" "\n\t"
115 " movw %%ax, (%0)" "\n\t"
116 " addl %1, %0" "\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"
127 : "r"((PBYTE
)SurfObj
->pvScan0
+ (y1
* SurfObj
->lDelta
) + (x
* sizeof (WORD
))),
128 "r"(SurfObj
->lDelta
), "r"(y2
- y1
), "a"(c
)
129 : "cc", "memory", "%ecx");
131 PBYTE byteaddr
= (ULONG_PTR
)SurfObj
->pvScan0
+ y1
* SurfObj
->lDelta
;
132 PWORD addr
= (PWORD
)byteaddr
+ x
;
133 LONG lDelta
= SurfObj
->lDelta
;
135 byteaddr
= (PBYTE
)addr
;
140 addr
= (PWORD
)byteaddr
;
146 DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
148 LONG i
, j
, sx
, sy
, xColor
, f1
;
149 PBYTE SourceBits
, DestBits
, SourceLine
, DestLine
;
150 PBYTE SourceBits_4BPP
, SourceLine_4BPP
;
151 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ (BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
153 switch(BltInfo
->SourceSurface
->iBitmapFormat
)
156 sx
= BltInfo
->SourcePoint
.x
;
157 sy
= BltInfo
->SourcePoint
.y
;
159 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
161 sx
= BltInfo
->SourcePoint
.x
;
162 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
164 if(DIB_1BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
) == 0)
166 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 0));
168 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 1));
177 SourceBits_4BPP
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + (BltInfo
->SourcePoint
.x
>> 1);
179 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
181 SourceLine_4BPP
= SourceBits_4BPP
;
182 sx
= BltInfo
->SourcePoint
.x
;
185 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
187 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
,
188 (*SourceLine_4BPP
& altnotmask
[f1
]) >> (4 * (1 - f1
)));
189 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, xColor
);
190 if(f1
== 1) { SourceLine_4BPP
++; f1
= 0; } else { f1
= 1; }
194 SourceBits_4BPP
+= BltInfo
->SourceSurface
->lDelta
;
199 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + BltInfo
->SourcePoint
.x
;
202 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
204 SourceBits
= SourceLine
;
207 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
209 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *SourceBits
);
214 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
215 DestLine
+= BltInfo
->DestSurface
->lDelta
;
220 if (NULL
== BltInfo
->XlateSourceToDest
|| 0 != (BltInfo
->XlateSourceToDest
->flXlate
& XO_TRIVIAL
))
222 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
224 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
225 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
227 RtlMoveMemory(DestBits
, SourceBits
, 2 * (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
));
228 SourceBits
+= BltInfo
->SourceSurface
->lDelta
;
229 DestBits
+= BltInfo
->DestSurface
->lDelta
;
234 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
235 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
236 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
238 RtlMoveMemory(DestBits
, SourceBits
, 2 * (BltInfo
->DestRect
.right
- BltInfo
->DestRect
.left
));
239 SourceBits
-= BltInfo
->SourceSurface
->lDelta
;
240 DestBits
-= BltInfo
->DestSurface
->lDelta
;
246 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
248 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
250 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
252 SourceBits
= SourceLine
;
254 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
256 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((WORD
*)SourceBits
));
260 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
261 DestLine
+= BltInfo
->DestSurface
->lDelta
;
266 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
- BltInfo
->DestRect
.top
- 1) * BltInfo
->SourceSurface
->lDelta
) + 2 * BltInfo
->SourcePoint
.x
;
267 DestLine
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ ((BltInfo
->DestRect
.bottom
- 1) * BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
268 for (j
= BltInfo
->DestRect
.bottom
- 1; BltInfo
->DestRect
.top
<= j
; j
--)
270 SourceBits
= SourceLine
;
272 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
274 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((WORD
*)SourceBits
));
278 SourceLine
-= BltInfo
->SourceSurface
->lDelta
;
279 DestLine
-= BltInfo
->DestSurface
->lDelta
;
286 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 3 * BltInfo
->SourcePoint
.x
;
289 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
291 SourceBits
= SourceLine
;
294 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
296 xColor
= (*(SourceBits
+ 2) << 0x10) +
297 (*(SourceBits
+ 1) << 0x08) +
299 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, xColor
);
304 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
305 DestLine
+= BltInfo
->DestSurface
->lDelta
;
310 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+ (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) + 4 * BltInfo
->SourcePoint
.x
;
313 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
315 SourceBits
= SourceLine
;
318 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
320 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, *((PDWORD
) SourceBits
));
325 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
326 DestLine
+= BltInfo
->DestSurface
->lDelta
;
331 DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
338 /* Optimize for bitBlt */
340 DIB_16BPP_ColorFill(SURFOBJ
* DestSurface
, RECTL
* DestRect
, ULONG color
)
344 #if defined(_M_IX86) && !defined(_MSC_VER)
345 /* This is about 10% faster than the generic C code below */
346 ULONG delta
= DestSurface
->lDelta
;
347 ULONG width
= (DestRect
->right
- DestRect
->left
) ;
348 PULONG pos
= (PULONG
) ((PBYTE
)DestSurface
->pvScan0
+ DestRect
->top
* delta
+ (DestRect
->left
<<1));
349 color
= (color
&0xffff); /* If the color value is "abcd", put "abcdabcd" into color */
350 color
+= (color
<<16);
352 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
354 __asm__
__volatile__ (
358 " test $0x03, %%edi\n" /* Align to fullword boundary */
364 " mov %%ebx,%%ecx\n" /* Setup count of fullwords to fill */
366 " rep stosl\n" /* The actual fill */
367 " test $0x01, %%ebx\n" /* One left to do at the right side? */
372 : "a" (color
), "r" (width
), "m" (pos
)
373 : "%ecx", "%ebx", "%edi");
374 pos
=(PULONG
)((ULONG_PTR
)pos
+ delta
);
379 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
381 DIB_16BPP_HLine (DestSurface
, DestRect
->left
, DestRect
->right
, DestY
, color
);
387 =======================================
388 Stretching functions goes below
389 Some parts of code are based on an
390 article "Bresenhame image scaling"
391 Dr. Dobb Journal, May 2002
392 =======================================
395 typedef unsigned short PIXEL
;
397 /* 16-bit HiColor (565 format) */
398 __inline PIXEL
average16(PIXEL a
, PIXEL b
)
400 // This one doesn't work
405 unsigned short mask = ~ (((a | b) & 0x0410) << 1);
406 return ((a & mask) + (b & mask)) >> 1;
409 // This one should be correct, but it's too long
411 unsigned char r1, g1, b1, r2, g2, b2, rr, gr, br;
414 r1 = (a & 0xF800) >> 11;
415 g1 = (a & 0x7E0) >> 5;
418 r2 = (b & 0xF800) >> 11;
419 g2 = (b & 0x7E0) >> 5;
426 res = (rr << 11) + (gr << 5) + br;
430 return a
; // FIXME: Depend on SetStretchMode
433 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
434 void ScaleLineAvg16(PIXEL
*Target
, PIXEL
*Source
, int SrcWidth
, int TgtWidth
)
436 int NumPixels
= TgtWidth
;
437 int IntPart
= SrcWidth
/ TgtWidth
;
438 int FractPart
= SrcWidth
% TgtWidth
;
439 int Mid
= TgtWidth
>> 1;
444 skip
= (TgtWidth
< SrcWidth
) ? 0 : (TgtWidth
/ (2*SrcWidth
) + 1);
447 while (NumPixels
-- > 0) {
450 p
= average16(p
, *(Source
+1));
464 FinalCopy16(PIXEL
*Target
, PIXEL
*Source
, PSPAN ClipSpans
, UINT ClipSpansCount
, UINT
*SpanIndex
,
465 UINT DestY
, RECTL
*DestRect
)
469 while (ClipSpans
[*SpanIndex
].Y
< DestY
470 || (ClipSpans
[*SpanIndex
].Y
== DestY
471 && ClipSpans
[*SpanIndex
].X
+ ClipSpans
[*SpanIndex
].Width
< DestRect
->left
))
474 if (ClipSpansCount
<= *SpanIndex
)
476 /* No more spans, everything else is clipped away, we're done */
480 while (ClipSpans
[*SpanIndex
].Y
== DestY
)
482 if (ClipSpans
[*SpanIndex
].X
< DestRect
->right
)
484 Left
= max(ClipSpans
[*SpanIndex
].X
, DestRect
->left
);
485 Right
= min(ClipSpans
[*SpanIndex
].X
+ ClipSpans
[*SpanIndex
].Width
, DestRect
->right
);
486 memcpy(Target
+ Left
- DestRect
->left
, Source
+ Left
- DestRect
->left
,
487 (Right
- Left
) * sizeof(PIXEL
));
490 if (ClipSpansCount
<= *SpanIndex
)
492 /* No more spans, everything else is clipped away, we're done */
500 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
501 BOOLEAN
ScaleRectAvg16(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
502 RECTL
* DestRect
, RECTL
*SourceRect
,
503 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
504 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
507 int NumPixels
= DestRect
->bottom
- DestRect
->top
;
508 int IntPart
= (((SourceRect
->bottom
- SourceRect
->top
) / (DestRect
->bottom
- DestRect
->top
)) * SourceSurf
->lDelta
) >> 1;
509 int FractPart
= (SourceRect
->bottom
- SourceRect
->top
) % (DestRect
->bottom
- DestRect
->top
);
510 int Mid
= (DestRect
->bottom
- DestRect
->top
) >> 1;
513 PIXEL
*ScanLine
, *ScanLineAhead
;
514 PIXEL
*PrevSource
= NULL
;
515 PIXEL
*PrevSourceAhead
= NULL
;
516 PIXEL
*Target
= (PIXEL
*) ((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->top
* DestSurf
->lDelta
) + 2 * DestRect
->left
);
517 PIXEL
*Source
= (PIXEL
*) ((PBYTE
)SourceSurf
->pvScan0
+ (SourceRect
->top
* SourceSurf
->lDelta
) + 2 * SourceRect
->left
);
523 if (! ClipobjToSpans(&ClipSpans
, &ClipSpansCount
, ClipRegion
, DestRect
))
527 if (0 == ClipSpansCount
)
529 /* No clip spans == empty clipping region, everything clipped away */
530 ASSERT(NULL
== ClipSpans
);
533 skip
= (DestRect
->bottom
- DestRect
->top
< SourceRect
->bottom
- SourceRect
->top
) ? 0 : ((DestRect
->bottom
- DestRect
->top
) / (2 * (SourceRect
->bottom
- SourceRect
->top
)) + 1);
536 ScanLine
= (PIXEL
*)ExAllocatePool(PagedPool
, (DestRect
->right
- DestRect
->left
) * sizeof(PIXEL
));
537 ScanLineAhead
= (PIXEL
*)ExAllocatePool(PagedPool
, (DestRect
->right
- DestRect
->left
) * sizeof(PIXEL
));
539 DestY
= DestRect
->top
;
541 while (NumPixels
-- > 0) {
542 if (Source
!= PrevSource
) {
543 if (Source
== PrevSourceAhead
) {
544 /* the next scan line has already been scaled and stored in
545 * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead
548 PIXEL
*tmp
= ScanLine
;
549 ScanLine
= ScanLineAhead
;
552 ScaleLineAvg16(ScanLine
, Source
, SourceRect
->right
- SourceRect
->left
, DestRect
->right
- DestRect
->left
);
557 if (E
>= Mid
&& PrevSourceAhead
!= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
)) {
559 ScaleLineAvg16(ScanLineAhead
, (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
), SourceRect
->right
- SourceRect
->left
, DestRect
->right
- DestRect
->left
);
560 for (x
= 0; x
< DestRect
->right
- DestRect
->left
; x
++)
561 ScanLine
[x
] = average16(ScanLine
[x
], ScanLineAhead
[x
]);
562 PrevSourceAhead
= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
);
565 if (! FinalCopy16(Target
, ScanLine
, ClipSpans
, ClipSpansCount
, &SpanIndex
, DestY
, DestRect
))
567 /* No more spans, everything else is clipped away, we're done */
568 ExFreePool(ClipSpans
);
569 ExFreePool(ScanLine
);
570 ExFreePool(ScanLineAhead
);
574 Target
= (PIXEL
*)((BYTE
*)Target
+ DestSurf
->lDelta
);
577 if (E
>= DestRect
->bottom
- DestRect
->top
) {
578 E
-= DestRect
->bottom
- DestRect
->top
;
579 Source
= (PIXEL
*)((BYTE
*)Source
+ SourceSurf
->lDelta
);
583 if (skip
> 0 && Source
!= PrevSource
)
584 ScaleLineAvg16(ScanLine
, Source
, SourceRect
->right
- SourceRect
->left
, DestRect
->right
- DestRect
->left
);
586 if (! FinalCopy16(Target
, ScanLine
, ClipSpans
, ClipSpansCount
, &SpanIndex
, DestY
, DestRect
))
588 /* No more spans, everything else is clipped away, we're done */
589 ExFreePool(ClipSpans
);
590 ExFreePool(ScanLine
);
591 ExFreePool(ScanLineAhead
);
595 Target
= (PIXEL
*)((BYTE
*)Target
+ DestSurf
->lDelta
);
598 ExFreePool(ClipSpans
);
599 ExFreePool(ScanLine
);
600 ExFreePool(ScanLineAhead
);
606 //NOTE: If you change something here, please do the same in other dibXXbpp.c files!
607 BOOLEAN
DIB_16BPP_StretchBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
608 RECTL
* DestRect
, RECTL
*SourceRect
,
609 POINTL
* MaskOrigin
, POINTL BrushOrigin
,
610 CLIPOBJ
*ClipRegion
, XLATEOBJ
*ColorTranslation
,
626 DPRINT("DIB_16BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
627 BitsPerFormat(SourceSurf
->iBitmapFormat
), SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
628 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
630 SrcSizeY
= SourceRect
->bottom
- SourceRect
->top
;
631 SrcSizeX
= SourceRect
->right
- SourceRect
->left
;
633 DesSizeY
= DestRect
->bottom
- DestRect
->top
;
634 DesSizeX
= DestRect
->right
- DestRect
->left
;
636 switch(SourceSurf
->iBitmapFormat
)
640 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
641 /* This is a reference implementation, it hasn't been optimized for speed */
643 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
644 DestRect
->top
* DestSurf
->lDelta
);
646 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
648 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
650 sy
= ((DesY
* SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
652 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
655 sx
= ((DesX
* SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
657 if(DIB_1BPP_GetPixel(SourceSurf
, sx
, sy
) == 0)
659 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
, 0);
660 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
664 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
, 1);
665 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
668 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
673 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
674 /* This is a reference implementation, it hasn't been optimized for speed */
676 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
677 DestRect
->top
* DestSurf
->lDelta
);
679 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
681 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
683 sy
= ((DesY
* SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
685 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
688 sx
= ((DesX
* SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
689 color
= DIB_4BPP_GetPixel(SourceSurf
, sx
, sy
);
691 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
, color
);
692 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
694 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
699 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
700 /* This is a reference implementation, it hasn't been optimized for speed */
702 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
703 DestRect
->top
* DestSurf
->lDelta
);
705 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
707 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
709 sy
= ((DesY
* SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
711 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
714 sx
= ((DesX
* SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
715 color
= DIB_8BPP_GetPixel(SourceSurf
, sx
, sy
);
717 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
, color
);
718 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
720 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
726 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
727 /* This is a reference implementation, it hasn't been optimized for speed */
729 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
730 DestRect
->top
* DestSurf
->lDelta
);
732 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
734 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
736 sy
= ((DesY
* SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
738 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
741 sx
= ((DesX
* SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
742 color
= DIB_24BPP_GetPixel(SourceSurf
, sx
, sy
);
744 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
, color
);
745 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
747 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
752 /* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
753 /* This is a reference implementation, it hasn't been optimized for speed */
755 DestBits
= (PULONG
)((PBYTE
)DestSurf
->pvScan0
+ (DestRect
->left
<< 1) +
756 DestRect
->top
* DestSurf
->lDelta
);
758 DifflDelta
= DestSurf
->lDelta
- (DesSizeX
<< 1);
760 for (DesY
=0; DesY
<DesSizeY
; DesY
++)
762 sy
= ((DesY
* SrcSizeY
) / DesSizeY
) + SourceRect
->top
;
764 for (DesX
=0; DesX
<DesSizeX
; DesX
++)
767 sx
= ((DesX
* SrcSizeX
) / DesSizeX
) + SourceRect
->left
;
768 color
= DIB_32BPP_GetPixel(SourceSurf
, sx
, sy
);
770 *DestBits
= XLATEOBJ_iXlate(ColorTranslation
, color
);
771 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
773 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ DifflDelta
);
778 return ScaleRectAvg16(DestSurf
, SourceSurf
, DestRect
, SourceRect
, MaskOrigin
, BrushOrigin
,
779 ClipRegion
, ColorTranslation
, Mode
);
783 DPRINT1("DIB_16BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf
->iBitmapFormat
));
793 DIB_16BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
794 RECTL
* DestRect
, POINTL
*SourcePoint
,
795 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
797 ULONG RoundedRight
, X
, Y
, SourceX
, SourceY
, Source
, wd
, Dest
;
800 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x1);
801 SourceY
= SourcePoint
->y
;
802 DestBits
= (ULONG
*)((PBYTE
)DestSurf
->pvScan0
+
803 (DestRect
->left
<< 1) +
804 DestRect
->top
* DestSurf
->lDelta
);
805 wd
= DestSurf
->lDelta
- ((DestRect
->right
- DestRect
->left
) << 1);
807 for(Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
809 SourceX
= SourcePoint
->x
;
810 for(X
= DestRect
->left
; X
< RoundedRight
; X
+= 2, DestBits
++, SourceX
+= 2)
814 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
815 if(Source
!= iTransColor
)
818 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFFFF);
821 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
+ 1, SourceY
);
822 if(Source
!= iTransColor
)
825 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) << 16);
831 if(X
< DestRect
->right
)
833 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
834 if(Source
!= iTransColor
)
836 *((USHORT
*)DestBits
) = (USHORT
)XLATEOBJ_iXlate(ColorTranslation
, Source
);
839 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
842 DestBits
= (ULONG
*)((ULONG_PTR
)DestBits
+ wd
);
867 static __inline UCHAR
870 return (val
> 31) ? 31 : val
;
873 static __inline UCHAR
876 return (val
> 63) ? 63 : val
;
880 DIB_16BPP_AlphaBlend(SURFOBJ
* Dest
, SURFOBJ
* Source
, RECTL
* DestRect
,
881 RECTL
* SourceRect
, CLIPOBJ
* ClipRegion
,
882 XLATEOBJ
* ColorTranslation
, BLENDOBJ
* BlendObj
)
884 INT Rows
, Cols
, SrcX
, SrcY
;
885 register PUSHORT Dst
;
887 BLENDFUNCTION BlendFunc
;
888 register NICEPIXEL16 DstPixel
;
889 register NICEPIXEL32 SrcPixel
;
892 DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
893 SourceRect
->left
, SourceRect
->top
, SourceRect
->right
, SourceRect
->bottom
,
894 DestRect
->left
, DestRect
->top
, DestRect
->right
, DestRect
->bottom
);
896 ASSERT(DestRect
->bottom
- DestRect
->top
== SourceRect
->bottom
- SourceRect
->top
&&
897 DestRect
->right
- DestRect
->left
== SourceRect
->right
- SourceRect
->left
);
899 BlendFunc
= BlendObj
->BlendFunction
;
900 if (BlendFunc
.BlendOp
!= AC_SRC_OVER
)
902 DPRINT1("BlendOp != AC_SRC_OVER\n");
905 if (BlendFunc
.BlendFlags
!= 0)
907 DPRINT1("BlendFlags != 0\n");
910 if ((BlendFunc
.AlphaFormat
& ~AC_SRC_ALPHA
) != 0)
912 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc
.AlphaFormat
);
915 if ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0 &&
916 BitsPerFormat(Source
->iBitmapFormat
) != 32)
918 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
922 Dst
= (PUSHORT
)((ULONG_PTR
)Dest
->pvScan0
+ (DestRect
->top
* Dest
->lDelta
) +
923 (DestRect
->left
<< 1));
924 DstDelta
= Dest
->lDelta
- ((DestRect
->right
- DestRect
->left
) << 1);
925 SrcBpp
= BitsPerFormat(Source
->iBitmapFormat
);
927 Rows
= DestRect
->bottom
- DestRect
->top
;
928 SrcY
= SourceRect
->top
;
931 Cols
= DestRect
->right
- DestRect
->left
;
932 SrcX
= SourceRect
->left
;
937 DstPixel
.us
= DIB_GetSource(Source
, SrcX
++, SrcY
, ColorTranslation
);
938 SrcPixel
.col
.red
= (DstPixel
.col
.red
<< 3) | (DstPixel
.col
.red
>> 2);
939 SrcPixel
.col
.green
= (DstPixel
.col
.green
<< 2) | (DstPixel
.col
.green
>> 4);
940 SrcPixel
.col
.blue
= (DstPixel
.col
.blue
<< 3) | (DstPixel
.col
.blue
>> 2);
944 SrcPixel
.ul
= DIB_GetSourceIndex(Source
, SrcX
++, SrcY
);
946 SrcPixel
.col
.red
= SrcPixel
.col
.red
* BlendFunc
.SourceConstantAlpha
/ 255;
947 SrcPixel
.col
.green
= SrcPixel
.col
.green
* BlendFunc
.SourceConstantAlpha
/ 255;
948 SrcPixel
.col
.blue
= SrcPixel
.col
.blue
* BlendFunc
.SourceConstantAlpha
/ 255;
949 SrcPixel
.col
.alpha
= (SrcBpp
== 32) ? (SrcPixel
.col
.alpha
* BlendFunc
.SourceConstantAlpha
/ 255) : BlendFunc
.SourceConstantAlpha
;
951 Alpha
= ((BlendFunc
.AlphaFormat
& AC_SRC_ALPHA
) != 0) ?
952 SrcPixel
.col
.alpha
: BlendFunc
.SourceConstantAlpha
;
955 DstPixel
.col
.red
= Clamp5(DstPixel
.col
.red
* (255 - Alpha
) / 255 + (SrcPixel
.col
.red
>> 3));
956 DstPixel
.col
.green
= Clamp6(DstPixel
.col
.green
* (255 - Alpha
) / 255 + (SrcPixel
.col
.green
>> 2));
957 DstPixel
.col
.blue
= Clamp5(DstPixel
.col
.blue
* (255 - Alpha
) / 255 + (SrcPixel
.col
.blue
>> 3));
958 *Dst
++ = DstPixel
.us
;
960 Dst
= (PUSHORT
)((ULONG_PTR
)Dst
+ DstDelta
);