⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dibapi.cpp

📁 用于网络传输时的Jpg和Bmp格式相互转换的API封装
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    // fill in some default values if they are zero 
 
    if (lpbi->biClrUsed == 0) 
        lpbi->biClrUsed = nNumColors; 
 
    if (lpbi->biSizeImage == 0) 
    { 
        lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 
                31) & ~31) >> 3) * lpbi->biHeight; 
    } 
 
    // get a proper-sized buffer for header, color table and bits 
 
    GlobalUnlock(hDIB); 
    hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize + nNumColors * 
            sizeof(RGBQUAD) + lpbi->biSizeImage, 0); 
 
    if (!hDIBtmp) // can't resize buffer for loading 
        goto ErrExitNoUnlock; //MPB 
    else 
        hDIB = hDIBtmp; 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 
 
    // read the color table 
 
    ReadFile (hFile, (LPBYTE)(lpbi) + lpbi->biSize, 
            nNumColors * sizeof(RGBQUAD), &dwRead, NULL); 
 
    // offset to the bits from start of DIB header 
 
    offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD); 
 
    // If the bfOffBits field is non-zero, then the bits might *not* be 
    // directly following the color table in the file.  Use the value in 
    // bfOffBits to seek the bits. 
 
    if (bmfHeader.bfOffBits != 0L) 
        SetFilePointer(hFile, bmfHeader.bfOffBits, NULL, FILE_BEGIN); 
 
    if (ReadFile(hFile, (LPBYTE)lpbi + offBits, lpbi->biSizeImage, &dwRead, 
            NULL)) 
        goto OKExit; 
 
ErrExit: 
    GlobalUnlock(hDIB);     
 
ErrExitNoUnlock:     
    GlobalFree(hDIB); 
    return NULL; 
 
OKExit: 
    GlobalUnlock(hDIB); 
    return hDIB; 
} 

/************************************************************************* 
 * 
 * Function:  WriteDIBFile (HANDLE, int) 
 * 
 *  Purpose:  Writes a global chunk of DIB memory to specified file 
 * 
 *  Returns:  TRUE if success, else FALSE
 * 
 * Comments:  BITMAPFILEHEADER is stripped off of the DIB.  Everything 
 *            from the end of the BITMAPFILEHEADER structure on is 
 *            returned in the global memory handle. 
 * 
 * 
 * NOTE: The DIB API were not written to handle OS/2 DIBs, so this 
 * function will reject any file that is not a Windows DIB. 
 * 
 *************************************************************************/ 
BOOL WriteDIBFile(HDIB hDib, HANDLE fh) 
{ 
    BITMAPFILEHEADER    bmfHdr;     // Header for Bitmap file 
    LPBITMAPINFOHEADER  lpBI;       // Pointer to DIB info structure 
    DWORD               dwDIBSize; 
    DWORD               dwWritten; 

    if (!hDib) 
        return FALSE; 

    // Get a pointer to the DIB memory, the first of which contains 
    // a BITMAPINFO structure 
 
    lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
    if (!lpBI) 
    { 
        CloseHandle(fh); 
        return FALSE; 
    } 
 
    // Check to see if we're dealing with an OS/2 DIB.  If so, don't 
    // save it because our functions aren't written to deal with these 
    // DIBs. 
 
    if (lpBI->biSize != sizeof(BITMAPINFOHEADER)) 
    { 
        GlobalUnlock(hDib); 
        CloseHandle(fh); 
        return FALSE; 
    } 
 
    // Fill in the fields of the file header 
 
    // Fill in file type (first 2 bytes must be "BM" for a bitmap) 
 
    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, 
    // like HC 3.0). 
    // 
    // So, instead let's calculate the size manually. 
    // 
    // To do this, 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. 
 
    // Partial Calculation 
 
    dwDIBSize = *(LPDWORD)lpBI + PaletteSize((LPBYTE)lpBI);   
 
    // Now calculate the size of the image 
 
    // It's an RLE bitmap, we can't calculate size, so trust the biSizeImage 
    // field 
 
    if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4)) 
        dwDIBSize += 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; 
 
        dwDIBSize += 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 = dwDIBSize + sizeof(BITMAPFILEHEADER); 
    bmfHdr.bfReserved1 = 0; 
    bmfHdr.bfReserved2 = 0; 
 
    // Now, calculate the offset the actual bitmap bits will be in 
    // the file -- It's the Bitmap file header plus the DIB header, 
    // plus the size of the color table. 
     
    bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize + 
            PaletteSize((LPBYTE)lpBI); 
 
    // Write the file header 
 
    WriteFile(fh, (LPBYTE)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); 
 
    // Write the DIB header and the bits -- use local version of 
    // MyWrite, so we can write more than 32767 bytes of data 
     
    WriteFile(fh, (LPBYTE)lpBI, dwDIBSize, &dwWritten, NULL); 
 
    GlobalUnlock(hDib); 
 
    if (dwWritten == 0) 
        return FALSE; // oops, something happened in the write 
    else 
        return TRUE; // Success code 
} 
 
