From 964636c2ab1690228d6f2c61fe2e3560cd38e65d Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Thu, 18 Dec 2003 18:30:48 +0000 Subject: [PATCH] Stretchblitting 8->8 bpp implemented svn path=/trunk/; revision=7121 --- reactos/subsys/win32k/dib/dib16bpp.c | 12 +- reactos/subsys/win32k/dib/dib32bpp.c | 9 +- reactos/subsys/win32k/dib/dib8bpp.c | 159 ++++++++++++++++++++++++++- 3 files changed, 163 insertions(+), 17 deletions(-) diff --git a/reactos/subsys/win32k/dib/dib16bpp.c b/reactos/subsys/win32k/dib/dib16bpp.c index 5dd915c2f14..657c1ab80ea 100644 --- a/reactos/subsys/win32k/dib/dib16bpp.c +++ b/reactos/subsys/win32k/dib/dib16bpp.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dib16bpp.c,v 1.14 2003/12/18 18:09:48 fireball Exp $ */ +/* $Id: dib16bpp.c,v 1.15 2003/12/18 18:30:48 fireball Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -352,7 +352,7 @@ DIB_16BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, typedef unsigned short PIXEL; /* 16-bit HiColor (565 format) */ -inline PIXEL average(PIXEL a, PIXEL b) +inline PIXEL average16(PIXEL a, PIXEL b) { // This one doesn't work /* @@ -404,7 +404,7 @@ void ScaleLineAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth) while (NumPixels-- > 0) { p = *Source; if (E >= Mid) - p = average(p, *(Source+1)); + p = average16(p, *(Source+1)); *Target++ = p; Source += IntPart; E += FractPart; @@ -418,7 +418,7 @@ void ScaleLineAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth) } //NOTE: If you change something here, please do the same in other dibXXbpp.c files! -void ScaleRectAvg(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight, +void ScaleRectAvg16(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight, int TgtWidth, int TgtHeight, int srcPitch, int dstPitch) { int NumPixels = TgtHeight; @@ -457,7 +457,7 @@ void ScaleRectAvg(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight, int x; ScaleLineAvg16(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth); for (x = 0; x < TgtWidth; x++) - ScanLine[x] = average(ScanLine[x], ScanLineAhead[x]); + ScanLine[x] = average16(ScanLine[x], ScanLineAhead[x]); PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch); } /* if */ @@ -513,7 +513,7 @@ BOOLEAN DIB_16BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + 2 * SourceRect->left; DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + 2 * DestRect->left; - ScaleRectAvg((PIXEL *)DestLine, (PIXEL *)SourceLine, + ScaleRectAvg16((PIXEL *)DestLine, (PIXEL *)SourceLine, SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top, DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta); break; diff --git a/reactos/subsys/win32k/dib/dib32bpp.c b/reactos/subsys/win32k/dib/dib32bpp.c index abe6b28a1eb..8befe68b4e3 100644 --- a/reactos/subsys/win32k/dib/dib32bpp.c +++ b/reactos/subsys/win32k/dib/dib32bpp.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dib32bpp.c,v 1.8 2003/12/18 18:09:48 fireball Exp $ */ +/* $Id: dib32bpp.c,v 1.9 2003/12/18 18:30:48 fireball Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -301,13 +301,6 @@ typedef unsigned long PIXEL; /* 32-bit Color (___ format) */ inline PIXEL average32(PIXEL a, PIXEL b) { -/* - if (a == b) { - return a; - } else { - unsigned short mask = ~ (((a | b) & 0x0410) << 1); - return ((a & mask) + (b & mask)) >> 1; - }*/ /* if */ return a; // FIXME: Temp hack to remove "PCB-effect" from the image } diff --git a/reactos/subsys/win32k/dib/dib8bpp.c b/reactos/subsys/win32k/dib/dib8bpp.c index 04da50d9402..73011e65b77 100644 --- a/reactos/subsys/win32k/dib/dib8bpp.c +++ b/reactos/subsys/win32k/dib/dib8bpp.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: dib8bpp.c,v 1.9 2003/12/08 18:05:30 fireball Exp $ */ +/* $Id: dib8bpp.c,v 1.10 2003/12/18 18:30:48 fireball Exp $ */ #undef WIN32_LEAN_AND_MEAN #include #include @@ -341,14 +341,167 @@ DIB_8BPP_BitBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, return TRUE; } +/* +======================================= + Stretching functions goes below + Some parts of code are based on an + article "Bresenhame image scaling" + Dr. Dobb Journal, May 2002 +======================================= +*/ + +typedef unsigned char PIXEL; + +/* 16-bit HiColor (565 format) */ +inline PIXEL average8(PIXEL a, PIXEL b) +{ + return a; // FIXME: Depend on SetStretchMode +} + +//NOTE: If you change something here, please do the same in other dibXXbpp.c files! +void ScaleLineAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int TgtWidth) +{ + int NumPixels = TgtWidth; + int IntPart = SrcWidth / TgtWidth; + int FractPart = SrcWidth % TgtWidth; + int Mid = TgtWidth / 2; + int E = 0; + int skip; + PIXEL p; + + skip = (TgtWidth < SrcWidth) ? 0 : (TgtWidth / (2*SrcWidth) + 1); + NumPixels -= skip; + + while (NumPixels-- > 0) { + p = *Source; + if (E >= Mid) + p = average8(p, *(Source+1)); + *Target++ = p; + Source += IntPart; + E += FractPart; + if (E >= TgtWidth) { + E -= TgtWidth; + Source++; + } /* if */ + } /* while */ + while (skip-- > 0) + *Target++ = *Source; +} + +//NOTE: If you change something here, please do the same in other dibXXbpp.c files! +void ScaleRectAvg8(PIXEL *Target, PIXEL *Source, int SrcWidth, int SrcHeight, + int TgtWidth, int TgtHeight, int srcPitch, int dstPitch) +{ + int NumPixels = TgtHeight; + int IntPart = (SrcHeight / TgtHeight) * (SrcWidth+1); + int FractPart = SrcHeight % TgtHeight; + int Mid = TgtHeight / 2; + int E = 0; + int skip; + PIXEL *ScanLine, *ScanLineAhead; + PIXEL *PrevSource = NULL; + PIXEL *PrevSourceAhead = NULL; + + skip = (TgtHeight < SrcHeight) ? 0 : (TgtHeight / (2*SrcHeight) + 1); + NumPixels -= skip; + + ScanLine = (PIXEL*)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); // FIXME: Should we use PagedPool here? + ScanLineAhead = (PIXEL *)ExAllocatePool(NonPagedPool, TgtWidth*sizeof(PIXEL)); + + while (NumPixels-- > 0) { + if (Source != PrevSource) { + if (Source == PrevSourceAhead) { + /* the next scan line has already been scaled and stored in + * ScanLineAhead; swap the buffers that ScanLine and ScanLineAhead + * point to + */ + PIXEL *tmp = ScanLine; + ScanLine = ScanLineAhead; + ScanLineAhead = tmp; + } else { + ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth); + } /* if */ + PrevSource = Source; + } /* if */ + + if (E >= Mid && PrevSourceAhead != (PIXEL *)((BYTE *)Source + srcPitch)) { + int x; + ScaleLineAvg8(ScanLineAhead, (PIXEL *)((BYTE *)Source + srcPitch), SrcWidth, TgtWidth); + for (x = 0; x < TgtWidth; x++) + ScanLine[x] = average8(ScanLine[x], ScanLineAhead[x]); + PrevSourceAhead = (PIXEL *)((BYTE *)Source + srcPitch); + } /* if */ + + memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL)); + Target = (PIXEL *)((BYTE *)Target + dstPitch); + Source += IntPart; + E += FractPart; + if (E >= TgtHeight) { + E -= TgtHeight; + Source = (PIXEL *)((BYTE *)Source + srcPitch); + } /* if */ + } /* while */ + + if (skip > 0 && Source != PrevSource) + ScaleLineAvg8(ScanLine, Source, SrcWidth, TgtWidth); + while (skip-- > 0) { + memcpy(Target, ScanLine, TgtWidth*sizeof(PIXEL)); + Target = (PIXEL *)((BYTE *)Target + dstPitch); + } /* while */ + + ExFreePool(ScanLine); + ExFreePool(ScanLineAhead); +} + BOOLEAN DIB_8BPP_StretchBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, SURFGDI *DestGDI, SURFGDI *SourceGDI, RECTL* DestRect, RECTL *SourceRect, POINTL* MaskOrigin, POINTL* BrushOrigin, XLATEOBJ *ColorTranslation, ULONG Mode) { - DbgPrint("DIB_8BPP_StretchBlt: Source BPP: %u\n", SourceGDI->BitsPerPixel); - return FALSE; + BYTE *SourceLine, *DestLine; + + DbgPrint("DIB_8BPP_StretchBlt: Source BPP: %u, srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", + SourceGDI->BitsPerPixel, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, + DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); + + switch(SourceGDI->BitsPerPixel) + { + case 1: + return FALSE; + break; + + case 4: + return FALSE; + break; + + case 8: + SourceLine = SourceSurf->pvScan0 + (SourceRect->top * SourceSurf->lDelta) + SourceRect->left; + DestLine = DestSurf->pvScan0 + (DestRect->top * DestSurf->lDelta) + DestRect->left; + + ScaleRectAvg8((PIXEL *)DestLine, (PIXEL *)SourceLine, + SourceRect->right-SourceRect->left, SourceRect->bottom-SourceRect->top, + DestRect->right-DestRect->left, DestRect->bottom-DestRect->top, SourceSurf->lDelta, DestSurf->lDelta); + break; + + case 16: + return FALSE; + break; + + case 24: + return FALSE; + break; + + case 32: + return FALSE; + break; + + default: + DbgPrint("DIB_8BPP_StretchBlt: Unhandled Source BPP: %u\n", SourceGDI->BitsPerPixel); + return FALSE; + } + + return TRUE; } /* EOF */