在openmv对图像提取roi,这里用到了提取像素位的函数。
在collections.h中定义了相关的结构体和功能函数声明。
// bitmap //
typedef struct bitmap
{
size_t size;
char *data;
}
__attribute__((aligned(8)))bitmap_t;
void bitmap_alloc(bitmap_t *ptr, size_t size);
void bitmap_free(bitmap_t *ptr);
void bitmap_clear(bitmap_t *ptr);
void bitmap_bit_set(bitmap_t *ptr, size_t index);
bool bitmap_bit_get(bitmap_t *ptr, size_t index);
为bitmap申请内存单元。如何通过bit数来申请内存单元?
#define CHAR_BITS (sizeof(char) * 8) //计算一个字节所需要的的bit数
#define CHAR_MASK (CHAR_BITS - 1) //
#define CHAR_SHIFT IM_LOG2(CHAR_MASK) //求解log2 计算偏移量。
// bitmap //
void bitmap_alloc(bitmap_t *ptr, size_t size)
{
ptr->size = size;
ptr->data = (char *) fb_alloc0(((size + CHAR_MASK) >> CHAR_SHIFT) * sizeof(char));
}
通过上面代码,可以看到给定的单位长度:size。通过((size + CHAR_MASK) >> CHAR_SHIFT) * sizeof(char) ,其中的size+CHAR_MASK类似于四舍五入的思想,将不够一个char的拼接成一个char。后面执行>>CHAR_SHIFT是将bit数转化为对用的char数。最后*sizeof(char),求出最终内存单元大小。调用的fb_alloc0函数是具有一定内存管理的(基于malloc)。这个在这里就不细说,可以在后面的随笔记录里面书写。
2、void bitmap_free(bitmap_t *ptr); 释放已经申请的内存单元
void bitmap_free(bitmap_t *ptr)
{
if (ptr->data) {
fb_free();
}
}
很有趣的是:这里给了参数bitmap_t *ptr,但是在函数中只用到了检测是否含有数据,ptr->data。之后便调用fb_free();没有参数。没有参数怎么知道释放哪些内存单元?这就很有趣了。
进一步查看一下fb_free()
void fb_free()
{
uint8_t i;
for(i=0; i
通过函数可以知道,这里的内存块是具有一定管理能力的,通过 m_fb_alloc_addr[i].valid && m_fb_alloc_addr[i].count==m_count_max_now 这个条件来匹配当前需要释放的内存单元是哪个。这种方式应该是用在一些临时变量里面不适用于全局内存管理。在一些临时变量申请之后,函数的最后在释放其内存。防止堆栈溢出。关于这一块的管理是在fb_alloc.c中说明。可以在以后的随笔中书写。
3、void bitmap_clear(bitmap_t *ptr); 清楚内存单元,其实就是讲数据bit全部变为0
void bitmap_clear(bitmap_t *ptr)
{
memset(ptr->data, 0, ((ptr->size + CHAR_MASK) >> CHAR_SHIFT) * sizeof(char));
}
这里就没有什么好说的,利用memset设置所欲申请内存单元为0.
4、void bitmap_bit_set(bitmap_t *ptr, size_t index) 置位某一位bit。
void bitmap_bit_set(bitmap_t *ptr, size_t index)
{
ptr->data[index >> CHAR_SHIFT] |= 1 << (index & CHAR_MASK);
}
这里面有几个简单计算说一下:第一个如果通过给的bit位置算出char的位置。
这里使用的是 index>>CHAR_SHIFT来完成的。
第二个问题是确定了那个char,那么在这个char里面的那个位,通过index&CHAR_MASK来确定.。
以上就是自己对于openmv源码中的bitmap的简单理解。记录一下,方便自己以后加深理解。