Skip to content

Instantly share code, notes, and snippets.

@kazuki-ma
Created February 24, 2012 14:13
Show Gist options
  • Save kazuki-ma/1901180 to your computer and use it in GitHub Desktop.
Save kazuki-ma/1901180 to your computer and use it in GitHub Desktop.
OpenCV Custom Allocator for OpenGL, DirectX, QImage
// 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