Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendib16bpp.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: Win32 subsystem 00003 * LICENSE: See COPYING in the top level directory 00004 * FILE: subsystems/win32/win32k/dib/dib16bpp.c 00005 * PURPOSE: Device Independant Bitmap functions, 16bpp 00006 * PROGRAMMERS: Jason Filby 00007 * Thomas Bluemel 00008 * Gregor Anich 00009 */ 00010 00011 #include <win32k.h> 00012 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 VOID 00017 DIB_16BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c) 00018 { 00019 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta; 00020 PWORD addr = (PWORD)byteaddr + x; 00021 00022 *addr = (WORD)c; 00023 } 00024 00025 ULONG 00026 DIB_16BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y) 00027 { 00028 PBYTE byteaddr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta; 00029 PWORD addr = (PWORD)byteaddr + x; 00030 return (ULONG)(*addr); 00031 } 00032 00033 VOID 00034 DIB_16BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c) 00035 { 00036 PDWORD addr = (PDWORD)((PWORD)((PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta) + x1); 00037 00038 #if defined(_M_IX86) && !defined(_MSC_VER) 00039 /* This is about 10% faster than the generic C code below */ 00040 LONG Count = x2 - x1; 00041 00042 __asm__ __volatile__ ( 00043 " cld\n" 00044 " mov %0, %%eax\n" 00045 " shl $16, %%eax\n" 00046 " andl $0xffff, %0\n" /* If the pixel value is "abcd", put "abcdabcd" in %eax */ 00047 " or %0, %%eax\n" 00048 " mov %2, %%edi\n" 00049 " test $0x03, %%edi\n" /* Align to fullword boundary */ 00050 " jz 0f\n" 00051 " stosw\n" 00052 " dec %1\n" 00053 " jz 1f\n" 00054 "0:\n" 00055 " mov %1,%%ecx\n" /* Setup count of fullwords to fill */ 00056 " shr $1,%%ecx\n" 00057 " rep stosl\n" /* The actual fill */ 00058 " test $0x01, %1\n" /* One left to do at the right side? */ 00059 " jz 1f\n" 00060 " stosw\n" 00061 "1:\n" 00062 : /* no output */ 00063 : "r"(c), "r"(Count), "m"(addr) 00064 : "%eax", "%ecx", "%edi"); 00065 #else /* _M_IX86 */ 00066 LONG cx = x1; 00067 DWORD cc; 00068 00069 if (0 != (cx & 0x01)) 00070 { 00071 *((PWORD) addr) = (WORD)c; 00072 cx++; 00073 addr = (PDWORD)((PWORD)(addr) + 1); 00074 } 00075 cc = ((c & 0xffff) << 16) | (c & 0xffff); 00076 while(cx + 1 < x2) 00077 { 00078 *addr++ = cc; 00079 cx += 2; 00080 } 00081 if (cx < x2) 00082 { 00083 *((PWORD) addr) = (WORD)c; 00084 } 00085 #endif /* _M_IX86 */ 00086 } 00087 00088 00089 VOID 00090 DIB_16BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) 00091 { 00092 #if defined(_M_IX86) && !defined(_MSC_VER) 00093 asm volatile( 00094 " testl %2, %2" "\n\t" 00095 " jle 2f" "\n\t" 00096 " movl %2, %%ecx" "\n\t" 00097 " shrl $2, %2" "\n\t" 00098 " andl $3, %%ecx" "\n\t" 00099 " jz 1f" "\n\t" 00100 "0:" "\n\t" 00101 " movw %%ax, (%0)" "\n\t" 00102 " addl %1, %0" "\n\t" 00103 " decl %%ecx" "\n\t" 00104 " jnz 0b" "\n\t" 00105 " testl %2, %2" "\n\t" 00106 " jz 2f" "\n\t" 00107 "1:" "\n\t" 00108 " movw %%ax, (%0)" "\n\t" 00109 " addl %1, %0" "\n\t" 00110 " movw %%ax, (%0)" "\n\t" 00111 " addl %1, %0" "\n\t" 00112 " movw %%ax, (%0)" "\n\t" 00113 " addl %1, %0" "\n\t" 00114 " movw %%ax, (%0)" "\n\t" 00115 " addl %1, %0" "\n\t" 00116 " decl %2" "\n\t" 00117 " jnz 1b" "\n\t" 00118 "2:" "\n\t" 00119 : /* no output */ 00120 : "r"((PBYTE)SurfObj->pvScan0 + (y1 * SurfObj->lDelta) + (x * sizeof (WORD))), 00121 "r"(SurfObj->lDelta), "r"(y2 - y1), "a"(c) 00122 : "cc", "memory", "%ecx"); 00123 #else 00124 PBYTE byteaddr = (PBYTE)(ULONG_PTR)SurfObj->pvScan0 + y1 * SurfObj->lDelta; 00125 PWORD addr = (PWORD)byteaddr + x; 00126 LONG lDelta = SurfObj->lDelta; 00127 00128 byteaddr = (PBYTE)addr; 00129 while(y1++ < y2) 00130 { 00131 *addr = (WORD)c; 00132 00133 byteaddr += lDelta; 00134 addr = (PWORD)byteaddr; 00135 } 00136 #endif 00137 } 00138 00139 BOOLEAN 00140 DIB_16BPP_BitBltSrcCopy(PBLTINFO BltInfo) 00141 { 00142 LONG i, j, sx, sy, xColor, f1; 00143 PBYTE SourceBits, DestBits, SourceLine, DestLine; 00144 PBYTE SourceBits_4BPP, SourceLine_4BPP; 00145 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 2 * BltInfo->DestRect.left; 00146 00147 switch(BltInfo->SourceSurface->iBitmapFormat) 00148 { 00149 case BMF_1BPP: 00150 sx = BltInfo->SourcePoint.x; 00151 sy = BltInfo->SourcePoint.y; 00152 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 00153 { 00154 sx = BltInfo->SourcePoint.x; 00155 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 00156 { 00157 if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0) 00158 { 00159 DIB_16BPP_PutPixel(BltInfo->DestSurface, i, j, 00160 XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0)); 00161 } 00162 else 00163 { 00164 DIB_16BPP_PutPixel(BltInfo->DestSurface, i, j, 00165 XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1)); 00166 } 00167 sx++; 00168 } 00169 sy++; 00170 } 00171 break; 00172 00173 case BMF_4BPP: 00174 SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00175 (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 00176 (BltInfo->SourcePoint.x >> 1); 00177 00178 for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++) 00179 { 00180 SourceLine_4BPP = SourceBits_4BPP; 00181 sx = BltInfo->SourcePoint.x; 00182 f1 = sx & 1; 00183 00184 for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++) 00185 { 00186 xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 00187 (*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1))); 00188 DIB_16BPP_PutPixel(BltInfo->DestSurface, i, j, xColor); 00189 if(f1 == 1) 00190 { 00191 SourceLine_4BPP++; 00192 f1 = 0; 00193 } 00194 else 00195 { 00196 f1 = 1; 00197 } 00198 sx++; 00199 } 00200 SourceBits_4BPP += BltInfo->SourceSurface->lDelta; 00201 } 00202 break; 00203 00204 case BMF_8BPP: 00205 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00206 (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 00207 BltInfo->SourcePoint.x; 00208 DestLine = DestBits; 00209 00210 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 00211 { 00212 SourceBits = SourceLine; 00213 DestBits = DestLine; 00214 00215 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 00216 { 00217 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate( 00218 BltInfo->XlateSourceToDest, *SourceBits); 00219 SourceBits += 1; 00220 DestBits += 2; 00221 } 00222 00223 SourceLine += BltInfo->SourceSurface->lDelta; 00224 DestLine += BltInfo->DestSurface->lDelta; 00225 } 00226 break; 00227 00228 case BMF_16BPP: 00229 if (NULL == BltInfo->XlateSourceToDest || 0 != 00230 (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL)) 00231 { 00232 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) 00233 { 00234 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00235 (BltInfo->SourcePoint.y * 00236 BltInfo->SourceSurface->lDelta) + 2 * 00237 BltInfo->SourcePoint.x; 00238 00239 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 00240 { 00241 RtlMoveMemory(DestBits, SourceBits, 00242 2 * (BltInfo->DestRect.right - 00243 BltInfo->DestRect.left)); 00244 00245 SourceBits += BltInfo->SourceSurface->lDelta; 00246 DestBits += BltInfo->DestSurface->lDelta; 00247 } 00248 } 00249 else 00250 { 00251 SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00252 ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - 00253 BltInfo->DestRect.top - 1) * 00254 BltInfo->SourceSurface->lDelta) + 2 * 00255 BltInfo->SourcePoint.x; 00256 00257 DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + 00258 ((BltInfo->DestRect.bottom - 1) * 00259 BltInfo->DestSurface->lDelta) + 2 * 00260 BltInfo->DestRect.left; 00261 00262 for (j = BltInfo->DestRect.bottom - 1; 00263 BltInfo->DestRect.top <= j; j--) 00264 { 00265 RtlMoveMemory(DestBits, SourceBits, 2 * 00266 (BltInfo->DestRect.right - 00267 BltInfo->DestRect.left)); 00268 00269 SourceBits -= BltInfo->SourceSurface->lDelta; 00270 DestBits -= BltInfo->DestSurface->lDelta; 00271 } 00272 } 00273 } 00274 else 00275 { 00276 if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) 00277 { 00278 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00279 (BltInfo->SourcePoint.y * 00280 BltInfo->SourceSurface->lDelta) + 2 * 00281 BltInfo->SourcePoint.x; 00282 00283 DestLine = DestBits; 00284 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 00285 { 00286 SourceBits = SourceLine; 00287 DestBits = DestLine; 00288 for (i = BltInfo->DestRect.left; i < 00289 BltInfo->DestRect.right; i++) 00290 { 00291 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate( 00292 BltInfo->XlateSourceToDest, 00293 *((WORD *)SourceBits)); 00294 SourceBits += 2; 00295 DestBits += 2; 00296 } 00297 SourceLine += BltInfo->SourceSurface->lDelta; 00298 DestLine += BltInfo->DestSurface->lDelta; 00299 } 00300 } 00301 else 00302 { 00303 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00304 ((BltInfo->SourcePoint.y + 00305 BltInfo->DestRect.bottom - 00306 BltInfo->DestRect.top - 1) * 00307 BltInfo->SourceSurface->lDelta) + 2 * 00308 BltInfo->SourcePoint.x; 00309 00310 DestLine = (PBYTE)BltInfo->DestSurface->pvScan0 + 00311 ((BltInfo->DestRect.bottom - 1) * 00312 BltInfo->DestSurface->lDelta) + 2 * 00313 BltInfo->DestRect.left; 00314 00315 for (j = BltInfo->DestRect.bottom - 1; 00316 BltInfo->DestRect.top <= j; j--) 00317 { 00318 SourceBits = SourceLine; 00319 DestBits = DestLine; 00320 for (i = BltInfo->DestRect.left; i < 00321 BltInfo->DestRect.right; i++) 00322 { 00323 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate( 00324 BltInfo->XlateSourceToDest, 00325 *((WORD *)SourceBits)); 00326 SourceBits += 2; 00327 DestBits += 2; 00328 } 00329 SourceLine -= BltInfo->SourceSurface->lDelta; 00330 DestLine -= BltInfo->DestSurface->lDelta; 00331 } 00332 } 00333 } 00334 break; 00335 00336 case BMF_24BPP: 00337 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00338 (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 00339 3 * BltInfo->SourcePoint.x; 00340 00341 DestLine = DestBits; 00342 00343 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 00344 { 00345 SourceBits = SourceLine; 00346 DestBits = DestLine; 00347 00348 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 00349 { 00350 xColor = (*(SourceBits + 2) << 0x10) + 00351 (*(SourceBits + 1) << 0x08) + (*(SourceBits)); 00352 00353 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate( 00354 BltInfo->XlateSourceToDest, xColor); 00355 00356 SourceBits += 3; 00357 DestBits += 2; 00358 } 00359 SourceLine += BltInfo->SourceSurface->lDelta; 00360 DestLine += BltInfo->DestSurface->lDelta; 00361 } 00362 break; 00363 00364 case BMF_32BPP: 00365 SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + 00366 (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 00367 4 * BltInfo->SourcePoint.x; 00368 00369 DestLine = DestBits; 00370 00371 for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++) 00372 { 00373 SourceBits = SourceLine; 00374 DestBits = DestLine; 00375 00376 for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++) 00377 { 00378 *((WORD *)DestBits) = (WORD)XLATEOBJ_iXlate( 00379 BltInfo->XlateSourceToDest, 00380 *((PDWORD) SourceBits)); 00381 SourceBits += 4; 00382 DestBits += 2; 00383 } 00384 00385 SourceLine += BltInfo->SourceSurface->lDelta; 00386 DestLine += BltInfo->DestSurface->lDelta; 00387 } 00388 break; 00389 00390 default: 00391 DPRINT1("DIB_16BPP_Bitblt: Unhandled Source BPP: %u\n", 00392 BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat)); 00393 return FALSE; 00394 } 00395 00396 return TRUE; 00397 } 00398 00399 /* Optimize for bitBlt */ 00400 BOOLEAN 00401 DIB_16BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color) 00402 { 00403 LONG DestY; 00404 00405 #if defined(_M_IX86) && !defined(_MSC_VER) 00406 /* This is about 10% faster than the generic C code below */ 00407 ULONG delta = DestSurface->lDelta; 00408 ULONG width = (DestRect->right - DestRect->left) ; 00409 PULONG pos = (PULONG) ((PBYTE)DestSurface->pvScan0 + DestRect->top * delta + (DestRect->left<<1)); 00410 color = (color&0xffff); /* If the color value is "abcd", put "abcdabcd" into color */ 00411 color += (color<<16); 00412 00413 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++) 00414 { 00415 __asm__ __volatile__ ( 00416 "cld\n\t" 00417 "mov %1,%%ebx\n\t" 00418 "mov %2,%%edi\n\t" 00419 "test $0x03, %%edi\n\t" /* Align to fullword boundary */ 00420 "jz 1f\n\t" 00421 "stosw\n\t" 00422 "dec %%ebx\n\t" 00423 "jz 2f\n" 00424 "1:\n\t" 00425 "mov %%ebx,%%ecx\n\t" /* Setup count of fullwords to fill */ 00426 "shr $1,%%ecx\n\t" 00427 "rep stosl\n\t" /* The actual fill */ 00428 "test $0x01, %%ebx\n\t" /* One left to do at the right side? */ 00429 "jz 2f\n\t" 00430 "stosw\n" 00431 "2:" 00432 : 00433 : "a" (color), "r" (width), "m" (pos) 00434 : "%ecx", "%ebx", "%edi"); 00435 pos =(PULONG)((ULONG_PTR)pos + delta); 00436 } 00437 #else /* _M_IX86 */ 00438 00439 for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++) 00440 { 00441 DIB_16BPP_HLine (DestSurface, DestRect->left, DestRect->right, DestY, color); 00442 } 00443 #endif 00444 return TRUE; 00445 } 00446 00447 BOOLEAN 00448 DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, 00449 RECTL* DestRect, RECTL *SourceRect, 00450 XLATEOBJ *ColorTranslation, ULONG iTransColor) 00451 { 00452 LONG RoundedRight, X, Y, SourceX = 0, SourceY = 0, wd; 00453 ULONG *DestBits, Source, Dest; 00454 00455 LONG DstHeight; 00456 LONG DstWidth; 00457 LONG SrcHeight; 00458 LONG SrcWidth; 00459 00460 DstHeight = DestRect->bottom - DestRect->top; 00461 DstWidth = DestRect->right - DestRect->left; 00462 SrcHeight = SourceRect->bottom - SourceRect->top; 00463 SrcWidth = SourceRect->right - SourceRect->left; 00464 00465 RoundedRight = DestRect->right - ((DestRect->right - DestRect->left) & 0x1); 00466 DestBits = (ULONG*)((PBYTE)DestSurf->pvScan0 + 00467 (DestRect->left << 1) + 00468 DestRect->top * DestSurf->lDelta); 00469 wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 1); 00470 00471 for(Y = DestRect->top; Y < DestRect->bottom; Y++) 00472 { 00473 SourceY = SourceRect->top+(Y - DestRect->top) * SrcHeight / DstHeight; 00474 for(X = DestRect->left; X < RoundedRight; X += 2, DestBits++, SourceX += 2) 00475 { 00476 Dest = *DestBits; 00477 00478 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth; 00479 if (SourceX >= 0 && SourceY >= 0 && 00480 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 00481 { 00482 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 00483 if(Source != iTransColor) 00484 { 00485 Dest &= 0xFFFF0000; 00486 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFF); 00487 } 00488 } 00489 00490 SourceX = SourceRect->left+(X+1 - DestRect->left) * SrcWidth / DstWidth; 00491 if (SourceX >= 0 && SourceY >= 0 && 00492 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 00493 { 00494 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 00495 if(Source != iTransColor) 00496 { 00497 Dest &= 0xFFFF; 00498 Dest |= (XLATEOBJ_iXlate(ColorTranslation, Source) << 16); 00499 } 00500 } 00501 00502 *DestBits = Dest; 00503 } 00504 00505 if(X < DestRect->right) 00506 { 00507 SourceX = SourceRect->left+(X - DestRect->left) * SrcWidth / DstWidth; 00508 if (SourceX >= 0 && SourceY >= 0 && 00509 SourceSurf->sizlBitmap.cx > SourceX && SourceSurf->sizlBitmap.cy > SourceY) 00510 { 00511 Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY); 00512 if(Source != iTransColor) 00513 { 00514 *((USHORT*)DestBits) = (USHORT)XLATEOBJ_iXlate(ColorTranslation, 00515 Source); 00516 } 00517 } 00518 00519 DestBits = (PULONG)((ULONG_PTR)DestBits + 2); 00520 } 00521 00522 DestBits = (ULONG*)((ULONG_PTR)DestBits + wd); 00523 } 00524 00525 return TRUE; 00526 } 00527 00528 /* EOF */ Generated on Sun May 27 2012 04:38:15 for ReactOS by
1.7.6.1
|