Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

ImageServices.cpp

Go to the documentation of this file.
00001 //
00002 // ImageServices.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Plugins.h"
00025 #include "ImageServices.h"
00026 #include "ImageFile.h"
00027 #include "ImageServiceBitmap.h"
00028 
00029 #ifdef _DEBUG
00030 #define new DEBUG_NEW
00031 #undef THIS_FILE
00032 static char THIS_FILE[] = __FILE__;
00033 #endif
00034 
00035 IMPLEMENT_DYNAMIC(CImageServices, CComObject)
00036 
00037 LPCTSTR RT_JPEG = _T("JPEG");
00038 LPCTSTR RT_PNG = _T("PNG");
00039 
00040 
00042 // CImageServices construction
00043 
00044 CImageServices::CImageServices()
00045 {
00046         m_bCOM = GetCurrentThreadId() == AfxGetApp()->m_nThreadID;
00047 }
00048 
00049 CImageServices::~CImageServices()
00050 {
00051         Cleanup();
00052 }
00053 
00055 // CImageServices load operations
00056 
00057 BOOL CImageServices::LoadFromMemory(CImageFile* pFile, LPCTSTR pszType, LPCVOID pData, DWORD nLength, BOOL bScanOnly, BOOL bPartialOk)
00058 {
00059         IImageServicePlugin* pService = GetService( pszType );
00060         if ( pService == NULL ) return FALSE;
00061         
00062         IMAGESERVICEDATA pParams;
00063         ZeroMemory( &pParams, sizeof(pParams) );
00064         
00065         pParams.cbSize          = sizeof(pParams);
00066         pParams.nComponents     = 3;
00067         
00068         if ( bScanOnly ) pParams.nFlags |= IMAGESERVICE_SCANONLY;
00069         if ( bPartialOk ) pParams.nFlags |= IMAGESERVICE_PARTIAL_IN;
00070         
00071         SAFEARRAY* pInput;
00072         LPBYTE pTarget;
00073         
00074         if ( FAILED( SafeArrayAllocDescriptor( 1, &pInput ) ) || pInput == NULL ) return FALSE;
00075         
00076         pInput->cbElements = 1;
00077         pInput->rgsabound[ 0 ].lLbound = 0;
00078         pInput->rgsabound[ 0 ].cElements = nLength;
00079         SafeArrayAllocData( pInput );
00080         
00081         if ( FAILED( SafeArrayAccessData( pInput, (void HUGEP* FAR*)&pTarget ) ) ) return FALSE;
00082         
00083         CopyMemory( pTarget, pData, nLength );
00084         SafeArrayUnaccessData( pInput );
00085         
00086         SAFEARRAY* pArray = NULL;
00087         HINSTANCE hRes = AfxGetResourceHandle();
00088         BOOL bSuccess = SUCCEEDED( pService->LoadFromMemory( pInput, &pParams, &pArray ) );
00089         AfxSetResourceHandle( hRes );
00090         
00091         SafeArrayDestroy( pInput );
00092         
00093         return PostLoad( pFile, &pParams, pArray, bSuccess );
00094 }
00095 
00096 const CLSID CLSID_AVIThumb = { 0x4956C5F5, 0xD9A8, 0x4CBB, { 0x89, 0x94, 0xF5, 0x3C, 0xF5, 0x5C, 0xFD, 0xF5 } };
00097 
00098 BOOL CImageServices::LoadFromFile(CImageFile* pFile, LPCTSTR pszType, HANDLE hFile, DWORD nLength, BOOL bScanOnly, BOOL bPartialOk)
00099 {
00100         CLSID* pCLSID = NULL;
00101         IImageServicePlugin* pService = GetService( pszType, &pCLSID );
00102         if ( pService == NULL ) return FALSE;
00103         
00104         IMAGESERVICEDATA pParams;
00105         ZeroMemory( &pParams, sizeof(pParams) );
00106         
00107         pParams.cbSize          = sizeof(pParams);
00108         pParams.nComponents     = 3;
00109         
00110         if ( bScanOnly ) pParams.nFlags |= IMAGESERVICE_SCANONLY;
00111         if ( bPartialOk ) pParams.nFlags |= IMAGESERVICE_PARTIAL_IN;
00112         
00113         SAFEARRAY* pArray       = NULL;
00114         HINSTANCE hRes          = AfxGetResourceHandle();
00115         HRESULT hr                      = E_FAIL;
00116         
00117         if ( pCLSID != NULL && *pCLSID == CLSID_AVIThumb && *pszType != '.' )
00118         {
00119                 USES_CONVERSION;
00120                 LPCSTR pszASCII = T2CA(pszType);
00121                 hr = pService->LoadFromFile( (HANDLE)pszASCII, 0xFEFEFEFE, &pParams, &pArray );
00122         }
00123         else
00124         {
00125                 hr = pService->LoadFromFile( hFile, nLength, &pParams, &pArray );
00126         }
00127         
00128         AfxSetResourceHandle( hRes );
00129         
00130         if ( hr != E_NOTIMPL ) return PostLoad( pFile, &pParams, pArray, SUCCEEDED( hr ) );
00131         
00132         pFile->Clear();
00133         if ( pArray != NULL ) SafeArrayDestroy( pArray );
00134         
00135         HANDLE hMap = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
00136         if ( hMap == INVALID_HANDLE_VALUE ) return FALSE;
00137         
00138         DWORD nPosition = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
00139         BOOL bMapped = FALSE;
00140         
00141         if ( LPCVOID pBuffer = MapViewOfFile( hMap, FILE_MAP_READ, 0, nPosition, nLength ) )
00142         {
00143                 bMapped = LoadFromMemory( pFile, pszType, pBuffer, nLength, bScanOnly, bPartialOk );
00144                 UnmapViewOfFile( pBuffer );
00145         }
00146         
00147         CloseHandle( hMap );
00148         
00149         return bMapped;
00150 }
00151 
00153 // CImageServices post load
00154 
00155 BOOL CImageServices::PostLoad(CImageFile* pFile, IMAGESERVICEDATA* pParams, SAFEARRAY* pArray, BOOL bSuccess)
00156 {
00157         pFile->Clear();
00158 
00159         if ( ! bSuccess )
00160         {
00161                 if ( pArray != NULL ) SafeArrayDestroy( pArray );
00162                 return FALSE;
00163         }
00164 
00165         pFile->m_bScanned               = TRUE;
00166         pFile->m_nWidth                 = pParams->nWidth;
00167         pFile->m_nHeight                = pParams->nHeight;
00168         pFile->m_nComponents    = pParams->nComponents;
00169 
00170         if ( pArray == NULL ) return TRUE;
00171         
00172         pFile->m_bLoaded = TRUE;
00173         
00174         LONG nArray = 0;
00175         SafeArrayGetUBound( pArray, 1, &nArray );
00176         nArray++;
00177         
00178         LONG nFullSize = pParams->nWidth * pParams->nComponents;
00179         while ( nFullSize & 3 ) nFullSize++;
00180         nFullSize *= pParams->nHeight;
00181         
00182         if ( nArray != nFullSize )
00183         {
00184                 SafeArrayDestroy( pArray );
00185                 return FALSE;
00186         }
00187         
00188         pFile->m_pImage = new BYTE[ nArray ];
00189         
00190         LPBYTE pData;
00191         SafeArrayAccessData( pArray, (VOID**)&pData );
00192         CopyMemory( pFile->m_pImage, pData, nArray );
00193         SafeArrayUnaccessData( pArray );
00194         SafeArrayDestroy( pArray );
00195         
00196         return TRUE;
00197 }
00198 
00200 // CImageServices save operations
00201 
00202 BOOL CImageServices::SaveToMemory(CImageFile* pFile, LPCTSTR pszType, int nQuality, LPBYTE* ppBuffer, DWORD* pnLength)
00203 {
00204         *ppBuffer = NULL;
00205         *pnLength = 0;
00206         
00207         IImageServicePlugin* pService = GetService( pszType );
00208         if ( pService == NULL ) return FALSE;
00209         
00210         SAFEARRAY* pSource = ImageToArray( pFile );
00211         if ( pSource == NULL ) return FALSE;
00212         
00213         IMAGESERVICEDATA pParams;
00214         ZeroMemory( &pParams, sizeof(pParams) );
00215         
00216         pParams.cbSize          = sizeof(pParams);
00217         pParams.nWidth          = pFile->m_nWidth;
00218         pParams.nHeight         = pFile->m_nHeight;
00219         pParams.nComponents     = pFile->m_nComponents;
00220         pParams.nQuality        = nQuality;
00221         
00222         SAFEARRAY* pOutput = NULL;
00223         HINSTANCE hRes = AfxGetResourceHandle();
00224         BOOL bSuccess = SUCCEEDED( pService->SaveToMemory( &pOutput, &pParams, pSource ) );
00225         AfxSetResourceHandle( hRes );
00226         
00227         SafeArrayDestroy( pSource );
00228         
00229         if ( pOutput == NULL ) return FALSE;
00230         
00231         SafeArrayGetUBound( pOutput, 1, (PLONG)pnLength );
00232         (*pnLength)++;
00233 
00234         LPBYTE pEncoded;
00235         SafeArrayAccessData( pOutput, (VOID**)&pEncoded );
00236         
00237         *ppBuffer = new BYTE[ *pnLength ];
00238         CopyMemory( *ppBuffer, pEncoded, *pnLength );
00239         
00240         SafeArrayUnaccessData( pOutput );
00241         SafeArrayDestroy( pOutput );
00242         
00243         return TRUE;
00244 }
00245 
00246 BOOL CImageServices::SaveToFile(CImageFile* pFile, LPCTSTR pszType, int nQuality, HANDLE hFile, DWORD* pnLength)
00247 {
00248         if ( pnLength ) *pnLength = 0;
00249         
00250         IImageServicePlugin* pService = GetService( pszType );
00251         if ( pService == NULL ) return FALSE;
00252         
00253         SAFEARRAY* pSource = ImageToArray( pFile );
00254         if ( pSource == NULL ) return FALSE;
00255         
00256         IMAGESERVICEDATA pParams;
00257         ZeroMemory( &pParams, sizeof(pParams) );
00258         
00259         pParams.cbSize          = sizeof(pParams);
00260         pParams.nWidth          = pFile->m_nWidth;
00261         pParams.nHeight         = pFile->m_nHeight;
00262         pParams.nComponents     = pFile->m_nComponents;
00263         pParams.nQuality        = nQuality;
00264         
00265         DWORD nBefore = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
00266         
00267         HINSTANCE hRes = AfxGetResourceHandle();
00268         BOOL bSuccess = SUCCEEDED( pService->SaveToFile( hFile, &pParams, pSource ) );
00269         AfxSetResourceHandle( hRes );
00270         
00271         SafeArrayDestroy( pSource );
00272         
00273         if ( pnLength )
00274         {
00275                 DWORD nAfter = SetFilePointer( hFile, 0, NULL, FILE_CURRENT );
00276                 *pnLength = nAfter - nBefore;
00277         }
00278         
00279         return bSuccess;
00280 }
00281 
00283 // CImageServices pre save utility
00284 
00285 SAFEARRAY* CImageServices::ImageToArray(CImageFile* pFile)
00286 {
00287         SAFEARRAY* pOutput;
00288         
00289         if ( FAILED( SafeArrayAllocDescriptor( 1, &pOutput ) ) || pOutput == NULL ) return NULL;
00290         
00291         DWORD nLength = pFile->m_nWidth * pFile->m_nComponents;
00292         while ( nLength & 3 ) nLength ++;
00293         nLength *= pFile->m_nHeight;
00294         
00295         pOutput->cbElements = 1;
00296         pOutput->rgsabound[ 0 ].lLbound = 0;
00297         pOutput->rgsabound[ 0 ].cElements = nLength;
00298         
00299         if ( FAILED( SafeArrayAllocData( pOutput ) ) ) return NULL;
00300         
00301         LPBYTE pTarget;
00302         if ( FAILED( SafeArrayAccessData( pOutput, (void HUGEP* FAR*)&pTarget ) ) ) return NULL;
00303         
00304         CopyMemory( pTarget, pFile->m_pImage, nLength );
00305         
00306         SafeArrayUnaccessData( pOutput );
00307         
00308         return pOutput;
00309 }
00310 
00312 // CImageServices service discovery and control
00313 
00314 IImageServicePlugin* CImageServices::GetService(LPCTSTR pszFile, CLSID** ppCLSID)
00315 {
00316         LPCTSTR pszType = _tcsrchr( pszFile, '.' );
00317         if ( pszType == NULL ) return NULL;
00318         
00319         IImageServicePlugin* pService = NULL;
00320         CString strType( pszType );
00321         CharLower( strType.GetBuffer() );
00322         strType.ReleaseBuffer();
00323         
00324         if ( m_pService.Lookup( strType, (void*&)pService ) )
00325         {
00326                 if ( pService != NULL && ppCLSID != NULL )
00327                 {
00328                         m_pCLSID.Lookup( strType, (void*&)*ppCLSID );
00329                 }
00330                 
00331                 return pService;
00332         }
00333         else
00334         {
00335                 CLSID pCLSID = { 0 };
00336                 
00337                 pService = LoadService( strType, &pCLSID );
00338                 m_pService.SetAt( strType, pService );
00339                 
00340                 if ( pService != NULL )
00341                 {
00342                         CLSID* pCopy = new CLSID;
00343                         *pCopy = pCLSID;
00344                         delete m_pCLSID[ strType ];
00345                         m_pCLSID[ strType ] = pCopy;
00346                         if ( ppCLSID != NULL ) *ppCLSID = pCopy;
00347                 }
00348                 
00349                 return pService;
00350         }
00351 }
00352 
00353 IImageServicePlugin* CImageServices::LoadService(LPCTSTR pszType, CLSID* ppCLSID)
00354 {
00355         IImageServicePlugin* pService = NULL;
00356         
00357         DWORD dwContext = 0;
00358         if ( _tcscmp( pszType, _T(".bmp") ) == 0 )
00359         {
00360                 return CBitmapImageService::Create();
00361         }
00362         else if ( _tcscmp( pszType, _T(".avi") ) == 0 )
00363         {
00364                 dwContext = CLSCTX_NO_CUSTOM_MARSHAL;
00365         }
00366         
00367         CLSID pCLSID;
00368         
00369         if ( ! Plugins.LookupCLSID( _T("ImageService"), pszType, pCLSID ) ) return NULL;
00370         
00371         if ( ppCLSID != NULL ) *ppCLSID = pCLSID;
00372         
00373         if ( ! m_bCOM )
00374         {
00375                 if ( FAILED( CoInitializeEx( NULL, COINIT_MULTITHREADED ) ) ) return NULL;
00376                 m_bCOM = TRUE;
00377         }
00378         
00379         HINSTANCE hRes = AfxGetResourceHandle();
00380         HRESULT hResult = CoCreateInstance( pCLSID, NULL, CLSCTX_INPROC_SERVER|dwContext,
00381                 IID_IImageServicePlugin, (void**)&pService );
00382         AfxSetResourceHandle( hRes );
00383         
00384         if ( FAILED( hResult ) )
00385         {
00386                 //theApp.Message( MSG_DEBUG, _T("CImageServices::CoCreateInstance() -> %lu"), hResult );
00387                 return NULL;
00388         }
00389         
00390         return pService;
00391 }
00392 
00394 // CImageServices cleanup
00395 
00396 void CImageServices::Cleanup()
00397 {
00398         CString strType;
00399         POSITION pos;
00400         
00401         for ( pos = m_pService.GetStartPosition() ; pos ; )
00402         {
00403                 IImageServicePlugin* pService = NULL;
00404                 m_pService.GetNextAssoc( pos, strType, (void*&)pService );
00405                 if ( pService != NULL ) pService->Release();
00406         }
00407         
00408         m_pService.RemoveAll();
00409         
00410         for ( pos = m_pCLSID.GetStartPosition() ; pos ; )
00411         {
00412                 CLSID* pCLSID = NULL;
00413                 m_pCLSID.GetNextAssoc( pos, strType, (void*&)pCLSID );
00414                 if ( pCLSID != NULL ) delete pCLSID;
00415         }
00416         
00417         m_pCLSID.RemoveAll();
00418         
00419         if ( m_bCOM && ( GetCurrentThreadId() != AfxGetApp()->m_nThreadID ) )
00420         {
00421                 m_bCOM = FALSE;
00422                 CoUninitialize();
00423         }
00424 }
00425 
00427 // CImageServices load bitmap
00428 
00429 BOOL CImageServices::LoadBitmap(CBitmap* pBitmap, UINT nResourceID, LPCTSTR pszType)
00430 {
00431         if ( pBitmap->m_hObject == NULL ) pBitmap->DeleteObject();
00432 
00433         CImageServices pService;
00434         CImageFile pFile( &pService );
00435         if ( ! pFile.LoadFromResource( AfxGetResourceHandle(), nResourceID, pszType ) ) return FALSE;
00436         if ( ! pFile.EnsureRGB() ) return FALSE;
00437         pBitmap->Attach( pFile.CreateBitmap() );
00438 
00439         return TRUE;
00440 }

Generated on Thu Dec 15 10:39:43 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2