📄 dib24bpp.c
字号:
/*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: dib24bpp.c 23732 2006-08-26 23:26:39Z greatlrd $ */
#include <w32k.h>
#define NDEBUG
#include <debug.h>
VOID
DIB_24BPP_PutPixel(SURFOBJ *SurfObj, LONG x, LONG y, ULONG c)
{
PBYTE addr = (PBYTE)SurfObj->pvScan0 + (y * SurfObj->lDelta) + (x << 1) + x;
*(PUSHORT)(addr) = c & 0xFFFF;
*(addr + 2) = (c >> 16) & 0xFF;
}
ULONG
DIB_24BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y)
{
PBYTE addr = (PBYTE)SurfObj->pvScan0 + y * SurfObj->lDelta + (x << 1) + x;
return *(PUSHORT)(addr) + (*(addr + 2) << 16);
}
VOID
DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c)
{
PBYTE addr = (PBYTE)SurfObj->pvScan0 + y1 * SurfObj->lDelta + (x << 1) + x;
LONG lDelta = SurfObj->lDelta;
c &= 0xFFFFFF;
while(y1++ < y2) {
*(PUSHORT)(addr) = c & 0xFFFF;
*(addr + 2) = c >> 16;
addr += lDelta;
}
}
BOOLEAN
DIB_24BPP_BitBltSrcCopy(PBLTINFO BltInfo)
{
LONG i, j, sx, sy, xColor, f1;
PBYTE SourceBits, DestBits, SourceLine, DestLine;
PBYTE SourceBits_4BPP, SourceLine_4BPP;
PWORD SourceBits_16BPP, SourceLine_16BPP;
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + BltInfo->DestRect.left * 3;
switch(BltInfo->SourceSurface->iBitmapFormat)
{
case BMF_1BPP:
sx = BltInfo->SourcePoint.x;
sy = BltInfo->SourcePoint.y;
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
{
sx = BltInfo->SourcePoint.x;
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
{
if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0)
{
DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0));
} else {
DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1));
}
sx++;
}
sy++;
}
break;
case BMF_4BPP:
SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1);
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
{
SourceLine_4BPP = SourceBits_4BPP;
DestLine = DestBits;
sx = BltInfo->SourcePoint.x;
f1 = sx & 1;
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
{
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest,
(*SourceLine_4BPP & altnotmask[f1]) >> (4 * (1 - f1)));
*DestLine++ = xColor & 0xff;
*(PWORD)DestLine = xColor >> 8;
DestLine += 2;
if(f1 == 1) { SourceLine_4BPP++; f1 = 0; } else { f1 = 1; }
sx++;
}
SourceBits_4BPP += BltInfo->SourceSurface->lDelta;
DestBits += BltInfo->DestSurface->lDelta;
}
break;
case BMF_8BPP:
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + BltInfo->SourcePoint.x;
DestLine = DestBits;
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
{
SourceBits = SourceLine;
DestBits = DestLine;
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
{
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceBits);
*DestBits = xColor & 0xff;
*(PWORD)(DestBits + 1) = xColor >> 8;
SourceBits += 1;
DestBits += 3;
}
SourceLine += BltInfo->SourceSurface->lDelta;
DestLine += BltInfo->DestSurface->lDelta;
}
break;
case BMF_16BPP:
SourceBits_16BPP = (PWORD)((PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 2 * BltInfo->SourcePoint.x);
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
{
SourceLine_16BPP = SourceBits_16BPP;
DestLine = DestBits;
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
{
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *SourceLine_16BPP);
*DestLine++ = xColor & 0xff;
*(PWORD)DestLine = xColor >> 8;
DestLine += 2;
SourceLine_16BPP++;
}
SourceBits_16BPP = (PWORD)((PBYTE)SourceBits_16BPP + BltInfo->SourceSurface->lDelta);
DestBits += BltInfo->DestSurface->lDelta;
}
break;
case BMF_24BPP:
if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL))
{
if (BltInfo->DestRect.top < BltInfo->SourcePoint.y)
{
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
{
RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
SourceBits += BltInfo->SourceSurface->lDelta;
DestBits += BltInfo->DestSurface->lDelta;
}
}
else
{
SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + ((BltInfo->SourcePoint.y + BltInfo->DestRect.bottom - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x;
DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 3 * BltInfo->DestRect.left;
for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--)
{
RtlMoveMemory(DestBits, SourceBits, 3 * (BltInfo->DestRect.right - BltInfo->DestRect.left));
SourceBits -= BltInfo->SourceSurface->lDelta;
DestBits -= BltInfo->DestSurface->lDelta;
}
}
}
else
{
sx = BltInfo->SourcePoint.x;
sy = BltInfo->SourcePoint.y;
for (j=BltInfo->DestRect.top; j<BltInfo->DestRect.bottom; j++)
{
sx = BltInfo->SourcePoint.x;
for (i=BltInfo->DestRect.left; i<BltInfo->DestRect.right; i++)
{
DWORD pixel = DIB_24BPP_GetPixel(BltInfo->SourceSurface, sx, sy);
DIB_24BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, pixel));
sx++;
}
sy++;
}
}
break;
case BMF_32BPP:
SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x;
DestLine = DestBits;
for (j = BltInfo->DestRect.top; j < BltInfo->DestRect.bottom; j++)
{
SourceBits = SourceLine;
DestBits = DestLine;
for (i = BltInfo->DestRect.left; i < BltInfo->DestRect.right; i++)
{
xColor = XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, *((PDWORD) SourceBits));
*DestBits = xColor & 0xff;
*(PWORD)(DestBits + 1) = xColor >> 8;
SourceBits += 4;
DestBits += 3;
}
SourceLine += BltInfo->SourceSurface->lDelta;
DestLine += BltInfo->DestSurface->lDelta;
}
break;
default:
DbgPrint("DIB_24BPP_Bitblt: Unhandled Source BPP: %u\n", BitsPerFormat(BltInfo->SourceSurface->iBitmapFormat));
return FALSE;
}
return TRUE;
}
BOOLEAN
DIB_24BPP_BitBlt(PBLTINFO BltInfo)
{
ULONG DestX, DestY;
ULONG SourceX, SourceY;
ULONG PatternY = 0;
ULONG Dest, Source = 0, Pattern = 0;
BOOL UsesSource;
BOOL UsesPattern;
PBYTE DestBits;
UsesSource = ROP4_USES_SOURCE(BltInfo->Rop4);
UsesPattern = ROP4_USES_PATTERN(BltInfo->Rop4);
SourceY = BltInfo->SourcePoint.y;
DestBits = (PBYTE)(
(PBYTE)BltInfo->DestSurface->pvScan0 +
(BltInfo->DestRect.left << 1) + BltInfo->DestRect.left +
BltInfo->DestRect.top * BltInfo->DestSurface->lDelta);
if (UsesPattern)
{
if (BltInfo->PatternSurface)
{
PatternY = (BltInfo->DestRect.top + BltInfo->BrushOrigin.y) %
BltInfo->PatternSurface->sizlBitmap.cy;
}
else
{
Pattern = BltInfo->Brush->iSolidColor;
}
}
for (DestY = BltInfo->DestRect.top; DestY < BltInfo->DestRect.bottom; DestY++)
{
SourceX = BltInfo->SourcePoint.x;
for (DestX = BltInfo->DestRect.left; DestX < BltInfo->DestRect.right; DestX++, DestBits += 3, SourceX++)
{
Dest = *((PUSHORT)DestBits) + (*(DestBits + 2) << 16);
if (UsesSource)
{
Source = DIB_GetSource(BltInfo->SourceSurface, SourceX, SourceY, BltInfo->XlateSourceToDest);
}
if (BltInfo->PatternSurface)
{
Pattern = DIB_GetSource(BltInfo->PatternSurface, (DestX + BltInfo->BrushOrigin.x) % BltInfo->PatternSurface->sizlBitmap.cx, PatternY, BltInfo->XlatePatternToDest);
}
Dest = DIB_DoRop(BltInfo->Rop4, Dest, Source, Pattern) & 0xFFFFFF;
*(PUSHORT)(DestBits) = Dest & 0xFFFF;
*(DestBits + 2) = Dest >> 16;
}
SourceY++;
if (BltInfo->PatternSurface)
{
PatternY++;
PatternY %= BltInfo->PatternSurface->sizlBitmap.cy;
}
DestBits -= (BltInfo->DestRect.right - BltInfo->DestRect.left) * 3;
DestBits += BltInfo->DestSurface->lDelta;
}
return TRUE;
}
/* BitBlt Optimize */
BOOLEAN
DIB_24BPP_ColorFill(SURFOBJ* DestSurface, RECTL* DestRect, ULONG color)
{
ULONG DestY;
#if defined(_M_IX86) && !defined(_MSC_VER)
PBYTE xaddr = (PBYTE)DestSurface->pvScan0 + DestRect->top * DestSurface->lDelta + (DestRect->left << 1) + DestRect->left;
PBYTE addr;
ULONG Count;
ULONG xCount=DestRect->right - DestRect->left;
for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
{
Count = xCount;
addr = xaddr;
xaddr = (PBYTE)((ULONG_PTR)addr + DestSurface->lDelta);
if (Count < 8)
{
/* For small fills, don't bother doing anything fancy */
while (Count--)
{
*(PUSHORT)(addr) = color;
addr += 2;
*(addr) = color >> 16;
addr += 1;
}
}
else
{
/* Align to 4-byte address */
while (0 != ((ULONG_PTR) addr & 0x3))
{
*(PUSHORT)(addr) = color;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -