我需要将从一种专有设备SDK检索到的医学图像数据传递给来自第二个供应商的另一个专有设备SDK中的图像处理函数。
第一个函数以平面RGB格式给出图像:
int mrcpgk_retrieve_frame(uint16_t *r, uint16_t *g, uint16_t *b, int w, int h);
uint16_t的原因是设备可以切换为输出每个颜色值编码为16位浮点值。但是,我正在“字节模式”下运行,因此每个颜色值的前8位始终为零。
另一个设备SDK的第二个函数定义如下:
BOOL process_cpgk_image(const PBYTE rgba, DWORD width, DWORD height);
因此,我们将以下位填充到三个缓冲区中:(16位平面RGB)
R: 0000000 rrrrrrrr 00000000 rrrrrrrr ...
G: 0000000 gggggggg 00000000 gggggggg ...
B: 0000000 bbbbbbbb 00000000 bbbbbbbb ...
期望的输出以比特为单位表示:
RGBA: rrrrrrrrggggggggbbbbbbbb00000000 rrrrrrrrggggggggbbbbbbbb00000000 ....
我们无法访问这些函数的源代码,也无法更改环境。目前,我们已经实现了以下基本的“桥接”来连接这两个设备:
void process_frames(int width, int height)
{
uint16_t *r = (uint16_t*)malloc(width*height*sizeof(uint16_t));
uint16_t *g = (uint16_t*)malloc(width*height*sizeof(uint16_t));
uint16_t *b = (uint16_t*)malloc(width*height*sizeof(uint16_t));
uint8_t *rgba = (uint8_t*)malloc(width*height*4);
int i;
memset(rgba, 0, width*height*4);
while ( mrcpgk_retrieve_frame(r, g, b, width, height) != 0 )
{
for (i=0; i<width*height; i++)
{
rgba[4*i+0] = (uint8_t)r[i];
rgba[4*i+1] = (uint8_t)g[i];
rgba[4*i+2] = (uint8_t)b[i];
}
process_cpgk_image(rgba, width, height);
}
free(r);
free(g);
free(b);
free(rgba);
}
这段代码本身运行良好,但是处理许多高分辨率图像时会花费很长时间。 处理和检索的两个功能非常快速,而我们的桥梁目前成为了瓶颈。
我知道如何使用SSE2内在函数进行基本算术,逻辑和移位操作,但不知道如何使用MMX,SSE2或[S] SSE3加速这种16位平面rgb到打包rgba的转换?
(首选SSE2,因为仍然有一些2005年以前的设备在使用)。