Должно быть довольно просто написать эту функцию с использованием векторных встроенных функций.Я не знаю, какой процессор, компилятор или формат упакованного пикселя вы используете, поэтому приведу пример реализации с использованием встроенных функций GCC и MMX для x86.Также должно быть легко перевести этот код в код ARM NEON, PowerPC Altivec или x86 / x64 SSE.
Это должно преобразовать планарный RGB в 32-битную упакованную RGBA, хотя ARGB фактически более распространен.Если вам нужен 24-битный RGB, вам нужно будет немного креативнее.«Руководство разработчика программного обеспечения» для вашего процессора станет вашим лучшим другом при написании этого небольшого фрагмента кода, и вам также необходимо прочитать документацию для вашего компилятора.
SIMD очень хорошо справится с этим, вы можетерасскажите, насколько короткий код ниже.Обратите внимание, что приведенный ниже код на самом деле C99, а не C ++, поскольку C99 предоставляет доступ к ключевому слову restrict
, которое может уменьшить количество загрузок и сгенерированных хранилищ.
Также обратите внимание, что этот код имеет строгие требования выравнивания.1008 *
#include <stddef.h>
#if defined(USE_MMX)
typedef char v8qi __attribute__ ((vector_size(8)));
void pack_planes3(void *dest, const void *src[3], size_t n)
{
v8qi *restrict dp = dest, x, y, zero = { 0, 0, 0, 0, 0, 0, 0, 0 };
const v8qi *restrict sp1 = src[0];
const v8qi *restrict sp2 = src[1];
const v8qi *restrict sp3 = src[2];
size_t i;
for (i = 0; i < n; i += 8) {
x = __builtin_ia32_punpckhbw(*sp1, *sp3);
y = __builtin_ia32_punpckhbw(*sp2, zero);
dp[0] = __builtin_ia32_punpckhbw(x, y);
dp[1] = __builtin_ia32_punpcklbw(x, y);
x = __builtin_ia32_punpcklbw(*sp1, *sp3);
y = __builtin_ia32_punpcklbw(*sp2, zero);
dp[2] = __builtin_ia32_punpckhbw(x, y);
dp[3] = __builtin_ia32_punpcklbw(x, y);
sp1++;
sp2++;
sp3++;
dp += 4;
}
}
#else
/* Scalar implementation goes here */
#endif