#include <GPUCV/DataDsc_CvMat.h>
#include <GPUCVTexture/TextureRecycler.h>
#include <GPUCVTexture/Texture.h>
#include <GPUCV/toolscvg.h>
//==================================================
DataDsc_CvMat::DataDsc_CvMat()
: DataDsc_CPU("DataDsc_CvMat")
,m_CvArr(NULL)
,m_CvMat(NULL)
{
}
//==================================================
DataDsc_CvMat::~DataDsc_CvMat(void)
{
Free();
}
//==================================================
/*virtual*/
DataDsc_Base * DataDsc_CvMat::CloneToNew(bool _datatransfer/*=true*/)
{
DataDsc_CvMat * TempTex = new DataDsc_CvMat();
return TempTex->Clone(this,_datatransfer);
}
//==================================================
/*virtual*/
DataDsc_CvMat* DataDsc_CvMat::Clone(DataDsc_CvMat* _source, bool _datatransfer/*=true*/)
{
DataDsc_Base::Clone(_source, _datatransfer);
DataDsc_CvMat* newDD = _Clone(_source->_GetCvMat(), _datatransfer);
//CvMat are used as DataContainerID, so we need to update it.
//we can't do ti here cause the object don't know its new parent yet
//this is done in DataContainer::_CopyAllDataDsc
//newDD->GetParent()->SetID(newDD->_GetCvMat());
return newDD;
}
//==================================================
/*virtual*/
bool DataDsc_CvMat::CopyTo(DataDsc_Base* _destination, bool _datatransfer/*=true*/)
{
CLASS_FCT_SET_NAME_TPL_STR(_destination->GetDscType(),"CopyTo");
TEXTUREDESC_COPY_START(_destination,_datatransfer);
//copy to CvMat => clone
DataDsc_CvMat * TempCvMat = dynamic_cast<DataDsc_CvMat *>(_destination);
if(TempCvMat)
{
return TempCvMat->Clone(this, _datatransfer);
}
//======================
//copy to Cpu =>
DataDsc_CPU * TempCPU = dynamic_cast<DataDsc_CPU *>(_destination);
if(TempCPU)
{
TempCPU->Allocate();
PIXEL_STORAGE_TYPE * tmpdata = *TempCPU->_GetPixelsData();
memcpy(tmpdata, _GetPixelsData(), GetDataSize());
return true;
}
//======================
return false;
}
//==================================================
/*virtual*/
bool DataDsc_CvMat::CopyFrom(DataDsc_Base* _source, bool _datatransfer/*=true*/)
{
CLASS_FCT_SET_NAME_TPL_STR(_source->GetDscType(),"CopyFrom");
TEXTUREDESC_COPY_START(_source,_datatransfer);
//copy from Iplimage => clone
DataDsc_CvMat * TempCvMat = dynamic_cast<DataDsc_CvMat *>(_source);
if(TempCvMat)
{
return Clone(TempCvMat, _datatransfer);
}
//======================
//copy from Cpu =>
DataDsc_CPU * TempCPU = dynamic_cast<DataDsc_CPU *>(_source);
if(TempCPU)
{
Allocate();
PIXEL_STORAGE_TYPE * tmpdata = _GetPixelsData();
memcpy(tmpdata, TempCPU->_GetPixelsData(), GetDataSize());
return true;
}
//======================
return false;
}
//==================================================
/*virtual*/
void DataDsc_CvMat::Allocate(void)
{
CLASS_FCT_SET_NAME("Allocate");
if(!IsAllocated())
{
CLASS_DEBUG("");
CLASS_FCT_PROF_CREATE_START();
CLASS_ASSERT(m_CvMat, "DataDsc_CvMat::Allocate()=> not CvMat, can't allocate data");
cvCreateData(m_CvMat);
CLASS_ASSERT(m_CvMat->data.ptr, "DataDsc_CvMat::Allocate()=> Allocation failed");
_SetPixelsData((PIXEL_STORAGE_TYPE **)&m_CvMat->data.ptr);
}
}
//==================================================
/*virtual*/
void DataDsc_CvMat::Free()
{
CLASS_FCT_SET_NAME("Free");
if(IsAllocated())
{
CLASS_DEBUG("");
CLASS_FCT_PROF_CREATE_START();
cvReleaseData(m_CvMat);
DataDsc_Base::Free();
}
_SetPixelsData((PIXEL_STORAGE_TYPE**)&m_CvMat->data.ptr);
}
//==================================================
/*virtual*/
bool DataDsc_CvMat::IsAllocated()const
{
if(m_pixels)
return (*m_pixels)? true:false;
return false;
}
//==================================================
/*virtual*/
void * DataDsc_CvMat::GetNewParentID()const
{
return _GetCvMat();
}
//==================================================
//==================================================
//Local functions
//==================================================
//==================================================
void DataDsc_CvMat::_SetCvMat(CvMat ** _mat)
{
CLASS_FCT_SET_NAME("_SetCvMat");
m_CvArr = (CvArr**)_mat;
m_CvMat = *_mat;
CLASS_DEBUG("");
if(m_CvMat->data.ptr)
SetDataFlag(true);
else
SetDataFlag(false);
if(GetParent())
GetParent()->RemoveAllDataDscExcept<DataDsc_CvMat>();
_SetSize(m_CvMat->width, m_CvMat->height);
_SetPixelsData((PIXEL_STORAGE_TYPE**) &m_CvMat->data.ptr);
//here, we do it manually without calling SetFormat
m_glPixelType = ConvertPixelType_LocalToGL();
m_glPixelFormat = ConvertPixelFormat_LocalToGL();
m_nChannels = GetGLNbrComponent(m_glPixelFormat);
//check the number of channels...
GLuint NewWidth=0;
GLenum NewFormat=0;
GLenum NewType=0;
GLenum NewChannel=0;
switch(m_nChannels)
{
case 1: if (IS_MULTIPLE_OF(m_CvMat->width, 4))
{
NewWidth = m_CvMat->width/4;
NewFormat = GL_BGRA;
}
else if (IS_MULTIPLE_OF(m_CvMat->width, 3))
{
NewWidth = m_CvMat->width/3;
NewFormat = GL_BGR;// BGRA;
//we force the number of channel here
//cause some hardware does not support CL_LUMINANCE_APLHA
NewChannel = 3;
}
else if (IS_MULTIPLE_OF(m_CvMat->width, 2))
{
GPUCV_PERF_WARNING("Matrix processing using multiple of 2 is not working yet due to some GL_LUMINANCE_ALPHA format compatibility. Downgrading to multiple of one that could reduce performances.");
#if 0
NewWidth = m_CvMat->width/2;
NewFormat = GL_BGR;// BGRA;
//cause some hardware does not support CL_LUMINANCE_APLHA
NewChannel = 2;
#endif
}
break;
case 2:
if (IS_MULTIPLE_OF(m_CvMat->width, 4))
{
NewWidth = m_CvMat->width/2;
NewFormat = GL_BGRA;
}
break;
case 3://nothing to do
case 4://nothing to do
break;
}
#if _GPUCV_SUPPORT_CVMAT
if(NewWidth)
{//set new properties
_SetSize(NewWidth, m_CvMat->height);
if(NewChannel)
_SetNChannels(NewChannel);//_ForceNChannels(NewChannel);
SetFormat(NewFormat,m_glPixelType);
}
#endif
}
//==================================================
CvMat* DataDsc_CvMat::_GetCvMat()const
{
return m_CvMat;
}
//==================================================
CvMat** DataDsc_CvMat::_GetCvMatPtr()const
{
return (CvMat**)m_CvArr;
}
//==================================================
DataDsc_CvMat* DataDsc_CvMat::_Clone(const CvMat* _source, bool _datatransfer/*=true*/)
{
CLASS_FCT_SET_NAME("_Clone");
CLASS_DEBUG("");
CV_FUNCNAME("DataDsc_CvMat::_Clone()");
CLASS_ASSERT(_source, "DataDsc_CvMat::_Clone(CvMat)=>Empty source!");
__BEGIN__
if(_source == m_CvMat)
{
CLASS_WARNING("Cloning A with A..??");
return NULL;
}
#if _GPUCV_SUPPORT_CVMAT
CvMat * dst=NULL;
if(_datatransfer)
{
cvReleaseMat(&m_CvMat);
m_CvMat = cvCloneMat(_source);
m_CvArr = (void**)&m_CvMat;
//GetParent()->SetDataFlag<DataDsc_CvMat>(true,false);
}
else
{
if( !CV_IS_MAT_HDR( _source ))
CV_ERROR( CV_StsBadArg, "Bad CvMat header" );
if(m_CvMat==NULL)
{
CV_CALL( dst = cvCreateMatHeader( _source->rows, _source->cols, _source->type ));
}
else
{
dst = m_CvMat;
}
if( _source->data.ptr )
{
CV_CALL( cvCreateData( dst ));
CV_CALL( cvCopy( _source, dst ));
}
//==========================
m_CvMat = dst;
m_CvArr = (void**)&m_CvMat;
}
#endif
__END__
return this;
}
//==================================================
/*virtual*/
void DataDsc_CvMat::ConvertPixelFormat_GLToLocal(const GLuint _pixelFormat)
{
//if(m_CvMat)
// m_CvMat->nChannels = cvgConvertGLTexFormatToCV(_pixelFormat, m_CvMat->channelSeq);
}
//==================================================
/*virtual*/
GLuint DataDsc_CvMat::ConvertPixelFormat_LocalToGL(void)
{
GLuint InternalFormat=0;
GLuint Format=0;
GLuint PixType=0;
if(m_CvMat)
{
cvgConvertCVMatrixFormatToGL(m_CvMat, InternalFormat, Format, PixType);
return Format;
}
else
return m_glPixelFormat;
}
//==================================================
/*virtual*/
void DataDsc_CvMat::ConvertPixelType_GLToLocal(const GLuint _pixelType)
{
#if _GPUCV_SUPPORT_CVMAT
//m_glPixelType = _pixelType;
//if(m_CvMat)
// m_CvMat->type = cvgConvertGLPixTypeToCV(_pixelType);
#endif
}
//==================================================
/*virtual*/
GLuint DataDsc_CvMat::ConvertPixelType_LocalToGL(void)
{
#if _GPUCV_SUPPORT_CVMAT
GLuint InternalFormat=0;
GLuint Format=0;
GLuint PixType=0;
if(m_CvMat)
{
cvgConvertCVMatrixFormatToGL(m_CvMat, InternalFormat, Format, PixType);
return PixType;
//cvgConvertCVPixTypeToGL(m_CvMat);
}
else
#endif
return m_glPixelType;
}
//==================================================
|