Support unrar64.dll
[xy_vsfilter.git] / src / subpic / SubPicImpl.cpp
blob9425d9bb0562c5f35d2f74f0ac2c7208ed1f945c
1 /*
2 * $Id: SubPicImpl.cpp 2786 2010-12-17 16:42:55Z XhmikosR $
4 * (C) 2003-2006 Gabest
5 * (C) 2006-2010 see AUTHORS
7 * This Program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
12 * This Program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Make; see the file COPYING. If not, write to
19 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 * http://www.gnu.org/copyleft/gpl.html
24 #include "stdafx.h"
25 #include "SubPicImpl.h"
26 #include "CRect2.h"
27 #include "../DSUtil/DSUtil.h"
28 #include "../DSUtil/xy_utils.h"
31 // CSubPicImplHelper
34 CSubPicImplHelper::CSubPicImplHelper()
35 : m_rtStart(0), m_rtStop(0)
36 , m_rtSegmentStart(0), m_rtSegmentStop(0)
37 , m_rcDirty(0, 0, 0, 0), m_maxsize(0, 0), m_size(0, 0), m_vidrect(0, 0, 0, 0)
38 , m_VirtualTextureSize(0, 0), m_VirtualTextureTopLeft (0, 0)
42 // ISubPic
44 STDMETHODIMP_(REFERENCE_TIME) CSubPicImplHelper::GetStart() const
46 return(m_rtStart);
49 STDMETHODIMP_(REFERENCE_TIME) CSubPicImplHelper::GetStop() const
51 return(m_rtStop);
54 STDMETHODIMP_(REFERENCE_TIME) CSubPicImplHelper::GetSegmentStart()
56 if (m_rtSegmentStart) {
57 return(m_rtSegmentStart);
59 return(m_rtStart);
62 STDMETHODIMP_(REFERENCE_TIME) CSubPicImplHelper::GetSegmentStop()
64 if (m_rtSegmentStop) {
65 return(m_rtSegmentStop);
67 return(m_rtStop);
70 STDMETHODIMP_(void) CSubPicImplHelper::SetSegmentStart(REFERENCE_TIME rtStart)
72 m_rtSegmentStart = rtStart;
75 STDMETHODIMP_(void) CSubPicImplHelper::SetSegmentStop(REFERENCE_TIME rtStop)
77 m_rtSegmentStop = rtStop;
80 STDMETHODIMP_(void) CSubPicImplHelper::SetStart(REFERENCE_TIME rtStart)
82 m_rtStart = rtStart;
85 STDMETHODIMP_(void) CSubPicImplHelper::SetStop(REFERENCE_TIME rtStop)
87 m_rtStop = rtStop;
90 STDMETHODIMP CSubPicImplHelper::CopyTo(ISubPic* pSubPic)
92 if(!pSubPic)
93 return E_POINTER;
95 pSubPic->SetStart(m_rtStart);
96 pSubPic->SetStop(m_rtStop);
97 pSubPic->SetSegmentStart(m_rtSegmentStart);
98 pSubPic->SetSegmentStop(m_rtSegmentStop);
99 pSubPic->SetDirtyRect(m_rcDirty);
100 pSubPic->SetSize(m_size, m_vidrect);
101 pSubPic->SetVirtualTextureSize(m_VirtualTextureSize, m_VirtualTextureTopLeft);
103 return S_OK;
106 STDMETHODIMP CSubPicImplHelper::GetDirtyRect(RECT* pDirtyRect) const
108 return pDirtyRect ? *pDirtyRect = m_rcDirty, S_OK : E_POINTER;
111 STDMETHODIMP CSubPicImplHelper::GetSourceAndDest(SIZE* pSize, RECT* pRcSource, RECT* pRcDest)
113 CheckPointer (pRcSource, E_POINTER);
114 CheckPointer (pRcDest, E_POINTER);
116 if(m_size.cx > 0 && m_size.cy > 0) {
117 CRect rcTemp = m_rcDirty;
119 // FIXME
120 rcTemp.DeflateRect(1, 1);
122 *pRcSource = rcTemp;
124 rcTemp.OffsetRect (m_VirtualTextureTopLeft);
125 *pRcDest = CRect (rcTemp.left * pSize->cx / m_VirtualTextureSize.cx,
126 rcTemp.top * pSize->cy / m_VirtualTextureSize.cy,
127 rcTemp.right * pSize->cx / m_VirtualTextureSize.cx,
128 rcTemp.bottom * pSize->cy / m_VirtualTextureSize.cy);
130 return S_OK;
131 } else {
132 return E_INVALIDARG;
136 STDMETHODIMP CSubPicImplHelper::SetDirtyRect(RECT* pDirtyRect)
138 return pDirtyRect ? m_rcDirty = *pDirtyRect, S_OK : E_POINTER;
141 STDMETHODIMP CSubPicImplHelper::GetMaxSize(SIZE* pMaxSize) const
143 return pMaxSize ? *pMaxSize = m_maxsize, S_OK : E_POINTER;
146 STDMETHODIMP CSubPicImplHelper::SetSize(SIZE size, RECT vidrect)
148 m_size = size;
149 m_vidrect = vidrect;
151 if(m_size.cx > m_maxsize.cx) {
152 m_size.cy = MulDiv(m_size.cy, m_maxsize.cx, m_size.cx);
153 m_size.cx = m_maxsize.cx;
156 if(m_size.cy > m_maxsize.cy) {
157 m_size.cx = MulDiv(m_size.cx, m_maxsize.cy, m_size.cy);
158 m_size.cy = m_maxsize.cy;
161 if(m_size.cx != size.cx || m_size.cy != size.cy) {
162 m_vidrect.top = MulDiv(m_vidrect.top, m_size.cx, size.cx);
163 m_vidrect.bottom = MulDiv(m_vidrect.bottom, m_size.cx, size.cx);
164 m_vidrect.left = MulDiv(m_vidrect.left, m_size.cy, size.cy);
165 m_vidrect.right = MulDiv(m_vidrect.right, m_size.cy, size.cy);
167 m_VirtualTextureSize = m_size;
169 return S_OK;
172 STDMETHODIMP CSubPicImplHelper::SetVirtualTextureSize (const SIZE pSize, const POINT pTopLeft)
174 m_VirtualTextureSize.SetSize (pSize.cx, pSize.cy);
175 m_VirtualTextureTopLeft.SetPoint (pTopLeft.x, pTopLeft.y);
177 return S_OK;
181 // CSubPicImpl
184 CSubPicImpl::CSubPicImpl()
185 :CUnknown(NAME("CSubPicImpl"), NULL)
186 ,CSubPicImplHelper()
191 STDMETHODIMP CSubPicImpl::NonDelegatingQueryInterface( REFIID riid, void** ppv )
193 return
194 QI(ISubPic)
195 __super::NonDelegatingQueryInterface(riid, ppv);
199 // CSubPicExImpl
202 CSubPicExImpl::CSubPicExImpl()
203 :CUnknown(NAME("CSubPicExImpl"),NULL),CSubPicImplHelper()
208 STDMETHODIMP CSubPicExImpl::NonDelegatingQueryInterface( REFIID riid, void** ppv )
210 return
211 QI(ISubPicEx)
212 (riid == __uuidof(ISubPic)) ? GetInterface( static_cast<ISubPicEx*>(this), ppv) :
213 __super::NonDelegatingQueryInterface(riid, ppv);
216 STDMETHODIMP CSubPicExImpl::CopyTo( ISubPicEx* pSubPicEx )
218 if(!pSubPicEx)
219 return E_POINTER;
221 pSubPicEx->SetStart(m_rtStart);
222 pSubPicEx->SetStop(m_rtStop);
223 pSubPicEx->SetSegmentStart(m_rtSegmentStart);
224 pSubPicEx->SetSegmentStop(m_rtSegmentStop);
225 pSubPicEx->SetDirtyRectEx(&m_rectListDirty);
226 pSubPicEx->SetSize(m_size, m_vidrect);
227 pSubPicEx->SetVirtualTextureSize(m_VirtualTextureSize, m_VirtualTextureTopLeft);
229 return S_OK;
232 STDMETHODIMP CSubPicExImpl::SetDirtyRect(RECT* pDirtyRect)
234 HRESULT hr = CSubPicImplHelper::SetDirtyRect(pDirtyRect);
235 if(hr && pDirtyRect)
237 m_rectListDirty.RemoveAll();
238 m_rectListDirty.AddTail(*pDirtyRect);
239 return S_OK;
241 else
243 return E_POINTER;
247 STDMETHODIMP CSubPicExImpl::SetDirtyRectEx(CAtlList<CRect>* dirtyRectList)
249 if(dirtyRectList!=NULL)
251 m_rectListDirty.RemoveAll();
252 m_rcDirty.SetRectEmpty();
254 POSITION tagPos = NULL;
255 POSITION pos = dirtyRectList->GetHeadPosition();
256 while(pos!=NULL)
258 m_rcDirty |= dirtyRectList->GetNext(pos);
260 MergeRects(*dirtyRectList, &m_rectListDirty);
261 return S_OK;
263 return E_POINTER;
266 STDMETHODIMP CSubPicExImpl::GetDirtyRects( CAtlList<const CRect>& dirtyRectList /*[out]*/ ) const
268 POSITION pos = m_rectListDirty.GetHeadPosition();
269 while(pos!=NULL)
271 dirtyRectList.AddTail(m_rectListDirty.GetNext(pos));
273 return S_OK;
276 STDMETHODIMP CSubPicExImpl::Unlock( RECT* pDirtyRect /*[in]*/ )
278 if(pDirtyRect)
280 CAtlList<CRect> tmp;
281 tmp.AddTail(*pDirtyRect);
282 return Unlock(&tmp);
284 else
286 return Unlock( reinterpret_cast<CAtlList<CRect>*>(NULL) );
292 // CSubPicAllocatorImpl
295 CSubPicAllocatorImpl::CSubPicAllocatorImpl(SIZE cursize, bool fDynamicWriteOnly, bool fPow2Textures )
296 : CUnknown(NAME("ISubPicAllocatorImpl"), NULL)
297 , m_cursize(cursize)
298 , m_fDynamicWriteOnly(fDynamicWriteOnly)
299 , m_fPow2Textures(fPow2Textures)
301 m_curvidrect = CRect(CPoint(0,0), m_cursize);
304 STDMETHODIMP CSubPicAllocatorImpl::NonDelegatingQueryInterface(REFIID riid, void** ppv)
306 return
307 QI(ISubPicAllocator)
308 __super::NonDelegatingQueryInterface(riid, ppv);
311 // ISubPicAllocator
313 STDMETHODIMP CSubPicAllocatorImpl::SetCurSize(SIZE cursize)
315 m_cursize = cursize;
316 return S_OK;
319 STDMETHODIMP CSubPicAllocatorImpl::SetCurVidRect(RECT curvidrect)
321 m_curvidrect = curvidrect;
322 return S_OK;
325 STDMETHODIMP CSubPicAllocatorImpl::GetStatic(ISubPic** ppSubPic)
327 if(!ppSubPic) {
328 return E_POINTER;
331 if(!m_pStatic) {
332 if(!Alloc(true, &m_pStatic) || !m_pStatic) {
333 return E_OUTOFMEMORY;
337 m_pStatic->SetSize(m_cursize, m_curvidrect);
339 (*ppSubPic = m_pStatic)->AddRef();
341 return S_OK;
344 STDMETHODIMP CSubPicAllocatorImpl::AllocDynamic(ISubPic** ppSubPic)
346 if(!ppSubPic) {
347 return E_POINTER;
350 if(!Alloc(false, ppSubPic) || !*ppSubPic) {
351 return E_OUTOFMEMORY;
354 (*ppSubPic)->SetSize(m_cursize, m_curvidrect);
356 return S_OK;
359 STDMETHODIMP_(bool) CSubPicAllocatorImpl::IsDynamicWriteOnly()
361 return(m_fDynamicWriteOnly);
364 STDMETHODIMP CSubPicAllocatorImpl::ChangeDevice(IUnknown* pDev)
366 m_pStatic = NULL;
367 return S_OK;
371 // CSubPicExAllocatorImpl
374 CSubPicExAllocatorImpl::CSubPicExAllocatorImpl( SIZE cursize, bool fDynamicWriteOnly, bool fPow2Textures )
375 :CUnknown(NAME("CSubPicExAllocatorImpl"), NULL)
376 , m_cursize(cursize)
377 , m_fDynamicWriteOnly(fDynamicWriteOnly)
378 , m_fPow2Textures(fPow2Textures)
383 STDMETHODIMP CSubPicExAllocatorImpl::NonDelegatingQueryInterface(REFIID riid, void** ppv)
385 return
386 QI(ISubPicExAllocator)
387 QI(ISubPicAllocator)
388 __super::NonDelegatingQueryInterface(riid, ppv);
391 // ISubPicAllocator
393 STDMETHODIMP CSubPicExAllocatorImpl::SetCurSize(SIZE cursize)
395 m_cursize = cursize;
396 return S_OK;
399 STDMETHODIMP CSubPicExAllocatorImpl::SetCurVidRect(RECT curvidrect)
401 m_curvidrect = curvidrect;
402 return S_OK;
405 STDMETHODIMP CSubPicExAllocatorImpl::GetStatic(ISubPic** ppSubPic)
407 if( !ppSubPic )
409 return GetStaticEx(NULL);
411 else
413 ISubPicEx *temp;
414 HRESULT result = GetStaticEx(&temp);
415 *ppSubPic = temp;
416 return result;
420 STDMETHODIMP CSubPicExAllocatorImpl::AllocDynamic(ISubPic** ppSubPic)
422 if( !ppSubPic )
424 return AllocDynamicEx(NULL);
426 else
428 ISubPicEx *temp;
429 HRESULT result = AllocDynamicEx(&temp);
430 *ppSubPic = temp;
431 return result;
435 STDMETHODIMP_(bool) CSubPicExAllocatorImpl::IsDynamicWriteOnly()
437 return(m_fDynamicWriteOnly);
440 STDMETHODIMP CSubPicExAllocatorImpl::ChangeDevice(IUnknown* pDev)
442 m_pStatic = NULL;
443 return S_OK;
446 // ISubPicExAllocator
448 STDMETHODIMP CSubPicExAllocatorImpl::GetStaticEx(ISubPicEx** ppSubPic)
450 if(!ppSubPic) {
451 return E_POINTER;
454 if(!m_pStatic) {
455 if(!AllocEx(true, &m_pStatic) || !m_pStatic) {
456 return E_OUTOFMEMORY;
460 m_pStatic->SetSize(m_cursize, m_curvidrect);
462 (*ppSubPic = m_pStatic)->AddRef();
464 return S_OK;
467 STDMETHODIMP CSubPicExAllocatorImpl::AllocDynamicEx(ISubPicEx** ppSubPic)
469 if(!ppSubPic) {
470 return E_POINTER;
473 if(!AllocEx(false, ppSubPic) || !*ppSubPic) {
474 return E_OUTOFMEMORY;
477 (*ppSubPic)->SetSize(m_cursize, m_curvidrect);
479 return S_OK;
482 bool CSubPicExAllocatorImpl::Alloc( bool fStatic, ISubPic** ppSubPic )
484 if(ppSubPic==NULL)
486 return AllocEx(fStatic, NULL);
488 else
490 ISubPicEx *temp;
491 bool result = AllocEx(fStatic, &temp);
492 *ppSubPic = temp;
493 return result;
497 STDMETHODIMP_(int) CSubPicExAllocatorImpl::SetSpdColorType( int color_type )
499 (color_type);
500 return MSP_RGBA;
503 STDMETHODIMP_(bool) CSubPicExAllocatorImpl::IsSpdColorTypeSupported( int type )
505 return MSP_RGBA==type;