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

📄 imageservicebitmap.cpp

📁 p2p软件
💻 CPP
字号:
//
// ImageServiceBitmap.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza 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.
//
// Shareaza 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 Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "ImageServiceBitmap.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNAMIC(CBitmapImageService, CCmdTarget)

BEGIN_INTERFACE_MAP(CBitmapImageService, CCmdTarget)
	INTERFACE_PART(CBitmapImageService, IID_IImageServicePlugin, Service)
END_INTERFACE_MAP()

BEGIN_MESSAGE_MAP(CBitmapImageService, CCmdTarget)
	//{{AFX_MSG_MAP(CBitmapImageService)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CBitmapImageService

CBitmapImageService::CBitmapImageService()
{
}

CBitmapImageService::~CBitmapImageService()
{
}

IImageServicePlugin* CBitmapImageService::Create()
{
	CBitmapImageService* pThis = new CBitmapImageService();
	return &pThis->m_xService;
}

/////////////////////////////////////////////////////////////////////////////
// CBitmapImageService operations

IMPLEMENT_UNKNOWN(CBitmapImageService, Service)

STDMETHODIMP CBitmapImageService::XService::LoadFromFile(HANDLE hFile, DWORD nLength, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* FAR* ppImage)
{
	METHOD_PROLOGUE( CBitmapImageService, Service )
	
	LPBYTE pRowBuf, pRowIn, pRowOut, pData;
	BITMAPFILEHEADER pBFH;
	BITMAPINFOHEADER pBIH;
	RGBQUAD pPalette[256];
	LONG nWidth, nHeight;
	DWORD nRead;
	
	DWORD nBaseAddress = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
	
	ReadFile( hFile, &pBFH, sizeof(pBFH), &nRead, NULL );
	if ( nRead != sizeof(pBFH) ) return E_FAIL;
	ReadFile( hFile, &pBIH, sizeof(pBIH), &nRead, NULL );
	if ( nRead != sizeof(pBIH) ) return E_FAIL;
	
	if ( pBFH.bfType != 'MB' ) return E_FAIL;
	if ( pBIH.biBitCount != 8 && pBIH.biBitCount != 24 ) return E_FAIL;
	
	nWidth	= (int)pBIH.biWidth;
	nHeight	= (int)pBIH.biHeight;
	
	pParams->nWidth		= nWidth;
	pParams->nHeight	= nHeight;
	
	if ( pParams->nFlags & IMAGESERVICE_SCANONLY ) return S_OK;
	
	if ( pBIH.biBitCount == 8 )
	{
		ReadFile( hFile, pPalette, sizeof(RGBQUAD) * 256, &nRead, NULL );
		if ( nRead != sizeof(RGBQUAD) * 256 ) return E_FAIL;
	}
	
	if ( pBFH.bfOffBits )
	{
		if ( SetFilePointer( hFile, nBaseAddress + pBFH.bfOffBits, NULL, FILE_BEGIN )
			 != nBaseAddress + pBFH.bfOffBits ) return E_FAIL;
	}
	
	for ( UINT nInPitch = nWidth * pBIH.biBitCount / 8 ; nInPitch & 3 ; ) nInPitch++;
	for ( UINT nOutPitch = nWidth * 3 ; nOutPitch & 3 ; ) nOutPitch++;

	pRowBuf	= new BYTE[ nInPitch ];

	UINT nArray = nOutPitch * (UINT)nHeight;

	*ppImage = SafeArrayCreateVector( VT_UI1, 0, nArray );
	SafeArrayAccessData( *ppImage, (VOID**)&pData );

	for ( int nY = nHeight - 1 ; nY >= 0 ; nY-- )
	{
		ReadFile( hFile, pRowBuf, nInPitch, &nRead, NULL );

		if ( nRead != nInPitch )
		{
			delete [] pRowBuf;
			SafeArrayUnaccessData( *ppImage );
			if ( pParams->nFlags & IMAGESERVICE_PARTIAL_IN )
			{
				pParams->nFlags |= IMAGESERVICE_PARTIAL_OUT;
				return S_OK;
			}
			else
			{
				SafeArrayDestroy( *ppImage );
				*ppImage = NULL;
				return E_FAIL;
			}
		}

		pRowOut	= &pData[ nY * nOutPitch ];
		pRowIn	= pRowBuf;
		
		for ( int nX = 0 ; nX < nWidth ; nX++ )
		{
			BYTE bRed, bGreen, bBlue;

			if ( pBIH.biBitCount == 24 )
			{
				bBlue	= *pRowIn++;
				bGreen	= *pRowIn++;
				bRed	= *pRowIn++;
			}
			else
			{
				bRed	= pPalette[ *pRowIn ].rgbRed;
				bGreen	= pPalette[ *pRowIn ].rgbGreen;
				bBlue	= pPalette[ *pRowIn++ ].rgbBlue;
			}

			*pRowOut++	= bRed;
			*pRowOut++	= bGreen;
			*pRowOut++	= bBlue;
		}
	}

	SafeArrayUnaccessData( *ppImage );

	delete [] pRowBuf;

	return S_OK;
}

