2 * PROJECT: Win32 subsystem
3 * LICENSE: See COPYING in the top level directory
4 * FILE: subsystems/win32/win32k/dib/dib16bpp.c
5 * PURPOSE: Device Independant Bitmap functions, 16bpp
6 * PROGRAMMERS: Jason Filby
17 DIB_16BPP_PutPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
, ULONG c
)
19 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
;
20 PWORD addr
= (PWORD
)byteaddr
+ x
;
26 DIB_16BPP_GetPixel(SURFOBJ
*SurfObj
, LONG x
, LONG y
)
28 PBYTE byteaddr
= (PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
;
29 PWORD addr
= (PWORD
)byteaddr
+ x
;
30 return (ULONG
)(*addr
);
34 DIB_16BPP_HLine(SURFOBJ
*SurfObj
, LONG x1
, LONG x2
, LONG y
, ULONG c
)
36 PDWORD addr
= (PDWORD
)((PWORD
)((PBYTE
)SurfObj
->pvScan0
+ y
* SurfObj
->lDelta
) + x1
);
38 #if defined(_M_IX86) && !defined(_MSC_VER)
39 /* This is about 10% faster than the generic C code below */
42 __asm__
__volatile__ (
46 " andl $0xffff, %0\n" /* If the pixel value is "abcd", put "abcdabcd" in %eax */
49 " test $0x03, %%edi\n" /* Align to fullword boundary */
55 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */
57 " rep stosl\n" /* The actual fill */
58 " test $0x01, %1\n" /* One left to do at the right side? */
63 : "r"(c
), "r"(Count
), "m"(addr
)
64 : "%eax", "%ecx", "%edi");
71 *((PWORD
) addr
) = (WORD
)c
;
73 addr
= (PDWORD
)((PWORD
)(addr
) + 1);
75 cc
= ((c
& 0xffff) << 16) | (c
& 0xffff);
83 *((PWORD
) addr
) = (WORD
)c
;
90 DIB_16BPP_VLine(SURFOBJ
*SurfObj
, LONG x
, LONG y1
, LONG y2
, ULONG c
)
92 #if defined(_M_IX86) && !defined(_MSC_VER)
94 " testl %2, %2" "\n\t"
96 " movl %2, %%ecx" "\n\t"
98 " andl $3, %%ecx" "\n\t"
101 " movw %%ax, (%0)" "\n\t"
102 " addl %1, %0" "\n\t"
105 " testl %2, %2" "\n\t"
108 " movw %%ax, (%0)" "\n\t"
109 " addl %1, %0" "\n\t"
110 " movw %%ax, (%0)" "\n\t"
111 " addl %1, %0" "\n\t"
112 " movw %%ax, (%0)" "\n\t"
113 " addl %1, %0" "\n\t"
114 " movw %%ax, (%0)" "\n\t"
115 " addl %1, %0" "\n\t"
120 : "r"((PBYTE
)SurfObj
->pvScan0
+ (y1
* SurfObj
->lDelta
) + (x
* sizeof (WORD
))),
121 "r"(SurfObj
->lDelta
), "r"(y2
- y1
), "a"(c
)
122 : "cc", "memory", "%ecx");
124 PBYTE byteaddr
= (PBYTE
)(ULONG_PTR
)SurfObj
->pvScan0
+ y1
* SurfObj
->lDelta
;
125 PWORD addr
= (PWORD
)byteaddr
+ x
;
126 LONG lDelta
= SurfObj
->lDelta
;
128 byteaddr
= (PBYTE
)addr
;
134 addr
= (PWORD
)byteaddr
;
140 DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo
)
142 LONG i
, j
, sx
, sy
, xColor
, f1
;
143 PBYTE SourceBits
, DestBits
, SourceLine
, DestLine
;
144 PBYTE SourceBits_4BPP
, SourceLine_4BPP
;
145 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+ (BltInfo
->DestRect
.top
* BltInfo
->DestSurface
->lDelta
) + 2 * BltInfo
->DestRect
.left
;
147 switch(BltInfo
->SourceSurface
->iBitmapFormat
)
150 sx
= BltInfo
->SourcePoint
.x
;
151 sy
= BltInfo
->SourcePoint
.y
;
152 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
154 sx
= BltInfo
->SourcePoint
.x
;
155 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
157 if(DIB_1BPP_GetPixel(BltInfo
->SourceSurface
, sx
, sy
) == 0)
159 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
,
160 XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 0));
164 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
,
165 XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
, 1));
174 SourceBits_4BPP
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
175 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
176 (BltInfo
->SourcePoint
.x
>> 1);
178 for (j
=BltInfo
->DestRect
.top
; j
<BltInfo
->DestRect
.bottom
; j
++)
180 SourceLine_4BPP
= SourceBits_4BPP
;
181 sx
= BltInfo
->SourcePoint
.x
;
184 for (i
=BltInfo
->DestRect
.left
; i
<BltInfo
->DestRect
.right
; i
++)
186 xColor
= XLATEOBJ_iXlate(BltInfo
->XlateSourceToDest
,
187 (*SourceLine_4BPP
& altnotmask
[f1
]) >> (4 * (1 - f1
)));
188 DIB_16BPP_PutPixel(BltInfo
->DestSurface
, i
, j
, xColor
);
200 SourceBits_4BPP
+= BltInfo
->SourceSurface
->lDelta
;
205 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
206 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
207 BltInfo
->SourcePoint
.x
;
210 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
212 SourceBits
= SourceLine
;
215 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
217 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
218 BltInfo
->XlateSourceToDest
, *SourceBits
);
223 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
224 DestLine
+= BltInfo
->DestSurface
->lDelta
;
229 if (NULL
== BltInfo
->XlateSourceToDest
|| 0 !=
230 (BltInfo
->XlateSourceToDest
->flXlate
& XO_TRIVIAL
))
232 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
234 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
235 (BltInfo
->SourcePoint
.y
*
236 BltInfo
->SourceSurface
->lDelta
) + 2 *
237 BltInfo
->SourcePoint
.x
;
239 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
241 RtlMoveMemory(DestBits
, SourceBits
,
242 2 * (BltInfo
->DestRect
.right
-
243 BltInfo
->DestRect
.left
));
245 SourceBits
+= BltInfo
->SourceSurface
->lDelta
;
246 DestBits
+= BltInfo
->DestSurface
->lDelta
;
251 SourceBits
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
252 ((BltInfo
->SourcePoint
.y
+ BltInfo
->DestRect
.bottom
-
253 BltInfo
->DestRect
.top
- 1) *
254 BltInfo
->SourceSurface
->lDelta
) + 2 *
255 BltInfo
->SourcePoint
.x
;
257 DestBits
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+
258 ((BltInfo
->DestRect
.bottom
- 1) *
259 BltInfo
->DestSurface
->lDelta
) + 2 *
260 BltInfo
->DestRect
.left
;
262 for (j
= BltInfo
->DestRect
.bottom
- 1;
263 BltInfo
->DestRect
.top
<= j
; j
--)
265 RtlMoveMemory(DestBits
, SourceBits
, 2 *
266 (BltInfo
->DestRect
.right
-
267 BltInfo
->DestRect
.left
));
269 SourceBits
-= BltInfo
->SourceSurface
->lDelta
;
270 DestBits
-= BltInfo
->DestSurface
->lDelta
;
276 if (BltInfo
->DestRect
.top
< BltInfo
->SourcePoint
.y
)
278 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
279 (BltInfo
->SourcePoint
.y
*
280 BltInfo
->SourceSurface
->lDelta
) + 2 *
281 BltInfo
->SourcePoint
.x
;
284 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
286 SourceBits
= SourceLine
;
288 for (i
= BltInfo
->DestRect
.left
; i
<
289 BltInfo
->DestRect
.right
; i
++)
291 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
292 BltInfo
->XlateSourceToDest
,
293 *((WORD
*)SourceBits
));
297 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
298 DestLine
+= BltInfo
->DestSurface
->lDelta
;
303 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
304 ((BltInfo
->SourcePoint
.y
+
305 BltInfo
->DestRect
.bottom
-
306 BltInfo
->DestRect
.top
- 1) *
307 BltInfo
->SourceSurface
->lDelta
) + 2 *
308 BltInfo
->SourcePoint
.x
;
310 DestLine
= (PBYTE
)BltInfo
->DestSurface
->pvScan0
+
311 ((BltInfo
->DestRect
.bottom
- 1) *
312 BltInfo
->DestSurface
->lDelta
) + 2 *
313 BltInfo
->DestRect
.left
;
315 for (j
= BltInfo
->DestRect
.bottom
- 1;
316 BltInfo
->DestRect
.top
<= j
; j
--)
318 SourceBits
= SourceLine
;
320 for (i
= BltInfo
->DestRect
.left
; i
<
321 BltInfo
->DestRect
.right
; i
++)
323 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
324 BltInfo
->XlateSourceToDest
,
325 *((WORD
*)SourceBits
));
329 SourceLine
-= BltInfo
->SourceSurface
->lDelta
;
330 DestLine
-= BltInfo
->DestSurface
->lDelta
;
337 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
338 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
339 3 * BltInfo
->SourcePoint
.x
;
343 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
345 SourceBits
= SourceLine
;
348 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
350 xColor
= (*(SourceBits
+ 2) << 0x10) +
351 (*(SourceBits
+ 1) << 0x08) + (*(SourceBits
));
353 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
354 BltInfo
->XlateSourceToDest
, xColor
);
359 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
360 DestLine
+= BltInfo
->DestSurface
->lDelta
;
365 SourceLine
= (PBYTE
)BltInfo
->SourceSurface
->pvScan0
+
366 (BltInfo
->SourcePoint
.y
* BltInfo
->SourceSurface
->lDelta
) +
367 4 * BltInfo
->SourcePoint
.x
;
371 for (j
= BltInfo
->DestRect
.top
; j
< BltInfo
->DestRect
.bottom
; j
++)
373 SourceBits
= SourceLine
;
376 for (i
= BltInfo
->DestRect
.left
; i
< BltInfo
->DestRect
.right
; i
++)
378 *((WORD
*)DestBits
) = (WORD
)XLATEOBJ_iXlate(
379 BltInfo
->XlateSourceToDest
,
380 *((PDWORD
) SourceBits
));
385 SourceLine
+= BltInfo
->SourceSurface
->lDelta
;
386 DestLine
+= BltInfo
->DestSurface
->lDelta
;
391 DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n",
392 BitsPerFormat(BltInfo
->SourceSurface
->iBitmapFormat
));
399 /* Optimize for bitBlt */
401 DIB_16BPP_ColorFill(SURFOBJ
* DestSurface
, RECTL
* DestRect
, ULONG color
)
405 #if defined(_M_IX86) && !defined(_MSC_VER)
406 /* This is about 10% faster than the generic C code below */
407 ULONG delta
= DestSurface
->lDelta
;
408 ULONG width
= (DestRect
->right
- DestRect
->left
) ;
409 PULONG pos
= (PULONG
) ((PBYTE
)DestSurface
->pvScan0
+ DestRect
->top
* delta
+ (DestRect
->left
<<1));
410 color
= (color
&0xffff); /* If the color value is "abcd", put "abcdabcd" into color */
411 color
+= (color
<<16);
413 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
415 __asm__
__volatile__ (
419 "test $0x03, %%edi\n\t" /* Align to fullword boundary */
425 "mov %%ebx,%%ecx\n\t" /* Setup count of fullwords to fill */
427 "rep stosl\n\t" /* The actual fill */
428 "test $0x01, %%ebx\n\t" /* One left to do at the right side? */
433 : "a" (color
), "r" (width
), "m" (pos
)
434 : "%ecx", "%ebx", "%edi");
435 pos
=(PULONG
)((ULONG_PTR
)pos
+ delta
);
439 for (DestY
= DestRect
->top
; DestY
< DestRect
->bottom
; DestY
++)
441 DIB_16BPP_HLine (DestSurface
, DestRect
->left
, DestRect
->right
, DestY
, color
);
448 DIB_16BPP_TransparentBlt(SURFOBJ
*DestSurf
, SURFOBJ
*SourceSurf
,
449 RECTL
* DestRect
, RECTL
*SourceRect
,
450 XLATEOBJ
*ColorTranslation
, ULONG iTransColor
)
452 LONG RoundedRight
, X
, Y
, SourceX
= 0, SourceY
= 0, wd
;
453 ULONG
*DestBits
, Source
, Dest
;
460 DstHeight
= DestRect
->bottom
- DestRect
->top
;
461 DstWidth
= DestRect
->right
- DestRect
->left
;
462 SrcHeight
= SourceRect
->bottom
- SourceRect
->top
;
463 SrcWidth
= SourceRect
->right
- SourceRect
->left
;
465 RoundedRight
= DestRect
->right
- ((DestRect
->right
- DestRect
->left
) & 0x1);
466 DestBits
= (ULONG
*)((PBYTE
)DestSurf
->pvScan0
+
467 (DestRect
->left
<< 1) +
468 DestRect
->top
* DestSurf
->lDelta
);
469 wd
= DestSurf
->lDelta
- ((DestRect
->right
- DestRect
->left
) << 1);
471 for(Y
= DestRect
->top
; Y
< DestRect
->bottom
; Y
++)
473 SourceY
= SourceRect
->top
+(Y
- DestRect
->top
) * SrcHeight
/ DstHeight
;
474 for(X
= DestRect
->left
; X
< RoundedRight
; X
+= 2, DestBits
++, SourceX
+= 2)
478 SourceX
= SourceRect
->left
+(X
- DestRect
->left
) * SrcWidth
/ DstWidth
;
479 if (SourceX
>= 0 && SourceY
>= 0 &&
480 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
482 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
483 if(Source
!= iTransColor
)
486 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) & 0xFFFF);
490 SourceX
= SourceRect
->left
+(X
+1 - DestRect
->left
) * SrcWidth
/ DstWidth
;
491 if (SourceX
>= 0 && SourceY
>= 0 &&
492 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
494 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
495 if(Source
!= iTransColor
)
498 Dest
|= (XLATEOBJ_iXlate(ColorTranslation
, Source
) << 16);
505 if(X
< DestRect
->right
)
507 SourceX
= SourceRect
->left
+(X
- DestRect
->left
) * SrcWidth
/ DstWidth
;
508 if (SourceX
>= 0 && SourceY
>= 0 &&
509 SourceSurf
->sizlBitmap
.cx
> SourceX
&& SourceSurf
->sizlBitmap
.cy
> SourceY
)
511 Source
= DIB_GetSourceIndex(SourceSurf
, SourceX
, SourceY
);
512 if(Source
!= iTransColor
)
514 *((USHORT
*)DestBits
) = (USHORT
)XLATEOBJ_iXlate(ColorTranslation
,
519 DestBits
= (PULONG
)((ULONG_PTR
)DestBits
+ 2);
522 DestBits
= (ULONG
*)((ULONG_PTR
)DestBits
+ wd
);