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

📄 dib.cpp

📁 虚拟打印机
💻 CPP
字号:
/* * * dib.cpp * *    Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com * */#include "dib.h"#include "mathutils.h"#include "utils.h"DWORD CalculateDWORDAligned(IN DWORD dw) ;DWORD CalculateBytesPerLine(IN DWORD dwPixelsPerLine) ;// *************************************************************************************************// **  class DibFromMemory  ************************************************************************// *************************************************************************************************DibFromMemory::DibFromMemory(void) : m_bInited(FALSE), m_pbi(NULL), m_pBits(NULL) {	m_szd_Inches.cx = m_szd_Inches.cy = m_ptdLogPix.x = m_ptdLogPix.y = 0;}DibFromMemory::~DibFromMemory() {	// NOTHING TO DELETE}BOOL DibFromMemory::Init(const void *pMemImage, DWORD dwImageSize) {	BOOL bRetValue = FALSE;	const BITMAPFILEHEADER *pbfh = (const BITMAPFILEHEADER *) pMemImage;	if (pbfh->bfType == 0x4d42 && 		pbfh->bfSize == dwImageSize && 		pbfh->bfReserved1 == 0 && 		pbfh->bfReserved2 == 0	) {		m_pBits = (PCBYTE) pMemImage + pbfh->bfOffBits;		DWORD dwOffset = sizeof(*pbfh);		m_pbi = (const BITMAPINFO*) ( (PCBYTE) pMemImage + dwOffset );		if (m_pbi->bmiHeader.biSize == sizeof(m_pbi->bmiHeader)) {			m_sz_Pixels.cx = m_pbi->bmiHeader.biWidth;			m_sz_Pixels.cy = m_pbi->bmiHeader.biHeight;			BOOL bGotLogPix = FALSE;			if (m_pbi->bmiHeader.biXPelsPerMeter != 0 &&				m_pbi->bmiHeader.biYPelsPerMeter != 0			) {				m_ptdLogPix.x = (double) m_pbi->bmiHeader.biXPelsPerMeter * MM_PER_INCH / 1000;				m_ptdLogPix.y = (double) m_pbi->bmiHeader.biYPelsPerMeter * MM_PER_INCH / 1000;							bGotLogPix = TRUE;			} else {				HDC hdcRef = ::GetDC(NULL);				if (hdcRef != NULL) {					int hs = ::GetDeviceCaps(hdcRef, HORZSIZE);					int vs = ::GetDeviceCaps(hdcRef, VERTSIZE);					int hr = ::GetDeviceCaps(hdcRef, HORZRES);					int vr = ::GetDeviceCaps(hdcRef, VERTRES);					::ReleaseDC(NULL, hdcRef);					m_ptdLogPix.x = (double) hr / hs * MM_PER_INCH;					m_ptdLogPix.y = (double) vr / vs * MM_PER_INCH;					bGotLogPix = TRUE;				}			}			if (bGotLogPix) {				m_szd_Inches.cx = m_pbi->bmiHeader.biWidth / m_ptdLogPix.x;				m_szd_Inches.cy = m_pbi->bmiHeader.biHeight / m_ptdLogPix.y;				bRetValue = TRUE;			}		}	}	if (bRetValue) {		m_bInited = TRUE;	}	return bRetValue;}int DibFromMemory::StretchDIBits(HDC hdc, const RECT& rDest, const RECT& rSrc, DWORD dwRop) const {	ASSERT(m_bInited);	int kRetValue = 		::StretchDIBits(			hdc,			rDest.left, rDest.top, RW(rDest), RH(rDest),			rSrc.left, rSrc.top, RW(rSrc), RH(rSrc),			m_pBits, m_pbi, DIB_RGB_COLORS,			dwRop			);	return kRetValue;}int DibFromMemory::StretchDIBits(	HDC hdc, int xDest, int yDest, int cxDest, int cyDest, 	int xSrc, int ySrc, int cxSrc, int cySrc, DWORD dwRop) const {	ASSERT(m_bInited);	int kRetValue = 		::StretchDIBits(			hdc,			xDest, yDest, cxDest, cyDest,			xSrc, ySrc, cxSrc, cySrc,			m_pBits, m_pbi, DIB_RGB_COLORS,			dwRop			);	return kRetValue;}const POINTD& DibFromMemory::GetLogPix(void) const { 	ASSERT(m_bInited); 	return m_ptdLogPix; }const SIZED& DibFromMemory::GetSize_Inches(void) const { 	ASSERT(m_bInited); 	return m_szd_Inches; }const SIZE& DibFromMemory::GetSize_Pixels(void) const { 	ASSERT(m_bInited); 	return m_sz_Pixels; }// *************************************************************************************************// **  class DibFromFileMap  ***********************************************************************// *************************************************************************************************DibFromFileMap::DibFromFileMap(void) {	// NOTHING TO DO}DibFromFileMap::~DibFromFileMap() {	// NOTHING TO DO}BOOL DibFromFileMap::Open(const tstring& tstrFileName) {	BOOL bRetValue = FALSE;	try {		if (m_mfm.Open(tstrFileName)) {			if (this->Init(m_mfm.GetBasePtr(), m_mfm.GetSize())) {				bRetValue = TRUE;			}		}	} catch(...) {	}	if (!bRetValue) {		try { if (m_mfm.IsOpen()) { m_mfm.Close(); } } catch(...) {}	}	return bRetValue;}void DibFromFileMap::Close(void) {	m_bInited = FALSE;	m_mfm.Close();}// *************************************************************************************************// **  class My24BPPDIBSection  ********************************************************************// *************************************************************************************************My24BPPDIBSection::My24BPPDIBSection(void) { 	m_hbmp = NULL;}My24BPPDIBSection::~My24BPPDIBSection() { 	this->Close();}HBITMAP My24BPPDIBSection::Create(IN HDC hdc, IN const tstring& tstrFileName, 	IN const SIZED& szd_Inches, IN const POINTD& ptdLogPix) {	ASSERT( !this->IsOpen() );	ASSERT( m_hbmp == NULL );	DWORD dwPixelDataOffset;	DWORD dwImagePixelDataBytes;	SIZE szImage_Pixels;	DWORD dwFileSize ;	if (TheirCalculateSizes(dwFileSize, dwPixelDataOffset, dwImagePixelDataBytes, szImage_Pixels, 							szd_Inches, ptdLogPix)) {		try {			BOOL bCreated = m_mfm.Create(tstrFileName, dwFileSize);			if (bCreated) {				::BITMAPFILEHEADER bfh;				::ZeroMemory(&bfh, sizeof(bfh));				bfh.bfType = 0x4d42;				bfh.bfSize = dwFileSize;				bfh.bfOffBits = dwPixelDataOffset;				::BITMAPINFOHEADER bih;				::ZeroMemory(&bih, sizeof(bih));				bih.biSize = sizeof(bih);				bih.biWidth = szImage_Pixels.cx;				bih.biHeight = szImage_Pixels.cy;				bih.biBitCount = 24;				bih.biPlanes = 1;				bih.biCompression = BI_RGB; 				bih.biSizeImage = dwImagePixelDataBytes;				bih.biXPelsPerMeter = RoundToLong(ptdLogPix.x * INCHES_PER_MM * 1000);				bih.biYPelsPerMeter = RoundToLong(ptdLogPix.y * INCHES_PER_MM * 1000);				DWORD dwOffset = 0;				* (BITMAPFILEHEADER *) m_mfm.GetOffsetPtr(dwOffset) = bfh;				dwOffset += sizeof(bfh);				::LPBITMAPINFO lpbmi = (::LPBITMAPINFO) m_mfm.GetOffsetPtr(dwOffset);				* (::LPBITMAPINFOHEADER) lpbmi = bih;				HANDLE hSection = m_mfm.GetFileMapHandle();				UINT uUsage = DIB_RGB_COLORS;				VOID *pBits = NULL;				DWORD dwtemp = sizeof(DWORD);				m_hbmp = ::CreateDIBSection(					hdc,					lpbmi,					uUsage,					&pBits,					hSection,					dwPixelDataOffset					);				if (m_hbmp != NULL) {					m_ptdLogPix = ptdLogPix;					m_szd_Inches = szd_Inches;					m_sz_Pixels = szImage_Pixels;				}			}		} catch(...) {			if (m_hbmp != NULL) {				::DeleteObject(m_hbmp);				m_hbmp = NULL;			}		}	}	if (m_hbmp == NULL) {		if (m_mfm.IsOpen()) {			m_mfm.Close();		}	}	return m_hbmp;}BOOL My24BPPDIBSection::IsOpen(void) const {	BOOL bOpen = m_mfm.IsOpen();	ASSERT( !bOpen || m_hbmp != NULL  );	return bOpen;}void My24BPPDIBSection::Close(void) {	if (m_hbmp != NULL) {		::DeleteObject(m_hbmp);	}	if (m_mfm.IsOpen()) {		m_mfm.Close();	}}const POINTD& My24BPPDIBSection::GetLogPix(void) const {	ASSERT(this->IsOpen());	return m_ptdLogPix;}const SIZED& My24BPPDIBSection::GetSize_Inches(void) const {	ASSERT(this->IsOpen());	return m_szd_Inches;}const SIZE& My24BPPDIBSection::GetSize_Pixels(void) const {	ASSERT(this->IsOpen());	return m_sz_Pixels;}// ****// **** class My24BPPDIBSection:  static members// ****BOOL My24BPPDIBSection::TheirCalculateFileSize(	OUT DWORD& dwFileSize,	OUT SIZE& szImage_Pixels, 	IN const SIZED& szd_Inches, 	IN const POINTD& ptdLogPix	)  {	DWORD dwPixelDataOffset;	DWORD dwImagePixelDataBytes;	BOOL bRetValue = My24BPPDIBSection::TheirCalculateSizes(		dwFileSize,		dwPixelDataOffset,		dwImagePixelDataBytes,		szImage_Pixels,		szd_Inches,		ptdLogPix		);	return bRetValue;}BOOL My24BPPDIBSection::TheirCalculateSizes(	OUT DWORD& dwFileSize,	OUT DWORD& dwPixelDataOffset, 	OUT DWORD& dwImagePixelDataBytes,	OUT SIZE& szImage_Pixels,	IN const SIZED& szd_Inches, 	IN const POINTD& ptdLogPix) {	BOOL bRetValue = FALSE;	// NOTE:  MAY BE THAT WIN95 DIB LINES ARE "WORD" ALIGNED (?)	// ALTHOUGH I REMEMBER 4-BYTE ALIGNMENT BACK TO WIN 3.1	szImage_Pixels.cx = RoundToLong(szd_Inches.cx * ptdLogPix.x);	szImage_Pixels.cy = RoundToLong(szd_Inches.cy * ptdLogPix.y);	DWORD dwBytesPerLine = CalculateBytesPerLine(szImage_Pixels.cx);	DWORD dwPixelDataOffsetUnAligned = sizeof(::BITMAPFILEHEADER) + sizeof(::BITMAPINFOHEADER);	dwPixelDataOffset = CalculateDWORDAligned(dwPixelDataOffsetUnAligned);	double dTemp = dwBytesPerLine;	dTemp *= szImage_Pixels.cy;	// SHOULD BE ABLE TO HANDLE UP TO UNSIGNED DWORD MAX, BUT BEING CONSERVATIVE	if (dTemp < 0x7fffffffL - dwPixelDataOffset) {		dwImagePixelDataBytes = dwBytesPerLine * szImage_Pixels.cy;		dwFileSize = dwPixelDataOffset + dwImagePixelDataBytes;		bRetValue = TRUE;	}	return bRetValue;}// *********************************************************************************************// **  MODULE PRIVATE ROUTINES  ****************************************************************// *********************************************************************************************static DWORD CalculateDWORDAligned(IN DWORD dw) {	DWORD dwRetValue = (dw + 3) & ( ~ (DWORD) 3 );	return dwRetValue;}static DWORD CalculateBytesPerLine(IN DWORD dwPixelsPerLine) {	// LINES MUST BE 4-BYTE ALIGNED AKA 32 BIT	DWORD dwBytesUnAligned = dwPixelsPerLine * 3;	DWORD dwBytesAligned = CalculateDWORDAligned(dwBytesUnAligned);	return dwBytesAligned;}

⌨️ 快捷键说明

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