RGB888转RGB565使用C代码来实现是非常简单的,但就是比较耗时,使用NEON很容易实现这个功能,而且速度还能有很大的提升,以下是将16个RGB888像素点转为RGB565的代码
uint8x16x3_t v = vld3q_u8(rgb);
uint8x16_t r5 = vshrq_n_u8(v.val[0], 3);
uint8x16_t g6 = vshrq_n_u8(v.val[1], 2);
uint8x16_t b5 = vshrq_n_u8(v.val[2], 3);
uint16x8_t temp = vshll_n_u8(vget_low_u8(r5), 8);
uint16x8_t r5_l = vqshlq_n_u16(temp, 3);
uint16x8_t g6_l = vshll_n_u8(vget_low_u8(g6), 5);
uint16x8_t b5_l = vmovl_u8(vget_low_u8(b5));
uint16x8_t rg56_l = vorrq_u16(r5_l, g6_l);
uint16x8_t rgb565_l = vorrq_u16(rg56_l, b5_l);
vst1q_u16(rgb565, rgb565_l);
temp = vshll_n_u8(vget_high_u8(r5), 8);
uint16x8_t r5_h = vqshlq_n_u16(temp, 3);
uint16x8_t g6_h = vshll_n_u8(vget_high_u8(g6), 5);
uint16x8_t b5_h = vmovl_u8(vget_high_u8(b5));
uint16x8_t rg56_h = vorrq_u16(r5_h, g6_h);
uint16x8_t rgb565_h = vorrq_u16(rg56_h, b5_h);
vst1q_u16(rgb565 + 8, rgb565_h);
在实现了这段代码后,编译的时候遇到了如下的报错:
error:constant 11 out of range 0 - 8
编译器并没有能正确的指出错误的是哪一行代码,后来发现是将R右移11位的操作
vshll_n_u8(vget_low_u8(r5), 11);
以上写法会导致这个error,即右移的最大范围是8,而这里要右移11。
所以这里拆成了两次移位来实现右移11位。
这篇博客介绍了如何利用ARM NEON指令集优化RGB888到RGB565的颜色转换过程,通过提供一段C代码展示了16个像素点的转换方法。在实现过程中,作者遇到并解决了右移位数超过限制的问题,通过两次移位操作避免了编译错误。文章强调了NEON优化对于提高转换效率的重要性。

被折叠的 条评论
为什么被折叠?



