HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap) { DWORD dwLen; HANDLE hDIB; HDC hDC; LPBITMAPINFOHEADER lpbi; HANDLE hTemp; // Figure out the size needed to hold the BITMAPINFO structure // (which includes the BITMAPINFOHEADER and the color table). dwLen = bi.biSize + PaletteSize((LPSTR) &bi); hDIB = GlobalAlloc(GHND,dwLen); // Check that DIB handle is valid if (!hDIB) return NULL; // Set up the BITMAPINFOHEADER in the newly allocated global memory, // then call GetDIBits() with lpBits = NULL to have it fill in the // biSizeImage field for us. lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); *lpbi = bi; hDC = GetDC(NULL); GetDIBits(hDC, hBitmap, 0, (UINT) bi.biHeight, NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); ReleaseDC(NULL, hDC); // If the driver did not fill in the biSizeImage field, // fill it in -- NOTE: this is a bug in the driver! if (lpbi->biSizeImage == 0) lpbi->biSizeImage = WIDTHBYTES((DWORD)lpbi->biWidth * lpbi->biBitCount) * lpbi->biHeight; // Get the size of the memory block we need dwLen = lpbi->biSize + PaletteSize((LPSTR) &bi) + lpbi->biSizeImage; // Unlock the memory block GlobalUnlock(hDIB); // ReAlloc the buffer big enough to hold all the bits if (hTemp = GlobalReAlloc(hDIB,dwLen,0)) return hTemp; else { // Else free memory block and return failure GlobalFree(hDIB); return NULL; } }
/******************************************************************************************** > void BitmapExportPaletteControl::Render(ReDrawInfoType *pInfo) Author: Jonathan_Payne (Xara Group Ltd) <*****@*****.**> Created: 19/12/2000 Returns: Draw the palette. This assumes that the pInfo struct contains a DC to draw with. ********************************************************************************************/ void BitmapExportPaletteControl::Render(ReDrawInfoType *pInfo) { DocRect PaletteSize(0, 0, pInfo->dx, pInfo->dy); // Create a RenderRegion so that we can draw the control RenderRegion *pRender = CreateOSRenderRegion(&PaletteSize, pInfo); if (pRender == 0) return; // Could not create a RenderRegion // Decide if we are going to render the palette if (!m_Palette.GetNumberOfColours()) { // We are not rendering a palette so just draw a grey box RenderGrey(&PaletteSize, pRender); } else { // Check the selection and mouse over colour are valid if (m_SelectedCell > m_Palette.GetNumberOfColours()) m_SelectedCell = INVALID_COLOUR_VALUE; if (m_MouseOverCell > m_Palette.GetNumberOfColours()) m_MouseOverCell = INVALID_COLOUR_VALUE; // We are rendering a full palette RenderPalette(&PaletteSize, pRender, pInfo->dy, pInfo->pClipRect); } DestroyOSRenderRegion(pRender); }
BOOL CDib::ReadMemory(LPVOID MemorInfo,DWORD Length) { ASSERT(MemorInfo!=NULL); ASSERT(Length!=0L); m_dwLength=Length; try { if(!AllocateMemory()) { return FALSE; } memcpy(m_lpBuf,MemorInfo,m_dwLength); } catch(...) { AfxMessageBox("Memory Error"); return FALSE; } if(m_lpBMFH->bfType!=0x4d42) { return FALSE; } ASSERT((m_lpBMIH->biBitCount==1)||(m_lpBMIH->biBitCount==4)|| (m_lpBMIH->biBitCount==8)||(m_lpBMIH->biBitCount==24)); if(m_lpBMFH->bfOffBits>sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ PaletteSize(m_lpBMI)) return FALSE; m_lpData=(LPBYTE)m_lpBMFH+m_lpBMFH->bfOffBits; m_nBits=m_lpBMIH->biBitCount; return TRUE; }
/**************************************************************************** * * 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; }
/**************************************************************************** * * FUNCTION: CreateBlankNewFormatIcon * * PURPOSE: Creates a blank icon image for a new format * * PARAMS: LPICONIMAGE lpii - pointer to icon image data * * RETURNS: BOOL - TRUE for success, FALSE for failure * * History: * July '95 - Created * \****************************************************************************/ BOOL CreateBlankNewFormatIcon( LPICONIMAGE lpii ) { DWORD dwFinalSize; BITMAPINFOHEADER bmih; // Fill in the bitmap header ZeroMemory( &bmih, sizeof( BITMAPINFOHEADER ) ); bmih.biSize = sizeof( BITMAPINFOHEADER ); bmih.biBitCount = lpii->Colors; bmih.biClrUsed = 0; // How big will the final thing be? // Well, it'll have a header dwFinalSize = sizeof( BITMAPINFOHEADER ); // and a color table (even if it's zero length) dwFinalSize += PaletteSize( (LPSTR)&bmih ); // and XOR bits dwFinalSize += lpii->Height * WIDTHBYTES( lpii->Width * lpii->Colors ); // and AND bits. That's about it :) dwFinalSize += lpii->Height * WIDTHBYTES( lpii->Width ); // Allocate some memory for it lpii->lpBits = malloc( dwFinalSize ); ZeroMemory( lpii->lpBits, dwFinalSize ); lpii->dwNumBytes = dwFinalSize; lpii->lpbi = (LPBITMAPINFO)(lpii->lpBits); lpii->lpXOR = (LPSTR)(lpii->lpbi) + sizeof(BITMAPINFOHEADER) + PaletteSize( (LPSTR)&bmih ); lpii->lpAND = lpii->lpXOR + (lpii->Height * WIDTHBYTES( lpii->Width * lpii->Colors )); // The bitmap header is zeros, fill it out lpii->lpbi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); lpii->lpbi->bmiHeader.biWidth = lpii->Width; // Don't forget the funky height*2 icon resource thing lpii->lpbi->bmiHeader.biHeight = lpii->Height * 2; lpii->lpbi->bmiHeader.biPlanes = 1; lpii->lpbi->bmiHeader.biBitCount = lpii->Colors; lpii->lpbi->bmiHeader.biCompression = BI_RGB; return TRUE; }
BOOL CImage::SaveBMP(LPCTSTR lpszFileName) { ///* CFile file; CFileException fe; BITMAPFILEHEADER bmfHdr; LPBITMAPINFOHEADER lpBI; DWORD dwDIBSize; if (!file.Open(lpszFileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite, &fe)) return FALSE; if (m_hImage == NULL) return FALSE; lpBI = (LPBITMAPINFOHEADER)::GlobalLock((HGLOBAL)m_hImage); if (lpBI == NULL) return FALSE; bmfHdr.bfType = DIB_HEADER_MARKER; // "BM" dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI); if((lpBI->biCompression==BI_RLE8) || (lpBI->biCompression==BI_RLE4)) dwDIBSize += lpBI->biSizeImage; else { DWORD dwBmBitsSize; // Size of Bitmap Bits only dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight; dwDIBSize += dwBmBitsSize; lpBI->biSizeImage = dwBmBitsSize; } bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER); bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+lpBI->biSize + PaletteSize((LPSTR)lpBI); TRY { file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); //file.WriteHuge(lpBI, dwDIBSize); file.Write(lpBI, dwDIBSize); } CATCH (CFileException, e) { ::GlobalUnlock((HGLOBAL) m_hImage); THROW_LAST(); }
void C256bmp::OnPaint() { CPaintDC dc(this); /* device context for painting */ BITMAPINFO *pb=GetBitmap(); if (pb) { BITMAPINFOHEADER *pbh=( BITMAPINFOHEADER*)pb; HPALETTE hpal=CreateBIPalette (pbh); LPSTR pbits = (LPSTR)pbh + (WORD)pbh->biSize + PaletteSize(pbh); HPALETTE holdpal=::SelectPalette(dc.m_hDC,hpal,FALSE); if (!hSystemPalette) hSystemPalette=holdpal; ::RealizePalette(dc.m_hDC); ::SetDIBitsToDevice(dc.m_hDC,0,0,pbh->biWidth,pbh->biHeight,0,0,0,pbh->biHeight,pbits,pb,DIB_RGB_COLORS); ::SelectPalette(dc.m_hDC,holdpal,FALSE); ::DeleteObject(hpal); } ValidateRect(0); }
BOOL WriteDIB ( LPSTR szFile, HANDLE hdib) { BITMAPFILEHEADER hdr; LPBITMAPINFOHEADER lpbi; HFILE fh; OFSTRUCT of; if (!hdib) return FALSE; fh = OpenFile(szFile, &of, (UINT)OF_CREATE|OF_READWRITE); if (fh == -1) return FALSE; lpbi = (VOID FAR *)GlobalLock (hdib); /* Fill in the fields of the file header */ hdr.bfType = BFT_BITMAP; hdr.bfSize = GlobalSize (hdib) + SIZEOF_BITMAPFILEHEADER_PACKED; hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; hdr.bfOffBits = (DWORD) (SIZEOF_BITMAPFILEHEADER_PACKED + lpbi->biSize + PaletteSize(lpbi)); /* Write the file header */ /* write bfType*/ _lwrite(fh, (LPSTR)&hdr.bfType, (UINT)sizeof (WORD)); /* now pass over extra word, and only write next 3 DWORDS!*/ _lwrite(fh, (LPSTR)&hdr.bfSize, sizeof(DWORD) * 3); /* this struct already DWORD aligned!*/ /* Write the DIB header and the bits */ _lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib)); GlobalUnlock (hdib); _lclose(fh); return TRUE; }
/**************************************************************************** * * FUNCTION: WriteBMPFile * * PURPOSE: Writes a BMP file from CF_DIB format * * PARAMS: LPCTSTR szFileName - the name of the file to read * LPBYTE - pointer to the CF_DIB, NULL for failure * * RETURNS: BOOL - TRUE for success, FALSE for Failure * * History: * July '95 - Created * \****************************************************************************/ BOOL WriteBMPFile( LPCTSTR szFileName, LPBYTE lpDIB ) { HANDLE hFile; BITMAPFILEHEADER bfh; DWORD dwBytes, dwBytesToWrite; LPBITMAPINFOHEADER lpbmih; // Open the file if( (hFile=CreateFile( szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) { MessageBox( NULL, "Error opening file", szFileName, MB_OK ); return FALSE; } bfh.bfType = 0x4d42; bfh.bfReserved1 = 0; bfh.bfReserved2 = 0; bfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) + PaletteSize( lpDIB ); bfh.bfSize = (bfh.bfOffBits + ((LPBITMAPINFOHEADER)lpDIB)->biHeight * BytesPerLine((LPBITMAPINFOHEADER)lpDIB))/4; // Write the header if( ( ! WriteFile( hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytes, NULL ) ) || ( dwBytes != sizeof( BITMAPFILEHEADER ) ) ) { CloseHandle( hFile ); MessageBox( NULL, "Error Writing file", szFileName, MB_OK ); return FALSE; } lpbmih = (LPBITMAPINFOHEADER)lpDIB; lpbmih->biHeight /= 2; dwBytesToWrite = bfh.bfOffBits + (lpbmih->biHeight * BytesPerLine(lpbmih)); if( ( ! WriteFile( hFile, lpDIB, dwBytesToWrite, &dwBytes, NULL ) ) || ( dwBytes != dwBytesToWrite ) ) { CloseHandle( hFile ); MessageBox( NULL, "Error Writing file", szFileName, MB_OK ); return FALSE; } lpbmih->biHeight *= 2; CloseHandle( hFile ); return TRUE; }
void CDib::CreatFromHandle(HDIB hDib) { ASSERT (hDib!=NULL); DWORD dwSizeDib=GlobalSize(hDib); void* lpDib = ::GlobalLock(hDib); m_dwLength=dwSizeDib+sizeof(BITMAPFILEHEADER); DWORD dwLenHead=sizeof(BITMAPFILEHEADER); DWORD dwLen = m_dwLength-dwLenHead; if(!AllocateMemory()) return; memcpy((LPBYTE)m_lpBMIH,lpDib,dwLen); int nPaletteSize=PaletteSize(m_lpBMI); m_lpBMFH->bfType=0x4d42;//"BM" m_lpBMFH->bfSize=m_dwLength; m_lpBMFH->bfReserved1=0; m_lpBMFH->bfReserved2=0; m_lpBMFH->bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ nPaletteSize; ::GlobalUnlock(hDib); }
LPSTR FindDIBBits(LPSTR lpDIB) { return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB)); }
HDIB ChangeBitmapFormat(HBITMAP hBitmap, WORD wBitCount, DWORD dwCompression, HPALETTE hPal) { HDC hDC; // Screen DC HDIB hNewDIB=NULL; // Handle to new DIB BITMAP Bitmap; // BITMAP data structure BITMAPINFOHEADER bi; // Bitmap info. header LPBITMAPINFOHEADER lpbi; // Pointer to bitmap header HPALETTE hOldPal=NULL; // Handle to palette WORD NewBPP; // New bits per pixel DWORD NewComp; // New compression format // Check for a valid bitmap handle if (!hBitmap) return NULL; // Validate wBitCount and dwCompression // They must match correctly (i.e., BI_RLE4 and 4 BPP or // BI_RLE8 and 8BPP, etc.) or we return failure if (wBitCount == 0) { NewComp = dwCompression; if (NewComp == BI_RLE4) NewBPP = 4; else if (NewComp == BI_RLE8) NewBPP = 8; else // Not enough info */ return NULL; } else if (wBitCount == 1 && dwCompression == BI_RGB) { NewBPP = wBitCount; NewComp = BI_RGB; } else if (wBitCount == 4) { NewBPP = wBitCount; if (dwCompression == BI_RGB || dwCompression == BI_RLE4) NewComp = dwCompression; else return NULL; } else if (wBitCount == 8) { NewBPP = wBitCount; if (dwCompression == BI_RGB || dwCompression == BI_RLE8) NewComp = dwCompression; else return NULL; } else if (wBitCount == 24 && dwCompression == BI_RGB) { NewBPP = wBitCount; NewComp = BI_RGB; } else return NULL; // Get info about the bitmap GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); // Fill in the BITMAPINFOHEADER appropriately bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = NewBPP; bi.biCompression = NewComp; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // Go allocate room for the new DIB hNewDIB = AllocRoomForDIB(bi, hBitmap); if (!hNewDIB) return NULL; // Get a pointer to the new DIB lpbi = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB); // If we have a palette, get a DC and select/realize it if (hPal) { hDC = GetDC(NULL); hOldPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); } // Call GetDIBits and get the new DIB bits if (!GetDIBits(hDC, hBitmap, 0, (UINT) lpbi->biHeight, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi, DIB_RGB_COLORS)) { GlobalUnlock(hNewDIB); GlobalFree(hNewDIB); hNewDIB = NULL; } // Clean up and return if (hOldPal) { SelectPalette(hDC, hOldPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); } // Unlock the new DIB's memory block if (hNewDIB) GlobalUnlock(hNewDIB); return hNewDIB; }
WORD SaveDIB(HDIB hDib, const char* lpFileName) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure HANDLE fh; // file handle for opened file DWORD dwDIBSize; DWORD dwWritten; if (!hDib) return ERR_INVALIDHANDLE; fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (fh == INVALID_HANDLE_VALUE) return ERR_OPEN; // Get a pointer to the DIB memory, the first of which contains // a BITMAPINFO structure lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib); if (!lpBI) { CloseHandle(fh); return ERR_LOCK; } // 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 ERR_NOT_DIB; } // 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((LPSTR)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((LPSTR)lpBI); // Write the file header WriteFile(fh, (LPSTR)&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, (LPSTR)lpBI, dwDIBSize, &dwWritten, NULL); GlobalUnlock(hDib); CloseHandle(fh); if (dwWritten == 0) return ERR_OPEN; // oops, something happened in the write else return 0; // Success code }
BOOL WINAPI SaveDIB(HDIB hDib, CFile& file) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure DWORD dwDIBSize; if (hDib == NULL) return FALSE; /* * Get a pointer to the DIB memory, the first of which contains * a BITMAPINFO structure */ 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) } /* * 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). // // 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. dwDIBSize = *(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 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((LPSTR)lpBI); TRY { // Write the file header file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); // // Write the DIB header and the bits // file.Write(lpBI, dwDIBSize); } CATCH (CFileException, e) { ::GlobalUnlock((HGLOBAL) hDib); THROW_LAST(); }
LPSTR CIconExtractor::FindDIBBits(LPSTR lpbi) { return (lpbi + *reinterpret_cast<LPDWORD>(lpbi) + PaletteSize(lpbi)); }
/**************************************************************************** * * 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; }
WORD FAR SaveDIB(HDIB hDib, LPSTR lpFileName) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure int fh; // file handle for opened file OFSTRUCT of; // OpenFile structure DWORD dwDIBSize; DWORD dwError; // Error return from MyWrite if (!hDib) return ERR_INVALIDHANDLE; fh = OpenFile(lpFileName, &of, OF_CREATE | OF_READWRITE); if (fh == -1) return ERR_OPEN; /* * Get a pointer to the DIB memory, the first of which contains * a BITMAPINFO structure */ lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib); if (!lpBI) return ERR_LOCK; // 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); return ERR_NOT_DIB; } /* * 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. dwDIBSize = *(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 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((LPSTR)lpBI); /* Write the file header */ _lwrite(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER)); /* * Write the DIB header and the bits -- use local version of * MyWrite, so we can write more than 32767 bytes of data */ dwError = MyWrite(fh, (LPSTR)lpBI, dwDIBSize); GlobalUnlock(hDib); _lclose(fh); if (dwError == 0) return ERR_OPEN; // oops, something happened in the write else return 0; // Success code }
//--------------------------------------------------------------------- // // Function: FindDIBBits // // Purpose: Given a pointer to a DIB, returns a pointer to the // DIB's bitmap bits. // // Parms: lpbi == pointer to DIB header (either BITMAPINFOHEADER // or BITMAPCOREHEADER) // // History: Date Reason // 6/01/91 Created // //--------------------------------------------------------------------- static LPSTR FindDIBBits (LPSTR lpbi) { return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi)); }
LPSTR CIconExtractor::FindDIBBits(LPSTR lpbi) { return (lpbi + *(LPDWORD)lpbi + PaletteSize(lpbi)); }
HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal) { BITMAP bm; // bitmap structure BITMAPINFOHEADER bi; // bitmap header LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER DWORD dwLen; // size of memory block HANDLE hDIB, h; // handle to DIB, temp handle HDC hDC; // handle to DC WORD biBits; // bits per pixel // check if bitmap handle is valid if (!hBitmap) return NULL; // fill in BITMAP structure, return NULL if it didn't work if (!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm)) return NULL; // if no palette is specified, use default palette if (hPal == NULL) hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE); // calculate bits per pixel biBits = bm.bmPlanes * bm.bmBitsPixel; // make sure bits per pixel is valid if (biBits <= 1) biBits = 1; else if (biBits <= 4) biBits = 4; else if (biBits <= 8) biBits = 8; else if (biBits <= 24) biBits = 24; else biBits = 32; // initialize BITMAPINFOHEADER bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = biBits; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // calculate size of memory block required to store BITMAPINFO dwLen = bi.biSize + PaletteSize((LPSTR)&bi); // get a DC hDC = GetDC(NULL); // select and realize our palette hPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); // alloc memory block to store our bitmap hDIB = GlobalAlloc(GHND, dwLen); // if we couldn't get memory block if (!hDIB) { // clean up and return NULL SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); return NULL; } // lock memory and get pointer to it lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); /// use our bitmap info. to fill BITMAPINFOHEADER *lpbi = bi; // call GetDIBits with a NULL lpBits param, so it will calculate the // biSizeImage field for us GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi, DIB_RGB_COLORS); // get the info. returned by GetDIBits and unlock memory block bi = *lpbi; GlobalUnlock(hDIB); // if the driver did not fill in the biSizeImage field, make one up if (bi.biSizeImage == 0) bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight; // realloc the buffer big enough to hold all the bits dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + bi.biSizeImage; if (h = GlobalReAlloc(hDIB, dwLen, 0)) hDIB = h; else { // clean up and return NULL GlobalFree(hDIB); hDIB = NULL; SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); return NULL; } // lock memory block and get pointer to it */ lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); // call GetDIBits with a NON-NULL lpBits param, and actualy get the // bits this time if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0) { // clean up and return NULL GlobalUnlock(hDIB); hDIB = NULL; SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); return NULL; } bi = *lpbi; // clean up GlobalUnlock(hDIB); SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); // return handle to the DIB return hDIB; }
HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) { BITMAPINFOHEADER bi; // bitmap header LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER DWORD dwLen; // size of memory block HDIB hDIB; DWORD dwBytesPerLine; // Number of bytes per scanline // Make sure bits per pixel is valid if (wBitCount <= 1) wBitCount = 1; else if (wBitCount <= 4) wBitCount = 4; else if (wBitCount <= 8) wBitCount = 8; else if (wBitCount <= 24) wBitCount = 24; else wBitCount = 4; // set default value to 4 if parameter is bogus // initialize BITMAPINFOHEADER bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = dwWidth; // fill in width from parameter bi.biHeight = dwHeight; // fill in height from parameter bi.biPlanes = 1; // must be 1 bi.biBitCount = wBitCount; // from parameter bi.biCompression = BI_RGB; bi.biSizeImage = 0; // 0's here mean "default" bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // calculate size of memory block required to store the DIB. This // block should be big enough to hold the BITMAPINFOHEADER, the color // table, and the bits dwBytesPerLine = WIDTHBYTES(wBitCount * dwWidth); dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight); // alloc memory block to store our bitmap hDIB = GlobalAlloc(GHND, dwLen); // major bummer if we couldn't get memory block if (!hDIB) return NULL; // lock memory and get pointer to it lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); // use our bitmap info structure to fill in first part of // our DIB with the BITMAPINFOHEADER *lpbi = bi; // Since we don't know what the colortable and bits should contain, // just leave these blank. Unlock the DIB and return the HDIB. GlobalUnlock(hDIB); //return handle to the DIB return hDIB; }
HANDLE DibFromBitmap ( HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal) { BITMAP bm; BITMAPINFOHEADER bi; BITMAPINFOHEADER FAR *lpbi; DWORD dwLen; HANDLE hdib; HANDLE h; HDC hdc; if (!hbm) return NULL; if (hpal == NULL) hpal = GetStockObject(DEFAULT_PALETTE); GetObject(hbm,sizeof(bm),(LPSTR)&bm); if (biBits == 0) biBits = bm.bmPlanes * bm.bmBitsPixel; if (biBits == 16) biBits = 24; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = biBits; bi.biCompression = biStyle; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; dwLen = bi.biSize + PaletteSize(&bi); hdc = GetDC(NULL); hpal = SelectPalette(hdc,hpal,FALSE); RealizePalette(hdc); hdib = GlobalAlloc(GHND,dwLen); if (!hdib){ SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return NULL; } lpbi = (VOID FAR *)GlobalLock(hdib); *lpbi = bi; /* call GetDIBits with a NULL lpBits param, so it will calculate the * biSizeImage field for us */ GetDIBits(hdc, hbm, 0L, (DWORD)bi.biHeight, (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; GlobalUnlock(hdib); /* If the driver did not fill in the biSizeImage field, make one up */ if (bi.biSizeImage == 0){ bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight; if (biStyle != BI_RGB) bi.biSizeImage = (bi.biSizeImage * 3) / 2; } /* realloc the buffer big enough to hold all the bits */ dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage; if (h = GlobalReAlloc(hdib,dwLen,0)) hdib = h; else{ GlobalFree(hdib); hdib = NULL; SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return hdib; } /* call GetDIBits with a NON-NULL lpBits param, and actualy get the * bits this time */ lpbi = (VOID FAR *)GlobalLock(hdib); if (GetDIBits( hdc, hbm, 0L, (DWORD)bi.biHeight, (LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS) == 0){ GlobalUnlock(hdib); hdib = NULL; SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return NULL; } bi = *lpbi; GlobalUnlock(hdib); SelectPalette(hdc,hpal,FALSE); ReleaseDC(NULL,hdc); return hdib; }
HDIB ChangeDIBFormat(HDIB hDIB, WORD wBitCount, DWORD dwCompression) { HDC hDC; // Handle to DC HBITMAP hBitmap; // Handle to bitmap BITMAP Bitmap; // BITMAP data structure BITMAPINFOHEADER bi; // Bitmap info header LPBITMAPINFOHEADER lpbi; // Pointer to bitmap info HDIB hNewDIB = NULL; // Handle to new DIB HPALETTE hPal, hOldPal; // Handle to palette, prev pal WORD DIBBPP, NewBPP; // DIB bits per pixel, new bpp DWORD DIBComp, NewComp;// DIB compression, new compression // Check for a valid DIB handle if (!hDIB) return NULL; // Get the old DIB's bits per pixel and compression format lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); DIBBPP = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; DIBComp = ((LPBITMAPINFOHEADER)lpbi)->biCompression; GlobalUnlock(hDIB); // Validate wBitCount and dwCompression // They must match correctly (i.e., BI_RLE4 and 4 BPP or // BI_RLE8 and 8BPP, etc.) or we return failure if (wBitCount == 0) { NewBPP = DIBBPP; if ((dwCompression == BI_RLE4 && NewBPP == 4) || (dwCompression == BI_RLE8 && NewBPP == 8) || (dwCompression == BI_RGB)) NewComp = dwCompression; else return NULL; } else if (wBitCount == 1 && dwCompression == BI_RGB) { NewBPP = wBitCount; NewComp = BI_RGB; } else if (wBitCount == 4) { NewBPP = wBitCount; if (dwCompression == BI_RGB || dwCompression == BI_RLE4) NewComp = dwCompression; else return NULL; } else if (wBitCount == 8) { NewBPP = wBitCount; if (dwCompression == BI_RGB || dwCompression == BI_RLE8) NewComp = dwCompression; else return NULL; } else if (wBitCount == 24 && dwCompression == BI_RGB) { NewBPP = wBitCount; NewComp = BI_RGB; } else return NULL; // Save the old DIB's palette hPal = CreateDIBPalette(hDIB); if (!hPal) return NULL; // Convert old DIB to a bitmap hBitmap = DIBToBitmap(hDIB, hPal); if (!hBitmap) { DeleteObject(hPal); return NULL; } // Get info about the bitmap GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); // Fill in the BITMAPINFOHEADER appropriately bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = Bitmap.bmWidth; bi.biHeight = Bitmap.bmHeight; bi.biPlanes = 1; bi.biBitCount = NewBPP; bi.biCompression = NewComp; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // Go allocate room for the new DIB hNewDIB = AllocRoomForDIB(bi, hBitmap); if (!hNewDIB) return NULL; // Get a pointer to the new DIB lpbi = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB); // Get a DC and select/realize our palette in it hDC = GetDC(NULL); hOldPal = SelectPalette(hDC, hPal, FALSE); RealizePalette(hDC); // Call GetDIBits and get the new DIB bits if (!GetDIBits(hDC, hBitmap, 0, (UINT) lpbi->biHeight, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi, DIB_RGB_COLORS)) { GlobalUnlock(hNewDIB); GlobalFree(hNewDIB); hNewDIB = NULL; } // Clean up and return SelectPalette(hDC, hOldPal, TRUE); RealizePalette(hDC); ReleaseDC(NULL, hDC); // Unlock the new DIB's memory block if (hNewDIB) GlobalUnlock(hNewDIB); DeleteObject(hBitmap); DeleteObject(hPal); return hNewDIB; }
WORD FAR CJpegFile::SaveDIB(HDIB hDib, LPSTR lpFileName) { BITMAPFILEHEADER bmfHdr; // Header for Bitmap file LPBITMAPINFOHEADER lpBI; // Pointer to DIB info structure HANDLE fh; // file handle for opened file DWORD dwDIBSize; // DWORD dwError; // Error return from MyWrite DWORD nWritten; if (!hDib) return ERR_INVALIDHANDLE; fh = CreateFile(lpFileName, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (fh == INVALID_HANDLE_VALUE) return ERR_OPEN; /* * Get a pointer to the DIB memory, the first of which contains * a BITMAPINFO structure */ lpBI = (LPBITMAPINFOHEADER)GlobalLock(hDib); if (!lpBI) return ERR_LOCK; // 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); return ERR_NOT_DIB; } /* * 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. dwDIBSize = *(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 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((LPSTR)lpBI); // Encrypt Data BYTE *encrypt_data; DWORD encrypt_len, i, j; BYTE random_byte[4]; // Generate Random Byte. srand((unsigned)time( NULL )); for(i = 0; i < 4; i++) random_byte[i] = rand() % 0x100; encrypt_len = sizeof(BITMAPFILEHEADER)+dwDIBSize+4; encrypt_data = new BYTE[encrypt_len]; for(i = 0, j = 0; i < 4; i++, j++) { encrypt_data[j] = Encrypt(random_byte[i]); } for(i = 0; i < sizeof(BITMAPFILEHEADER); i++, j++) { encrypt_data[j] = Encrypt(*((BYTE *)(&bmfHdr)+i)); } for(i = 0; i < dwDIBSize; i++, j++) { encrypt_data[j] = Encrypt(*((BYTE *)lpBI + i)); } __ASSERT(j == encrypt_len, "Size Different"); WriteFile(fh, (LPCVOID)encrypt_data, encrypt_len, &nWritten, NULL); /* Write the file header */ // WriteFile(fh, (LPCVOID)&bmfHdr, sizeof(BITMAPFILEHEADER), &nWritten, NULL); /* * Write the DIB header and the bits -- use local version of * MyWrite, so we can write more than 32767 bytes of data */ // dwError = MyWrite(fh, (LPSTR)lpBI, dwDIBSize); // WriteFile(fh, (LPCVOID)lpBI, dwDIBSize, &nWritten, NULL); GlobalUnlock(hDib); CloseHandle(fh); delete[] encrypt_data; return 0; // if (dwError == 0) // return ERR_OPEN; // oops, something happened in the write // else // return 0; // Success code }