我一直在研究Bitmap(.bmp)文件格式一段时间,试图找出如何构建read函数。一般的想法是支持所有常见的压缩类型,安全并且仍然可以快速加载到(自定义)通用内存映像中,以便在机器视觉库中进行进一步处理。
考虑到性能,我认为最好为每个bitcount +压缩类型星座编写一个尽可能高效的循环。以下是BI_RGB
的搜索结果:
if (bmpi.biCompression == BI_RGB){
if (bmpi.biBitCount >= 24){
// Here, every byte is each channel's value (assuming order is GBR(A))
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
index = row + x;
*(res->data++) = read_data[index + 2]; // R
*(res->data++) = read_data[index + 1]; // G
*(res->data++) = read_data[index]; // B
}
}
}
else if (bmpi.biBitCount == 16){
// Without a bitfield mask, it's assumed 555 (instead of the common 565) with the last bit discarded
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
val = (WORD)&read_data[row + x];
*(res->data++) = map16to255[((val >> 10) & 31)]; // R
*(res->data++) = map16to255[((val >> 5) & 31)]; // G
*(res->data++) = map16to255[(val & 31)]; // B
}
}
}
else if (bmpi.biBitCount == 8){
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
memcpy(res->data, &colors[read_data[row + x]], 3); // Copy RGB from color table
res->data += 3; // Increment
}
}
}
else if (bmpi.biBitCount == 4){
// 2 pixels per byte
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
index = row + x;
memcpy(res->data, &colors[(read_data[index] & 15)], 3);
res->data += 3;
memcpy(res->data, &colors[(read_data[index] >> 4)], 3);
res->data += 3;
}
}
}
else{
// 8 pixels per byte
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
index = row + x;
for (i = 0; i < 8; i++){
memcpy(res->data, &colors[((read_data[index] >> i) & 1)], 3);
res->data += 3;
}
}
}
}
}
说实话,它看起来不漂亮。 然后我考虑分配一个函数指针,只写一个循环,但担心它会以某种方式使它变慢。至少它会添加一层混淆(正在发生的事情)。如果它清楚地显示正在发生的事情以及目的是什么,我宁愿拥有臃肿的代码
typedef void(*pxl_proc) (int index, BYTEP read_data, BYTEP in_data, PRGBQUAD colors);
//...
pxl_proc func = _24_rgb;
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
func(row + x, read_data, res->data, colors);
}
}
我感觉这种方法是不必要的,并且有一种处理位图的一般方法,同时仍然快速或快速。
我该怎么做?这个&#34;足够好&#34;专业图书馆?