ios - 在 iOS 上如何快速将 RGB24 转换为 BGR24?

标签 ios assembly rgb neon accelerate-framework

我使用 Accelerate.framework 中的 vImageConvert_RGB888toPlanar8vImageConvert_Planar8toRGB888 将 RGB24 转换为 BGR24,但是当需要转换的数据非常大时,例如 3M 或 4M,需要花在这上面的时间大约是 10ms。所以有人知道一些足够快的想法吗?我的代码是这样的:

- (void)transformRGBToBGR:(const UInt8 *)pict{
rgb.data = (void *)pict;

vImage_Error error = vImageConvert_RGB888toPlanar8(&rgb,&red,&green,&blue,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImageConvert_RGB888toARGB8888 error");
}

error = vImageConvert_Planar8toRGB888(&blue,&green,&red,&bgr,kvImageNoFlags);
if (error != kvImageNoError) {
    NSLog(@"vImagePermuteChannels_ARGB8888 error");
}

free((void *)pict);
}

最佳答案

通过 RGB888ToPlanar8 调用,您可以分散数据,然后再次收集数据。这是非常非常非常糟糕的。如果 33% 的内存开销可以承受,请尝试使用 RGBA 格式并就地置换 B/R 字节。

如果您想节省 33% 的百分比,那么我可能会建议以下内容。迭代所有像素,但只读取 4 字节的倍数(因为 lcm(3,4) 是 12,即 3 个双字)。

uint8_t* src_image;
uint8_t* dst_image;

uint32_t* src = (uint32_t*)src_image;
uint32_t* dst = (uint32_t*)dst_image;

uint32_t v1, v2, v3;
uint32_t nv1, nv2, nv3;
for(int i = 0 ; i < num_pixels / 12 ; i++)
{
     // read 12 bytes
     v1 = *src++;
     v2 = *src++;
     v3 = *src++;
     // shuffle bits in the pixels
     // [R1 G1 B1 R2 | G2 B2 R3 G3 | B3 R4 G4 B4]
     nv1 = // [B1 G1 R1 B2]
      ((v1 >> 8) & 0xFF) | (v1 & 0x00FF0000) | ((v1 >> 16) & 0xFF) | ((v2 >> 24) & 0xFF);
     nv2 = // [G2 R2 B3 G3]
       ...
     nv3 = // [R3 B4 G4 R4]
       ...
     // write 12 bytes
     *dst++ = nv1;
     *dst++ = nv2;
     *dst++ = nv3;
}

使用 NEON 内在函数可以做得更好。

请参阅此链接 from ARM's website查看 24 位交换是如何完成的。

BGR 到 RGB 可以像这样就地完成:

void neon_asm_convert_BGR_TO_RGB(uint8_t* img, 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"
        "# swap d0 and d2 - R and B\n"
        "vswp d0, d2   \n"
        "# store 3 64-bit regs: \n"
        "vst3.8      {d0,d1,d2}, [%0]!      \n"
        "subs        %1, %1, #1       \n"
        "bne         0b            \n"
        :
        : "r"(img), "r"(numPixels24)
        : "r4", "r5"
     );
}

关于ios - 在 iOS 上如何快速将 RGB24 转换为 BGR24?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11683864/

相关文章:

opengl-es - 如何在 OpenGL ES 中不转换 rgb 显示 yuv 格式的数据?

javascript - 如何在来回转换时保持 RGB 和 HSL 整数值一致?

ios - connectionDidFinishLoading 中的 TableView 重新加载数据时出错(通过 json 解析)

assembly - Lua 5.1 汇编器存在吗?

ios - MKMapView 显示用户位置崩溃

assembly - 这个 x86-64 代码中的 lea 有什么作用?

c++ - x86 Intel Assembly 和 C++ - 数组周围的堆栈已损坏

android - 如何将图像转换为灰度?

ios - SWIFT - Collection View 单元格大小

c++ - iOS错误的opencv框架