使用neon实现RGB888转RGB565

这篇博客介绍了如何利用ARM NEON指令集优化RGB888到RGB565的颜色转换过程,通过提供一段C代码展示了16个像素点的转换方法。在实现过程中,作者遇到并解决了右移位数超过限制的问题,通过两次移位操作避免了编译错误。文章强调了NEON优化对于提高转换效率的重要性。

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位。

NEON的右移位数是由限制的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值