diff --git a/reactos/apps/tests/dibtest/dibtest.c b/reactos/apps/tests/dibtest/dibtest.c index 2fd4296e085..81d532b4e43 100644 --- a/reactos/apps/tests/dibtest/dibtest.c +++ b/reactos/apps/tests/dibtest/dibtest.c @@ -64,7 +64,7 @@ void DIBTest(void) // 1BPP Test Test1BPP(Desktop); - Sleep(10000); + Sleep(50000); // Free up everything DeleteDC(Desktop); diff --git a/reactos/include/win32k/bitmaps.h b/reactos/include/win32k/bitmaps.h index 749a4dd2264..7121140a2eb 100644 --- a/reactos/include/win32k/bitmaps.h +++ b/reactos/include/win32k/bitmaps.h @@ -22,6 +22,7 @@ typedef struct _BITMAPOBJ /* For device-independent bitmaps: */ DIBSECTION *dib; + RGBQUAD *ColorMap; } BITMAPOBJ, *PBITMAPOBJ; /* Internal interface */ diff --git a/reactos/install.bat b/reactos/install.bat index 15ade47706a..0912556a0f1 100644 --- a/reactos/install.bat +++ b/reactos/install.bat @@ -110,6 +110,7 @@ copy apps\tests\pteb\pteb.exe %ROS_INSTALL%\bin copy apps\tests\consume\consume.exe %ROS_INSTALL%\bin copy apps\tests\vmtest\vmtest.exe %ROS_INSTALL%\bin copy apps\tests\gditest\gditest.exe %ROS_INSTALL%\bin +copy apps\tests\dibtest\dibtest.exe %ROS_INSTALL%\bin copy apps\tests\mstest\msserver.exe %ROS_INSTALL%\bin copy apps\tests\mstest\msclient.exe %ROS_INSTALL%\bin copy apps\tests\nptest\npserver.exe %ROS_INSTALL%\bin diff --git a/reactos/subsys/win32k/dib/dib1bpp.c b/reactos/subsys/win32k/dib/dib1bpp.c index e2d36efdb48..a3af45a0290 100644 --- a/reactos/subsys/win32k/dib/dib1bpp.c +++ b/reactos/subsys/win32k/dib/dib1bpp.c @@ -16,13 +16,13 @@ PFN_DIB_PutPixel DIB_1BPP_PutPixel(PSURFOBJ SurfObj, LONG x, LONG y, ULONG c) addr += y * SurfObj->lDelta + (x >> 3); - if(c == 1) + if(c == 0) { - *addr = (*addr | mask1Bpp[mod(x, 8)]); + *addr = (*addr ^ mask1Bpp[mod(x, 8)]); } else { - *addr = (*addr ^ mask1Bpp[mod(x, 8)]); + *addr = (*addr | mask1Bpp[mod(x, 8)]); } } @@ -36,17 +36,17 @@ PFN_DIB_GetPixel DIB_1BPP_GetPixel(PSURFOBJ SurfObj, LONG x, LONG y) PFN_DIB_HLine DIB_1BPP_HLine(PSURFOBJ SurfObj, LONG x1, LONG x2, LONG y, ULONG c) { - LONG cx = x1; - - while(cx <= x2) { - DIB_1BPP_PutPixel(SurfObj, cx, y, c); + while(x1 <= x2) { + DIB_1BPP_PutPixel(SurfObj, x1, y, c); + x1++; } } PFN_DIB_VLine DIB_1BPP_VLine(PSURFOBJ SurfObj, LONG x, LONG y1, LONG y2, ULONG c) { - while(y1++ <= y2) { + while(y1 <= y2) { DIB_1BPP_PutPixel(SurfObj, x, y1, c); + y1++; } } diff --git a/reactos/subsys/win32k/eng/copybits.c b/reactos/subsys/win32k/eng/copybits.c index bacaeb97e7f..d3f4528223e 100644 --- a/reactos/subsys/win32k/eng/copybits.c +++ b/reactos/subsys/win32k/eng/copybits.c @@ -34,6 +34,11 @@ BOOLEAN CopyBitsCopy(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, // Assign GetPixel DIB function according to bytes per pixel switch(DestGDI->BitsPerPixel) { + case 1: + return DIB_To_1BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI, + DestRect, SourcePoint, Delta, ColorTranslation); + break; + case 4: return DIB_To_4BPP_Bitblt(DestSurf, SourceSurf, DestGDI, SourceGDI, DestRect, SourcePoint, Delta, ColorTranslation); diff --git a/reactos/subsys/win32k/eng/lineto.c b/reactos/subsys/win32k/eng/lineto.c index 955b38264c2..ce09b708546 100644 --- a/reactos/subsys/win32k/eng/lineto.c +++ b/reactos/subsys/win32k/eng/lineto.c @@ -42,6 +42,12 @@ EngLineTo(SURFOBJ *Surface, // Assign DIB functions according to bytes per pixel switch(BitsPerFormat(Surface->iBitmapFormat)) { + case 1: + DIB_PutPixel = (PFN_DIB_PutPixel)DIB_1BPP_PutPixel; + DIB_HLine = (PFN_DIB_HLine)DIB_1BPP_HLine; + DIB_VLine = (PFN_DIB_VLine)DIB_1BPP_VLine; + break; + case 4: DIB_PutPixel = (PFN_DIB_PutPixel)DIB_4BPP_PutPixel; DIB_HLine = (PFN_DIB_HLine)DIB_4BPP_HLine; diff --git a/reactos/subsys/win32k/eng/mem.c b/reactos/subsys/win32k/eng/mem.c index 7b8178d306a..ba88a6401b5 100644 --- a/reactos/subsys/win32k/eng/mem.c +++ b/reactos/subsys/win32k/eng/mem.c @@ -37,16 +37,17 @@ EngFreeMem(PVOID Mem) PVOID STDCALL EngAllocUserMem(ULONG cj, ULONG tag) { -/* PVOID newMem; + PVOID newMem = NULL; + NTSTATUS status; - return ZwAllocateVirtualMemory(mycurrentprocess, newMem, 0, cj, - MEM_COMMIT, PAGE_READWRITE); */ + status = ZwAllocateVirtualMemory(NtCurrentProcess(), &newMem, 0, &cj, MEM_COMMIT, PAGE_READWRITE); - return NULL; + if(status != STATUS_SUCCESS) return NULL; + return newMem; } VOID STDCALL EngFreeUserMem(PVOID pv) { -/* ZwFreeVirtualMemory (mycurrentprocess, pv, 0, MEM_DECOMMIT); */ + ZwFreeVirtualMemory (NtCurrentProcess(), &pv, 0, MEM_DECOMMIT); } diff --git a/reactos/subsys/win32k/eng/xlate.c b/reactos/subsys/win32k/eng/xlate.c index 226f56fabb8..c49ed99bc6c 100644 --- a/reactos/subsys/win32k/eng/xlate.c +++ b/reactos/subsys/win32k/eng/xlate.c @@ -53,7 +53,7 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors, PVIDEO_CLUTDATA cSourceColor; PVIDEO_CLUTDATA cDestColors; LONG idx = 0, i, rt; - ULONG cxRed, cxGreen, cxBlue, BestMatch = 65535; + ULONG cxRed, cxGreen, cxBlue, BestMatch = 16777215; // Simple cache -- only one value because we don't want to waste time // if the colors aren't very sequential diff --git a/reactos/subsys/win32k/objects/dc.c b/reactos/subsys/win32k/objects/dc.c index 767d013550f..4e68234581f 100644 --- a/reactos/subsys/win32k/objects/dc.c +++ b/reactos/subsys/win32k/objects/dc.c @@ -1,4 +1,4 @@ -/* $Id: dc.c,v 1.41 2002/09/19 22:41:57 jfilby Exp $ +/* $Id: dc.c,v 1.42 2002/09/24 20:22:10 jfilby Exp $ * * DC.C - Device context functions * @@ -939,6 +939,7 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) PXLATEOBJ XlateObj; PPALGDI PalGDI; WORD objectMagic; + ULONG NumColors; if(!hDC || !hGDIObj) return NULL; @@ -998,6 +999,16 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) // if we're working with a DIB, get the palette [fixme: only create if the selected palette is null] if(pb->dib) { + dc->w.bitsPerPixel = pb->dib->dsBmih.biBitCount; + + if(pb->dib->dsBmih.biBitCount <= 8) + { + if(pb->dib->dsBmih.biBitCount == 1) { NumColors = 2; } else + if(pb->dib->dsBmih.biBitCount == 4) { NumColors = 16; } else + if(pb->dib->dsBmih.biBitCount == 8) { NumColors = 256; } + + dc->w.hPalette = EngCreatePalette(PAL_INDEXED, NumColors, pb->ColorMap, 0, 0, 0); + } else if((pb->dib->dsBmih.biBitCount > 8) && (pb->dib->dsBmih.biBitCount < 24)) { dc->w.hPalette = EngCreatePalette(PAL_BITFIELDS, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0); @@ -1006,6 +1017,8 @@ HGDIOBJ STDCALL W32kSelectObject(HDC hDC, HGDIOBJ hGDIObj) { dc->w.hPalette = EngCreatePalette(PAL_RGB, pb->dib->dsBmih.biClrUsed, NULL, 0, 0, 0); } + } else { + dc->w.bitsPerPixel = pb->bitmap.bmBitsPixel; } break; #if UPDATEREGIONS diff --git a/reactos/subsys/win32k/objects/dib.c b/reactos/subsys/win32k/objects/dib.c index 8c9070dd77f..3864719fb41 100644 --- a/reactos/subsys/win32k/objects/dib.c +++ b/reactos/subsys/win32k/objects/dib.c @@ -402,7 +402,7 @@ HBITMAP STDCALL W32kCreateDIBSection(HDC hDC, if ((dc = DC_HandleToPtr(hDC))) { hbitmap = DIB_CreateDIBSection(dc, bmi, Usage, Bits, hSection, dwOffset, 0); - DC_ReleasePtr( hDC ); + DC_ReleasePtr(hDC); } if (bDesktopDC) @@ -419,12 +419,11 @@ HBITMAP DIB_CreateDIBSection( HBITMAP res = 0; BITMAPOBJ *bmp = NULL; DIBSECTION *dib = NULL; - int *colorMap = NULL; - int nColorMap; // Fill BITMAP32 structure with DIB data BITMAPINFOHEADER *bi = &bmi->bmiHeader; INT effHeight, totalSize; + UINT Entries = 0; BITMAP bm; DbgPrint("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n", @@ -446,27 +445,27 @@ HBITMAP DIB_CreateDIBSection( totalSize = bi->biSizeImage && bi->biCompression != BI_RGB ? bi->biSizeImage : bm.bmWidthBytes * effHeight; -/* if (section) - bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS, - 0L, offset, totalSize); +/* bm.bmBits = MapViewOfFile(section, FILE_MAP_ALL_ACCESS, + 0L, offset, totalSize); */ + DbgPrint("DIB_CreateDIBSection: Cannot yet handle section DIBs\n"); else if (ovr_pitch && offset) bm.bmBits = (LPVOID) offset; - else { */ + else { offset = 0; -/* bm.bmBits = VirtualAlloc(NULL, totalSize, - MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); */ + bm.bmBits = EngAllocUserMem(totalSize, 0); + } - bm.bmBits = ExAllocatePool(NonPagedPool, totalSize); +/* bm.bmBits = ExAllocatePool(NonPagedPool, totalSize); */ -/* } */ - - if (usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *)); + if(usage == DIB_PAL_COLORS) memcpy(bmi->bmiColors, (UINT *)DIB_MapPaletteColors(dc, bmi), sizeof(UINT *)); // Allocate Memory for DIB and fill structure if (bm.bmBits) + { dib = ExAllocatePool(PagedPool, sizeof(DIBSECTION)); RtlZeroMemory(dib, sizeof(DIBSECTION)); + } if (dib) { @@ -515,10 +514,20 @@ HBITMAP DIB_CreateDIBSection( bmp->dib = (DIBSECTION *) dib; } } + + /* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical + device. Obviously, this is left out of the ReactOS implementation. Instead, we call + W32kSetDIBColorTable. */ + if(bi->biBitCount == 1) { Entries = 2; } else + if(bi->biBitCount == 4) { Entries = 16; } else + if(bi->biBitCount == 8) { Entries = 256; } + + bmp->ColorMap = ExAllocatePool(NonPagedPool, sizeof(RGBQUAD)*Entries); + RtlCopyMemory(bmp->ColorMap, bmi->bmiColors, sizeof(RGBQUAD)*Entries); } // Clean up in case of errors - if (!res || !bmp || !dib || !bm.bmBits || (bm.bmBitsPixel <= 8 && !colorMap)) + if (!res || !bmp || !dib || !bm.bmBits) { DbgPrint("got an error res=%08x, bmp=%p, dib=%p, bm.bmBits=%p\n", res, bmp, dib, bm.bmBits); /* if (bm.bmBits) @@ -529,7 +538,6 @@ HBITMAP DIB_CreateDIBSection( VirtualFree(bm.bmBits, 0L, MEM_RELEASE), bm.bmBits = NULL; } */ - if (colorMap) { ExFreePool(colorMap); colorMap = NULL; } if (dib) { ExFreePool(dib); dib = NULL; } if (bmp) { bmp = NULL; } if (res) { GDIOBJ_FreeObj(res, GO_BITMAP_MAGIC); res = 0; } @@ -558,6 +566,7 @@ HBITMAP DIB_CreateDIBSection( // Return BITMAP handle and storage location if (bm.bmBits && bits) *bits = bm.bmBits; + return res; } diff --git a/reactos/subsys/win32k/objects/palette.c b/reactos/subsys/win32k/objects/palette.c index d676098142c..b4e150dcfed 100644 --- a/reactos/subsys/win32k/objects/palette.c +++ b/reactos/subsys/win32k/objects/palette.c @@ -4,6 +4,7 @@ #include #include #include +#include "../include/palette.h" static int PALETTE_firstFree = 0; static unsigned char PALETTE_freeList[256]; @@ -57,6 +58,8 @@ HPALETTE PALETTE_Init(void) // GDI_ReleaseObj( hpalette ); } +/* palette_size = visual->map_entries; */ + return hpalette; } @@ -80,6 +83,61 @@ static void PALETTE_FormatSystemPalette(void) PALETTE_freeList[j] = 0; } +/* Ported from WINE 20020804 (graphics\x11drv\palette.c) */ +static int SysPaletteLookupPixel( COLORREF col, BOOL skipReserved ) +{ + int i, best = 0, diff = 0x7fffffff; + int r,g,b; + + for( i = 0; i < palette_size && diff ; i++ ) + { + if( !(COLOR_sysPal[i].peFlags & PC_SYS_USED) || (skipReserved && COLOR_sysPal[i].peFlags & PC_SYS_RESERVED) ) + continue; + + r = COLOR_sysPal[i].peRed - GetRValue(col); + g = COLOR_sysPal[i].peGreen - GetGValue(col); + b = COLOR_sysPal[i].peBlue - GetBValue(col); + + r = r*r + g*g + b*b; + + if( r < diff ) { best = i; diff = r; } + } + return best; +} + +/* Ported from WINE 20020804 (graphics\x11drv\palette.c) */ +/* Make sure this is required - ROS's xlate may make this redundant */ +UINT WINAPI GetNearestPaletteIndex( + HPALETTE hpalette, /* [in] Handle of logical color palette */ + COLORREF color) /* [in] Color to be matched */ +{ + PPALOBJ palObj = (PPALOBJ)AccessUserObject(hpalette); + UINT index = 0; + + if( palObj ) + { + int i, diff = 0x7fffffff; + int r,g,b; + PALETTEENTRY* entry = palObj->logpalette->palPalEntry; + + for( i = 0; i < palObj->logpalette->palNumEntries && diff ; i++, entry++) + { + if (!(entry->peFlags & PC_SYS_USED)) continue; + + r = entry->peRed - GetRValue(color); + g = entry->peGreen - GetGValue(color); + b = entry->peBlue - GetBValue(color); + + r = r*r + g*g + b*b; + + if( r < diff ) { index = i; diff = r; } + } +// GDI_ReleaseObj( hpalette ); + } + DPRINT("(%04x,%06lx): returning %d\n", hpalette, color, index ); + return index; +} + void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size) { int i = 0; @@ -190,3 +248,139 @@ int PALETTE_SetMapping(PPALOBJ palPtr, UINT uStart, UINT uNum, BOOL mapOnly) } return iRemapped; } + +/* Return the physical color closest to 'color'. */ +/* Ported from WINE 20020804 (graphics\x11drv\palette.c) */ +int PALETTE_ToPhysical( PDC dc, COLORREF color ) +{ + WORD index = 0; + HPALETTE hPal = (dc)? dc->w.hPalette: W32kGetStockObject(DEFAULT_PALETTE); + unsigned char spec_type = color >> 24; + PPALOBJ palPtr = (PPALOBJ)AccessUserObject(hPal); + + /* palPtr can be NULL when DC is being destroyed */ + if( !palPtr ) return 0; + + if ( PALETTE_PaletteFlags & PALETTE_FIXED ) + { + /* there is no colormap limitation; we are going to have to compute + * the pixel value from the visual information stored earlier + */ + + unsigned long red, green, blue; + unsigned idx = 0; + + switch(spec_type) + { + case 1: /* PALETTEINDEX */ + + if( (idx = color & 0xffff) >= palPtr->logpalette->palNumEntries) + { + DPRINT("RGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx); +// GDI_ReleaseObj( hPal ); + return 0; + } + + if( palPtr->mapping ) + { + int ret = palPtr->mapping[idx]; +// GDI_ReleaseObj( hPal ); + return ret; + } + color = *(COLORREF*)(palPtr->logpalette->palPalEntry + idx); + break; + + default: + color &= 0xffffff; + /* fall through to RGB */ + + case 0: /* RGB */ + if( dc && (dc->w.bitsPerPixel == 1) ) + { +// GDI_ReleaseObj( hPal ); + return (((color >> 16) & 0xff) + + ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0; + } + + } + + red = GetRValue(color); green = GetGValue(color); blue = GetBValue(color); + + if (PALETTE_Graymax) + { + /* grayscale only; return scaled value */ +// GDI_ReleaseObj( hPal ); + return ( (red * 30 + green * 59 + blue * 11) * PALETTE_Graymax) / 25500; + } + else + { + /* scale each individually and construct the TrueColor pixel value */ + if (PALETTE_PRed.scale < 8) + red = red >> (8-PALETTE_PRed.scale); + else if (PALETTE_PRed.scale > 8) + red = red << (PALETTE_PRed.scale-8) | + red >> (16-PALETTE_PRed.scale); + if (PALETTE_PGreen.scale < 8) + green = green >> (8-PALETTE_PGreen.scale); + else if (PALETTE_PGreen.scale > 8) + green = green << (PALETTE_PGreen.scale-8) | + green >> (16-PALETTE_PGreen.scale); + if (PALETTE_PBlue.scale < 8) + blue = blue >> (8-PALETTE_PBlue.scale); + else if (PALETTE_PBlue.scale > 8) + blue = blue << (PALETTE_PBlue.scale-8) | + blue >> (16-PALETTE_PBlue.scale); + +// GDI_ReleaseObj( hPal ); + return (red << PALETTE_PRed.shift) | (green << PALETTE_PGreen.shift) | (blue << PALETTE_PBlue.shift); + } + } + else + { + + if( !palPtr->mapping ) + DPRINT("Palette %04x is not realized\n", dc->w.hPalette); + + switch(spec_type) /* we have to peruse DC and system palette */ + { + default: + color &= 0xffffff; + /* fall through to RGB */ + + case 0: /* RGB */ + if( dc && (dc->w.bitsPerPixel == 1) ) + { +// GDI_ReleaseObj( hPal ); + return (((color >> 16) & 0xff) + + ((color >> 8) & 0xff) + (color & 0xff) > 255*3/2) ? 1 : 0; + } + + index = SysPaletteLookupPixel( color, FALSE); + +/* if (PALETTE_PaletteToXPixel) index = PALETTE_PaletteToXPixel[index]; */ + + /* DPRINT(palette,"RGB(%lx) -> pixel %i\n", color, index); + */ + break; + case 1: /* PALETTEINDEX */ + index = color & 0xffff; + + if( index >= palPtr->logpalette->palNumEntries ) + DbgPrint("RGB(%lx) : index %i is out of bounds\n", color, index); + else if( palPtr->mapping ) index = palPtr->mapping[index]; + + /* DPRINT(palette,"PALETTEINDEX(%04x) -> pixel %i\n", (WORD)color, index); + */ + break; + case 2: /* PALETTERGB */ + index = GetNearestPaletteIndex( hPal, color ); + if (palPtr->mapping) index = palPtr->mapping[index]; + /* DPRINT(palette,"PALETTERGB(%lx) -> pixel %i\n", color, index); + */ + break; + } + } + +// GDI_ReleaseObj( hPal ); + return index; +}