home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Internet 2000 May / MICD_2000_05.iso / CBuilder5 / INSTALL / DATA1.CAB / Program_Built_Files / Include / dtbase.cpp < prev    next >
C/C++ Source or Header  |  2000-02-01  |  56KB  |  1,634 lines

  1. /*******************************************************************************
  2. * DTBase.cpp *
  3. *------------*
  4. *   Description:
  5. *    This module contains the CDXBaseNTo1 transform
  6. *-------------------------------------------------------------------------------
  7. *  Created By: Edward W. Connell                            Date: 07/28/97
  8. *  Copyright (C) 1997 Microsoft Corporation
  9. *  All Rights Reserved
  10. *
  11. *-------------------------------------------------------------------------------
  12. *  Revisions:
  13. *
  14. *******************************************************************************/
  15. //--- Additional includes
  16. #include "stdafx.h"
  17. #include <DXTrans.h>
  18. #include "DTBase.h"
  19. #include "new.h"
  20.  
  21. //--- Initialize static member of debug scope class
  22. #ifdef _DEBUG
  23. CDXTDbgFlags CDXTDbgScope::m_DebugFlags;
  24. #endif
  25.  
  26. //--- This should only be used locally in this file. We duplicated this GUID
  27. //    value to avoid having to include DDraw.
  28. static const IID IID_IDXDupDirectDraw =
  29.     { 0x6C14DB80,0xA733,0x11CE, { 0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 } };
  30.  
  31. static const IID IID_IDXDupDDrawSurface =
  32.     { 0x6C14DB81,0xA733,0x11CE, { 0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 } };
  33.  
  34. static const IID IID_IDXDupDirect3DRM =
  35.     {0x2bc49361, 0x8327, 0x11cf, {0xac, 0x4a, 0x0, 0x0, 0xc0, 0x38, 0x25, 0xa1 } };
  36.  
  37. static const IID IID_IDXDupDirect3DRM3 =
  38.     {0x4516ec83, 0x8f20, 0x11d0, {0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3 } };
  39.  
  40. static const IID IID_IDXDupDirect3DRMMeshBuilder3 =
  41.     { 0x4516ec82, 0x8f20, 0x11d0, { 0x9b, 0x6d, 0x00, 0x00, 0xc0, 0x78, 0x1b, 0xc3} };
  42.  
  43. HRESULT CDXDataPtr::Assign(BOOL bMesh, IUnknown * pObject, IDXSurfaceFactory *pSurfaceFactory)
  44. {
  45.     HRESULT hr = S_OK;
  46.     if (pObject)
  47.     {
  48.         IUnknown *pNative = NULL;
  49.         if (!bMesh)
  50.         {
  51.             //--- Try to get a DX surface
  52.             hr = pObject->QueryInterface( IID_IDXSurface, (void **)&pNative );
  53.             if( FAILED( hr ) )
  54.             {
  55.                 IDirectDrawSurface *pSurf;
  56.                 //--- Try to get a DDraw surface
  57.                 hr = pObject->QueryInterface( IID_IDXDupDDrawSurface, (void **)&pSurf );
  58.                 if( SUCCEEDED( hr ) )
  59.                 {
  60.                     //--- Create a DXSurface from the DDraw surface
  61.                     hr = pSurfaceFactory->CreateFromDDSurface(
  62.                                 pSurf, NULL, 0, NULL, IID_IDXSurface,
  63.                                 (void **)&pNative );
  64.                     pSurf->Release();
  65.                 }
  66.             }
  67.         }
  68.         else // Must be a mesh builder
  69.         {
  70.             hr = pObject->QueryInterface(IID_IDXDupDirect3DRMMeshBuilder3, (void **)&pNative);
  71.         }
  72.         if (SUCCEEDED(hr))
  73.         {
  74.             Release();
  75.             m_pNativeInterface = pNative;
  76.             pObject->AddRef();
  77.             m_pUnkOriginalObject = pObject;
  78.             if (SUCCEEDED(pNative->QueryInterface(IID_IDXBaseObject, (void **)&m_pBaseObj)))
  79.             {
  80.                 m_pBaseObj->GetGenerationId(&m_dwLastDirtyGenId);
  81.                 m_dwLastDirtyGenId--;
  82.             }
  83.             if (!bMesh)
  84.             {   
  85.                 ((IDXSurface *)pNative)->GetPixelFormat(NULL, &m_SampleFormat);
  86.             }
  87.         }
  88.         else
  89.         {
  90.             if (hr == E_NOINTERFACE)
  91.             {
  92.                 hr = E_INVALIDARG;
  93.             }
  94.         }
  95.     }
  96.     else 
  97.     {
  98.         Release();
  99.     }
  100.     return hr;
  101. } /* CDXDataPtr::Assign */
  102.  
  103. bool CDXDataPtr::IsDirty(void)
  104. {
  105.     if (m_pBaseObj)
  106.     {
  107.         DWORD dwOldId = m_dwLastDirtyGenId;
  108.         m_pBaseObj->GetGenerationId(&m_dwLastDirtyGenId);
  109.         return dwOldId != m_dwLastDirtyGenId;
  110.     }
  111.     else
  112.     {
  113.         return false;
  114.     }
  115.  
  116. }
  117.  
  118. DWORD CDXDataPtr::GenerationId(void)
  119. {
  120.     if (m_pBaseObj)
  121.     {
  122.         DWORD dwGenId;
  123.         m_pBaseObj->GetGenerationId(&dwGenId);
  124.         return dwGenId;
  125.     }
  126.     else
  127.     {
  128.         return 0;
  129.     }
  130. }
  131.  
  132.  
  133. bool CDXDataPtr::UpdateGenerationId(void)
  134. {
  135.     if (m_pBaseObj)
  136.     {
  137.         DWORD dwOldId = m_dwLastUpdGenId;
  138.         m_pBaseObj->GetGenerationId(&m_dwLastUpdGenId);
  139.         return dwOldId != m_dwLastUpdGenId;
  140.     }
  141.     else
  142.     {
  143.         return false;
  144.     }
  145. } /* CDXDataPtr::UpdateGenerationId */
  146.  
  147. ULONG CDXDataPtr::ObjectSize(void)
  148. {
  149.     ULONG ulSize = 0;
  150.     if (m_pBaseObj)
  151.     {
  152.         m_pBaseObj->GetObjectSize(&ulSize);
  153.     }
  154.     return ulSize;    
  155. }
  156.  
  157. /*****************************************************************************
  158. * CDXBaseNTo1::CDXBaseNTo1 *
  159. *--------------------------*
  160. *   Description:
  161. *       Constructor
  162. *-----------------------------------------------------------------------------
  163. *   Created By: Ed Connell                            Date: 07/28/97
  164. *-----------------------------------------------------------------------------
  165. *   Parameters:
  166. *****************************************************************************/
  167. CDXBaseNTo1::CDXBaseNTo1() :
  168.     m_aInputs(NULL),
  169.     m_ulNumInputs(0),
  170.     m_ulNumProcessors(1),   // Default to one until task manager is set
  171.     m_dwGenerationId(1),
  172.     m_dwCleanGenId(0),
  173.     m_Duration(1.0f),
  174.     m_StepResolution(0.0f),
  175.     m_Progress(0.0f),
  176.     m_dwBltFlags(0),
  177.     m_bPickDoneByBase(false),
  178.     m_bInMultiThreadWorkProc(FALSE),
  179.     m_fQuality(0.5f),   // Default to normal quality.
  180.     //  Wait forever before timing out on a lock by default
  181.     m_ulLockTimeOut(INFINITE),
  182.     //
  183.     //  Override these flags if your object does not support one or more of these options.
  184.     //  Typically, 3-D effects should set this member to 0.
  185.     //
  186.     m_dwMiscFlags(DXTMF_BLEND_WITH_OUTPUT | DXTMF_DITHER_OUTPUT |
  187.                   DXTMF_BLEND_SUPPORTED | DXTMF_DITHER_SUPPORTED | DXTMF_BOUNDS_SUPPORTED | DXTMF_PLACEMENT_SUPPORTED),
  188.     //
  189.     //  If your object has a different number of objects or a different number of
  190.     //  required objects than 1, simply set these members in the body of your
  191.     //  constructor or in FinalConstruct().  For every input that is > the number
  192.     //  required, that input will be reported as optional.
  193.     //
  194.     //  If your transform takes 2 required inputs, set both to 2.
  195.     //  If your transform takes 2 optional inputs, set MaxInputs = 2, NumInRequired = 0
  196.     //  If your transform takes 1 required and 2 optional inputs,
  197.     //      set MaxInputs = 2, NumInRequired = 1
  198.     //
  199.     //  For more complex combinations of optinal/required, you will need to override
  200.     //  the OnSetup method of this base class, and override the methods
  201.     //      GetInOutInfo
  202.     //
  203.     m_ulMaxInputs(1),
  204.     m_ulNumInRequired(1),
  205.     //
  206.     //  If the intputs or output types are not surfaces then set appropriate object type
  207.     //
  208.     m_dwOptionFlags(0),     // Inputs and output are surfaces, don't have to be the same size
  209.     m_ulMaxImageBands(DXB_MAX_IMAGE_BANDS)
  210. {
  211.     DXTDBG_FUNC( "CDXBaseNTo1::CDXBaseNTo1" );
  212.     //
  213.     //  Set event handles to NULL.
  214.     //
  215.     memset(m_aEvent, 0, sizeof(m_aEvent));
  216. } /* CDXBaseNTo1::CDXBaseNTo1 */
  217.  
  218. /*****************************************************************************
  219. * CDXBaseNTo1::~CDXBaseNTo1 *
  220. *---------------------------*
  221. *   Description:
  222. *       Constructor
  223. *-----------------------------------------------------------------------------
  224. *   Created By: Ed Connell                            Date: 07/28/97
  225. *-----------------------------------------------------------------------------
  226. *   Parameters:
  227. *****************************************************************************/
  228. CDXBaseNTo1::~CDXBaseNTo1()
  229. {
  230.     DXTDBG_FUNC( "CDXBaseNTo1::~CDXBaseNTo1" );
  231.     _ReleaseReferences();
  232.     delete[] m_aInputs;
  233.  
  234.     //--- Release event objects
  235.     for(ULONG i = 0; i < DXB_MAX_IMAGE_BANDS; ++i )
  236.     {
  237.         if( m_aEvent[i] ) ::CloseHandle( m_aEvent[i] );
  238.     }
  239. } /* CDXBaseNTo1::~CDXBaseNTo1 */
  240.  
  241.  
  242. /*****************************************************************************
  243. * CDXBaseNTo1::_ReleaseRefernces *
  244. *--------------------------------*
  245. *   Description:
  246. *       Releases all references to input and output objects
  247. *-----------------------------------------------------------------------------
  248. *   Created By: RAL
  249. *-----------------------------------------------------------------------------
  250. *   Parameters:
  251. *****************************************************************************/
  252. void CDXBaseNTo1::_ReleaseReferences()
  253. {
  254.     //--- Release data objects
  255.     if( m_aInputs )
  256.     {
  257.         for( ULONG i = 0; i < m_ulNumInputs; ++i )
  258.         {
  259.             m_aInputs[i].Release();
  260.         }
  261.     }
  262.  
  263.     m_Output.Release();
  264. } /* CDXBaseNTo1::_ReleaseRefernces */
  265.  
  266.  
  267.  
  268. STDMETHODIMP CDXBaseNTo1::GetGenerationId(ULONG *pGenerationId)
  269. {
  270.     DXTDBG_FUNC( "CDXBaseNTo1::GetGenerationId" );
  271.     if (DXIsBadWritePtr(pGenerationId, sizeof(*pGenerationId)))
  272.     {
  273.         return E_POINTER;
  274.     }
  275.     Lock();
  276.     OnUpdateGenerationId();
  277.     *pGenerationId = m_dwGenerationId;
  278.     Unlock();
  279.     return S_OK;
  280. }
  281.  
  282. STDMETHODIMP CDXBaseNTo1::IncrementGenerationId(BOOL bRefresh)
  283. {
  284.     DXTDBG_FUNC( "CDXBaseNTo1::IncrementGenerationId" );
  285.     HRESULT hr = S_OK;
  286.     Lock();
  287.     m_dwGenerationId++;
  288.     if (bRefresh)
  289.     {
  290.         //
  291.         //  If we have any inputs or outputs, call Setup again to refresh all internal
  292.         //  knowledge about the surfaces (formats, height or width could change, etc.)
  293.         //
  294.         //  Note that we need to AddRef the objects prior to calling Setup becuase the
  295.         //  DXTransform may be the only object holding a referec
  296.         //
  297.         ULONG cInputs = m_ulNumInputs;
  298.         ULONG cOutputs = 0;
  299.         IUnknown *pOutput = m_Output.m_pUnkOriginalObject;
  300.         if (pOutput)
  301.         {
  302.             cOutputs = 1;
  303.             pOutput->AddRef();
  304.         }
  305.         IUnknown ** ppInputs = NULL;
  306.         if (cInputs)
  307.         {
  308.             ppInputs = (IUnknown **)_alloca(m_ulNumInputs * sizeof(IUnknown *));
  309.             for (ULONG i = 0; i < cInputs; i++)
  310.             {
  311.                 ppInputs[i] = m_aInputs[i].m_pUnkOriginalObject;
  312.                 if (ppInputs[i]) ppInputs[i]->AddRef();
  313.             }
  314.         }
  315.         if (cInputs || cOutputs)    // If we're not setup, skip this step.
  316.         {
  317.             hr = Setup(ppInputs, cInputs, &pOutput, cOutputs, 0);
  318.             if (pOutput) pOutput->Release();
  319.             for (ULONG i = 0; i < cInputs; i++)
  320.             {
  321.                 if (ppInputs[i]) ppInputs[i]->Release();
  322.             }
  323.         }
  324.     }
  325.     Unlock();
  326.     return hr;
  327. }
  328.  
  329.  
  330. STDMETHODIMP CDXBaseNTo1::GetObjectSize(ULONG *pcbSize)
  331. {
  332.     DXTDBG_FUNC( "CDXBaseNTo1::GetObjectSize" );
  333.     HRESULT hr = S_OK;
  334.     if (DXIsBadWritePtr(pcbSize, sizeof(*pcbSize)))
  335.     {
  336.         hr = E_POINTER;
  337.     }
  338.     else
  339.     {
  340.     Lock();
  341.         *pcbSize = OnGetObjectSize();
  342.         Unlock();
  343.     }
  344.     return hr;
  345. }
  346.  
  347.  
  348. void CDXBaseNTo1::_ReleaseServices(void)
  349. {
  350.     m_cpTransFact.Release();
  351.     m_cpSurfFact.Release();
  352.     m_cpTaskMgr.Release();
  353.     m_cpDirectDraw.Release();
  354.     m_cpDirect3DRM.Release();
  355. }
  356.  
  357. //
  358. //  The documentation for SetSite indicates that it is invaid to return
  359. //  an error from this function, even if the site does not support the
  360. //  functionality we want.  So, even if there is no service provider, or
  361. //  the required services are not available, we will return S_OK.
  362. //
  363. STDMETHODIMP CDXBaseNTo1::SetSite(IUnknown * pUnkSite)
  364. {
  365.     DXTDBG_FUNC( "CDXBaseNTo1::SetSite" );
  366.     HRESULT hr = S_OK;
  367.     Lock();
  368.     m_cpUnkSite = pUnkSite;
  369.     _ReleaseServices();
  370.     if (pUnkSite)
  371.     {
  372.         if (DXIsBadInterfacePtr(pUnkSite))
  373.         {
  374.             hr = E_INVALIDARG;
  375.         }
  376.         else
  377.         {
  378.             HRESULT hr2;
  379.             hr2 = pUnkSite->QueryInterface(IID_IDXTransformFactory, (void **)&m_cpTransFact);
  380.         if (SUCCEEDED(hr2))
  381.         {
  382.                 //
  383.                 //  Allocate memory for inputs if necessary
  384.                 //
  385.                 if (m_aInputs == NULL && m_ulMaxInputs)
  386.                 {
  387.                     m_aInputs  = new CDXDataPtr[m_ulMaxInputs];
  388.                     if (!m_aInputs)
  389.                     {
  390.                         _ASSERT(TRUE);
  391.                         hr2 = E_OUTOFMEMORY;
  392.                     }
  393.                 }
  394.                 hr2 = m_cpTransFact->QueryService( SID_SDXSurfaceFactory, IID_IDXSurfaceFactory, (void **)&m_cpSurfFact);
  395.                 if (SUCCEEDED(hr2))
  396.                 {
  397.                     hr2 = m_cpTransFact->QueryService( SID_SDXTaskManager, IID_IDXTaskManager, (void **)&m_cpTaskMgr);
  398.                 }
  399.                 if (SUCCEEDED(hr2))
  400.                 {
  401.                     m_cpTaskMgr->QueryNumProcessors(&m_ulNumProcessors);
  402.                     if (m_ulMaxImageBands && (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)) == 0)
  403.                     {
  404.                         for (ULONG i = 0; SUCCEEDED(hr2) && i < m_ulMaxImageBands; i++)
  405.                         {
  406.                             //
  407.                             // In theory we could get back here after failing to create an event, or
  408.                             // by getting a new site, so make sure it's non-null before creating one.
  409.                             //
  410.                             if (m_aEvent[i] == NULL)
  411.                             {
  412.                                 m_aEvent[i] = ::CreateEvent(NULL, true, false, NULL);
  413.                                 if (m_aEvent[i] == NULL)
  414.                                 {
  415.                                     hr2 = E_OUTOFMEMORY;
  416.                                 }
  417.                             }
  418.  
  419.                         }
  420.                     }
  421.                 }
  422.                 if (SUCCEEDED(hr2))
  423.                 {
  424.                     hr2 = m_cpTransFact->QueryService(SID_SDirectDraw, IID_IDXDupDirectDraw, (void**)&m_cpDirectDraw);
  425.                 }
  426.                 if (SUCCEEDED(hr2) && 
  427.                     (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)))
  428.                 {
  429.                     hr2 = m_cpTransFact->QueryService(SID_SDirect3DRM, IID_IDXDupDirect3DRM3, (void **)&m_cpDirect3DRM);
  430.                 }
  431.                 if (FAILED(hr2))
  432.                 {
  433.                     _ASSERT(TRUE);
  434.                     _ReleaseServices();
  435.                 }
  436.             }
  437.         }
  438.     }
  439.     Unlock();
  440.     return hr;
  441. }
  442.  
  443.  
  444. STDMETHODIMP CDXBaseNTo1::GetSite(REFIID riid, void **ppv)
  445. {
  446.     DXTDBG_FUNC( "CDXBaseNTo1::GetSite" );
  447.     HRESULT hr = S_OK;
  448.     if( DXIsBadWritePtr(ppv, sizeof(*ppv)) )
  449.     {
  450.         hr = E_POINTER;
  451.     }
  452.     else
  453.     {
  454.         Lock();
  455.         if (m_cpUnkSite)
  456.         {
  457.             hr = m_cpUnkSite->QueryInterface(riid, ppv);
  458.         }
  459.         else
  460.         {
  461.             *ppv = NULL;
  462.             hr = E_FAIL;    // This is the proper documented return code
  463.                             // for this interface if no service provider.
  464.         }
  465.         Unlock();
  466.     }
  467.     return hr;
  468.  
  469.  
  470. void CDXBaseNTo1::_UpdateBltFlags(void)
  471. {
  472.     m_dwBltFlags = 0;
  473.     if ((m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER) == 0)
  474.     {
  475.         if (m_dwMiscFlags & DXTMF_BLEND_WITH_OUTPUT) 
  476.         {
  477.             if ((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) || m_ulNumInputs == 0)
  478.             {
  479.                 m_dwBltFlags |= DXBOF_DO_OVER;
  480.             }
  481.             else
  482.             {
  483.                 for(ULONG i = 0; i < m_ulNumInputs; ++i )
  484.                 {
  485.                     if (InputSampleFormat(i) & DXPF_TRANSPARENCY)
  486.                     {
  487.                         m_dwBltFlags |= DXBOF_DO_OVER;
  488.                         break;
  489.                     }
  490.                 }
  491.             }
  492.         }
  493.         //
  494.         //  Set the dither flag to true only if output error is > at least one input
  495.         //
  496.         if (m_dwMiscFlags & DXTMF_DITHER_OUTPUT)
  497.         {
  498.             ULONG OutputErr = (OutputSampleFormat() & DXPF_ERRORMASK);
  499.             if (OutputErr)
  500.             {
  501.                 if (m_ulNumInputs)
  502.                 {
  503.                     for(ULONG i = 0; i < m_ulNumInputs; ++i )
  504.                     {
  505.                         if (InputSurface(i) && (ULONG)(InputSampleFormat(i) & DXPF_ERRORMASK) < OutputErr)
  506.                         {
  507.                             m_dwBltFlags |= DXBOF_DITHER;
  508.                             break;
  509.                         }
  510.                     }
  511.                 }
  512.                 else
  513.                 {
  514.                     //
  515.                     // If output has no error then don't set dither in blt flags
  516.                     //  
  517.                     if (OutputErr)
  518.                     {
  519.                         m_dwBltFlags |= DXBOF_DITHER; 
  520.                     }
  521.                 }
  522.             }
  523.         }
  524.     }
  525. }
  526.  
  527.  
  528.  
  529. /*****************************************************************************
  530. * CDXBaseNTo1::Setup *
  531. *--------------------*
  532. *   Description:
  533. *       The Setup method is used to perform any required one-time setup
  534. *   before the Execute method is called. Single surfaces or SurfaceSets may
  535. *   be used as arguments in any combination. 
  536. *   If punkOutputs is NULL, Execute will allocate an output result of the
  537. *   appropriate size and return it.
  538. *   if punkInputs and punkOutputs are NULL and it is a quick setup, the current
  539. *   input and output objects are released.
  540. *-----------------------------------------------------------------------------
  541. *   Created By: Ed Connell                            Date: 07/28/97
  542. *-----------------------------------------------------------------------------
  543. *   Parameters:
  544. *****************************************************************************/
  545. STDMETHODIMP CDXBaseNTo1::Setup( IUnknown * const * punkInputs, ULONG ulNumInputs,
  546.                                  IUnknown * const * punkOutputs, ULONG ulNumOutputs, DWORD dwFlags )
  547. {
  548.     DXTDBG_FUNC( "CDXBaseNTo1::Setup" );
  549.     //--- Lock object so state cannot change during setup
  550.     DXAUTO_OBJ_LOCK
  551.     HRESULT hr = S_OK;
  552.     ULONG i;
  553.  
  554.     //
  555.     //  Early out for null setup.  Forget about all other param validation, just do it.
  556.     //  
  557.     if (ulNumInputs == 0 && ulNumOutputs == 0)
  558.     {
  559.         _ReleaseReferences();
  560.         OnReleaseObjects();
  561.         return hr;
  562.     }
  563.  
  564.     //--- Validate Params
  565.     //--- Make sure we have a reference to the transform factory
  566.     if( !m_cpTransFact )
  567.     {
  568.         hr = DXTERR_UNINITIALIZED;
  569.         DXTDBG_MSG0( _CRT_ERROR, "\nTransform has not been initialized" );
  570.     }
  571.     else
  572.     {
  573.         //
  574.         //  We know that if we have a transform factory that we must also have
  575.         //  allocated m_aInputs since this is done on SetSite to avoid work during
  576.         //  each setup.
  577.         //
  578.         _ASSERT(m_aInputs || m_ulMaxInputs == 0);
  579.         if( dwFlags ||              // No flags are valid
  580.             ulNumOutputs != 1 ||
  581.             ulNumInputs < m_ulNumInRequired ||
  582.             ulNumInputs > m_ulMaxInputs ||
  583.             (ulNumInputs && DXIsBadReadPtr( punkInputs , sizeof( *punkInputs ) * ulNumInputs )) ||
  584.             DXIsBadReadPtr(punkOutputs, sizeof(*punkOutputs)) ||
  585.             DXIsBadInterfacePtr(punkOutputs[0]))
  586.         {
  587.             hr = E_INVALIDARG;
  588.             DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
  589.         }
  590.         else
  591.         {
  592.             for( i = 0; i < ulNumInputs; ++i )
  593.             {
  594.                 if((punkInputs[i] && DXIsBadInterfacePtr(punkInputs[i])) ||
  595.                     (punkInputs[i] == NULL && i < m_ulNumInRequired))
  596.                 {
  597.                     hr = E_INVALIDARG;
  598.                     DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
  599.                     break;
  600.                 }
  601.             }        
  602.         }
  603.     }
  604.  
  605.     //--- Allocate slots for input data object pointers
  606.     if( SUCCEEDED( hr ) )
  607.     {
  608.         //--- Release data objects
  609.         _ReleaseReferences();
  610.         m_ulNumInputs = ulNumInputs;
  611.     }
  612.  
  613.     //
  614.     //  Assign 
  615.     //
  616.     for( i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i )
  617.     {
  618.         hr = m_aInputs[i].Assign((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER), punkInputs[i], m_cpSurfFact);
  619.     }
  620.  
  621.     if( SUCCEEDED(hr) )
  622.     {
  623.         hr = m_Output.Assign((m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER), punkOutputs[0], m_cpSurfFact);
  624.     }   
  625.  
  626.     if (SUCCEEDED(hr) && (m_dwOptionFlags & DXBOF_SAME_SIZE_INPUTS))
  627.     {
  628.         hr = _MakeInputsSameSize();
  629.     }
  630.  
  631.     if (SUCCEEDED(hr))
  632.     {
  633.         _UpdateBltFlags();      // Do this before calling OnSetup...
  634.         hr = OnSetup(dwFlags);
  635.     }
  636.     
  637.     if (FAILED(hr))
  638.     {
  639.         _ReleaseReferences();
  640.         OnReleaseObjects();
  641.         DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup failed" );
  642.     }
  643.  
  644.     return hr;
  645. } /* CDXBaseNTo1::Setup */
  646.  
  647.  
  648. /*****************************************************************************
  649. * CDXBaseNTo1::_MakeInputsSameSize *
  650. *----------------------------------*
  651. *   Description:
  652. *-----------------------------------------------------------------------------
  653. *   Created By: RAL                            Date: 03/31/98
  654. *-----------------------------------------------------------------------------
  655. *   Parameters:
  656. *****************************************************************************/
  657.  
  658. HRESULT CDXBaseNTo1::_MakeInputsSameSize(void)
  659. {
  660.     _ASSERT((m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) == 0);
  661.  
  662.     HRESULT hr = S_OK;
  663.     if (m_ulNumInputs > 1)      // No need to do this for just one input!
  664.     {
  665.         CDXDBnds SurfBnds(false);
  666.         CDXDBnds Union(true);
  667.         for (ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; i++)
  668.         {
  669.             if (InputSurface(i))
  670.             {
  671.                 hr = SurfBnds.SetToSurfaceBounds(InputSurface(i));
  672.                 Union |= SurfBnds;
  673.             }
  674.         }
  675.         for (i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; i++)
  676.         {
  677.             if (InputSurface(i))
  678.             {
  679.                 hr = SurfBnds.SetToSurfaceBounds(InputSurface(i));
  680.                 if (SUCCEEDED(hr) && SurfBnds != Union)
  681.                 {
  682.                     IDXSurfaceModifier *pSurfMod;
  683.                     hr = ::CoCreateInstance(CLSID_DXSurfaceModifier, NULL, CLSCTX_INPROC,
  684.                                             IID_IDXSurfaceModifier, (void **)&pSurfMod);
  685.                     if (SUCCEEDED(hr))
  686.                     {
  687.                         POINT p;
  688.                         p.x = p.y = 0;
  689.                         if (m_dwOptionFlags & DXBOF_CENTER_INPUTS)
  690.                         {
  691.                             p.x = (Union.Width() - SurfBnds.Width()) / 2;
  692.                             p.y = (Union.Height() - SurfBnds.Height()) / 2;
  693.                         }
  694.                         pSurfMod->SetForeground(InputSurface(i), FALSE, &p);
  695.                         pSurfMod->SetBounds(&Union);
  696.                         InputSurface(i)->Release();
  697.                         pSurfMod->QueryInterface(IID_IDXSurface, (void **)&(m_aInputs[i].m_pNativeInterface));
  698.                         ((IDXSurface *)m_aInputs[i].m_pNativeInterface)->GetPixelFormat(NULL, &m_aInputs[i].m_SampleFormat);
  699.                         pSurfMod->Release();
  700.                     }
  701.                 }
  702.             }
  703.         }
  704.     }
  705.     return hr;
  706. }
  707.  
  708.  
  709. /*****************************************************************************
  710. * CDXBaseNTo1::Execute *
  711. *----------------------*
  712. *   Description:
  713. *       The Execute method is used to walk the inputs/outputs and break up the
  714. *   work into suitably sized pieces to spread symetrically accross the available
  715. *   processors in the system.
  716. *-----------------------------------------------------------------------------
  717. *   Created By: Ed Connell                            Date: 07/28/97
  718. *-----------------------------------------------------------------------------
  719. *   Parameters:
  720. *****************************************************************************/
  721. STDMETHODIMP CDXBaseNTo1::
  722.     Execute( const GUID* pRequestID, const DXBNDS *pClipBnds, const DXVEC *pPlacement )
  723. {
  724.     DXTDBG_FUNC( "CDXBaseNTo1::Execute" );
  725.     //--- Lock object so state cannot change during execution
  726.     DXAUTO_OBJ_LOCK
  727.     HRESULT hr = S_OK;
  728.  
  729.     //--- Check args
  730.     if( !HaveOutput() )
  731.     {
  732.         DXTDBG_MSG0( _CRT_ERROR, "\nTransform has not been initialized" );
  733.         return DXTERR_UNINITIALIZED;
  734.     }
  735.  
  736.     if (m_ulMaxImageBands == 0 ||
  737.         (m_dwOptionFlags & (DXBOF_INPUTS_MESHBUILDER | DXBOF_OUTPUT_MESHBUILDER)))
  738.     {
  739.         if ((pClipBnds && (m_dwMiscFlags & DXTMF_BOUNDS_SUPPORTED) == 0) ||
  740.             (pPlacement && (m_dwMiscFlags & DXTMF_PLACEMENT_SUPPORTED) == 0) )
  741.         {
  742.             DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
  743.             return E_INVALIDARG;
  744.         }
  745.         return OnExecute( pRequestID, pClipBnds, pPlacement );
  746.     }
  747.  
  748.     //--- Banded image working variables
  749.     CDXTWorkInfoNTo1 WI;
  750.  
  751.     if ((pClipBnds && pClipBnds->eType != DXBT_DISCRETE) ||
  752.         (pPlacement && pPlacement->eType != DXBT_DISCRETE))
  753.     {
  754.         hr = E_INVALIDARG;
  755.         DXTDBG_MSG0( _CRT_ERROR, "\nTransform setup with invalid args" );
  756.     }
  757.     else
  758.     {
  759.         hr = MapBoundsIn2Out( NULL, 0, 0, &WI.DoBnds );
  760.         if( hr == S_OK )
  761.         {
  762.             hr = WI.OutputBnds.SetToSurfaceBounds(OutputSurface());
  763.             if (hr == S_OK)
  764.             {
  765.                 hr = DXClipToOutputWithPlacement(WI.DoBnds, (CDXDBnds *)pClipBnds, WI.OutputBnds, (CDXDVec *)pPlacement);
  766.             }
  767.         }
  768.     }
  769.  
  770.     //--- Check for clipping early exit
  771.     if( hr != S_OK )
  772.     {
  773.         return hr;
  774.     }
  775.  
  776.     //=== Process ====================================================
  777.     _ASSERT(m_ulMaxImageBands <= DXB_MAX_IMAGE_BANDS);
  778.     ULONG ulNumBandsToDo = m_ulNumProcessors;
  779.     if( ulNumBandsToDo > 1 )
  780.     {
  781.         ulNumBandsToDo = 1 + ((WI.OutputBnds.Width() * WI.OutputBnds.Height()) / 0x1000);
  782.         if (ulNumBandsToDo > m_ulMaxImageBands)
  783.         {
  784.             ulNumBandsToDo = m_ulMaxImageBands;
  785.         }
  786.         if (ulNumBandsToDo > m_ulNumProcessors)
  787.         {
  788.             ulNumBandsToDo = m_ulNumProcessors;
  789.         }
  790.     }
  791.     hr = OnInitInstData(WI, ulNumBandsToDo);
  792.     if( SUCCEEDED( hr ) )
  793.     {
  794.         if (ulNumBandsToDo == 1 && pRequestID == NULL)
  795.         {
  796.             static BOOL bContinue = TRUE;
  797.             hr = WorkProc(WI, &bContinue);
  798.         }
  799.         else
  800.         {
  801.             _ASSERT( ulNumBandsToDo <= DXB_MAX_IMAGE_BANDS );
  802.             _ASSERT( m_aEvent[ulNumBandsToDo-1] );
  803.  
  804.             long lStartAtRow = WI.DoBnds[DXB_Y].Min;
  805.             ULONG ulRowCount = WI.DoBnds[DXB_Y].Max - lStartAtRow;
  806.             _ASSERT( ( ulRowCount / ulNumBandsToDo ) != 0 );
  807.  
  808.             //--- Init the work info structures
  809.             ULONG ulBand, RowsPerBand = ulRowCount / ulNumBandsToDo;
  810.             CDXTWorkInfoNTo1 *WIArray = (CDXTWorkInfoNTo1*)alloca( sizeof(CDXTWorkInfoNTo1) *
  811.                                                          ulNumBandsToDo );
  812.             DWORD *TaskIDs = (DWORD*)alloca( sizeof(DWORD) * ulNumBandsToDo );
  813.             DXTMTASKINFO* TaskInfo = (DXTMTASKINFO*)alloca( sizeof( DXTMTASKINFO ) *
  814.                                                             ulNumBandsToDo );
  815.  
  816.             //--- Build task info list
  817.             WI.hr       = S_OK;
  818.             WI.pvThis   =  this;
  819.             long Start  = lStartAtRow;
  820.             ULONG Count = RowsPerBand;
  821.             long OutputYDelta = WI.OutputBnds[DXB_Y].Min - WI.DoBnds[DXB_Y].Min;
  822.  
  823.             for( ulBand = 0; ulBand < ulNumBandsToDo; ++ulBand )
  824.             {
  825.                 memcpy( &WIArray[ulBand], &WI, sizeof( WI ) );
  826.                 WIArray[ulBand].DoBnds[DXB_Y].Min = Start;
  827.                 WIArray[ulBand].OutputBnds[DXB_Y].Min = Start + OutputYDelta;
  828.                 WIArray[ulBand].DoBnds[DXB_Y].Max = Start + Count;
  829.                 WIArray[ulBand].OutputBnds[DXB_Y].Max = Start + Count + OutputYDelta;
  830.  
  831.                 TaskInfo[ulBand].pfnTaskProc      = _TaskProc;
  832.                 TaskInfo[ulBand].pTaskData        = &WIArray[ulBand];
  833.                 TaskInfo[ulBand].pfnCompletionAPC = NULL;
  834.                 TaskInfo[ulBand].dwCompletionData = 0;
  835.                 TaskInfo[ulBand].pRequestID       = pRequestID;
  836.  
  837.                 //--- Advance
  838.                 Start += Count;
  839.                 //--- Check for a remainder and add on to the last band.
  840.                 if( ( ulRowCount - ( Start + Count ) ) < Count )
  841.                 {
  842.                     Count = ulRowCount - Start;
  843.                 }
  844.             }
  845.  
  846.             //
  847.             //  Procedural surfaces (and perhaps some transforms) need to "know" that
  848.             //  they are in a multi-threaded work procedure to avoid deadlocks.  Procedural
  849.             //  surfaces need to allow LockSurface to work WITHOUT taking the object
  850.             //  critical section.  Other transforms may also want to know this information
  851.             //  to avoid deadlocks.
  852.             //
  853.             m_bInMultiThreadWorkProc = TRUE;
  854.  
  855.             //--- Schedule the work and wait for it to complete
  856.             hr = m_cpTaskMgr->ScheduleTasks( TaskInfo, m_aEvent,
  857.                                              TaskIDs, ulNumBandsToDo, m_ulLockTimeOut );
  858.  
  859.             m_bInMultiThreadWorkProc = FALSE;
  860.  
  861.             //--- Check return codes from work info structures
  862.             //    return the first bad hr if any
  863.             for( ulBand = 0; SUCCEEDED( hr ) && ( ulBand < ulNumBandsToDo ); ++ulBand )
  864.             {
  865.                 hr = WIArray[ulBand].hr;
  866.                 if( hr != S_OK ) break;
  867.             }
  868.         }
  869.         OnFreeInstData( WI );
  870.     }
  871.  
  872. #ifdef _DEBUG
  873.     if( FAILED( hr ) ) DXTDBG_MSG1( _CRT_ERROR, "\nExecute failed. HR = %X", hr );
  874. #endif
  875.  
  876.     return hr;
  877. } /* CDXBaseNTo1::Execute */
  878.  
  879. /*****************************************************************************
  880. * CDXBaseNTo1::_ImageMapIn2Out *
  881. *------------------------------*
  882. *   Description:
  883. *-----------------------------------------------------------------------------
  884. *   Created By: RAL                            Date: 07/28/97
  885. *****************************************************************************/
  886. HRESULT CDXBaseNTo1::_ImageMapIn2Out( CDXDBnds & bnds, ULONG ulNumInBnds,
  887.                                       const CDXDBnds * pInBounds )
  888. {
  889.     HRESULT hr = S_OK;
  890.     if(ulNumInBnds)
  891.     {
  892.         for(ULONG i = 0; i < ulNumInBnds; ++i )
  893.         {
  894.             bnds |= pInBounds[i];
  895.         }
  896.     }
  897.     else
  898.     {
  899.         for( ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i )
  900.         {
  901.             if (InputSurface(i))
  902.             {
  903.                 CDXDBnds SurfBnds(InputSurface(i), hr);
  904.                 bnds |= SurfBnds;
  905.             }
  906.         }
  907.     }
  908.     if (SUCCEEDED(hr))
  909.     {
  910.         hr = DetermineBnds(bnds);
  911.     }
  912.     return hr;
  913. } /* CDXBaseNTo1::_ImageMapIn2Out */
  914.  
  915. /*****************************************************************************
  916. * CDXBaseNTo1::_MeshMapIn2Out *
  917. *-----------------------------*
  918. *   Description:
  919. *-----------------------------------------------------------------------------
  920. *   Created By: RAL                            Date: 07/28/97
  921. *****************************************************************************/
  922. HRESULT CDXBaseNTo1::_MeshMapIn2Out(CDXCBnds & bnds, ULONG ulNumInBnds, CDXCBnds * pInBounds)
  923. {
  924.     HRESULT hr = S_OK;
  925.     if (m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER)
  926.     {
  927.         if(ulNumInBnds)
  928.         {
  929.             for(ULONG i = 0; i < ulNumInBnds; ++i )
  930.             {
  931.                 bnds |= pInBounds[i];
  932.             }
  933.         }
  934.         else
  935.         {
  936.             for(ULONG i = 0; SUCCEEDED(hr) && i < m_ulNumInputs; ++i )
  937.             {
  938.                 if (InputMeshBuilder(i))
  939.                 {
  940.                     CDXCBnds MeshBnds(InputMeshBuilder(i), hr);
  941.                     bnds |= MeshBnds;
  942.                 }
  943.             }
  944.  
  945.         }
  946.     }
  947.     else
  948.     {
  949.         //  Already done -> bnds[DXB_T].Min = 0.0f;
  950.         bnds[DXB_X].Min = bnds[DXB_Y].Min = bnds[DXB_Z].Min = -1.0f;
  951.         bnds[DXB_X].Max = bnds[DXB_Y].Max = bnds[DXB_Z].Max = bnds[DXB_T].Max = 1.0f;
  952.     }
  953.  
  954.     //
  955.     //  Call the derived class to get the scale values.
  956.     //
  957.     if (SUCCEEDED(hr))
  958.     {
  959.     // Increase the size just a bit so we won't have rounding errors
  960.     // result in bounds that don't actually contain the result.
  961.     const float fBndsIncrease = 0.0001F;
  962.     float fTemp = bnds.Width() * fBndsIncrease;
  963.  
  964.     bnds[DXB_X].Min -= fTemp;
  965.     bnds[DXB_X].Max += fTemp;
  966.  
  967.     fTemp = fBndsIncrease * bnds.Height();
  968.     bnds[DXB_Y].Min -= fTemp;
  969.     bnds[DXB_Y].Max += fTemp;
  970.  
  971.     fTemp = fBndsIncrease * bnds.Depth();
  972.     bnds[DXB_Z].Min -= fTemp;
  973.     bnds[DXB_Z].Max += fTemp;
  974.  
  975.         hr = DetermineBnds(bnds);
  976.     }
  977.     return hr;
  978. } /* CDXBaseNTo1::_MeshMapIn2Out */
  979.  
  980. /*****************************************************************************
  981. * CDXBaseNTo1::MapBoundsIn2Out *
  982. *------------------------------*
  983. *   Description:
  984. *       The MapBoundsIn2Out method is used to perform coordinate transformation
  985. *   from the input to the output coordinate space.
  986. *-----------------------------------------------------------------------------
  987. *   Created By: Ed Connell                            Date: 07/28/97
  988. *-----------------------------------------------------------------------------
  989. *   Parameters:
  990. *****************************************************************************/
  991. STDMETHODIMP CDXBaseNTo1::MapBoundsIn2Out( const DXBNDS *pInBounds, ULONG ulNumInBnds,
  992.                                            ULONG ulOutIndex, DXBNDS *pOutBounds )
  993. {
  994.     DXTDBG_FUNC( "CDXBaseNTo1::MapBoundsIn2Out" );
  995.     if((ulNumInBnds && DXIsBadReadPtr( pInBounds, ulNumInBnds * sizeof( *pInBounds ) )) ||
  996.         ulOutIndex)
  997.     {
  998.         return E_INVALIDARG;
  999.     }
  1000.  
  1001.     if( DXIsBadWritePtr( pOutBounds, sizeof( *pOutBounds ) ) )
  1002.     {
  1003.         return E_POINTER;
  1004.     }
  1005.     //
  1006.     //  Set the bounds to empty and the appropriate type.
  1007.     //
  1008.     memset(pOutBounds, 0, sizeof(*pOutBounds));
  1009.     _ASSERT(DXBT_DISCRETE == 0);
  1010.     if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER)
  1011.     {
  1012.         pOutBounds->eType = DXBT_CONTINUOUS;
  1013.     }
  1014.  
  1015.     //
  1016.     //  Make sure all input bounds are of the correct type.
  1017.     //
  1018.     if( ulNumInBnds )
  1019.     {
  1020.         DXBNDTYPE eType = (m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER) ? DXBT_CONTINUOUS : DXBT_DISCRETE;
  1021.         for (ULONG i = 0; i < ulNumInBnds; i++)
  1022.         {
  1023.             if (pInBounds[i].eType != eType)
  1024.             {
  1025.                 return E_INVALIDARG;
  1026.             }
  1027.         }
  1028.     }
  1029.  
  1030.     //
  1031.     //  Now do the appropriate mapping
  1032.     //
  1033.     if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER)
  1034.     {
  1035.         //
  1036.         //  NOTE:  In the case of non-mesh inputs, the inputs are discrete, but they will
  1037.         //         be completely ignored by the function so it's OK to cast them to CDXCBnds
  1038.         //
  1039.         return _MeshMapIn2Out(*((CDXCBnds *)pOutBounds), ulNumInBnds, (CDXCBnds *)pInBounds);
  1040.     }
  1041.     else 
  1042.     {
  1043.         return _ImageMapIn2Out(*(CDXDBnds *)pOutBounds, ulNumInBnds, (CDXDBnds *)pInBounds);
  1044.     }
  1045. } /* CDXBaseNTo1::MapBoundsIn2Out */
  1046.  
  1047. /*****************************************************************************
  1048. * CDXBaseNTo1::MapBoundsOut2In *
  1049. *------------------------------*
  1050. *   Description:
  1051. *       The MapBoundsOut2In method is used to perform coordinate transformation
  1052. *   from the input to the output coordinate space.
  1053. *-----------------------------------------------------------------------------
  1054. *   Created By: Ed Connell                            Date: 07/28/97
  1055. *-----------------------------------------------------------------------------
  1056. *   Parameters:
  1057. *****************************************************************************/
  1058. STDMETHODIMP CDXBaseNTo1::
  1059.     MapBoundsOut2In( ULONG ulOutIndex, const DXBNDS *pOutBounds, ULONG ulInIndex, DXBNDS *pInBounds )
  1060. {
  1061.     DXTDBG_FUNC( "CDXBaseNTo1::MapBoundsOut2In" );
  1062.     HRESULT hr = S_OK;
  1063.     
  1064.     if (m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER)
  1065.     {
  1066.         hr = E_NOTIMPL;     // This is pointless for meshes.
  1067.     }
  1068.     else if(ulInIndex >= m_ulMaxInputs || ulOutIndex || DXIsBadReadPtr( pOutBounds, sizeof( *pOutBounds ) ) )
  1069.     {
  1070.         hr = E_INVALIDARG;
  1071.     }
  1072.     else if( DXIsBadWritePtr( pInBounds, sizeof( *pInBounds ) ) )
  1073.     {
  1074.         hr = E_POINTER;
  1075.     }
  1076.     else
  1077.     {
  1078.         *pInBounds = *pOutBounds;
  1079.     }
  1080.     return hr;
  1081. } /* CDXBaseNTo1::MapBoundsOut2In */
  1082.  
  1083. /*****************************************************************************
  1084. * CDXBaseNTo1::SetMiscFlags *
  1085. *---------------------------*
  1086. *   Description:
  1087. *-----------------------------------------------------------------------------
  1088. *   Created By: RAL                            Date: 10/30.97
  1089. *-----------------------------------------------------------------------------
  1090. *   Parameters:
  1091. *       bMiscFlags - New value to set 
  1092. *****************************************************************************/
  1093. STDMETHODIMP CDXBaseNTo1::SetMiscFlags( DWORD dwMiscFlags )
  1094.     DXTDBG_FUNC( "CDXBaseNTo1::SetMiscFlags" );
  1095.     HRESULT hr = S_OK;
  1096.     Lock();
  1097.     WORD wOpts = (WORD)dwMiscFlags;     // Ignore high word.  Only set low word.
  1098.     if (((WORD)m_dwMiscFlags) != wOpts)
  1099.     {
  1100.         if ((wOpts & (~DXTMF_VALID_OPTIONS)) ||
  1101.             ((wOpts & DXTMF_BLEND_WITH_OUTPUT) && (m_dwMiscFlags & DXTMF_BLEND_SUPPORTED) == 0) ||
  1102.             ((wOpts & DXTMF_DITHER_OUTPUT) && (m_dwMiscFlags & DXTMF_DITHER_SUPPORTED) == 0))
  1103.         {
  1104.             hr = E_INVALIDARG;
  1105.         }
  1106.         else
  1107.         {
  1108.             m_dwMiscFlags &= 0xFFFF0000;
  1109.             m_dwMiscFlags |= wOpts;
  1110.             _UpdateBltFlags();
  1111.             m_dwGenerationId++;
  1112.         }
  1113.     }
  1114.     Unlock();  
  1115.     return hr;
  1116. } /* CDXBaseNTo1::SetMiscFlags */
  1117.  
  1118. /*****************************************************************************
  1119. * CDXBaseNTo1::GetMiscFlags *
  1120. *----------------------------*
  1121. *   Description:
  1122. *-----------------------------------------------------------------------------
  1123. *   Created By: RAL                            Date: 10/30/97
  1124. *-----------------------------------------------------------------------------
  1125. *   Parameters:
  1126. *****************************************************************************/
  1127. STDMETHODIMP CDXBaseNTo1::GetMiscFlags( DWORD* pdwMiscFlags )
  1128. {
  1129.     if( DXIsBadWritePtr( pdwMiscFlags, sizeof( *pdwMiscFlags ) ) )
  1130.     {
  1131.         return E_POINTER;
  1132.     }
  1133.     *pdwMiscFlags = m_dwMiscFlags;
  1134.     return S_OK;
  1135. } /* CDXBaseNTo1::GetMiscFlags */
  1136.  
  1137.  
  1138. /*****************************************************************************
  1139. * CDXBaseNTo1::SetQuality *
  1140. *----------------------------*
  1141. *   Description:
  1142. *-----------------------------------------------------------------------------
  1143. *   Created By: RAL                            Date: 10/30/97
  1144. *-----------------------------------------------------------------------------
  1145. *   Parameters:
  1146. *****************************************************************************/
  1147. STDMETHODIMP CDXBaseNTo1::SetQuality(float fQuality)
  1148. {
  1149.     if ((m_dwMiscFlags & DXTMF_QUALITY_SUPPORTED) == 0)
  1150.     {
  1151.         return E_NOTIMPL;
  1152.     }
  1153.  
  1154.     if (fQuality < 0.0f || fQuality > 1.0f)
  1155.     {
  1156.         return E_INVALIDARG;
  1157.     }
  1158.  
  1159.     Lock();
  1160.     if (m_fQuality != fQuality)
  1161.     {
  1162.         m_fQuality = fQuality;
  1163.         m_dwGenerationId++;
  1164.     }
  1165.     Unlock();
  1166.  
  1167.     return S_OK;
  1168. }
  1169.  
  1170. /*****************************************************************************
  1171. * CDXBaseNTo1::GetQuality *
  1172. *-------------------------*
  1173. *   Description:
  1174. *-----------------------------------------------------------------------------
  1175. *   Created By: RAL                            Date: 10/30/97
  1176. *-----------------------------------------------------------------------------
  1177. *   Parameters:
  1178. *****************************************************************************/
  1179.  
  1180. STDMETHODIMP CDXBaseNTo1::GetQuality(float *pfQuality)
  1181. {
  1182.     HRESULT hr = S_OK;
  1183.  
  1184.     if ((m_dwMiscFlags & DXTMF_QUALITY_SUPPORTED) == 0)
  1185.     {
  1186.         hr = E_NOTIMPL;
  1187.     }
  1188.     else 
  1189.     {
  1190.         if( DXIsBadWritePtr( pfQuality, sizeof( *pfQuality ) ) )
  1191.         {
  1192.             hr = E_POINTER;
  1193.         }
  1194.         else
  1195.         {
  1196.             *pfQuality = m_fQuality;
  1197.         }
  1198.     }
  1199.     return hr;
  1200. }
  1201.  
  1202.  
  1203.  
  1204. /*****************************************************************************
  1205. * GetInOutInfo
  1206. *-----------------------------------------------------------------------------
  1207. *   Description:
  1208. *-----------------------------------------------------------------------------
  1209. *   Created By: RAL                                 Date: 12/10/97
  1210. *-----------------------------------------------------------------------------
  1211. *   Parameters:
  1212. *****************************************************************************/
  1213. STDMETHODIMP CDXBaseNTo1::GetInOutInfo( BOOL bOutput, ULONG ulIndex, DWORD *pdwFlags,
  1214.                                         GUID * pIDs, ULONG *pcIDs, IUnknown **ppUnkCurObj )
  1215. {
  1216.     DXTDBG_FUNC( "CDXBaseNTo1::GetInOutInfo" );
  1217.     HRESULT hr = S_FALSE;
  1218.     DWORD dwFlags = 0;
  1219.     BOOL bImage;
  1220.     if( bOutput )
  1221.     {
  1222.         bImage = !(m_dwOptionFlags & DXBOF_OUTPUT_MESHBUILDER);
  1223.         if (ulIndex == 0)
  1224.         {
  1225.             hr = S_OK;
  1226.         }
  1227.     }
  1228.     else
  1229.     {
  1230.         bImage = !(m_dwOptionFlags & DXBOF_INPUTS_MESHBUILDER);
  1231.         if (ulIndex < m_ulMaxInputs)
  1232.         {
  1233.             hr = S_OK;
  1234.             if (ulIndex >= m_ulNumInRequired)
  1235.             {
  1236.                 dwFlags = DXINOUTF_OPTIONAL;
  1237.             }
  1238.         }
  1239.     }
  1240.     if( hr == S_OK )
  1241.     {
  1242.         if( pdwFlags && !DXIsBadWritePtr( pdwFlags, sizeof( *pdwFlags ) ) )
  1243.         {
  1244.             *pdwFlags = dwFlags;
  1245.         }
  1246.  
  1247.         if( pIDs )
  1248.         {
  1249.             if( DXIsBadWritePtr( pcIDs, sizeof( *pcIDs ) ) ||
  1250.                 DXIsBadWritePtr( pIDs, *pcIDs * sizeof( *pIDs ) ) )
  1251.             {
  1252.                 hr = E_INVALIDARG;
  1253.             }
  1254.             else
  1255.             {
  1256.                 if (bImage)
  1257.                 {
  1258.                     if (*pcIDs > 0)
  1259.                     {
  1260.                         pIDs[0] = IID_IDXSurface;
  1261.                     }
  1262.                     if (*pcIDs > 1)
  1263.                     {
  1264.                         pIDs[1] = IID_IDXDupDDrawSurface;
  1265.                     }
  1266.                     else
  1267.                     {
  1268.                         hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
  1269.                     }
  1270.                     *pcIDs = 2;
  1271.                 }
  1272.                 else
  1273.                 {
  1274.                     if (*pcIDs > 0)
  1275.                     {
  1276.                         pIDs[0] = IID_IDXDupDirect3DRMMeshBuilder3;
  1277.                     }
  1278.                     else
  1279.                     {
  1280.                         hr = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
  1281.                     }
  1282.                     *pcIDs = 1;
  1283.                 }
  1284.             }
  1285.         }
  1286.         else if( pcIDs )
  1287.         {
  1288.             if( DXIsBadWritePtr( pcIDs, sizeof( *pcIDs ) ) )
  1289.             {
  1290.                 hr = E_POINTER;
  1291.             }
  1292.             else
  1293.             {
  1294.                 *pcIDs = bImage ? 2 : 1;
  1295.             }
  1296.         }
  1297.         if (hr == S_OK && ppUnkCurObj)
  1298.         {
  1299.             if (DXIsBadWritePtr(ppUnkCurObj, sizeof(*ppUnkCurObj)))
  1300.             {
  1301.                 hr = E_POINTER;
  1302.             }
  1303.             else
  1304.             {
  1305.                 if (bOutput)
  1306.                 {
  1307.                     *ppUnkCurObj = m_Output.m_pNativeInterface;
  1308.                 }
  1309.                 else
  1310.                 {
  1311.                     *ppUnkCurObj = NULL;
  1312.                     if (ulIndex < GetNumInputs())
  1313.                     {
  1314.                         *ppUnkCurObj = m_aInputs[ulIndex].m_pUnkOriginalObject;
  1315.                     }
  1316.                 }
  1317.                 if (*ppUnkCurObj)
  1318.                 {
  1319.                     (*ppUnkCurObj)->AddRef();
  1320.                 }
  1321.             }
  1322.         }
  1323.     }
  1324.     return hr;
  1325. } /* CDXBaseNTo1::GetInOutInfo */
  1326.  
  1327. /*****************************************************************************
  1328. * CDXBaseNTo1::OnUpdateGenerationId *
  1329. *-----------------------------------*
  1330. *   Description:
  1331. *-----------------------------------------------------------------------------
  1332. *   Created By: RAL                                 Date: 12/10/97
  1333. *-----------------------------------------------------------------------------
  1334. *   Parameters:
  1335. *****************************************************************************/
  1336. void CDXBaseNTo1::OnUpdateGenerationId(void)
  1337. {
  1338.     DXTDBG_FUNC( "CDXBaseNTo1::OnUpdateGenerationId" );
  1339.     if( (m_dwMiscFlags & DXTMF_INPLACE_OPERATION) &&
  1340.         m_Output.UpdateGenerationId())
  1341.     {
  1342.         m_dwGenerationId++;
  1343.     }
  1344.     for (ULONG i = 0; i < m_ulNumInputs; i++)
  1345.     {
  1346.         if (m_aInputs[i].UpdateGenerationId())
  1347.         {
  1348.             m_dwGenerationId++;
  1349.         }
  1350.     }
  1351. } /* CDXBaseNTo1::OnUpdateGenerationId */
  1352.  
  1353. /*****************************************************************************
  1354. * CDXBaseNTo1::OnGetObjectSize *
  1355. *------------------------------*
  1356. *   Description:
  1357. *-----------------------------------------------------------------------------
  1358. *   Created By: RAL                                 Date: 12/10/97
  1359. *****************************************************************************/
  1360. ULONG CDXBaseNTo1::OnGetObjectSize(void)
  1361. {
  1362.     return sizeof(*this);
  1363. }
  1364.  
  1365. //
  1366. //  Effect interface
  1367. //
  1368.  
  1369. /*****************************************************************************
  1370. * CDXBaseNTo1::get_Progress *
  1371. *---------------------------*
  1372. *   Description:
  1373. *-----------------------------------------------------------------------------
  1374. *   Created By: RAL                                 Date: 12/10/97
  1375. *****************************************************************************/
  1376. STDMETHODIMP CDXBaseNTo1::get_Progress(float *pVal)
  1377. {
  1378.     DXTDBG_FUNC( "CDXBaseNTo1::get_Progress" );
  1379.     HRESULT hr = S_OK;
  1380.     if( DXIsBadWritePtr(pVal, sizeof(*pVal)) )
  1381.     {
  1382.         hr = E_POINTER;
  1383.     }
  1384.     else
  1385.     {
  1386.         *pVal = m_Progress;
  1387.     }
  1388.     return hr;
  1389. }
  1390.  
  1391. /*****************************************************************************
  1392. * CDXBaseNTo1::put_Progress *
  1393. *---------------------------*
  1394. *   Description:
  1395. *-----------------------------------------------------------------------------
  1396. *   Created By: RAL                                 Date: 12/10/97
  1397. *****************************************************************************/
  1398. STDMETHODIMP CDXBaseNTo1::put_Progress(float newVal)
  1399. {
  1400.     DXTDBG_FUNC( "CDXBaseNTo1::put_Progress" );
  1401.     HRESULT hr = S_OK;
  1402.     if (newVal < 0.0 || newVal > 1.0f)
  1403.     {
  1404.         hr = E_INVALIDARG;
  1405.     }
  1406.     else
  1407.     {
  1408.         Lock();
  1409.         m_Progress = newVal;
  1410.         m_dwCleanGenId++;       // This should not make the transform "dirty" internally
  1411.         m_dwGenerationId++;     
  1412.         Unlock();
  1413.     }
  1414.     return hr;
  1415. }
  1416.  
  1417. /*****************************************************************************
  1418. * CDXBaseNTo1::get_StepResolution *
  1419. *---------------------------------*
  1420. *   Description:
  1421. *-----------------------------------------------------------------------------
  1422. *   Created By: RAL                                 Date: 12/10/97
  1423. *****************************************************************************/
  1424. STDMETHODIMP CDXBaseNTo1::get_StepResolution(float *pVal)
  1425. {
  1426.     DXTDBG_FUNC( "CDXBaseNTo1::get_StepResolution" );
  1427.     HRESULT hr = S_OK;
  1428.     if( DXIsBadWritePtr(pVal, sizeof(*pVal)) )
  1429.     {
  1430.         hr = E_POINTER;
  1431.     }
  1432.     else
  1433.     {
  1434.         *pVal = m_StepResolution;
  1435.     }
  1436.     return hr;
  1437. }
  1438.  
  1439. /*****************************************************************************
  1440. * CDXBaseNTo1::get_Duration *
  1441. *---------------------------*
  1442. *   Description:
  1443. *-----------------------------------------------------------------------------
  1444. *   Created By: RAL                                 Date: 12/10/97
  1445. *****************************************************************************/
  1446. STDMETHODIMP CDXBaseNTo1::get_Duration(float *pVal)
  1447. {
  1448.     DXTDBG_FUNC( "CDXBaseNTo1::get_Duration" );
  1449.     if( DXIsBadWritePtr(pVal, sizeof(*pVal)) )
  1450.     {
  1451.         return E_POINTER;
  1452.     }
  1453.     else
  1454.     {
  1455.         *pVal = m_Duration;
  1456.     }
  1457.     return S_OK;
  1458. }
  1459.  
  1460. /*****************************************************************************
  1461. * CDXBaseNTo1::put_Duration *
  1462. *---------------------------*
  1463. *   Description:
  1464. *-----------------------------------------------------------------------------
  1465. *   Created By: RAL                                 Date: 12/10/97
  1466. *****************************************************************************/
  1467. STDMETHODIMP CDXBaseNTo1::put_Duration(float newVal)
  1468. {
  1469.     DXTDBG_FUNC( "CDXBaseNTo1::put_Duration" );
  1470.     if (newVal <= 0.)
  1471.     {
  1472.         return E_INVALIDARG;
  1473.     }
  1474.     if(newVal != m_Duration)
  1475.     {
  1476.     Lock();
  1477.     m_dwGenerationId++;
  1478.         m_dwCleanGenId++;       // This should not make the transform "dirty" internally
  1479.         m_Duration = newVal;
  1480.         Unlock();
  1481.     }
  1482.     return S_OK;
  1483. }
  1484.  
  1485.  
  1486. /*****************************************************************************
  1487. * CDXBaseNTo1::PointPick *
  1488. *------------------------*
  1489. *   Description:
  1490. *-----------------------------------------------------------------------------
  1491. *   Created By: RAL                                 Date: 5/5/98
  1492. *****************************************************************************/
  1493. STDMETHODIMP CDXBaseNTo1::PointPick(const DXVEC *pPoint,
  1494.                                     ULONG * pulInputSurfaceIndex,
  1495.                                     DXVEC *pInputPoint)
  1496. {
  1497.     HRESULT hr = S_OK;
  1498.     BOOL bFoundIt = FALSE;
  1499.     if (DXIsBadReadPtr(pPoint, sizeof(*pPoint)) || pPoint->eType != DXBT_DISCRETE)
  1500.     {
  1501.         hr = E_INVALIDARG;
  1502.     }
  1503.     else 
  1504.     {
  1505.         if (DXIsBadWritePtr(pulInputSurfaceIndex, sizeof(*pulInputSurfaceIndex)) ||
  1506.             DXIsBadWritePtr(pInputPoint, sizeof(*pInputPoint)))
  1507.         {
  1508.             hr = E_POINTER;
  1509.         }
  1510.         else 
  1511.         {
  1512.             CDXDBnds OutBndsPoint(*((CDXDVec *)pPoint));
  1513.             CDXDVec & InVec = *(new(pInputPoint) CDXDVec(*((CDXDVec *)pPoint)));
  1514.             HRESULT hr2 = OnSurfacePick(OutBndsPoint, *pulInputSurfaceIndex, InVec);
  1515.             if (hr2 != E_NOTIMPL)
  1516.             {
  1517.                 hr = hr2;
  1518.             }
  1519.             else
  1520.             {
  1521.                 //--- The derived class does not implement so we will do
  1522.                 //    the hit test against the input for them.
  1523.                 ULONG * aulInIndex = (ULONG *)_alloca(sizeof(ULONG) * m_ulMaxInputs);
  1524.                 BYTE * aWeights = (BYTE *)_alloca(sizeof(BYTE) * m_ulMaxInputs);
  1525.                 ULONG ulNumToTest;
  1526.                 OnGetSurfacePickOrder(OutBndsPoint, ulNumToTest, aulInIndex, aWeights);
  1527.  
  1528.                 if( m_bPickDoneByBase && ( m_ulNumInputs > 1 ) )
  1529.                 {
  1530.                     //--- We don't know how to do multi-input picking from the base.
  1531.                     hr = E_NOTIMPL;
  1532.                 }
  1533.  
  1534.                 for (ULONG i = 0; SUCCEEDED(hr) && i < ulNumToTest; i++)
  1535.                 {
  1536.                     ULONG ulInput = aulInIndex[i];
  1537.                     if (HaveInput(ulInput) && aWeights[i])
  1538.                     {
  1539.                         CDXDBnds Out2InBnds(false);
  1540.                         hr = MapBoundsOut2In(0, &OutBndsPoint, ulInput, &Out2InBnds);
  1541.                         if (SUCCEEDED(hr))
  1542.                         {
  1543.                             CDXDBnds InSurfBnds(InputSurface(ulInput), hr);
  1544.                             if (SUCCEEDED(hr) && InSurfBnds.IntersectBounds(Out2InBnds))
  1545.                             {
  1546.                                 IDXARGBReadPtr * pPtr;
  1547.                                 hr = InputSurface(ulInput)->LockSurface(&InSurfBnds, m_ulLockTimeOut, DXLOCKF_READ, 
  1548.                                                                         IID_IDXARGBReadPtr, (void **)&pPtr, NULL);
  1549.                                 if( SUCCEEDED(hr) )
  1550.                                 {
  1551.                                     DXPMSAMPLE val;
  1552.                                     pPtr->UnpackPremult(&val, 1, FALSE);
  1553.                                     pPtr->Release();
  1554.                                     if (val.Alpha * aWeights[i] / 255)
  1555.                                     {
  1556.                                         InSurfBnds.GetMinVector(InVec);
  1557.                                         bFoundIt = TRUE;
  1558.                                         *pulInputSurfaceIndex = ulInput;
  1559.                                         break;
  1560.                                     }
  1561.                                 }
  1562.                             }   
  1563.                         }
  1564.                     }
  1565.                 }
  1566.                 if (SUCCEEDED(hr) & (!bFoundIt))
  1567.                 {
  1568.                     hr = S_FALSE;
  1569.                 }
  1570.             }
  1571.         }
  1572.     }
  1573.     return hr;
  1574. } /* CDXBaseNTo1::PointPick */
  1575.  
  1576. /*****************************************************************************
  1577. * RegisterTansform (STATIC member function)
  1578. *-----------------------------------------------------------------------------
  1579. *   Description:
  1580. *-----------------------------------------------------------------------------
  1581. *   Created By: RAL                                 Date: 12/10/97
  1582. *-----------------------------------------------------------------------------
  1583. *   Parameters:
  1584. *****************************************************************************/
  1585. HRESULT CDXBaseNTo1::
  1586. RegisterTransform(REFCLSID rcid, int ResourceId, ULONG cCatImpl, const CATID * pCatImpl,
  1587.                   ULONG cCatReq, const CATID * pCatReq, BOOL bRegister)
  1588. {
  1589.     DXTDBG_FUNC( "CDXBaseNTo1::RegisterTransform" );
  1590.     HRESULT hr = bRegister ? _Module.UpdateRegistryFromResource(ResourceId, bRegister) : S_OK;
  1591.     if (SUCCEEDED(hr))
  1592.     {
  1593.         CComPtr<ICatRegister> pCatRegister;
  1594.         HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC, IID_ICatRegister, (void **)&pCatRegister);
  1595.         if (SUCCEEDED(hr))
  1596.         {
  1597.             if (bRegister)
  1598.             {
  1599.                 hr = pCatRegister->RegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl);
  1600.                 if (SUCCEEDED(hr) && cCatReq && pCatReq) {
  1601.                     hr = pCatRegister->RegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq);
  1602.                 }
  1603.             } 
  1604.             else
  1605.             {
  1606.                 pCatRegister->UnRegisterClassImplCategories(rcid, cCatImpl, (CATID *)pCatImpl);
  1607.                 if (cCatReq && pCatReq)
  1608.                 {
  1609.                     pCatRegister->UnRegisterClassReqCategories(rcid, cCatReq, (CATID *)pCatReq);
  1610.                 }
  1611.             }
  1612.         }
  1613.     }
  1614.     if ((!bRegister) && SUCCEEDED(hr)) 
  1615.     { 
  1616.         _Module.UpdateRegistryFromResource(ResourceId, bRegister);
  1617.     }
  1618.     return hr;
  1619. }
  1620.  
  1621. //
  1622. //  BUGBUG -- try/except around this !
  1623. //  
  1624. void CDXBaseNTo1::_TaskProc(void* pTaskInfo, BOOL* pbContinue )
  1625.     _ASSERT( pTaskInfo );
  1626.     CDXTWorkInfoNTo1& WI = *((CDXTWorkInfoNTo1 *)pTaskInfo);
  1627.     CDXBaseNTo1& This = *((CDXBaseNTo1 *)WI.pvThis);
  1628.     WI.hr = This.WorkProc(WI, pbContinue);
  1629. }
  1630.  
  1631.