//--------------------------------------------------------------------- // // Function: DIBPaint // // Purpose: Painting routine for a DIB. Calls StretchDIBits() or // SetDIBitsToDevice() to paint the DIB. The DIB is // output to the specified DC, at the coordinates given // in lpDCRect. The area of the DIB to be output is // given by lpDIBRect. The specified palette is used. // // Parms: hDC == DC to do output to. // lpDCRect == Rectangle on DC to do output to. // hDIB == Handle to global memory with a DIB spec // in it (either a BITMAPINFO or BITMAPCOREINFO // followed by the DIB bits). // lpDIBRect == Rect of DIB to output into lpDCRect. // hPal == Palette to be used. // // History: Date Reason // 6/01/91 Created // //--------------------------------------------------------------------- static void DIBPaint (HDC hDC,LPRECT lpDCRect,HANDLE hDIB) { LPSTR lpDIBHdr, lpDIBBits; if (!hDIB) return; // Lock down the DIB, and get a pointer to the beginning of the bit // buffer. lpDIBHdr = GlobalLock (hDIB); lpDIBBits = FindDIBBits (lpDIBHdr); // Make sure to use the stretching mode best for color pictures. SetStretchBltMode (hDC, COLORONCOLOR); SetDIBitsToDevice (hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH (lpDCRect), // nDestWidth RECTHEIGHT (lpDCRect), // nDestHeight 0, // SrcX 0, // (int) DIBHeight (lpDIBHdr), // SrcY 0, // nStartScan (WORD) DIBHeight (lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO) lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage GlobalUnlock (hDIB); }
/**************************************************************************** * * 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; }
// load jpeg file BOOL CJpeg::Load(LPCSTR lpstrFileName) { UINT uWidth, uHeight, uWidthDW; // read the jpeg to a packed buffer of RGB bytes BYTE *lpTmpBuffer = ReadJPEGFile(lpstrFileName, &uWidth, &uHeight); if (lpTmpBuffer == NULL) return FALSE; // do this before DWORD-alignment!!! // swap red and blue for display BGRFromRGB(lpTmpBuffer, uWidth, uHeight); // now DWORD-align for display BYTE *lpBuffer = MakeDwordAlign(lpTmpBuffer, uWidth, uHeight, &uWidthDW); FreeBuffer(lpTmpBuffer); // flip for display VertFlipBuf(lpBuffer, uWidthDW, uHeight); BITMAPINFOHEADER bmiHeader; bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = uWidth; bmiHeader.biHeight = uHeight; bmiHeader.biPlanes = 1; bmiHeader.biBitCount = 24; bmiHeader.biCompression = BI_RGB; bmiHeader.biSizeImage = 0; bmiHeader.biXPelsPerMeter = 0; bmiHeader.biYPelsPerMeter = 0; bmiHeader.biClrUsed = 0; bmiHeader.biClrImportant = 0; // Allocate enough memory for the new CF_DIB, and copy bits DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER); DWORD dwBitsSize = WIDTHBYTES(uWidth*24) * uHeight; HDIB hDIB = GlobalAlloc(GHND, dwHeaderSize + dwBitsSize); if (hDIB == NULL) return FALSE; LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB); memcpy(lpDIB, (LPBYTE)&bmiHeader, dwHeaderSize); memcpy(FindDIBBits((LPBYTE)lpDIB), lpBuffer, dwBitsSize); FreeBuffer(lpBuffer); if (m_pDib != NULL) delete m_pDib; m_pDib = new CDib(); m_pDib->Attach(hDIB); return TRUE; }
HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal) { LPSTR lpDIBHdr, lpDIBBits; // pointer to DIB header, pointer to DIB bits HBITMAP hBitmap; // handle to device-dependent bitmap HDC hDC; // handle to DC HPALETTE hOldPal = NULL; // handle to a palette // if invalid handle, return NULL if (!hDIB) return NULL; // lock memory block and get a pointer to it lpDIBHdr = (LPSTR)GlobalLock(hDIB); // get a pointer to the DIB bits lpDIBBits = FindDIBBits(lpDIBHdr); // get a DC hDC = GetDC(NULL); if (!hDC) { // clean up and return NULL GlobalUnlock(hDIB); return NULL; } // select and realize palette if (hPal) hOldPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); // create bitmap from DIB info. and bits hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT, lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS); // restore previous palette if (hOldPal) SelectPalette(hDC, hOldPal, FALSE); // clean up ReleaseDC(NULL, hDC); GlobalUnlock(hDIB); // return handle to the bitmap return hBitmap; }
/**************************************************************************** * * FUNCTION: AdjustIconImagePointers * * PURPOSE: Adjusts internal pointers in icon resource struct * * PARAMS: LPICONIMAGE lpImage - the resource to handle * * RETURNS: BOOL - TRUE for success, FALSE for failure * * History: * July '95 - Created * \****************************************************************************/ BOOL AdjustIconImagePointers( LPICONIMAGE lpImage ) { // Sanity check if( lpImage==NULL ) return FALSE; // BITMAPINFO is at beginning of bits lpImage->lpbi = (LPBITMAPINFO)lpImage->lpBits; // Width - simple enough lpImage->Width = lpImage->lpbi->bmiHeader.biWidth; // Icons are stored in funky format where height is doubled - account for it lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight)/2; // How many colors? lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount; // XOR bits follow the header and color table lpImage->lpXOR = FindDIBBits((LPSTR)lpImage->lpbi); // AND bits follow the XOR bits lpImage->lpAND = lpImage->lpXOR + (lpImage->Height*BytesPerLine((LPBITMAPINFOHEADER)(lpImage->lpbi))); return TRUE; }
// DIBToDDB - Creates a DDB from a DIB // hDIB - Device independent bitmap HBITMAP DIBToDDB( HANDLE hDIB ) { HBITMAP hBitmap; LPBITMAPINFOHEADER lpbi; HPALETTE hPalette = NULL; HPALETTE hOldPal = NULL; HDC hDC; LPSTR lpDIBHdr, lpDIBBits; if ( hDIB == NULL ) return NULL; lpbi = ::GetBitmapInfo( hDIB ); if ( !::InitPalette((LPSTR)lpbi, &hPalette) ) return FALSE; hDC = ::GetDC( NULL ); if ( hPalette ) { // Select and realize the palette hOldPal = ::SelectPalette( hDC, hPalette, FALSE ); ::RealizePalette( hDC ); } lpDIBHdr = (LPSTR)lpbi; lpDIBBits = FindDIBBits(lpDIBHdr); hBitmap = ::CreateDIBitmap (hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT, lpDIBBits, (LPBITMAPINFO) lpbi, DIB_RGB_COLORS); if ( hPalette ) { ::SelectPalette( hDC, hOldPal, FALSE ); ::DeleteObject( hPalette ); } ::ReleaseDC (NULL, hDC ); return hBitmap; }
BOOL CIconExtractor::AdjustIconImagePointers(LPICONIMAGE lpImage) { if (!lpImage) return FALSE; // BITMAPINFO is at beginning of bits lpImage->lpbi = reinterpret_cast<LPBITMAPINFO>(lpImage->lpBits); // Width - simple enough lpImage->Width = lpImage->lpbi->bmiHeader.biWidth; // Icons are stored in funky format where height is doubled - account for it lpImage->Height = (lpImage->lpbi->bmiHeader.biHeight) / 2; // How many colors? lpImage->Colors = lpImage->lpbi->bmiHeader.biPlanes * lpImage->lpbi->bmiHeader.biBitCount; // XOR bits follow the header and color table lpImage->lpXOR = reinterpret_cast<PBYTE>(FindDIBBits(reinterpret_cast<LPSTR>(lpImage->lpbi))); // AND bits follow the XOR bits lpImage->lpAND = lpImage->lpXOR + (lpImage->Height * BytesPerLine(reinterpret_cast<LPBITMAPINFOHEADER>(lpImage->lpbi))); return TRUE; }
DWORD DIBPrint (HDC hPrnDC, HANDLE hDIB, LPRECT lpPrintRect, WORD wUnits, DWORD dwROP, BOOL fBanding, BOOL fUse31APIs) { RECT rect; LPSTR lpDIBHdr, lpBits; // Do some setup (like getting pointers to the DIB and its header, // and a printer DC). Also, set the global gbUseEscapes to force // using printer escapes or the 3.1 printing API. if (!hDIB) return 0; gbUseEscapes = !fUse31APIs; lpDIBHdr = (LPSTR)GlobalLock (hDIB); lpBits = FindDIBBits (lpDIBHdr); if (hPrnDC) { SetStretchBltMode (hPrnDC, COLORONCOLOR); TranslatePrintRect (hPrnDC, lpPrintRect, wUnits, (WORD) DIBWidth (lpDIBHdr), (WORD) DIBHeight (lpDIBHdr)); // Initialize the abort procedure. Then STARTDOC. bAbort = FALSE; if (fBanding) BandDIBToPrinter (hPrnDC, lpDIBHdr, lpBits, lpPrintRect); else { // When not doing banding, call PrintABand() to dump the // entire page to the printer in one shot (i.e. give it // a band that covers the entire printing rectangle, // and tell it to print graphics and text). rect = *lpPrintRect; PrintABand (hPrnDC, lpPrintRect, &rect, TRUE, TRUE, lpDIBHdr, lpBits); // Non-banding devices need the NEWFRAME or EndPage() call. } } // All done, clean up. GlobalUnlock (hDIB); I_UNUSED(dwROP); return 1; }
//******************* 保存为PCX (由CDib对象) *********************** BOOL LanImage::SavePcx(LPCTSTR lpstrFileName, CDib* pDib) { int i = 0; if (pDib == NULL) return FALSE; HDIB hDib = CopyHandle(pDib->GetHandle()); if (hDib == NULL) return FALSE; CDib* pDibTmp = new CDib(); pDibTmp->Attach(hDib); UINT uWidth = pDibTmp->GetWidth(); UINT uHeight = pDibTmp->GetHeight(); // 当打开的图像BitCount不为8时,转为8位格式 if (pDibTmp->GetBitCount() != 8) pDibTmp->ConvertFormat(8); // make PCX header PCXHEAD header; memset((LPBYTE)&header, 0, sizeof(PCXHEAD)); header.manufacturer = 0x0A; header.version = 5; header.encoding = 1; header.bit_per_pixel = 8; //header.bit_per_pixel = 24; header.xmin = 0; header.ymin = 0; header.xmax = uWidth-1; header.ymax = uHeight-1; //header.Xresolution; //header.Yresolution; header.palette[0] = (BYTE)0x00; // for correct process for mono header.palette[1] = (BYTE)0x00; header.palette[2] = (BYTE)0x00; header.palette[3] = (BYTE)0xff; header.palette[4] = (BYTE)0xff; header.palette[5] = (BYTE)0xff; //header.palette[48]; header.reserved = 0; header.color_planes = 1; header.byte_per_line = uWidth; header.palette_type = 1; //filler[58]; // construct PCX palette from DIB color table PCXPALETTE palette[256]; PALETTEENTRY PaletteColors[256]; pDibTmp->GetPalette()->GetPaletteEntries(0, 256, PaletteColors); for (i=0;i<256;i++) { palette[i].rgbRed = PaletteColors[i].peRed; palette[i].rgbGreen = PaletteColors[i].peGreen; palette[i].rgbBlue = PaletteColors[i].peBlue; } // get bits ptr HDIB hDIB = CopyHandle(pDibTmp->GetHandle()); delete pDibTmp; LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB); BYTE* lpBuffer = (BYTE *)FindDIBBits(lpDIB); WORD wWidthBytes = (WORD)BytesPerLine(lpDIB); /*** Open the PCX file ***/ FILE *outFile; if ((outFile=fopen(lpstrFileName,"wb")) == NULL) { GlobalUnlock(hDIB); GlobalFree(hDIB); return FALSE; } /*** Write the header ***/ fwrite((char *)&header, sizeof(PCXHEAD), 1, outFile); /*** Write image data ***/ for ( i=(int)uHeight-1; i>=0; --i) { if (! WritePCXLine(header.byte_per_line, lpBuffer+i*wWidthBytes, outFile)) { fclose(outFile); GlobalUnlock(hDIB); GlobalFree(hDIB); return FALSE; } } /*** Write the palette data ***/ fputc(0x0c, outFile); fwrite((char *)palette, 1, sizeof(palette), outFile); // clear & close fclose(outFile); GlobalUnlock(hDIB); GlobalFree(hDIB); return TRUE; }
/**************************************************************************** * * FUNCTION: ReadBMPFile * * PURPOSE: Reads a BMP file into CF_DIB format * * PARAMS: LPCTSTR szFileName - the name of the file to read * * RETURNS: LPBYTE - pointer to the CF_DIB, NULL for failure * * History: * July '95 - Created * \****************************************************************************/ LPBYTE ReadBMPFile( LPCTSTR szFileName ) { HANDLE hFile; BITMAPFILEHEADER bfh; DWORD dwBytes; LPBYTE lpDIB = NULL, lpTemp = NULL; WORD wPaletteSize = 0; DWORD dwBitsSize = 0; // Open the file if( (hFile=CreateFile( szFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) { MessageBox( NULL, "Error opening file", szFileName, MB_OK ); return NULL; } // Read the header if( ( ! ReadFile( hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytes, NULL ) ) || ( dwBytes != sizeof( BITMAPFILEHEADER ) ) ) { CloseHandle( hFile ); MessageBox( NULL, "Error reading file", szFileName, MB_OK ); return NULL; } // Does it look like a BMP file? if( ( bfh.bfType != 0x4d42 ) || (bfh.bfReserved1!=0) || (bfh.bfReserved2!=0) ) { CloseHandle( hFile ); MessageBox( NULL, "Not a recognised BMP format file", szFileName, MB_OK ); return NULL; } // Allocate some memory if( (lpDIB = malloc( sizeof( BITMAPINFO ) )) == NULL ) { CloseHandle( hFile ); MessageBox( NULL, "Failed to allocate memory for DIB", szFileName, MB_OK ); return NULL; } // Read in the BITMAPINFOHEADER if( (!ReadFile( hFile, lpDIB, sizeof(BITMAPINFOHEADER), &dwBytes, NULL )) || (dwBytes!=sizeof(BITMAPINFOHEADER)) ) { CloseHandle( hFile ); free( lpDIB ); MessageBox( NULL, "Error reading file", szFileName, MB_OK ); return NULL; } if( ((LPBITMAPINFOHEADER)lpDIB)->biSize != sizeof( BITMAPINFOHEADER ) ) { CloseHandle( hFile ); free( lpDIB ); MessageBox( NULL, "OS/2 style BMPs Not Supported", szFileName, MB_OK ); return NULL; } // How big are the elements? wPaletteSize = PaletteSize((LPSTR)lpDIB); dwBitsSize = ((LPBITMAPINFOHEADER)lpDIB)->biHeight * BytesPerLine((LPBITMAPINFOHEADER)lpDIB); // realloc to account for the total size of the DIB if( (lpTemp = realloc( lpDIB, sizeof( BITMAPINFOHEADER ) + wPaletteSize + dwBitsSize )) == NULL ) { CloseHandle( hFile ); MessageBox( NULL, "Failed to allocate memory for DIB", szFileName, MB_OK ); free( lpDIB ); return NULL; } lpDIB = lpTemp; // If there is a color table, read it if( wPaletteSize != 0 ) { if( (!ReadFile( hFile, ((LPBITMAPINFO)lpDIB)->bmiColors, wPaletteSize, &dwBytes, NULL )) || (dwBytes!=wPaletteSize) ) { CloseHandle( hFile ); free( lpDIB ); MessageBox( NULL, "Error reading file", szFileName, MB_OK ); return NULL; } } // Seek to the bits // checking against 0 in case some bogus app didn't set this element if( bfh.bfOffBits != 0 ) { if( SetFilePointer( hFile, bfh.bfOffBits, NULL, FILE_BEGIN ) == 0xffffffff ) { CloseHandle( hFile ); free( lpDIB ); MessageBox( NULL, "Error reading file", szFileName, MB_OK ); return NULL; } } // Read the image bits if( (!ReadFile( hFile, FindDIBBits(lpDIB), dwBitsSize, &dwBytes, NULL )) || (dwBytes!=dwBitsSize) ) { CloseHandle( hFile ); free( lpDIB ); MessageBox( NULL, "Error reading file", szFileName, MB_OK ); return NULL; } // clean up CloseHandle( hFile ); return lpDIB; }
HDIB LoadTIFFinDIB(LPSTR lpFileName) { TIFF *tif; unsigned long imageLength; unsigned long imageWidth; unsigned int BitsPerSample; unsigned long LineSize; unsigned int SamplePerPixel; unsigned long RowsPerStrip; int PhotometricInterpretation; long nrow; unsigned long row; char *buf; LPBITMAPINFOHEADER lpDIB; HDIB hDIB; char *lpBits; HGLOBAL hStrip; int i,l; int Align; tif = TIFFOpen(lpFileName, "r"); if (!tif) goto TiffOpenError; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample); TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation); LineSize = TIFFScanlineSize(tif); //Number of byte in ine line SamplePerPixel = (int) (LineSize/imageWidth); //Align = Number of byte to add at the end of each line of the DIB Align = 4 - (LineSize % 4); if (Align == 4) Align = 0; //Create a new DIB hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD) (BitsPerSample*SamplePerPixel)); lpDIB = (LPBITMAPINFOHEADER) GlobalLock(hDIB); if (!lpDIB) goto OutOfDIBMemory; if (lpDIB) lpBits = FindDIBBits((LPSTR) lpDIB); //In the tiff file the lines are save from up to down //In a DIB the lines must be save from down to up if (lpBits) { lpBits = FindDIBBits((LPSTR) lpDIB); lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1); //now lpBits pointe on the bottom line hStrip = GlobalAlloc(GHND,TIFFStripSize(tif)); buf = GlobalLock(hStrip); if (!buf) goto OutOfBufMemory; //PhotometricInterpretation = 2 image is RGB //PhotometricInterpretation = 3 image have a color palette if (PhotometricInterpretation == 3) { uint16* red; uint16* green; uint16* blue; int16 i; LPBITMAPINFO lpbmi; int Palette16Bits; TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); //Is the palette 16 or 8 bits ? if (checkcmap(1<<BitsPerSample, red, green, blue) == 16) Palette16Bits = TRUE; else Palette16Bits = FALSE; lpbmi = (LPBITMAPINFO)lpDIB; //load the palette in the DIB for (i = (1<<BitsPerSample)-1; i >= 0; i--) { if (Palette16Bits) { lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]); lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]); lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]); } else { lpbmi->bmiColors[i].rgbRed = (BYTE) red[i]; lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i]; lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i]; } } } //read the tiff lines and save them in the DIB //with RGB mode, we have to change the order of the 3 samples RGB <=> BGR for (row = 0; row < imageLength; row += RowsPerStrip) { nrow = (row + RowsPerStrip > imageLength ? imageLength - row : RowsPerStrip); if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf, nrow*LineSize)==-1) { goto TiffReadError; } else { for (l = 0; l < nrow; l++) { if (SamplePerPixel == 3) for (i=0; i< (int) (imageWidth); i++) { lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample PerPixel+2]; lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample PerPixel+1]; lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample PerPixel+0]; } else memcpy(lpBits, &buf[(int) (l*LineSize)], (int) imageWidth*SamplePerPixel); lpBits-=imageWidth*SamplePerPixel+Align; } } } GlobalUnlock(hStrip); GlobalFree(hStrip); GlobalUnlock(hDIB); TIFFClose(tif); }
/**************************************************** 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; }
/**************************************************** 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; }
BOOL FAR PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, HPALETTE hPal) { LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER LPSTR lpDIBBits; // Pointer to DIB bits BOOL bSuccess=FALSE; // Success/fail flag HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (!hDIB) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = GlobalLock(hDIB); lpDIBBits = FindDIBBits(lpDIBHdr); /* Select and realize our palette as background */ if (hPal) { hOldPal = SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); } /* Make sure to use the stretching mode best for color pictures */ SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)DIBHeight(lpDIBHdr) - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)DIBHeight(lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP /* Unlock the memory block */ GlobalUnlock(hDIB); /* Reselect old palette */ if (hOldPal) SelectPalette(hDC, hOldPal, FALSE); /* Return with success/fail flag */ return bSuccess; }
/************************************************************************* * * 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; }
/**************************************************************************** * * FUNCTION: ConvertDIBFormat * * PURPOSE: Creates a new DIB of the requested format, copies the source * image to the new DIB. * * PARAMS: LPBITMAPINFO lpSrcDIB - the source CF_DIB * UINT nWidth - width for new DIB * UINT nHeight - height for new DIB * UINT nbpp - bpp for new DIB * BOOL bStretch - TRUE to stretch source to dest * FALSE to take upper left of image * * RETURNS: LPBYTE - pointer to new CF_DIB memory block with new image * NULL on failure * * History: * July '95 - Created * \****************************************************************************/ LPBYTE ConvertDIBFormat( LPBITMAPINFO lpSrcDIB, UINT nWidth, UINT nHeight, UINT nbpp, BOOL bStretch ) { LPBITMAPINFO lpbmi = NULL; LPBYTE lpSourceBits, lpTargetBits, lpResult; HDC hDC = NULL, hSourceDC, hTargetDC; HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap; DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize; // Allocate and fill out a BITMAPINFO struct for the new DIB // Allow enough room for a 256-entry color table, just in case dwTargetHeaderSize = sizeof( BITMAPINFO ) + ( 256 * sizeof( RGBQUAD ) ); lpbmi = malloc( dwTargetHeaderSize ); lpbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); lpbmi->bmiHeader.biWidth = nWidth; lpbmi->bmiHeader.biHeight = nHeight; lpbmi->bmiHeader.biPlanes = 1; lpbmi->bmiHeader.biBitCount = nbpp; lpbmi->bmiHeader.biCompression = BI_RGB; lpbmi->bmiHeader.biSizeImage = 0; lpbmi->bmiHeader.biXPelsPerMeter = 0; lpbmi->bmiHeader.biYPelsPerMeter = 0; lpbmi->bmiHeader.biClrUsed = 0; lpbmi->bmiHeader.biClrImportant = 0; // Fill in the color table if( ! CopyColorTable( lpbmi, (LPBITMAPINFO)lpSrcDIB ) ) { free( lpbmi ); return NULL; } // Gonna use DIBSections and BitBlt() to do the conversion, so make 'em hDC = GetDC( NULL ); hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS, &lpTargetBits, NULL, 0 ); hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS, &lpSourceBits, NULL, 0 ); hSourceDC = CreateCompatibleDC( hDC ); hTargetDC = CreateCompatibleDC( hDC ); // Flip the bits on the source DIBSection to match the source DIB dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * BytesPerLine(&(lpSrcDIB->bmiHeader)); dwTargetBitsSize = lpbmi->bmiHeader.biHeight * BytesPerLine(&(lpbmi->bmiHeader)); memcpy( lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize ); // Select DIBSections into DCs hOldSourceBitmap = SelectObject( hSourceDC, hSourceBitmap ); hOldTargetBitmap = SelectObject( hTargetDC, hTargetBitmap ); // Set the color tables for the DIBSections if( lpSrcDIB->bmiHeader.biBitCount <= 8 ) SetDIBColorTable( hSourceDC, 0, 1 << lpSrcDIB->bmiHeader.biBitCount, lpSrcDIB->bmiColors ); if( lpbmi->bmiHeader.biBitCount <= 8 ) SetDIBColorTable( hTargetDC, 0, 1 << lpbmi->bmiHeader.biBitCount, lpbmi->bmiColors ); // If we are asking for a straight copy, do it if( (lpSrcDIB->bmiHeader.biWidth==lpbmi->bmiHeader.biWidth) && (lpSrcDIB->bmiHeader.biHeight==lpbmi->bmiHeader.biHeight) ) { BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY ); } else { // else, should we stretch it? if( bStretch ) { SetStretchBltMode( hTargetDC, COLORONCOLOR ); StretchBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight, SRCCOPY ); } else { // or just take the upper left corner of the source BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY ); } } // Clean up and delete the DCs SelectObject( hSourceDC, hOldSourceBitmap ); SelectObject( hSourceDC, hOldTargetBitmap ); DeleteDC( hSourceDC ); DeleteDC( hTargetDC ); ReleaseDC( NULL, hDC ); // Flush the GDI batch, so we can play with the bits GdiFlush(); // Allocate enough memory for the new CF_DIB, and copy bits lpResult = malloc( dwTargetHeaderSize + dwTargetBitsSize ); memcpy( lpResult, lpbmi, dwTargetHeaderSize ); memcpy( FindDIBBits( lpResult ), lpTargetBits, dwTargetBitsSize ); // final cleanup DeleteObject( hTargetBitmap ); DeleteObject( hSourceBitmap ); free( lpbmi ); return lpResult; }
/************************************************************************* * * 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; }