00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "ImageServiceBitmap.h"
00025
00026 #ifdef _DEBUG
00027 #define new DEBUG_NEW
00028 #undef THIS_FILE
00029 static char THIS_FILE[] = __FILE__;
00030 #endif
00031
00032 IMPLEMENT_DYNAMIC(CBitmapImageService, CCmdTarget)
00033
00034 BEGIN_INTERFACE_MAP(CBitmapImageService, CCmdTarget)
00035 INTERFACE_PART(CBitmapImageService, IID_IImageServicePlugin, Service)
00036 END_INTERFACE_MAP()
00037
00038 BEGIN_MESSAGE_MAP(CBitmapImageService, CCmdTarget)
00039
00040
00041 END_MESSAGE_MAP()
00042
00043
00045
00046
00047 CBitmapImageService::CBitmapImageService()
00048 {
00049 }
00050
00051 CBitmapImageService::~CBitmapImageService()
00052 {
00053 }
00054
00055 IImageServicePlugin* CBitmapImageService::Create()
00056 {
00057 CBitmapImageService* pThis = new CBitmapImageService();
00058 return &pThis->m_xService;
00059 }
00060
00062
00063
00064 IMPLEMENT_UNKNOWN(CBitmapImageService, Service)
00065
00066 STDMETHODIMP CBitmapImageService::XService::LoadFromFile(HANDLE hFile, DWORD nLength, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* FAR* ppImage)
00067 {
00068 METHOD_PROLOGUE( CBitmapImageService, Service )
00069
00070 LPBYTE pRowBuf, pData;
00071 BITMAPFILEHEADER pBFH;
00072 BITMAPINFOHEADER pBIH;
00073 RGBQUAD pPalette[256];
00074 LONG nWidth, nHeight;
00075 DWORD nRead;
00076
00077 DWORD nBaseAddress = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
00078
00079 ReadFile( hFile, &pBFH, sizeof(pBFH), &nRead, NULL );
00080 if ( nRead != sizeof(pBFH) ) return E_FAIL;
00081 ReadFile( hFile, &pBIH, sizeof(pBIH), &nRead, NULL );
00082 if ( nRead != sizeof(pBIH) ) return E_FAIL;
00083
00084 if ( pBFH.bfType != 'MB' ) return E_FAIL;
00085 if ( pBIH.biBitCount != 8 && pBIH.biBitCount != 24 ) return E_FAIL;
00086
00087 nWidth = (int)pBIH.biWidth;
00088 nHeight = (int)pBIH.biHeight;
00089
00090 pParams->nWidth = nWidth;
00091 pParams->nHeight = nHeight;
00092
00093 if ( pParams->nFlags & IMAGESERVICE_SCANONLY ) return S_OK;
00094
00095 if ( pBIH.biBitCount == 8 )
00096 {
00097 ReadFile( hFile, pPalette, sizeof(RGBQUAD) * 256, &nRead, NULL );
00098 if ( nRead != sizeof(RGBQUAD) * 256 ) return E_FAIL;
00099 }
00100
00101 if ( pBFH.bfOffBits )
00102 {
00103 if ( SetFilePointer( hFile, nBaseAddress + pBFH.bfOffBits, NULL, FILE_BEGIN )
00104 != nBaseAddress + pBFH.bfOffBits ) return E_FAIL;
00105 }
00106
00107 UINT nInPitch = nWidth * pBIH.biBitCount / 8;
00108 for ( ; nInPitch & 3 ; ) nInPitch++;
00109 UINT nOutPitch = nWidth * 3;
00110 for ( ; nOutPitch & 3 ; ) nOutPitch++;
00111
00112 pRowBuf = new BYTE[ nInPitch ];
00113
00114 UINT nArray = nOutPitch * (UINT)nHeight;
00115
00116 *ppImage = SafeArrayCreateVector( VT_UI1, 0, nArray );
00117 SafeArrayAccessData( *ppImage, (VOID**)&pData );
00118
00119 for ( int nY = nHeight - 1 ; nY >= 0 ; nY-- )
00120 {
00121 ReadFile( hFile, pRowBuf, nInPitch, &nRead, NULL );
00122
00123 if ( nRead != nInPitch )
00124 {
00125 delete [] pRowBuf;
00126 SafeArrayUnaccessData( *ppImage );
00127 if ( pParams->nFlags & IMAGESERVICE_PARTIAL_IN )
00128 {
00129 pParams->nFlags |= IMAGESERVICE_PARTIAL_OUT;
00130 return S_OK;
00131 }
00132 else
00133 {
00134 SafeArrayDestroy( *ppImage );
00135 *ppImage = NULL;
00136 return E_FAIL;
00137 }
00138 }
00139
00140
00141 if ( pBIH.biBitCount == 24 )
00142 {
00143 __asm {
00144 mov eax, nOutPitch
00145 mov edi, pData
00146 mul nY
00147 add edi, eax
00148 mov esi, pRowBuf
00149 mov ecx, nWidth
00150 loop1: mov ax, [esi]
00151 mov bl, [esi+2]
00152 mov [edi+1], ah
00153 mov [edi+2], al
00154 mov [edi], bl
00155 add esi, 3
00156 add edi, 3
00157 dec ecx
00158 jnz loop1
00159 }
00160 }
00161 else
00162 {
00163 __asm {
00164 mov eax, nOutPitch
00165 mul nY
00166 mov edi, pData
00167 add edi, eax
00168 mov esi, pRowBuf
00169 mov edx, nWidth
00170 xor eax, eax
00171 _loop: mov al, [esi]
00172 inc esi
00173 mov ebx, [pPalette+eax*4]
00174 bswap ebx
00175 mov [edi], bh
00176 shr ebx, 16
00177 mov [edi+1], bx
00178 add edi, 3
00179 dec edx
00180 jnz _loop
00181 }
00182 }
00183 }
00184 SafeArrayUnaccessData( *ppImage );
00185
00186 delete [] pRowBuf;
00187
00188 return S_OK;
00189 }
00190
00191 STDMETHODIMP CBitmapImageService::XService::LoadFromMemory(SAFEARRAY FAR* pMemory, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* FAR* ppImage)
00192 {
00193 METHOD_PROLOGUE( CBitmapImageService, Service )
00194
00195 LPBYTE pData;
00196 BITMAPFILEHEADER pBFH;
00197 BITMAPINFOHEADER pBIH;
00198 RGBQUAD pPalette[256];
00199 LONG nWidth, nHeight;
00200
00201 LPBYTE pSource = NULL;
00202 LONG nMemory = 0;
00203
00204 SafeArrayGetUBound( pMemory, 1, &nMemory );
00205 if ( ++nMemory <= sizeof(pBIH) + sizeof(pBFH) ) return E_FAIL;
00206 SafeArrayAccessData( pMemory, (void**)&pSource );
00207
00208 CopyMemory( &pBFH, pSource, sizeof(pBFH) );
00209 pSource += sizeof(pBFH);
00210 nMemory -= sizeof(pBFH);
00211 CopyMemory( &pBIH, pSource, sizeof(pBIH) );
00212 pSource += sizeof(pBIH);
00213 nMemory -= sizeof(pBIH);
00214
00215 if ( pBFH.bfType != 'MB' || ( pBIH.biBitCount != 8 && pBIH.biBitCount != 24 ) )
00216 {
00217 SafeArrayUnaccessData( pMemory );
00218 return E_FAIL;
00219 }
00220
00221 nWidth = (int)pBIH.biWidth;
00222 nHeight = (int)pBIH.biHeight;
00223
00224 pParams->nWidth = nWidth;
00225 pParams->nHeight = nHeight;
00226
00227 if ( pParams->nFlags & IMAGESERVICE_SCANONLY )
00228 {
00229 SafeArrayUnaccessData( pMemory );
00230 return S_OK;
00231 }
00232
00233 if ( pBIH.biBitCount == 8 )
00234 {
00235 if ( nMemory < sizeof(RGBQUAD) * 256 )
00236 {
00237 SafeArrayUnaccessData( pMemory );
00238 return E_FAIL;
00239 }
00240 CopyMemory( pPalette, pSource, sizeof(RGBQUAD) * 256 );
00241 pSource += sizeof(RGBQUAD) * 256;
00242 nMemory -= sizeof(RGBQUAD) * 256;
00243 }
00244
00245 if ( pBFH.bfOffBits )
00246 {
00247 SafeArrayUnaccessData( pMemory );
00248 SafeArrayGetUBound( pMemory, 1, &nMemory );
00249 if ( ++nMemory <= (LONG)pBFH.bfOffBits ) return E_FAIL;
00250 SafeArrayAccessData( pMemory, (void**)&pSource );
00251 pSource += pBFH.bfOffBits;
00252 nMemory -= pBFH.bfOffBits;
00253 }
00254
00255 UINT nInPitch = nWidth * pBIH.biBitCount / 8;
00256 for ( ; nInPitch & 3 ; ) nInPitch++;
00257 UINT nOutPitch = nWidth * 3;
00258 for ( ; nOutPitch & 3 ; ) nOutPitch++;
00259
00260 UINT nArray = nOutPitch * (UINT)nHeight;
00261
00262 *ppImage = SafeArrayCreateVector( VT_UI1, 0, nArray );
00263 SafeArrayAccessData( *ppImage, (VOID**)&pData );
00264
00265 for ( int nY = nHeight - 1 ; nY >= 0 ; nY-- )
00266 {
00267 if ( nMemory < (LONG)nInPitch )
00268 {
00269 SafeArrayUnaccessData( *ppImage );
00270 SafeArrayUnaccessData( pMemory );
00271
00272 if ( pParams->nFlags & IMAGESERVICE_PARTIAL_IN )
00273 {
00274 pParams->nFlags |= IMAGESERVICE_PARTIAL_OUT;
00275 return S_OK;
00276 }
00277 else
00278 {
00279 SafeArrayDestroy( *ppImage );
00280 *ppImage = NULL;
00281 return E_FAIL;
00282 }
00283 }
00284 pSource += nInPitch;
00285 nMemory -= nInPitch;
00286
00287 if ( pBIH.biBitCount == 24 )
00288 __asm {
00289 mov eax, nOutPitch
00290 mov edi, pData
00291 mul nY
00292 add edi, eax
00293 mov esi, pSource
00294 mov ecx, nWidth
00295 loop1: mov ax, [esi]
00296 mov bl, [esi+2]
00297 mov [edi+1], ah
00298 mov [edi+2], al
00299 mov [edi], bl
00300 add esi, 3
00301 add edi, 3
00302 dec ecx
00303 jnz loop1
00304 }
00305 else
00306 {
00307 __asm {
00308 mov eax, nOutPitch
00309 mul nY
00310 mov edi, pData
00311 add edi, eax
00312 mov esi, pSource
00313 mov edx, nWidth
00314 xor eax, eax
00315 _loop: mov al, [esi]
00316 inc esi
00317 mov ebx, [pPalette+eax*4]
00318 bswap ebx
00319 mov [edi], bh
00320 shr ebx, 16
00321 mov [edi+1], bx
00322 add edi, 3
00323 dec edx
00324 jnz _loop
00325 }
00326 }
00327 }
00328 SafeArrayUnaccessData( *ppImage );
00329 SafeArrayUnaccessData( pMemory );
00330
00331 return S_OK;
00332 }
00333
00334 STDMETHODIMP CBitmapImageService::XService::SaveToFile(HANDLE hFile, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* pImage)
00335 {
00336 METHOD_PROLOGUE( CBitmapImageService, Service )
00337 return E_NOTIMPL;
00338 }
00339
00340 STDMETHODIMP CBitmapImageService::XService::SaveToMemory(SAFEARRAY FAR* FAR* ppMemory, IMAGESERVICEDATA FAR* pParams, SAFEARRAY FAR* pImage)
00341 {
00342 METHOD_PROLOGUE( CBitmapImageService, Service )
00343 return E_NOTIMPL;
00344 }
00345