33 #ifndef GSLAM_GIMAGE_H 34 #define GSLAM_GIMAGE_H 41 #if defined(HAS_OPENCV) || defined(HAS_OPENCV3) 42 #include <opencv2/core/core.hpp> 44 typedef unsigned char uchar;
49 static inline int CV_XADD(
int* addr,
int delta)
51 static std::mutex mutex;
52 std::unique_lock<std::mutex> lock(mutex);
53 int tmp = *addr; *addr += delta;
return tmp;
59 #ifndef DOXYGEN_IGNORE_INTERNAL 69 GElementType_UserType=7
76 enum{Type=GElementType_UserType};
80 class GElement<uint8_t>
83 enum{Type=GElementType_8U};
90 enum{Type=GElementType_8S};
94 class GElement<int16_t>
97 enum{Type=GElementType_16S};
101 class GElement<uint16_t>
104 enum{Type=GElementType_16U};
108 class GElement<int32_t>
111 enum{Type=GElementType_32S};
115 class GElement<float>
118 enum{Type=GElementType_32F};
122 class GElement<double>
125 enum{Type=GElementType_64F};
128 template <
typename EleType=u
int8_t,
int channelSize=1>
131 enum{Type=((GElement<EleType>::Type&0x7)+((channelSize-1)<<3))};
136 enum { COPY_ON_MAP=1, HOST_COPY_OBSOLETE=2,
137 DEVICE_COPY_OBSOLETE=4, TEMP_UMAT=8, TEMP_COPIED_UMAT=24,
138 USER_ALLOCATED=32, DEVICE_MEM_MAPPED=64};
139 const void* prevAllocator;
140 const void* currAllocator;
152 UMatData* originalUMatData;
164 :cols(0),rows(0),flags(0),data(NULL),refCount(NULL)
169 GImage(
int rows_,
int cols_,
int type=GImageType<>::Type,uchar* src=NULL,
bool copy=
false,
int imageAlign=16)
170 :cols(cols_),rows(rows_),flags(type),data(NULL),refCount(NULL)
178 int byteNum=total()*elemSize();
179 if(byteNum<=0)
return;
180 int alignBytes=alignSize(byteNum, (
int)
sizeof(*refCount));
181 data=(uchar*)fastMalloc(alignBytes+
sizeof(
int*),imageAlign);
184 cols=0;rows=0;return ;
186 refCount=(
int*)(data+alignBytes);
189 memcpy(data,src,byteNum);
193 : cols(ref.cols),rows(ref.rows),flags(ref.flags),
194 data(ref.data),refCount(ref.refCount)
204 if(CV_XADD(refCount,-1)==1)
222 refCount=rhs.refCount;
223 if(refCount) CV_XADD(refCount,1);
227 static GImage create(
int rows,
int cols,
int type=GImageType<>::Type,uchar* src=NULL,
bool copy=
false,
int imageAlign=16)
229 return GImage(rows,cols,type,src,copy);
232 static GImage zeros(
int rows,
int cols,
int type=GImageType<>::Type,uchar* src=NULL,
bool copy=
false,
int imageAlign=16)
234 GImage result(rows,cols,type,src,copy,imageAlign);
235 memset(result.data,0,result.total()*result.elemSize());
239 bool empty()
const{
return !data;}
240 int elemSize()
const{
return channels()*elemSize1();}
241 int elemSize1()
const{
return (1<<((type()&0x7)>>1));}
243 int channels()
const{
return (type()>>3)+1;}
244 int type()
const{
return flags;}
245 int total()
const{
return cols*rows;}
249 return GImage(rows,cols,flags,data,
true);
252 template <
typename C>
253 C& at(
int idx){
return ((C*)data)[idx];}
255 template <
typename C>
256 C& at(
int ix,
int iy){
return ((C*)data)[iy*cols+ix];}
259 #if defined(HAS_OPENCV) || defined(HAS_OPENCV3) 260 #if CV_VERSION_EPOCH == 2 261 inline operator cv::Mat()
const 263 if(empty())
return cv::Mat();
264 cv::Mat result(rows,cols,type(),data);
267 result.refcount=refCount;
272 GImage(
const cv::Mat& mat)
273 : cols(mat.cols),rows(mat.rows),flags(mat.type()),
274 data(mat.data),refCount(mat.refcount)
276 if(refCount) CV_XADD(refCount,1);
278 #elif CV_VERSION_MAJOR == 3 279 inline operator cv::Mat()
const 281 if(!data)
return cv::Mat();
282 cv::Mat result(rows,cols,type(),data);
283 int byteNum=total()*elemSize();
284 int alignBytes=alignSize(byteNum, (
int)
sizeof(*refCount));
285 if(((uchar*)refCount)==data+alignBytes)
289 cv::UMatData* u=
new cv::UMatData(cv::Mat::getStdAllocator());
291 #if CV_VERSION_MINOR>=3 292 u->origdata=((uchar**)data)[-1];
296 u->userdata=refCount;
300 refCount=&u->refcount;
308 cv::UMatData* u=(cv::UMatData*)(((uchar*)refCount)-
sizeof(int)-
sizeof(cv::MatAllocator*)*2);
315 GImage(
const cv::Mat& mat)
316 : cols(mat.cols),rows(mat.rows),flags(mat.type()),
317 data(mat.data),refCount(NULL)
319 if(mat.u&&mat.u->currAllocator==cv::Mat::getStdAllocator())
322 refCount=(&mat.u->refcount);
327 int byteNum=total()*elemSize();
328 data=(uchar*)fastMalloc(byteNum+
sizeof(
int*));
331 cols=0;rows=0;return ;
333 refCount=(
int*)(data+byteNum);
336 memcpy(data,mat.data,byteNum);
345 size_t totalBytes=total()*elemSize();
346 int alignBytes=alignSize(totalBytes, (
int)
sizeof(*refCount));
347 if(refCount==((
int*)(data+alignBytes)))
356 UMatData* u=(UMatData*)(((uchar*)refCount)-offsetof(UMatData,refcount));
357 if(u->userdata==data+alignBytes)
360 refCount=(
int*)u->userdata;
361 if(CV_XADD(refCount,-1)==1)
368 assert(u->size==totalBytes);
378 template<
typename _Tp> _Tp* ptr(
int i0=0){
return (_Tp*)(data+i0*cols*elemSize());}
380 template<
typename _Tp>
const _Tp* ptr(
int i0=0)
const{
return (_Tp*)(data+i0*cols*elemSize());}
382 const GImage row(
int idx=0)
const{
return GImage(1,cols,type(),data+elemSize()*cols*idx);}
384 int getWidth()
const{
return cols;}
385 int getHeight()
const{
return rows;}
389 template<
typename _Tp>
static inline _Tp* alignPtr(_Tp* ptr,
int n=(
int)
sizeof(_Tp))
391 return (_Tp*)(((size_t)ptr + n-1) & -n);
394 void* fastMalloc(
size_t size ,
int imageAlign=16)
const 396 uchar* udata = (uchar*)malloc(size +
sizeof(
void*) + imageAlign);
399 uchar** adata = alignPtr((uchar**)udata + 1, imageAlign);
404 void fastFree(
void* ptr)
const 408 uchar* udata = ((uchar**)ptr)[-1];
413 static inline size_t alignSize(
size_t sz,
int n)
415 assert((n & (n - 1)) == 0);
416 return (sz + n-1) & -n;
419 void deallocate(UMatData* u)
const 424 assert(u->urefcount == 0);
425 assert(u->refcount == 0);
426 if( !(u->flags & UMatData::USER_ALLOCATED) )
428 uchar* udata = ((uchar**)u->origdata)[-1];
429 int n=u->origdata-udata;
430 if((n & (n - 1)) == 0&&n>=0&&n<=32){
431 fastFree(u->origdata);
433 else free(u->origdata);
442 mutable int* refCount;
The GImage class is a tiny implementation of image for removing dependency of opencv.
Definition: GImage.h:160