STDMETHODIMP CBitmapImageService::XService::LoadFromMemory(SAFEARRAY FAR* pMemory, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* FAR* ppImage)
{
	METHOD_PROLOGUE( CBitmapImageService, Service )
	
	LPBYTE pRowIn, pRowOut, pData;
	BITMAPFILEHEADER pBFH;
	BITMAPINFOHEADER pBIH;
	RGBQUAD pPalette[256];
	LONG nWidth, nHeight;

	LPBYTE pSource = NULL;
	LONG nMemory = 0;

	SafeArrayGetUBound( pMemory, 1, &nMemory );
	if ( ++nMemory <= sizeof(pBIH) + sizeof(pBFH) ) return E_FAIL;
	SafeArrayAccessData( pMemory, (void**)&pSource );
	
	CopyMemory( &pBFH, pSource, sizeof(pBFH) );
	pSource += sizeof(pBFH);
	nMemory -= sizeof(pBFH);
	CopyMemory( &pBIH, pSource, sizeof(pBIH) );
	pSource += sizeof(pBIH);
	nMemory -= sizeof(pBIH);
	
	if ( pBFH.bfType != 'MB' || ( pBIH.biBitCount != 8 && pBIH.biBitCount != 24 ) )
	{
		SafeArrayUnaccessData( pMemory );
		return E_FAIL;
	}
	
	nWidth	= (int)pBIH.biWidth;
	nHeight	= (int)pBIH.biHeight;
	
	pParams->nWidth		= nWidth;
	pParams->nHeight	= nHeight;
	
	if ( pParams->nFlags & IMAGESERVICE_SCANONLY )
	{
		SafeArrayUnaccessData( pMemory );
		return S_OK;
	}
	
	if ( pBIH.biBitCount == 8 )
	{
		if ( nMemory < sizeof(RGBQUAD) * 256 )
		{
			SafeArrayUnaccessData( pMemory );
			return E_FAIL;
		}
		CopyMemory( pPalette, pSource, sizeof(RGBQUAD) * 256 );
		pSource += sizeof(RGBQUAD) * 256;
		nMemory -= sizeof(RGBQUAD) * 256;
	}
	
	if ( pBFH.bfOffBits )
	{
		SafeArrayUnaccessData( pMemory );
		SafeArrayGetUBound( pMemory, 1, &nMemory );
		if ( ++nMemory <= (LONG)pBFH.bfOffBits ) return E_FAIL;
		SafeArrayAccessData( pMemory, (void**)&pSource );
		pSource += pBFH.bfOffBits;
		nMemory -= pBFH.bfOffBits;
	}
	
	for ( UINT nInPitch = nWidth * pBIH.biBitCount / 8 ; nInPitch & 3 ; ) nInPitch++;
	for ( UINT nOutPitch = nWidth * 3 ; nOutPitch & 3 ; ) nOutPitch++;
	
	UINT nArray = nOutPitch * (UINT)nHeight;
	
	*ppImage = SafeArrayCreateVector( VT_UI1, 0, nArray );
	SafeArrayAccessData( *ppImage, (VOID**)&pData );
	
	for ( int nY = nHeight - 1 ; nY >= 0 ; nY-- )
	{
		if ( nMemory < (LONG)nInPitch )
		{
			SafeArrayUnaccessData( *ppImage );
			SafeArrayUnaccessData( pMemory );

			if ( pParams->nFlags & IMAGESERVICE_PARTIAL_IN )
			{
				pParams->nFlags |= IMAGESERVICE_PARTIAL_OUT;
				return S_OK;
			}
			else
			{
				SafeArrayDestroy( *ppImage );
				*ppImage = NULL;
				return E_FAIL;
			}
		}
		
		pRowOut	= &pData[ nY * nOutPitch ];
		pRowIn	= pSource;

		pSource += nInPitch;
		nMemory -= nInPitch;
		
		for ( int nX = 0 ; nX < nWidth ; nX++ )
		{
			BYTE bRed, bGreen, bBlue;

			if ( pBIH.biBitCount == 24 )
			{
				bBlue	= *pRowIn++;
				bGreen	= *pRowIn++;
				bRed	= *pRowIn++;
			}
			else
			{
				bRed	= pPalette[ *pRowIn ].rgbRed;
				bGreen	= pPalette[ *pRowIn ].rgbGreen;
				bBlue	= pPalette[ *pRowIn++ ].rgbBlue;
			}

			*pRowOut++	= bRed;
			*pRowOut++	= bGreen;
			*pRowOut++	= bBlue;
		}
	}

	SafeArrayUnaccessData( *ppImage );
	SafeArrayUnaccessData( pMemory );
	
	return S_OK;
}

STDMETHODIMP CBitmapImageService::XService::SaveToFile(HANDLE hFile, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* pImage)
{
	METHOD_PROLOGUE( CBitmapImageService, Service )
	return E_NOTIMPL;
}

STDMETHODIMP CBitmapImageService::XService::SaveToMemory(SAFEARRAY FAR* FAR* ppMemory, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* pImage)
{
	METHOD_PROLOGUE( CBitmapImageService, Service )
	return E_NOTIMPL;
}

⌨️ 快捷键说明

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