Created
February 24, 2012 14:13
-
-
Save kazuki-ma/1901180 to your computer and use it in GitHub Desktop.
OpenCV Custom Allocator for OpenGL, DirectX, QImage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Custom Allocator for OpenCV's cv::Mat | |
// this code samples writen by facebook.com/matsuda.kazuki and published under public domain. | |
// You can copy and use this code in any situation under any license. | |
#ifndef __CVUT_ALLOCATOR__ | |
#define __CVUT_ALLOCATOR__ 1 | |
#include <opencv2/core/core.hpp> | |
// customAllocator | |
namespace cvut | |
{ | |
class BaseAllocator: public cv::MatAllocator | |
{ | |
public: | |
BaseAllocator() {} | |
virtual ~BaseAllocator() {} | |
// alignment size calculate function. | |
virtual int alignment_size(int dims, const int* sizes, const int type) = 0; | |
void allocate(int dims, const int* sizes, int type, int*& refcount, | |
uchar*& datastart, uchar*& data, size_t* step) | |
{ | |
// calcurate alignment size which determined by dims, sizes and type. | |
const int alignment = alignment_size(dims, sizes, type); | |
// latest step is always equals with element size. | |
// e.g. step[1] == 24 when matrix is 2-d CV_8UC3. | |
step[dims-1] = CV_ELEM_SIZE(type); | |
// calculate each step[x] from bottom to top. | |
// cv::alignSize is effective when step[dims - 2]. | |
for(int d = dims - 2; d >= 0; --d) { | |
step[d] = cv::alignSize(step[d+1] * sizes[d+1], alignment); | |
} | |
// total needed size of new allocation | |
const size_t total_image_bytes | |
= cv::alignSize(step[0] * sizes[0], std::max<size_t>(alignment, sizeof(*refcount))); | |
// allocate new memory region and save the its pointer. | |
uint8_t* const allocated_pointer | |
= reinterpret_cast<uint8_t*>(cv::fastMalloc(total_image_bytes + sizeof(*refcount))); | |
data = datastart = reinterpret_cast<uint8_t*>(allocated_pointer); | |
refcount = reinterpret_cast<int* >(allocated_pointer + total_image_bytes); | |
// set to refcount is 1 because its allocated now and its reference is 1 | |
// until this method. | |
*refcount = 1; | |
} | |
// deallocate | |
void deallocate(int* refcount, uchar* datastart, uchar* data) | |
{ | |
if (!refcount) return; // allocated by user | |
else cv::fastFree(datastart); // allocated by its allocator | |
} | |
}; | |
class ByteAllocator : public BaseAllocator { | |
public: | |
ByteAllocator (const int bytes) : alignment_byte(bytes){} | |
virtual ~ByteAllocator() {} | |
virtual int alignment_size(int dims, const int* sizes, const int type) { | |
return alignment_byte; | |
}; | |
int alignment_byte; | |
}; | |
class PixelAllocator : public BaseAllocator { | |
public: | |
PixelAllocator (const int pixels) : alignment_pixels(pixels){} | |
virtual ~PixelAllocator() {} | |
virtual int alignment_size(int dims, const int* sizes, const int type) { | |
return CV_ELEM_SIZE(type) * alignment_pixels; | |
}; | |
int alignment_pixels; | |
}; | |
} | |
#endif // #ifndef __CVUT_ALLOCATOR__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment