1 /* 2 * PROJECT: Win32 subsystem 3 * LICENSE: See COPYING in the top level directory 4 * FILE: win32ss/gdi/dib/dib32bpp.c 5 * PURPOSE: Device Independant Bitmap functions, 32bpp 6 * PROGRAMMERS: Jason Filby 7 * Thomas Bluemel 8 * Gregor Anich 9 */ 10 11 #include <win32k.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 VOID 17 DIB_32BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c) 18 { 19 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta; 20 PDWORD addr = (PDWORD)byteaddr + x; 21 22 *addr = c; 23 } 24 25 ULONG 26 DIB_32BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y) 27 { 28 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta; 29 PDWORD addr = (PDWORD)byteaddr + x; 30 31 return (ULONG)(*addr); 32 } 33 34 VOID 35 DIB_32BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) 36 { 37 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta; 38 PDWORD addr = (PDWORD)byteaddr + x; 39 LONG lDelta = SurfObj->lDelta >> 2; // >> 2 == / sizeof(DWORD) 40 41 byteaddr = (PBYTE)addr; 42 while (y1++ < y2) 43 { 44 *addr = (DWORD)c; 45 addr += lDelta; 46 } 47 } 48 49 BOOLEAN 50 DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo) 51 { 52 LONG i, j, sx, sy, xColor, f1; 53 PBYTE SourceBits, DestBits, SourceLine, DestLine; 54 PBYTE SourceBits_4BPP, SourceLine_4BPP; 55 PDWORD Source32, Dest32; 56 57 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 58 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) 59 + 4 * BltInfo->DestRect.left; 60 61 switch (BltInfo->SourceSurface->iBitmapFormat) 62 { 63 case BMF_1BPP: 64 65 sx = BltInfo->SourcePoint.x; 66 sy = BltInfo->SourcePoint.y; 67 68 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 69 { 70 sx = BltInfo->SourcePoint.x; 71 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 72 { 73 if (DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0) 74 { 75 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0)); 76 } else { 77 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1)); 78 } 79 sx++; 80 } 81 sy++; 82 } 83 break; 84 85 case BMF_4BPP: 86 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 87 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) 88 + (BltInfo->SourcePoint.x >> 1); 89 90 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 91 { 92 SourceLine_4BPP = SourceBits_4BPP; 93 sx = BltInfo->SourcePoint.x; 94 f1 = sx & 1; 95 96 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 97 { 98 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 99 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1))); 100 DIB_32BPP_PutPixel(BltInfo->DestSurface, i, j, xColor); 101 if (f1 == 1) { 102 SourceLine_4BPP++; 103 f1 = 0; 104 } else { 105 f1 = 1; 106 } 107 sx++; 108 } 109 110 SourceBits_4BPP += BltInfo->SourceSurface->lDelta; 111 } 112 break; 113 114 case BMF_8BPP: 115 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x; 116 DestLine = DestBits; 117 118 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 119 { 120 SourceBits = SourceLine; 121 DestBits = DestLine; 122 123 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 124 { 125 xColor = *SourceBits; 126 *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor); 127 SourceBits += 1; 128 DestBits += 4; 129 } 130 131 SourceLine += BltInfo->SourceSurface->lDelta; 132 DestLine += BltInfo->DestSurface->lDelta; 133 } 134 break; 135 136 case BMF_16BPP: 137 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x; 138 DestLine = DestBits; 139 140 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 141 { 142 SourceBits = SourceLine; 143 DestBits = DestLine; 144 145 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 146 { 147 xColor = *((PWORD) SourceBits); 148 *((PDWORD) DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor); 149 SourceBits += 2; 150 DestBits += 4; 151 } 152 153 SourceLine += BltInfo->SourceSurface->lDelta; 154 DestLine += BltInfo->DestSurface->lDelta; 155 } 156 break; 157 158 case BMF_24BPP: 159 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 160 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) 161 + 3 * BltInfo->SourcePoint.x; 162 DestLine = DestBits; 163 164 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 165 { 166 SourceBits = SourceLine; 167 DestBits = DestLine; 168 169 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 170 { 171 xColor = (*(SourceBits + 2) << 0x10) + 172 (*(SourceBits + 1) << 0x08) + 173 (*(SourceBits)); 174 *((PDWORD)DestBits) = (DWORD)XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, xColor); 175 SourceBits += 3; 176 DestBits += 4; 177 } 178 179 SourceLine += BltInfo->SourceSurface->lDelta; 180 DestLine += BltInfo->DestSurface->lDelta; 181 } 182 break; 183 184 case BMF_32BPP: 185 if (NULL == BltInfo->XlateSourceToDest || 186 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL)) 187 { 188 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) 189 { 190 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x; 191 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 192 { 193 RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left)); 194 SourceBits += BltInfo->SourceSurface->lDelta; 195 DestBits += BltInfo->DestSurface->lDelta; 196 } 197 } 198 else 199 { 200 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 201 + ((BltInfo->SourcePoint.y 202 + BltInfo->DestRect.bottom 203 - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) 204 + 4 * BltInfo->SourcePoint.x; 205 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left; 206 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--) 207 { 208 RtlMoveMemory(DestBits, SourceBits, 4 * (BltInfo->DestRect.right - BltInfo->DestRect.left)); 209 SourceBits -= BltInfo->SourceSurface->lDelta; 210 DestBits -= BltInfo->DestSurface->lDelta; 211 } 212 } 213 } 214 else 215 { 216 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) 217 { 218 SourceBits = ((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x); 219 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 220 { 221 if (BltInfo->DestRect.left < BltInfo->SourcePoint.x) 222 { 223 Dest32 = (DWORD *) DestBits; 224 Source32 = (DWORD *) SourceBits; 225 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 226 { 227 *Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++); 228 } 229 } 230 else 231 { 232 Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 233 Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 234 for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--) 235 { 236 *Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--); 237 } 238 } 239 SourceBits += BltInfo->SourceSurface->lDelta; 240 DestBits += BltInfo->DestSurface->lDelta; 241 } 242 } 243 else 244 { 245 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x; 246 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left; 247 for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--) 248 { 249 if (BltInfo->DestRect.left < BltInfo->SourcePoint.x) 250 { 251 Dest32 = (DWORD *) DestBits; 252 Source32 = (DWORD *) SourceBits; 253 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 254 { 255 *Dest32++ = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32++); 256 } 257 } 258 else 259 { 260 Dest32 = (DWORD *) DestBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 261 Source32 = (DWORD *) SourceBits + (BltInfo->DestRect.right - BltInfo->DestRect.left - 1); 262 for (i = BltInfo->DestRect.right - 1; BltInfo->DestRect.left <= i; i--) 263 { 264 *Dest32-- = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *Source32--); 265 } 266 } 267 SourceBits -= BltInfo->SourceSurface->lDelta; 268 DestBits -= BltInfo->DestSurface->lDelta; 269 } 270 } 271 } 272 break; 273 274 default: 275 DPRINT1("DIB_32BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat)); 276 return FALSE; 277 } 278 279 return TRUE; 280 } 281 282 BOOLEAN 283 DIB_32BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 284 RECTL* DestRect, RECTL *SourceRect, 285 XLATEOBJ *ColorTranslation, ULONG iTransColor) 286 { 287 LONG X, Y, SourceX, SourceY = 0, wd; 288 ULONG *DestBits, Source = 0; 289 290 LONG DstHeight; 291 LONG DstWidth; 292 LONG SrcHeight; 293 LONG SrcWidth; 294 295 DstHeight = DestRect->bottom - DestRect->top; 296 DstWidth = DestRect->right - DestRect->left; 297 SrcHeight = SourceRect->bottom - SourceRect->top; 298 SrcWidth = SourceRect->right - SourceRect->left; 299 300 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + 301 (DestRect->left << 2) + 302 DestRect->top * DestSurf->lDelta); 303 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2); 304 305 for (Y = DestRect->top; Y < DestRect->bottom; Y++) 306 { 307 SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight; 308 for (X = DestRect->left; X < DestRect->right; X++, DestBits++) 309 { 310 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth; 311 if (SourceX >= 0 && SourceY >= 0 && 312 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 313 { 314 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 315 if ((0x00FFFFFF & Source) != (0x00FFFFFF & iTransColor)) 316 { 317 *DestBits = XLATEOBJ_iXlate(ColorTranslation, Source); 318 } 319 } 320 } 321 322 DestBits = (ULONG*)((ULONG_PTR)DestBits + wd); 323 } 324 325 return TRUE; 326 } 327 328 typedef union { 329 ULONG ul; 330 struct { 331 UCHAR red; 332 UCHAR green; 333 UCHAR blue; 334 UCHAR alpha; 335 } col; 336 } NICEPIXEL32; 337 338 static __inline UCHAR 339 Clamp8(ULONG val) 340 { 341 return (val > 255) ? 255 : (UCHAR)val; 342 } 343 344 BOOLEAN 345 DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, 346 RECTL* SourceRect, CLIPOBJ* ClipRegion, 347 XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) 348 { 349 INT Rows, Cols, SrcX, SrcY; 350 register PULONG Dst; 351 BLENDFUNCTION BlendFunc; 352 register NICEPIXEL32 DstPixel, SrcPixel; 353 UCHAR Alpha, SrcBpp; 354 355 DPRINT("DIB_32BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", 356 SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, 357 DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); 358 359 BlendFunc = BlendObj->BlendFunction; 360 if (BlendFunc.BlendOp != AC_SRC_OVER) 361 { 362 DPRINT1("BlendOp != AC_SRC_OVER\n"); 363 return FALSE; 364 } 365 if (BlendFunc.BlendFlags != 0) 366 { 367 DPRINT1("BlendFlags != 0\n"); 368 return FALSE; 369 } 370 if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) 371 { 372 DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); 373 return FALSE; 374 } 375 if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && 376 BitsPerFormat(Source->iBitmapFormat) != 32) 377 { 378 DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); 379 return FALSE; 380 } 381 382 Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + 383 (DestRect->left << 2)); 384 SrcBpp = BitsPerFormat(Source->iBitmapFormat); 385 386 Rows = 0; 387 SrcY = SourceRect->top; 388 while (++Rows <= DestRect->bottom - DestRect->top) 389 { 390 Cols = 0; 391 SrcX = SourceRect->left; 392 while (++Cols <= DestRect->right - DestRect->left) 393 { 394 SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation); 395 SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255; 396 SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255; 397 SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255; 398 SrcPixel.col.alpha = (32 == SrcBpp) ? 399 (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255 : 400 BlendFunc.SourceConstantAlpha ; 401 402 Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? 403 SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha ; 404 405 DstPixel.ul = *Dst; 406 DstPixel.col.red = Clamp8((DstPixel.col.red * (255 - Alpha)) / 255 + SrcPixel.col.red) ; 407 DstPixel.col.green = Clamp8((DstPixel.col.green * (255 - Alpha)) / 255 + SrcPixel.col.green) ; 408 DstPixel.col.blue = Clamp8((DstPixel.col.blue * (255 - Alpha)) / 255 + SrcPixel.col.blue) ; 409 DstPixel.col.alpha = Clamp8((DstPixel.col.alpha * (255 - Alpha)) / 255 + SrcPixel.col.alpha) ; 410 *Dst++ = DstPixel.ul; 411 SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left); 412 } 413 Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) + 414 (DestRect->left << 2)); 415 SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top); 416 } 417 418 return TRUE; 419 } 420 421 /* EOF */ 422