📄 dib24bpp.c
字号:
addr += 2;
*(addr) = color >> 16;
addr += 1;
Count--;
}
/* If the color we need to fill with is 0ABC, then the final mem pattern
* (note little-endianness) would be:
*
* |C.B.A|C.B.A|C.B.A|C.B.A| <- pixel borders
* |C.B.A.C|B.A.C.B|A.C.B.A| <- ULONG borders
*
* So, taking endianness into account again, we need to fill with these
* ULONGs: CABC BCAB ABCA */
/* This is about 30% faster than the generic C code below */
__asm__ __volatile__ (
" movl %1, %%ecx\n"
" andl $0xffffff, %%ecx\n" /* 0ABC */
" movl %%ecx, %%ebx\n" /* Construct BCAB in ebx */
" shrl $8, %%ebx\n"
" movl %%ecx, %%eax\n"
" shll $16, %%eax\n"
" orl %%eax, %%ebx\n"
" movl %%ecx, %%edx\n" /* Construct ABCA in edx */
" shll $8, %%edx\n"
" movl %%ecx, %%eax\n"
" shrl $16, %%eax\n"
" orl %%eax, %%edx\n"
" movl %%ecx, %%eax\n" /* Construct CABC in eax */
" shll $24, %%eax\n"
" orl %%ecx, %%eax\n"
" movl %2, %%ecx\n" /* Load count */
" shr $2, %%ecx\n"
" movl %3, %%edi\n" /* Load dest */
".FL1:\n"
" movl %%eax, (%%edi)\n" /* Store 4 pixels, 12 bytes */
" movl %%ebx, 4(%%edi)\n"
" movl %%edx, 8(%%edi)\n"
" addl $12, %%edi\n"
" dec %%ecx\n"
" jnz .FL1\n"
" movl %%edi, %0\n"
: "=m"(addr)
: "m"(color), "m"(Count), "m"(addr)
: "%eax", "%ebx", "%ecx", "%edx", "%edi");
Count = Count & 0x03;
while (0 != Count--)
{
*(PUSHORT)(addr) = color;
addr += 2;
*(addr) = color >> 16;
addr += 1;
}
}
}
#else
for (DestY = DestRect->top; DestY< DestRect->bottom; DestY++)
{
DIB_24BPP_HLine(DestSurface, DestRect->left, DestRect->right, DestY, color);
}
#endif
return TRUE;
}
//NOTE: If you change something here, please do the same in other dibXXbpp.c files!
BOOLEAN DIB_24BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, RECTL *SourceRect,
POINTL* MaskOrigin, POINTL BrushOrigin,
CLIPOBJ *ClipRegion, XLATEOBJ *ColorTranslation,
ULONG Mode)
{
LONG SrcSizeY;
LONG SrcSizeX;
LONG DesSizeY;
LONG DesSizeX;
LONG sx;
LONG sy;
LONG DesX;
LONG DesY;
LONG color;
SrcSizeY = SourceRect->bottom - SourceRect->top;
SrcSizeX = SourceRect->right - SourceRect->left;
DesSizeY = DestRect->bottom - DestRect->top;
DesSizeX = DestRect->right - DestRect->left;
switch(SourceSurf->iBitmapFormat)
{
case BMF_1BPP:
/* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
/* This is a reference implementation, it hasn't been optimized for speed */
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
if(DIB_1BPP_GetPixel(SourceSurf, sx, sy) == 0)
{
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 0));
}
else
{
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, 1));
}
}
}
break;
case BMF_4BPP:
/* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
/* This is a reference implementation, it hasn't been optimized for speed */
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
color = DIB_4BPP_GetPixel(SourceSurf, sx, sy);
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
}
}
break;
case BMF_8BPP:
/* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
/* This is a reference implementation, it hasn't been optimized for speed */
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
color = DIB_8BPP_GetPixel(SourceSurf, sx, sy);
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
}
}
break;
case BMF_16BPP:
/* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
/* This is a reference implementation, it hasn't been optimized for speed */
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
color = DIB_16BPP_GetPixel(SourceSurf, sx, sy);
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
}
}
break;
case BMF_24BPP:
/* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
/* This is a reference implementation, it hasn't been optimized for speed */
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
color = DIB_24BPP_GetPixel(SourceSurf, sx, sy);
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
}
}
break;
case BMF_32BPP:
/* FIXME : MaskOrigin, BrushOrigin, ClipRegion, Mode ? */
/* This is a reference implementation, it hasn't been optimized for speed */
for (DesY=DestRect->top; DesY<DestRect->bottom; DesY++)
{
sy = (((DesY - DestRect->top) * SrcSizeY) / DesSizeY) + SourceRect->top;
for (DesX=DestRect->left; DesX<DestRect->right; DesX++)
{
sx = (((DesX - DestRect->left) * SrcSizeX) / DesSizeX) + SourceRect->left;
color = DIB_32BPP_GetPixel(SourceSurf, sx, sy);
DIB_24BPP_PutPixel(DestSurf, DesX, DesY, XLATEOBJ_iXlate(ColorTranslation, color));
}
}
break;
default:
//DPRINT1("DIB_24BPP_StretchBlt: Unhandled Source BPP: %u\n", BitsPerFormat(SourceSurf->iBitmapFormat));
return FALSE;
}
return TRUE;
}
BOOLEAN
DIB_24BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
RECTL* DestRect, POINTL *SourcePoint,
XLATEOBJ *ColorTranslation, ULONG iTransColor)
{
ULONG X, Y, SourceX, SourceY, Source, wd, Dest;
BYTE *DestBits;
SourceY = SourcePoint->y;
DestBits = (BYTE*)((PBYTE)DestSurf->pvScan0 +
(DestRect->left << 2) +
DestRect->top * DestSurf->lDelta);
wd = DestSurf->lDelta - ((DestRect->right - DestRect->left) << 2);
for(Y = DestRect->top; Y < DestRect->bottom; Y++)
{
SourceX = SourcePoint->x;
for(X = DestRect->left; X < DestRect->right; X++, DestBits += 3, SourceX++)
{
Source = DIB_GetSourceIndex(SourceSurf, SourceX, SourceY);
if(Source != iTransColor)
{
Dest = XLATEOBJ_iXlate(ColorTranslation, Source) & 0xFFFFFF;
*(PUSHORT)(DestBits) = Dest & 0xFFFF;
*(DestBits + 2) = Dest >> 16;
}
}
SourceY++;
DestBits = (BYTE*)((ULONG_PTR)DestBits + wd);
}
return TRUE;
}
typedef union {
ULONG ul;
struct {
UCHAR red;
UCHAR green;
UCHAR blue;
UCHAR alpha;
} col;
} NICEPIXEL32;
static __inline UCHAR
Clamp8(ULONG val)
{
return (val > 255) ? 255 : val;
}
BOOLEAN
DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
RECTL* SourceRect, CLIPOBJ* ClipRegion,
XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj)
{
INT Rows, Cols, SrcX, SrcY;
register PUCHAR Dst;
ULONG DstDelta;
BLENDFUNCTION BlendFunc;
register NICEPIXEL32 DstPixel, SrcPixel;
UCHAR Alpha, SrcBpp;
DPRINT("DIB_24BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top &&
DestRect->right - DestRect->left == SourceRect->right - SourceRect->left);
BlendFunc = BlendObj->BlendFunction;
if (BlendFunc.BlendOp != AC_SRC_OVER)
{
DPRINT1("BlendOp != AC_SRC_OVER\n");
return FALSE;
}
if (BlendFunc.BlendFlags != 0)
{
DPRINT1("BlendFlags != 0\n");
return FALSE;
}
if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0)
{
DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat);
return FALSE;
}
if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 &&
BitsPerFormat(Source->iBitmapFormat) != 32)
{
DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
return FALSE;
}
Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
(DestRect->left * 3));
DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3);
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
Rows = DestRect->bottom - DestRect->top;
SrcY = SourceRect->top;
while (--Rows >= 0)
{
Cols = DestRect->right - DestRect->left;
SrcX = SourceRect->left;
while (--Cols >= 0)
{
SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
DstPixel.ul = *Dst;
DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
*Dst = DstPixel.ul;
Dst = (PUCHAR)((ULONG_PTR)Dst + 3);
}
Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
SrcY++;
}
return TRUE;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -