/**************************************************************************** * * FUNCTION: DIBToIconImage * * PURPOSE: Converts a CF_DIB memory block to an icon image * * PARAMS: LPICONIMAGE lpii - pointer to icon image data * LPBYTE lpDIB - a pointer to the CF_DIB block * BOOL bStretchToFit - TRUE to stretch, FALSE to take * the upper left corner of the DIB * * RETURNS: BOOL - TRUE for success, FALSE for failure * * History: * July '95 - Created * \****************************************************************************/ BOOL DIBToIconImage( LPICONIMAGE lpii, LPBYTE lpDIB, BOOL bStretch ) { LPBYTE lpNewDIB; // Sanity check if( lpDIB == NULL ) return FALSE; // Let the DIB engine convert color depths if need be lpNewDIB = ConvertDIBFormat( (LPBITMAPINFO)lpDIB, lpii->Width, lpii->Height, lpii->Colors, bStretch ); // Now we have a cool new DIB of the proper size/color depth // Lets poke it into our data structures and be done with it // How big is it? lpii->dwNumBytes = sizeof( BITMAPINFOHEADER ) // Header + PaletteSize( (LPSTR)lpNewDIB ) // Palette + lpii->Height * BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB ) // XOR mask + lpii->Height * WIDTHBYTES( lpii->Width ); // AND mask // If there was already an image here, free it if( lpii->lpBits != NULL ) free( lpii->lpBits ); // Allocate enough room for the new image if( (lpii->lpBits = malloc( lpii->dwNumBytes )) == NULL ) { free( lpii ); return FALSE; } // Copy the bits memcpy( lpii->lpBits, lpNewDIB, sizeof( BITMAPINFOHEADER ) + PaletteSize( (LPSTR)lpNewDIB ) ); // Adjust internal pointers/variables for new image lpii->lpbi = (LPBITMAPINFO)(lpii->lpBits); lpii->lpbi->bmiHeader.biHeight *= 2; lpii->lpXOR = FindDIBBits( (LPSTR)(lpii->lpBits) ); memcpy( lpii->lpXOR, FindDIBBits((LPSTR)lpNewDIB), lpii->Height * BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB ) ); lpii->lpAND = lpii->lpXOR + lpii->Height * BytesPerLine( (LPBITMAPINFOHEADER)lpNewDIB ); memset( lpii->lpAND, 0, lpii->Height * WIDTHBYTES( lpii->Width ) ); // Free the source free( lpNewDIB ); return TRUE; }
/************************************************************************* * * ConvoluteDIB() * * Parameters: * * HDIB hDib - objective DIB handle * KERNEL *lpKernel - pointer of kernel used to convolute with DIB * int Strength - operation strength set to the convolute * int nKernelNum - kernel number used to convolute * * Return Value: * * BOOL - True is success, else False * * Description: * * This is the generic convolute function to DIB * ************************************************************************/ BOOL ConvoluteDIB(HDIB hDib, KERNEL *lpKernel, int Strength, int nKernelNum) { WaitCursorBegin(); HDIB hNewDib = NULL; // we only convolute 24bpp DIB, so first convert DIB to 24bpp WORD wBitCount = DIBBitCount(hDib); if (wBitCount != 24) hNewDib = ConvertDIBFormat(hDib, 24, NULL); else hNewDib = CopyHandle(hDib); if (! hNewDib) { WaitCursorEnd(); return FALSE; } // new DIB attributes WORD wDIBWidth = (WORD)DIBWidth(hNewDib); WORD wDIBHeight = (WORD)DIBHeight(hNewDib); WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib); DWORD dwImageSize = wBytesPerLine * wDIBHeight; // Allocate and lock memory for filtered image data HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize); if (!hFilteredBits) { WaitCursorEnd(); return FALSE; } LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits); // get bits address in DIB LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); LPBYTE lpDIBits = FindDIBBits(lpDIB); // convolute... for (int i=1; i<wDIBHeight-1; i++) for (int j=1; j<wDIBWidth-1; j++) { int red=0, green=0, blue=0; for (int k=0; k<nKernelNum; ++k) { int r=0, g=0, b=0; DoConvoluteDIB(&r, &g, &b, i, j, wBytesPerLine, lpDIBits, lpKernel+k); if (r > red) red = r; if (g > green) green = g; if (b > blue) blue = b; //red += r; green += g; blue += b; } // original RGB value in center pixel (j, i) LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); BYTE OldB = *(lpDIBits + lOffset++); BYTE OldG = *(lpDIBits + lOffset++); BYTE OldR = *(lpDIBits + lOffset); // When we get here, red, green and blue have the new RGB value. if (Strength != 10) { // Interpolate pixel data red = OldR + (((red - OldR) * Strength) / 10); green = OldG + (((green - OldG) * Strength) / 10); blue = OldB + (((blue - OldB) * Strength) / 10); } lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); *(lpDestImage + lOffset++) = BOUND(blue, 0, 255); *(lpDestImage + lOffset++) = BOUND(green, 0, 255); *(lpDestImage + lOffset) = BOUND(red, 0, 255); } // a filtered image is available in lpDestImage // copy it to DIB bits memcpy(lpDIBits, lpDestImage, dwImageSize); // cleanup temp buffers GlobalUnlock(hFilteredBits); GlobalFree(hFilteredBits); GlobalUnlock(hNewDib); // rebuild hDib HDIB hTmp = NULL; if (wBitCount != 24) hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL); else hTmp = CopyHandle(hNewDib); GlobalFree(hNewDib); DWORD dwSize = GlobalSize(hTmp); memcpy((LPBYTE)GlobalLock(hDib), (LPBYTE)GlobalLock(hTmp), dwSize); GlobalUnlock(hTmp); GlobalFree(hTmp); GlobalUnlock(hDib); WaitCursorEnd(); return TRUE; }
/**************************************************** WALhDIB() 参数: hDIB为输入的DIB句柄 返回值: 成功为TRUE;失败为FALSE 说明: 本函数实现DIB位图的快速沃尔什-哈达玛变换 ****************************************************/ BOOL WALhDIB(HDIB hDIB) { if (hDIB == NULL) return FALSE; // start wait cursor WaitCursorBegin(); HDIB hDib = NULL; HDIB hNewDib = NULL; // we only convolute 24bpp DIB, so first convert DIB to 24bpp WORD wBitCount = DIBBitCount(hDIB); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDIB, 24, NULL); hDib = CopyHandle(hNewDib); } else { hNewDib = CopyHandle(hDIB); hDib = CopyHandle(hDIB); } if (hNewDib == NULL && hDib == NULL) { WaitCursorEnd(); return FALSE; } // process! LPBYTE lpSrcDIB = (LPBYTE)GlobalLock(hDib); LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); LPBYTE lpInput = FindDIBBits(lpSrcDIB); LPBYTE lpOutput = FindDIBBits(lpDIB); int nWidth = DIBWidth(lpSrcDIB); int nHeight = DIBHeight(lpSrcDIB); int w=1,h=1,wp=0,hp=0; while(w*2<=nWidth) { w*=2; wp++; } while(h*2<=nHeight) { h*=2; hp++; } int x,y; BYTE *lpPoints=new BYTE[nWidth*nHeight]; GetPoints(nWidth,nHeight,lpInput,lpPoints); double *f=new double[w*h]; double *W=new double[w*h]; for(y=0;y<h;y++) { for(x=0;x<w;x++) { f[x+y*w]=Point(x,y); } } for(y=0;y<h;y++) { WALh(f+w*y,W+w*y,wp); } for(y=0;y<h;y++) { for(x=0;x<w;x++) { f[x*h+y]=W[x+w*y]; } } for(x=0;x<w;x++) { WALh(f+x*h,W+x*h,hp); } double a; memset(lpPoints,0,nWidth*nHeight); for(y=0;y<h;y++) { for(x=0;x<w;x++) { a=fabs(W[x*h+y]*1000); if (a>255) a=255; Point(x,nHeight-y-1)=(BYTE)a; } } delete f; delete W; PutPoints(nWidth,nHeight,lpOutput,lpPoints); delete lpPoints; // recover DWORD dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDib); GlobalUnlock(hNewDib); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL); lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hNewDib); dwSize = GlobalSize(hNewDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hNewDib); } else { lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hDib); dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hDib); } // cleanup GlobalFree(hDib); GlobalFree(hNewDib); // return WaitCursorEnd(); return TRUE; }
/************************************************************************* * * MedianFilterDIB() * * Parameters: * * HDIB hDib - objective DIB handle * * Return Value: * * BOOL - True is success, else False * * Description: * * This is the media filtering function to DIB * ************************************************************************/ BOOL MedianFilterDIB(HDIB hDib) { WaitCursorBegin(); HDIB hNewDib = NULL; // we only convolute 24bpp DIB, so first convert DIB to 24bpp WORD wBitCount = DIBBitCount(hDib); if (wBitCount != 24) hNewDib = ConvertDIBFormat(hDib, 24, NULL); else hNewDib = CopyHandle(hDib); if (! hNewDib) { WaitCursorEnd(); return FALSE; } // new DIB attributes WORD wDIBWidth = (WORD)DIBWidth(hNewDib); WORD wDIBHeight = (WORD)DIBHeight(hNewDib); WORD wBytesPerLine = (WORD)BytesPerLine(hNewDib); DWORD dwImageSize = wBytesPerLine * wDIBHeight; // Allocate and lock memory for filtered image data HGLOBAL hFilteredBits = GlobalAlloc(GHND, dwImageSize); if (!hFilteredBits) { WaitCursorEnd(); return FALSE; } LPBYTE lpDestImage = (LPBYTE)GlobalLock(hFilteredBits); // get bits address in DIB LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); LPBYTE lpDIBits = FindDIBBits(lpDIB); // convolute... for (int i=1; i<wDIBHeight-1; i++) for (int j=1; j<wDIBWidth-1; j++) { int red=0, green=0, blue=0; DoMedianFilterDIB(&red, &green, &blue, i, j, wBytesPerLine, lpDIBits); LONG lOffset= PIXEL_OFFSET(i,j, wBytesPerLine); *(lpDestImage + lOffset++) = BOUND(blue, 0, 255); *(lpDestImage + lOffset++) = BOUND(green, 0, 255); *(lpDestImage + lOffset) = BOUND(red, 0, 255); } // a filtered image is available in lpDestImage // copy it to DIB bits memcpy(lpDIBits, lpDestImage, dwImageSize); // cleanup temp buffers GlobalUnlock(hFilteredBits); GlobalFree(hFilteredBits); GlobalUnlock(hNewDib); // rebuild hDib HDIB hTmp = NULL; if (wBitCount != 24) hTmp = ConvertDIBFormat(hNewDib, wBitCount, NULL); else hTmp = CopyHandle(hNewDib); GlobalFree(hNewDib); DWORD dwSize = GlobalSize(hTmp); memcpy((LPBYTE)GlobalLock(hDib), (LPBYTE)GlobalLock(hTmp), dwSize); GlobalUnlock(hTmp); GlobalFree(hTmp); GlobalUnlock(hDib); WaitCursorEnd(); return TRUE; }
/**************************************************** FFTDIB() 参数: hDIB为输入的DIB句柄 返回值: 成功为TRUE;失败为FALSE 说明: 本函数实现DIB位图的快速傅立叶变换 ****************************************************/ BOOL FFTDIB(HDIB hDIB) { if (hDIB == NULL) return FALSE; // start wait cursor WaitCursorBegin(); HDIB hDib = NULL; HDIB hNewDib = NULL; // we only convolute 24bpp DIB, so first convert DIB to 24bpp WORD wBitCount = DIBBitCount(hDIB); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDIB, 24, NULL); hDib = CopyHandle(hNewDib); } else { hNewDib = CopyHandle(hDIB); hDib = CopyHandle(hDIB); } if (hNewDib == NULL && hDib == NULL) { WaitCursorEnd(); return FALSE; } // process! LPBYTE lpSrcDIB = (LPBYTE)GlobalLock(hDib); LPBYTE lpDIB = (LPBYTE)GlobalLock(hNewDib); LPBYTE lpInput = FindDIBBits(lpSrcDIB); LPBYTE lpOutput = FindDIBBits(lpDIB); int nWidth = DIBWidth(lpSrcDIB); int nHeight = DIBHeight(lpSrcDIB); int w=1,h=1,wp=0,hp=0; while(w*2<=nWidth) { w*=2; wp++; } while(h*2<=nHeight) { h*=2; hp++; } int x,y; BYTE *lpPoints=new BYTE[nWidth*nHeight]; GetPoints(nWidth,nHeight,lpInput,lpPoints); COMPLEX *TD=new COMPLEX[w*h]; COMPLEX *FD=new COMPLEX[w*h]; for(y=0;y<h;y++) { for(x=0;x<w;x++) { TD[x+w*y].re=Point(x,y); TD[x+w*y].im=0; } } for(y=0;y<h;y++) { FFT(&TD[w*y],&FD[w*y],wp); } for(y=0;y<h;y++) { for(x=0;x<w;x++) { TD[y+h*x]=FD[x+w*y]; // TD[x+w*y]=FD[x*h+y]; } } for(x=0;x<w;x++) { FFT(&TD[x*h],&FD[x*h],hp); } memset(lpPoints,0,nWidth*nHeight); double m; for(y=0;y<h;y++) { for(x=0;x<w;x++) { m=sqrt(FD[x*h+y].re*FD[x*h+y].re+FD[x*h+y].im*FD[x*h+y].im)/100; if (m>255) m=255; Point((x<w/2?x+w/2:x-w/2),nHeight-1-(y<h/2?y+h/2:y-h/2))=(BYTE)(m); } } delete TD; delete FD; PutPoints(nWidth,nHeight,lpOutput,lpPoints); delete lpPoints; // recover DWORD dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDib); GlobalUnlock(hNewDib); if (wBitCount != 24) { hNewDib = ConvertDIBFormat(hDib, wBitCount, NULL); lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hNewDib); dwSize = GlobalSize(hNewDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hNewDib); } else { lpSrcDIB = (LPBYTE)GlobalLock(hDIB); lpDIB = (LPBYTE)GlobalLock(hDib); dwSize = GlobalSize(hDib); memcpy(lpSrcDIB, lpDIB, dwSize); GlobalUnlock(hDIB); GlobalUnlock(hDib); } // cleanup GlobalFree(hDib); GlobalFree(hNewDib); // return WaitCursorEnd(); return TRUE; }