RGB888ToPlanar8 呼び出しを使用して、データを分散させてから、もう一度収集します。これは非常に非常に悪いです。33% のメモリ オーバーヘッドが許容できる場合は、RGBA 形式を使用して、B/R バイトをインプレースで並べ替えてみてください。
33% 節約したい場合は、次の方法をお勧めします。すべてのピクセルを繰り返しますが、4 バイトの倍数だけを読み取ります (lcm(3,4) は 12 なので、つまり 3 dwords です)。
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 組み込み関数を使用すると、さらに良い結果が得られます。
ARM の Web サイトのこのリンクを参照して、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"
);
}