55using namespace Gdiplus ;
66CThumbnailProvider::CThumbnailProvider ()
77{
8- DllAddRef ();
9- m_cRef = 1 ;
10- m_pSite = nullptr ;
8+ DllAddRef ();
9+ m_cRef = 1 ;
10+ m_pSite = nullptr ;
1111}
1212
1313CThumbnailProvider::~CThumbnailProvider ()
1414{
1515 if ( m_pSite )
16- {
17- m_pSite->Release ();
18- m_pSite = nullptr ;
19- }
20- DllRelease ();
16+ {
17+ m_pSite->Release ();
18+ m_pSite = nullptr ;
19+ }
20+ DllRelease ();
2121}
2222
2323STDMETHODIMP CThumbnailProvider::QueryInterface ( REFIID riid, void ** ppvObject )
@@ -28,26 +28,32 @@ STDMETHODIMP CThumbnailProvider::QueryInterface( REFIID riid, void** ppvObject )
2828 QITABENT ( CThumbnailProvider, IThumbnailProvider ),
2929 QITABENT ( CThumbnailProvider, IObjectWithSite ),
3030 { nullptr , 0 }
31- };
31+ };
3232 return QISearch ( this , qit, riid, ppvObject );
3333}
3434
3535STDMETHODIMP_ ( ULONG ) CThumbnailProvider::AddRef()
3636{
3737 const LONG cRef = InterlockedIncrement ( &m_cRef );
38- return cRef;
38+ return cRef;
3939}
4040
4141STDMETHODIMP_ ( ULONG ) CThumbnailProvider::Release()
4242{
4343 const LONG cRef = InterlockedDecrement ( &m_cRef );
4444 if ( 0 == cRef )
45- delete this ;
45+ delete this ;
4646 return cRef;
4747}
4848
4949STDMETHODIMP CThumbnailProvider::Initialize ( IStream* pstm, DWORD grfMode )
5050{
51+ if ( m_texture.IsLoaded () )
52+ return HRESULT_FROM_WIN32 ( ERROR_ALREADY_INITIALIZED );
53+
54+ if ( grfMode & STGM_READWRITE )
55+ return STG_E_ACCESSDENIED;
56+
5157 STATSTG stat;
5258 if ( pstm->Stat ( &stat, STATFLAG_NONAME ) != S_OK )
5359 return S_FALSE;
@@ -72,11 +78,16 @@ STDMETHODIMP CThumbnailProvider::GetThumbnail( UINT cx, HBITMAP* phbmp, WTS_ALPH
7278 *pdwAlpha = WTSAT_UNKNOWN;
7379 ULONG_PTR token;
7480 GdiplusStartupInput input;
75- if ( Ok == GdiplusStartup ( &token, &input, nullptr ) )
81+ if ( GdiplusStartup ( &token, &input, nullptr ) == Ok )
7682 {
83+ vlUInt32 compressedSize = 0 ;
84+ if ( vlUInt size; auto res = static_cast <byte*>( m_texture.GetResourceData ( VTF_RSRC_AUX_COMPRESSION_INFO, size ) ) )
85+ {
86+ compressedSize = size > sizeof ( AuxCompressionInfoHeader_t ) && reinterpret_cast <AuxCompressionInfoHeader_t*>( res )->m_CompressionLevel != 0 ? reinterpret_cast <AuxCompressionInfoEntry_t*>( res + m_texture.GetAuxInfoOffset ( 0 , 0 , 0 ) )->m_CompressedSize : 0 ;
87+ }
7788 const vlUInt w = m_texture.GetWidth (), h = m_texture.GetHeight ();
7889 byte* pConverted = new byte[CVTFFile::ComputeImageSize ( w, h, 1 , IMAGE_FORMAT_BGRA8888 )];
79- CVTFFile::Convert ( m_texture.GetData (), pConverted, w, h, m_texture.GetFormat (), IMAGE_FORMAT_BGRA8888 );
90+ CVTFFile::Convert ( m_texture.GetData (), pConverted, w, h, m_texture.GetFormat (), IMAGE_FORMAT_BGRA8888, compressedSize );
8091 Bitmap* pBitmap = new Bitmap ( w, h, w * 4 , PixelFormat32bppARGB, pConverted ); // delete?
8192 if ( pBitmap )
8293 {
@@ -85,10 +96,11 @@ STDMETHODIMP CThumbnailProvider::GetThumbnail( UINT cx, HBITMAP* phbmp, WTS_ALPH
8596 pBitmap->GetHBITMAP ( color, phbmp );
8697 *pdwAlpha = WTSAT_ARGB;
8798 }
99+ delete pBitmap;
88100 delete[] pConverted;
89101 }
90- GdiplusShutdown (token);
91- if ( *phbmp != nullptr )
102+ GdiplusShutdown ( token );
103+ if ( *phbmp != nullptr )
92104 return NOERROR;
93105 return E_NOTIMPL;
94106
@@ -104,26 +116,26 @@ STDMETHODIMP CThumbnailProvider::GetSite( REFIID riid, void** ppvSite )
104116STDMETHODIMP CThumbnailProvider::SetSite ( IUnknown* pUnkSite )
105117{
106118 if ( m_pSite )
107- {
108- m_pSite->Release ();
109- m_pSite = nullptr ;
110- }
119+ {
120+ m_pSite->Release ();
121+ m_pSite = nullptr ;
122+ }
111123
112- m_pSite = pUnkSite;
124+ m_pSite = pUnkSite;
113125 if ( m_pSite )
114126 m_pSite->AddRef ();
115127 return S_OK;
116128}
117129
118130STDAPI CThumbnailProvider_CreateInstance ( REFIID riid, void ** ppvObject )
119131{
120- *ppvObject = nullptr ;
132+ *ppvObject = nullptr ;
121133
122- CThumbnailProvider* ptp = new CThumbnailProvider ();
134+ CThumbnailProvider* ptp = new CThumbnailProvider ();
123135 if ( !ptp )
124136 return E_OUTOFMEMORY;
125137
126138 const HRESULT hr = ptp->QueryInterface ( riid, ppvObject );
127- ptp->Release ();
128- return hr;
139+ ptp->Release ();
140+ return hr;
129141}
0 commit comments