www.pudn.com > Hook-api-mir.rar > dibapi.cpp
// Copyright: www.pudn.com,程序员联合开发网,www.programsalon.com // 如果要使用或修改本程序,请保留次信息 // // dibapi.cpp // // Source file for Device-Independent Bitmap (DIB) API. Provides // the following functions: // // PaintDIB() - Painting routine for a DIB // CreateDIBPalette() - Creates a palette from a DIB // FindDIBBits() - Returns a pointer to the DIB bits // DIBWidth() - Gets the width of the DIB // DIBHeight() - Gets the height of the DIB // PaletteSize() - Gets the size required to store the DIB's palette // DIBNumColors() - Calculates the number of colors // in the DIB's color table // CopyHandle() - Makes a copy of the given global memory block // // This is a part of the Microsoft Foundation Classes C++ library. // Copyright (c) Microsoft Corporation. All rights reserved. // // This source code is only intended as a supplement to the // Microsoft Foundation Classes Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Microsoft Foundation Classes product. #include "stdafx.h" #include "dibapi.h" #include#include #include #include #include #include "util.h" #define DIB_HEADER_MARKER ((WORD) ('M' << 8) | 'B') /************************************************************************* * * PaintDIB() * * Parameters: * * HDC hDC - DC to do output to * * LPRECT lpDCRect - rectangle on DC to do output to * * HDIB hDIB - handle to global memory with a DIB spec * in it followed by the DIB bits * * LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect * * CPalette* pPal - pointer to CPalette containing DIB's palette * * Return Value: * * BOOL - TRUE if DIB was drawn, FALSE otherwise * * Description: * 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. * ************************************************************************/ BOOL WINAPI 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 hPal=NULL; // Our DIB's palette HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (hDIB == NULL) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); lpDIBBits = ::FindDIBBits(lpDIBHdr); // Get the DIB's palette, then select it into DC if (hPal != NULL) { //hPal = (HPALETTE) pPal->m_hObject; // Select as background since we have // already realized in forground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* 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 ::GlobalUnlock((HGLOBAL) hDIB); /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; } /************************************************************************* * * CreateDIBPalette() * * Parameter: * * HDIB hDIB - specifies the DIB * * Return Value: * * HPALETTE - specifies the palette * * Description: * * This function creates a palette from a DIB by allocating memory for the * logical palette, reading and storing the colors from the DIB's color table * into the logical palette, creating a palette from this logical palette, * and then returning the palette's handle. This allows the DIB to be * displayed using the best possible colors (important for DIBs with 256 or * more colors). * ************************************************************************/ /*int g_palette[5][256*4] = { 0,0,0,0,128,0,0,0,0,128,0,0,128,128,0,0,0,0,128,0,128,0,128,0,0,128,128,0,192,192,192,0,192,220,192, 0,212,208,200,0,255,251,240,0,58,110,165,0,128,128,128,0,255,0,0,0,0,255,0,0,255,255,0,0,0, 0,255,0,255,0,255,0,0,255,255,0,255,255,255,0,0,1,0,0,12,0,0,0,72,214,18,0,0,0,37,0,231,2, 150,124 216,7,37,0,112,216,18,0,223,250,149,124 35,251,149,124 196,216,18,0,188,216,18,0,0, 0,0,0,231,2,150,124 184,18,37,0,144,216,18,0,124,214,18,0,0,0,37,0,231,2,150,124 184,18,37,0,164,216,18,0,223,250,149,124 35,251,149,124 224,101,189,119 0,1,0,0,12,0,0,0,52,56,44,52 52,0,53,54 44,52,57,44 52,52,44,52 57,32,53,52 44,53,51,44 52,52,44,52 57,32,53,50,44,53,54,44 52,52,44,53 52,32,53,55 44,51,50,44 52,57,44,53 48,32,53,49 44,52,52,44 52,57,44,52 56,32,53,53 44,52,52,44 53,55,44,52 56,32,52,52 44,53,52,44 53,55,44,51 50,32,53,48 44,52,56,44 53,52,44,52 52,32,52,57 44,53,53,44 53,53,44,52 52,32,52,57 44,53,50,44 53,54,44,52 52,32,53,52 44,53,55,44 51,50,44,52 57,32,53,52 48,215,18,0,52,215,18,0,1,0,0,0,179,2,150,124 248,245,38,0,68,215,18,0,72,215,18,0,1,0,0,0,179,2,150,124 248,245,38,0,40,216,18,0,193,249,149,124 184,18,37,0,221,249,149,124 104,216,18,0,31,110,37,0,46,0,0,0,56,32,52,52 44,53,52,44 53,55,44,51 50,32,52,57 44,53,54,44 52,57,44,52 140,215,18,0,144,215,18,0,1,0,0,0,179,2,150,124 248,245,38,0,160,215,18,0,164,215,18,0,1,0,0,0,179,2,150,124 248,245,38,0,132,216,18,0,193,249,149,124 184,18,37,0,221,249,149,124 196,216,18,0,31,110,37,0,46,0,0,0,24,8,2,0,46,0,0,0,0,0,0,0,7,0,0, 0,240,109,37,0,52,216,18,0,128,246,149,124 0,0,0,0,255,255,255,255 240,109,37,0,76,142,130,124 1,0,0,0,56,0,0,0,0,0,37,0,0,0,37,0,0,0,0,0,24,8,2,0,46,0,0,0,92,246,38,0,64,216,18,0,120,43,150,124 127,43,150,124 92,246,38,0,24,8,2,0,46,0,0,0,255,255,255,255 7,0,0,0,179,33,150,124 144,216,18,0,128,246,149,124 0,0,0,0,255,255,255,255 240,109,37,0,76,142,130,124 1,0,0,0,56,0,0,0,0,0,37,0,0,0,37,0,0,0,0,0,56,0,0,0,8,2,0,0,65,0,0,0,176,215,1,0,180,215,18,0,232,243,18,0,232,243,18,0,128,246,149,124 224,249,149,124 255,255,255,255 221,249,149,124 179,33,150,124 0,0,37,0,0,0,0,0,0,246,38,0,168,216,18,0,195,33,150,124 0,246,38,0,224,101,189,119 204,216,18,0,34,96,130,124 196,216,18,0,12,0,0,0,240,2,252,0,0,0,0,0,0,0,0,0,0,0,0,0,240,2,252,0,12,0,0,0,224,101,189,119 183,20,243,0,224,216,18,0,184,193,243,0,67,58,92,80,114,111,103,114 97,109,32,70,105,108,101,115 92,83,104,97 110,100,97,92 76,101,103,101 110,100,32,111 39,0,0,0,60,186,225,119 0,0,0,0,0,0,0,0,10,0,0,0,0,0,0,0,238,217,18,0,10,0,0,0,238,217,18,0,120,217,18,0,0,0,0,0,255,255,255,255 0,0,0,0,1,0,0,0,160,217,18,0,152,185,225,119 239,217,18,0,0,0,0,0, 160,217,18,0,222,185,225,119 238,217,18,0,238,217,18,0,237,217,18,0,246,221,18,0,63,184,225, 119 0,0,0,0,11,0,136,1 0,0,0,0,1,0,0,0,0,0,0,0,254,255,255,255 60,192,243,0,212,217,18,0,0, 0,0,32 255,255,255,255 50,50,50,0,245,3,0,0,0,0,0,0,0,0,0,0,109,40,0,0,180,217,18,0,232,168, 225,119 228,217,18,0,48,192,243,0,196,217,18,0,1,0,0,0,29,102,189,119 7,102,189,119 160,18, 1,47 11,0,136,1 0,0,0,0,240,2,252,0,88,243,18,0,86,35,243,0,160,18,1,47 11,0,136,1 };*/ HPALETTE WINAPI CreateDIBPalette(HDIB hDIB) { HPALETTE hPal; LPLOGPALETTE lpPal; // pointer to a logical palette HANDLE hLogPal; // handle to a logical palette int i; // loop index WORD wNumColors; // number of colors in color table LPSTR lpbi; // pointer to packed-DIB LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0) LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (old) BOOL bWinStyleDIB; // flag which signifies whether this is a Win3.0,DIB BOOL bResult = FALSE; /* if handle to DIB is invalid, return FALSE */ if (hDIB == NULL) return FALSE; lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); /* get pointer to BITMAPINFO (Win 3.0) */ lpbmi = (LPBITMAPINFO)lpbi; /* get pointer to BITMAPCOREINFO (old 1.x) */ lpbmc = (LPBITMAPCOREINFO)lpbi; /* get the number of colors in the DIB */ wNumColors = ::DIBNumColors(lpbi); if (wNumColors != 0) { /* allocate memory block for logical palette */ hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * wNumColors); /* if not enough memory, clean up and return NULL */ if (hLogPal == 0) { ::GlobalUnlock((HGLOBAL) hDIB); return FALSE; } lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal); /* set version and number of palette entries */ lpPal->palVersion = PALVERSION; lpPal->palNumEntries = (WORD)wNumColors; /* is this a Win 3.0,DIB? */ char temp[4096], temp2[20]; temp[0] =0; bWinStyleDIB = IS_WIN30_DIB(lpbi); WriteLog("palette version:%d, num_entry:%d", lpPal->palVersion, lpPal->palNumEntries); for (i = 0; i < (int)wNumColors; i++) { if (bWinStyleDIB) { lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; lpPal->palPalEntry[i].peFlags = 0; } else { lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; lpPal->palPalEntry[i].peFlags = 0; } wsprintf(temp2, " %d,%d,%d,%d,", lpPal->palPalEntry[i].peRed, lpPal->palPalEntry[i].peGreen, lpPal->palPalEntry[i].peBlue, lpPal->palPalEntry[i].peFlags); } WriteLog(temp); /* create the palette and get handle to it */ hPal = CreatePalette(lpPal); ::GlobalUnlock((HGLOBAL) hLogPal); ::GlobalFree((HGLOBAL) hLogPal); } ::GlobalUnlock((HGLOBAL) hDIB); return hPal; } /************************************************************************* * * FindDIBBits() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * LPSTR - pointer to the DIB bits * * Description: * * This function calculates the address of the DIB's bits and returns a * pointer to the DIB bits. * ************************************************************************/ LPSTR WINAPI FindDIBBits(LPSTR lpbi) { return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi)); } /************************************************************************* * * DIBWidth() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * DWORD - width of the DIB * * Description: * * This function gets the width of the DIB from the BITMAPINFOHEADER * width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER * width field if it is an other-style DIB. * ************************************************************************/ DWORD WINAPI DIBWidth(LPSTR lpDIB) { LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB /* point to the header (whether Win 3.0,and old) */ lpbmi = (LPBITMAPINFOHEADER)lpDIB; lpbmc = (LPBITMAPCOREHEADER)lpDIB; /* return the DIB width if it is a Win 3.0,DIB */ if (IS_WIN30_DIB(lpDIB)) return lpbmi->biWidth; else /* it is an other-style DIB, so return its width */ return (DWORD)lpbmc->bcWidth; } /************************************************************************* * * DIBHeight() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * DWORD - height of the DIB * * Description: * * This function gets the height of the DIB from the BITMAPINFOHEADER * height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER * height field if it is an other-style DIB. * ************************************************************************/ DWORD WINAPI DIBHeight(LPSTR lpDIB) { LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB /* point to the header (whether old or Win 3.0,*/ lpbmi = (LPBITMAPINFOHEADER)lpDIB; lpbmc = (LPBITMAPCOREHEADER)lpDIB; /* return the DIB height if it is a Win 3.0,DIB */ if (IS_WIN30_DIB(lpDIB)) return lpbmi->biHeight; else /* it is an other-style DIB, so return its height */ return (DWORD)lpbmc->bcHeight; } /************************************************************************* * * PaletteSize() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * WORD - size of the color palette of the DIB * * Description: * * This function gets the size required to store the DIB's palette by * multiplying the number of colors by the size of an RGBQUAD (for a * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other- * style DIB). * ************************************************************************/ WORD WINAPI PaletteSize(LPSTR lpbi) { /* calculate the size required by the palette */ if (IS_WIN30_DIB (lpbi)) return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD)); else return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE)); } /************************************************************************* * * DIBNumColors() * * Parameter: * * LPSTR lpbi - pointer to packed-DIB memory block * * Return Value: * * WORD - number of colors in the color table * * Description: * * This function calculates the number of colors in the DIB's color table * by finding the bits per pixel for the DIB (whether Win3.0,or other-style * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256, * if 24, no colors in color table. * ************************************************************************/ WORD WINAPI DIBNumColors(LPSTR lpbi) { WORD wBitCount; // DIB bit count /* If this is a Windows-style DIB, the number of colors in the * color table can be less than the number of bits per pixel * allows for (i.e. lpbi->biClrUsed can be set to some value). * If this is the case, return the appropriate value. */ if (IS_WIN30_DIB(lpbi)) { DWORD dwClrUsed; dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; if (dwClrUsed != 0) return (WORD)dwClrUsed; } /* Calculate the number of colors in the color table based on * the number of bits per pixel for the DIB. */ if (IS_WIN30_DIB(lpbi)) wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; else wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; /* return number of colors based on bits per pixel */ switch (wBitCount) { case 1: return 2; case 4: return 16; case 8: return 256; default: return 0; } } ////////////////////////////////////////////////////////////////////////// //// Clipboard support //--------------------------------------------------------------------- // // Function: CopyHandle (from SDK DibView sample clipbrd.c) // // Purpose: Makes a copy of the given global memory block. Returns // a handle to the new memory block (NULL on error). // // Routine stolen verbatim out of ShowDIB. // // Parms: h == Handle to global memory to duplicate. // // Returns: Handle to new global memory block. // //--------------------------------------------------------------------- HGLOBAL WINAPI CopyHandle (HGLOBAL h) { if (h == NULL) return NULL; DWORD dwLen = (DWORD)::GlobalSize((HGLOBAL) h); HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); if (hCopy != NULL) { void* lpCopy = ::GlobalLock((HGLOBAL) hCopy); void* lp = ::GlobalLock((HGLOBAL) h); memcpy(lpCopy, lp, dwLen); ::GlobalUnlock(hCopy); ::GlobalUnlock(h); } return hCopy; } /************************************************************************* * * SaveDIB() * * Saves the specified DIB into the specified CFile. The CFile * is opened and closed by the caller. * * Parameters: * * HDIB hDib - Handle to the dib to save * * CFile& file - open CFile used to save DIB * * Return value: TRUE if successful, else FALSE or CFileException * *************************************************************************/ /*BOOL WINAPI SaveDIB(HDIB hDib, CFile& file) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure UINT nDIBSize; if (hDib == NULL) return FALSE; lpBI = (LPBITMAPINFOHEADER) ::GlobalLock((HGLOBAL) hDib); if (lpBI == NULL) return FALSE; if (!IS_WIN30_DIB(lpBI)) { ::GlobalUnlock((HGLOBAL) hDib); return FALSE; // It's an other-style DIB (save not supported) } bmfHdr.bfType = DIB_HEADER_MARKER; // "BM" // Calculating the size of the DIB is a bit tricky (if we want to // do it right). The easiest way to do this is to call GlobalSize() // on our global handle, but since the size of our global memory may have // been padded a few bytes, we may end up writing out a few too // many bytes to the file (which may cause problems with some apps). // // So, instead let's calculate the size manually (if we can) // // First, find size of header plus size of color table. Since the // first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains // the size of the structure, let's use this. nDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI); // Partial Calculation // Now calculate the size of the image if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) { // It's an RLE bitmap, we can't calculate size, so trust the // biSizeImage field nDIBSize += lpBI->biSizeImage; } else { DWORD dwBmBitsSize; // Size of Bitmap Bits only // It's not RLE, so size is Width (DWORD aligned) * Height dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight; nDIBSize += dwBmBitsSize; // Now, since we have calculated the correct size, why don't we // fill in the biSizeImage field (this will fix any .BMP files which // have this field incorrect). lpBI->biSizeImage = dwBmBitsSize; } // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER) bmfHdr.bfSize = nDIBSize + sizeof(BITMAPFILEHEADER); bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + PaletteSize((LPSTR)lpBI); TRY { // Write the file header file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // // Write the DIB header and the bits // file.Write(lpBI, nDIBSize); } CATCH (CFileException, e) { ::GlobalUnlock((HGLOBAL) hDib); THROW_LAST(); } END_CATCH ::GlobalUnlock((HGLOBAL) hDib); return TRUE; } */ /************************************************************************* Function: ReadDIBFile (CFile&) Purpose: Reads in the specified DIB file into a global chunk of memory. Returns: A handle to a dib (hDIB) if successful. NULL if an error occurs. Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything from the end of the BITMAPFILEHEADER structure on is returned in the global memory handle. *************************************************************************/ HDIB WINAPI ReadDIBFile(char *fname) { BITMAPFILEHEADER bmfHeader; UINT nBitsSize; HDIB hDIB; LPSTR pDIB; FILE *fp =fopen(fname, "rb"); if(fp ==NULL) return NULL; /* * get length of DIB in bytes for use when reading */ fseek(fp, 0, SEEK_END); nBitsSize = (UINT)ftell(fp); fseek(fp, 0, SEEK_SET); /* * Go read the DIB file header and check if it's valid. */ if (fread((LPSTR)&bmfHeader, 1, sizeof(bmfHeader), fp) != sizeof(bmfHeader)) { fclose(fp); return NULL; } if (bmfHeader.bfType != DIB_HEADER_MARKER) { fclose(fp); return NULL; } /* * Allocate memory for DIB */ hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, (DWORD)nBitsSize); if (hDIB == 0) { fclose(fp); return NULL; } pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); /* * Go read the bits. */ if (fread(pDIB, 1, nBitsSize - sizeof(BITMAPFILEHEADER), fp) != nBitsSize - sizeof(BITMAPFILEHEADER) ) { ::GlobalUnlock((HGLOBAL) hDIB); ::GlobalFree((HGLOBAL) hDIB); fclose(fp); return NULL; } ::GlobalUnlock((HGLOBAL) hDIB); fclose(fp); return hDIB; }