iOS 转换RGB24 为 RGBA

昨晚完成了一篇转换RGB24为BGR24的文章,今天续写如何将RGB24转换为RGBA。一点显著的不同是RGB占有3个字节,而RGBA则占有4个字节,相比RGB TO BGR的简单性,RGB TO RGBA一定需要为RGBA另外分配存储空间。类似于昨天的第一中方法这里就不再提供了,一是简单,二呢效率太低。

1.使用ACCERLERATE.FRAMEWORK提供的库函数 vImageConvert_RGB888toARGB8888 和 vImagePermuteChannels_ARGB8888

- (void)transformRGBToRGBA:(const UInt8 *)pict width:(int)width height:(int)height
{
    const uint8_t permuteMap[4] = {1,2,3,0};

    rgb.data = (void *)pict;
            
    vImage_Error error = vImageConvert_RGB888toARGB8888(&rgb,NULL,0,&argb,NO,kvImageNoFlags);
    if (error != kvImageNoError) {
        NSLog(@"vImageConvert_RGB888toARGB8888 error");
    }
    
    error = vImagePermuteChannels_ARGB8888(&argb,&rgba,permuteMap,kvImageNoFlags);
    if (error != kvImageNoError) {
        NSLog(@"vImagePermuteChannels_ARGB8888 error");
    }

    free((void *)pict);
}

这里的rgb,rgba,argb为 vImage_Buffer类型,表示具体的像素数据,是为数据源。可以看出首先使用 vImageConvert_RGB888toARGB8888 将 rgb 转换为 argb,然后使用  vImagePermuteChannels_ARGB8888 将argb 转换为 rgba。之所以经过两次转换,是因为iOS目前不支持argb格式。整个accerlerate.framework都是经过neon优化的,效率相当高。

2.第一种方法固然很快,但是要经过两次转换,少费周折。因此,这里我们祭出了终极杀器。

- (void) neon_asm_convert_RGB_TO_RGBA:(const UInt8 *) img toRGBABuffer:(const UInt8 *)bytes numPixel:(int) numPixels24
{
    // numPixels is divided by 24
    __asm__ volatile(
                     "0:                \n"
                     "# load 3 64-bit regs with interleave: \n"
                     "vld3.8      {d0,d1,d2}, [%0]!   \n"
                     "# store 4 64-bit regs: \n"
                     "vst4.8      {d0,d1,d2,d3}, [%2]!      \n"
                     "subs        %1, %1, #1       \n"
                     "bne         0b            \n"
                     :
                     : "r"(img), "r"(numPixels24), "+r"(bytes)
                     : "r6", "r7","r8"
                     );
    
    free((void *)img);
}

直接使用neon汇编节省了内存,避免了中间状态的转换,效率提升明显相比第一中方法。

posted @ 2012-07-31 18:13  CoderZHY  阅读(3337)  评论(0编辑  收藏  举报