/************************************************************************* 
 * 
 * FindDIBBits() 
 * 
 * Parameter: 
 * 
 * LPBYTE lpDIB      - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * LPBYTE            - pointer to the DIB bits 
 * 
 * Description: 
 * 
 * This function calculates the address of the DIB's bits and returns a 
 * pointer to the DIB bits. 
 * 
 ************************************************************************/ 
LPBYTE FindDIBBits(LPBYTE lpDIB) 
{ 
   return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB)); 
} 
 
/************************************************************************* 
 * 
 * DIBWidth() 
 * 
 * Parameter: 
 * 
 * LPBYTE lpDIB      - 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 OS/2-style DIB. 
 * 
 ************************************************************************/ 
DWORD DIBWidth(LPBYTE lpDIB) 
{ 
    LPBITMAPINFOHEADER   lpbmi;  // pointer to a Win 3.0-style DIB 
    LPBITMAPCOREHEADER   lpbmc;  // pointer to an OS/2-style DIB 
 
    // point to the header (whether Win 3.0 and OS/2) 
 
    lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
    lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
    // return the DIB width if it is a Win 3.0 DIB 
 
    if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) 
        return lpbmi->biWidth; 
    else  // it is an OS/2 DIB, so return its width 
        return (DWORD)lpbmc->bcWidth; 
} 
 
DWORD DIBWidth(HDIB hDIB) 
{ 
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
	DWORD dw = DIBWidth(lpDIB);
	GlobalUnlock(hDIB);
	return dw;
} 
 
/************************************************************************* 
 * 
 * DIBHeight() 
 * 
 * Parameter: 
 * 
 * LPBYTE lpDIB      - 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 OS/2-style DIB. 
 * 
 ************************************************************************/ 
DWORD DIBHeight(LPBYTE lpDIB) 
{ 
   LPBITMAPINFOHEADER   lpbmi;  // pointer to a Win 3.0-style DIB 
   LPBITMAPCOREHEADER   lpbmc;  // pointer to an OS/2-style DIB 
 
   // point to the header (whether OS/2 or Win 3.0 
 
   lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
   lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
    // return the DIB height if it is a Win 3.0 DIB 
    if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) 
        return lpbmi->biHeight; 
    else  // it is an OS/2 DIB, so return its height 
        return (DWORD)lpbmc->bcHeight; 
} 
 
DWORD DIBHeight(HDIB hDIB) 
{ 
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
	DWORD dw = DIBHeight(lpDIB);
	GlobalUnlock(hDIB);
	return dw;
} 
 
/************************************************************************* 
 * 
 * PaletteSize() 
 * 
 * Parameter: 
 * 
 * LPBYTE lpDIB      - 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 OS/2- 
 * style DIB). 
 * 
 ************************************************************************/ 
WORD PaletteSize(LPBYTE lpDIB) 
{ 
    // calculate the size required by the palette 
    if (IS_WIN30_DIB (lpDIB)) 
        return (DIBNumColors(lpDIB) * sizeof(RGBQUAD)); 
    else 
        return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE)); 
} 
 
WORD PaletteSize(HDIB hDIB) 
{ 
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
	WORD wSize = PaletteSize(lpDIB);
	GlobalUnlock(hDIB);
	return wSize;
} 
 
/************************************************************************* 
 * 
 * DIBNumColors() 
 * 
 * Parameter: 
 * 
 * LPBYTE lpDIB      - 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 OS/2-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 DIBNumColors(LPBYTE lpDIB) 
{ 
    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(lpDIB)) 
    { 
        DWORD dwClrUsed; 
 
        dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed; 
        if (dwClrUsed) 
 
        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(lpDIB)) 
        wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount; 
    else 
        wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->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; 
    } 
} 

WORD DIBNumColors(HDIB hDIB) 
{ 
	LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);
	WORD wSize = DIBNumColors(lpDIB);
	GlobalUnlock(hDIB);
	return wSize;
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -