Я работаю в C++ с массивом unsigned char, представляющим пиксели в изображении. Каждый пиксель имеет 3 канала (R, G, B). Изображение представлено линейно, вроде как
RGBRGBRGBRGB.....
Как я могу разделить каждый из R, G и B на отдельные массивы эффективно?
Я пытался:
for(int pos = 0; pos < srcWidth * srcHeight; pos++) {
int rgbPos = pos * 3;
splitChannels[0][pos] = rgbSrcData[rgbPos];
splitChannels[1][pos] = rgbSrcData[rgbPos + 1];
splitChannels[2][pos] = rgbSrcData[rgbPos + 2];
}
Но это удивительно медленно.
Благодарю!
Моя попытка: загрузить и сохранить байты четыре-четыре. Байт-скремблирование будет утомительным, но, возможно, пропускная способность улучшится.
// Load 4 interleaved pixels
unsigned int RGB0= ((int*)rgbSrcData)[i];
unsigned int RGB1= ((int*)rgbSrcData)[i + 1];
unsigned int RGB2= ((int*)rgbSrcData)[i + 2];
// Rearrange and store 4 unpacked pixels
((int*)splitChannels[0])[j]=
(RGB0 & 0xFF) | (RGB0 >> 24) | (RGB1 & 0xFF0000) | ((RGB2 & 0xFF00) << 16);
((int*)splitChannels[1])[j]=
((RGB0 & 0xFF00) >> 8) | (RGB1 & 0xFF) | (RGB1 >> 24) | (RGB2 & 0xFF0000) >> 16;
((int*)splitChannels[2])[j]=
((RGB0 & 0xFF0000) >> 16) | (RGB1 & 0xFF00) | ((RGB2 & 0xFF) >> 16) | (RGB2 & 0xFF000000);
(ПРЕДОСТЕРЕЖЕНИЕ: не отключено!) Возможна также версия с поддержкой сдвига.
Решение SSE было бы более сложным (шаг 3 не сочетается с степенями 2).
Отличная методика, используемая для ускорения работы, - это цикл размотки. Вы можете прочитать об этом здесь: http://en.wikipedia.org/wiki/Loop_unwinding