#include #include #include "drawdibi.h" #include "dither.h" //#define GRAY_SCALE extern BOOL gf286; extern UINT gwRasterCaps; void FAR PASCAL Map16to24(LPBITMAPINFOHEADER,LPVOID,int,int,int,int,LPBITMAPINFOHEADER,LPVOID,int,int,LPVOID); extern LPVOID glpDitherTable; ////////////////////////////////////////////////////////////////////////////// // // DitherInit() // ////////////////////////////////////////////////////////////////////////////// LPVOID VFWAPI DitherInit(LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR * lpDitherProc, LPVOID lpDitherTable) { switch ((int)lpbiOut->biBitCount) { case 8: if ((int)lpbiIn->biBitCount == 8 && (gwRasterCaps & RC_PALETTE)) return Dither8Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable); if ((int)lpbiIn->biBitCount == 8 && !(gwRasterCaps & RC_PALETTE)) return DitherDeviceInit(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable); if ((int)lpbiIn->biBitCount == 16) return Dither16Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable); if ((int)lpbiIn->biBitCount == 24) return Dither24Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable); if ((int)lpbiIn->biBitCount == 32) return Dither32Init(lpbiIn, lpbiOut, lpDitherProc, lpDitherTable); return (LPVOID)-1; case 24: #ifndef _WIN32 if (!gf286) #endif { if (lpbiIn->biBitCount == 16) { *lpDitherProc = Map16to24; return NULL; } else if (lpbiIn->biBitCount == 32) { *lpDitherProc = Map32to24; return NULL; } } return (LPVOID)-1; default: return (LPVOID)-1; } } ////////////////////////////////////////////////////////////////////////////// // // DitherTerm() // ////////////////////////////////////////////////////////////////////////////// void VFWAPI DitherTerm(LPVOID lpDitherTable) { if (lpDitherTable == glpDitherTable) Dither16Term(lpDitherTable); else Dither8Term(lpDitherTable); } ////////////////////////////////////////////////////////////////////////////// // // DitherDeviceInit() - dither to the colors of the display driver // ////////////////////////////////////////////////////////////////////////////// LPVOID FAR PASCAL DitherDeviceInit(LPBITMAPINFOHEADER lpbi, LPBITMAPINFOHEADER lpbiOut, DITHERPROC FAR *lpDitherProc, LPVOID lpDitherTable) { HBRUSH hbr; HDC hdcMem; HDC hdc; HBITMAP hbm; HBITMAP hbmT; int i; int nColors; LPRGBQUAD prgb; BITMAPINFOHEADER biSave = *lpbiOut; // // we dont need to re-init the dither table, unless it is not ours then // we should free it. // if (lpDitherTable == glpDitherTable) { DitherTerm(lpDitherTable); lpDitherTable = NULL; } if (lpDitherTable == NULL) { lpDitherTable = GlobalAllocPtr(GHND, 256*8*8); } if (lpDitherTable == NULL) return (LPVOID)-1; hdc = GetDC(NULL); hdcMem = CreateCompatibleDC(hdc); hbm = CreateCompatibleBitmap(hdc, 256*8, 8); hbmT = SelectObject(hdcMem, hbm); if ((nColors = (int)lpbi->biClrUsed) == 0) nColors = 1 << (int)lpbi->biBitCount; prgb = (LPRGBQUAD)(lpbi+1); for (i=0; ibiSize = sizeof(BITMAPINFOHEADER); lpbiOut->biPlanes = 1; lpbiOut->biBitCount = 8; lpbiOut->biWidth = 256*8; lpbiOut->biHeight = 8; lpbiOut->biCompression = BI_RGB; lpbiOut->biSizeImage = 256*8*8; lpbiOut->biXPelsPerMeter = 0; lpbiOut->biYPelsPerMeter = 0; lpbiOut->biClrUsed = 0; lpbiOut->biClrImportant = 0; GetDIBits(hdc, hbm, 0, 8, lpDitherTable, (LPBITMAPINFO)lpbiOut, DIB_RGB_COLORS); i = (int)lpbiOut->biClrUsed; *lpbiOut = biSave; lpbiOut->biClrUsed = i; DeleteObject(hbm); ReleaseDC(NULL, hdc); *lpDitherProc = Dither8; return (LPVOID)lpDitherTable; } ////////////////////////////////////////////////////////////////////////////// // // DitherTerm() // ////////////////////////////////////////////////////////////////////////////// void FAR PASCAL Dither8Term(LPVOID lpDitherTable) { if (lpDitherTable) GlobalFreePtr(lpDitherTable); } #ifdef _WIN32 // // call this to actually do the dither. // void FAR PASCAL Dither8( LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest LPVOID lpDst, // --> to destination bits int DstX, // Destination origin - x coordinate int DstY, // Destination origin - y coordinate int DstXE, // x extent of the BLT int DstYE, // y extent of the BLT LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source LPVOID lpSrc, // --> to source bits int SrcX, // Source origin - x coordinate int SrcY, // Source origin - y coordinate LPVOID lpDitherTable) // dither table. { int x,y; UINT wWidthSrc; UINT wWidthDst; BYTE _huge *pbS; BYTE _huge *pbD; DWORD dw; if (biDst->biBitCount != 8 || biSrc->biBitCount != 8) return; // tomor -- A little help! seems initialization is not done yet. if(!lpDitherTable) return; wWidthSrc = ((UINT)biSrc->biWidth+3)&~3; wWidthDst = ((UINT)biDst->biWidth+3)&~3; pbD = (BYTE _huge *)lpDst + DstX + DstY * wWidthDst; pbS = (BYTE _huge *)lpSrc + SrcX + SrcY * wWidthSrc; wWidthSrc -= DstXE; wWidthDst -= DstXE; #define DODITH8(px, x, y) ((LPBYTE)lpDitherTable)[((y) & 7) * 256 * 8 + (px) * 8 + (x & 7)] for (y=0; y24 mapping (in asm for win16) */ extern void FAR PASCAL Map16to24( LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest LPVOID lpDst, // --> to destination bits int DstX, // Destination origin - x coordinate int DstY, // Destination origin - y coordinate int DstXE, // x extent of the BLT int DstYE, // y extent of the BLT LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source LPVOID lpSrc, // --> to source bits int SrcX, // Source origin - x coordinate int SrcY, // Source origin - y coordinate LPVOID lpDitherTable) // dither table. { int x,y; UINT wWidthSrc; UINT wWidthDst; BYTE _huge *pbS; BYTE _huge *pbD; WORD wRGB; if (biDst->biBitCount != 24 || biSrc->biBitCount != 16) return; /* width of one row is nr pixels * size of pixel rounded to 4-bytes */ wWidthSrc = ((UINT) (biSrc->biWidth * 2) +3)&~3; wWidthDst = ((UINT) (biDst->biWidth * 3) +3)&~3; /* advance to start of source, dest rect within DIB */ pbD = (BYTE _huge *)lpDst + (DstX * 3) + DstY * wWidthDst; pbS = (BYTE _huge *)lpSrc + (SrcX * 2) + SrcY * wWidthSrc; /* amount to advance pointer to next line from end of source, dest rect */ wWidthSrc -= (DstXE * 2); wWidthDst -= (DstXE * 3); for (y=0; y> 2) & 0xf8; *pbD++ = (wRGB >> 7) & 0xf8; } pbS += wWidthSrc; pbD += wWidthDst; } } void FAR PASCAL Map32to24( LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of the dest LPVOID lpDst, // --> to destination bits int DstX, // Destination origin - x coordinate int DstY, // Destination origin - y coordinate int DstXE, // x extent of the BLT int DstYE, // y extent of the BLT LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of the source LPVOID lpSrc, // --> to source bits int SrcX, // Source origin - x coordinate int SrcY, // Source origin - y coordinate LPVOID lpDitherTable) // dither table. { int x,y; UINT wWidthSrc; UINT wWidthDst; BYTE _huge *pbS; BYTE _huge *pbD; if (biDst->biBitCount != 24 || biSrc->biBitCount != 32) return; /* width of one row is nr pixels * size of pixel rounded to 4-bytes */ //wWidthSrc = ((UINT) (biSrc->biWidth * 4) +3)&~3; // Multiplying by 4 ensures it is rounded to 4 bytes... wWidthSrc = (UINT) (biSrc->biWidth * 4); wWidthDst = ((UINT) (biDst->biWidth * 3) +3)&~3; /* advance to start of source, dest rect within DIB */ pbD = (BYTE _huge *)lpDst + (DstX * 3) + DstY * wWidthDst; pbS = (BYTE _huge *)lpSrc + (SrcX * 4) + SrcY * wWidthSrc; /* amount to advance pointer to next line from end of source, dest rect */ wWidthSrc -= (DstXE * 4); wWidthDst -= (DstXE * 3); for (y=0; y