Насколько это сложно?Вы можете настроить его так, чтобы копировать 4-байтовое слово за раз, что может быть немного быстрее в некоторых 32-битных системах:
void fast_unpack(char* rgba, const char* rgb, const int count) {
if(count==0)
return;
for(int i=count; --i; rgba+=4, rgb+=3) {
*(uint32_t*)(void*)rgba = *(const uint32_t*)(const void*)rgb;
}
for(int j=0; j<3; ++j) {
rgba[j] = rgb[j];
}
}
Дополнительный случай в конце заключается в том, чтобы разобраться с фактомчто в массиве rgb отсутствует байт.Вы также можете сделать это немного быстрее, используя выровненные ходы и инструкции SSE, работая с кратностью 4 пикселя за раз.Если вы чувствуете себя действительно честолюбивым, вы можете попробовать еще более ужасные запутанные вещи, такие как, например, предварительная загрузка строки кэша в регистры FP, а затем перетаскивание ее на другое изображение одновременно.Конечно, пробег, который вы получите от этих оптимизаций, будет сильно зависеть от конкретной конфигурации системы, на которую вы нацелены, и я бы очень скептически отнесся к тому, что делать что-то из этого вместо простой вещи очень много.
И мои простые эксперименты подтверждают, что это действительно немного немного быстрее, по крайней мере, на моей машине с x86.Вот эталонный тест:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <time.h>
void fast_unpack(char* rgba, const char* rgb, const int count) {
if(count==0)
return;
for(int i=count; --i; rgba+=4, rgb+=3) {
*(uint32_t*)(void*)rgba = *(const uint32_t*)(const void*)rgb;
}
for(int j=0; j<3; ++j) {
rgba[j] = rgb[j];
}
}
void simple_unpack(char* rgba, const char* rgb, const int count) {
for(int i=0; i<count; ++i) {
for(int j=0; j<3; ++j) {
rgba[j] = rgb[j];
}
rgba += 4;
rgb += 3;
}
}
int main() {
const int count = 512*512;
const int N = 10000;
char* src = (char*)malloc(count * 3);
char* dst = (char*)malloc(count * 4);
clock_t c0, c1;
double t;
printf("Image size = %d bytes\n", count);
printf("Number of iterations = %d\n", N);
printf("Testing simple unpack....");
c0 = clock();
for(int i=0; i<N; ++i) {
simple_unpack(dst, src, count);
}
c1 = clock();
printf("Done\n");
t = (double)(c1 - c0) / (double)CLOCKS_PER_SEC;
printf("Elapsed time: %lf\nAverage time: %lf\n", t, t/N);
printf("Testing tricky unpack....");
c0 = clock();
for(int i=0; i<N; ++i) {
fast_unpack(dst, src, count);
}
c1 = clock();
printf("Done\n");
t = (double)(c1 - c0) / (double)CLOCKS_PER_SEC;
printf("Elapsed time: %lf\nAverage time: %lf\n", t, t/N);
return 0;
}
А вот результаты (скомпилированы с g ++ -O3):
Размер изображения = 262144 байта
Количество итераций= 10000
Тестирование простой распаковки .... Выполнено
Истекшее время: 3.830000
Среднее время: 0.000383
Проверка сложной распаковки .... Выполнено
Истекшее время: 2.390000
Среднее время: 0.000239
Так что, может быть, на 40% быстрее в хороший день.