Серьезно? Есть библиотеки для такого рода конвертации. Но, честно говоря, это немного сложновато. Существуют библиотеки, использующие asm, или специализированные команды SSE для ускорения этого процесса, которые будут быстрыми, но довольно легко запустить собственный конвертер форматов в C / C ++.
Ваш основной процесс будет:
- С учетом буфера кодированных значений RGBA8888
- Создайте достаточно большой буфер для хранения значений RGBA4444 или RGBA5551. В этом случае все просто - вдвое меньше.
Зацикливание на исходном буфере, распаковка каждого компонента, перепаковка в целевой формат и запись его в целевой буфер.
void* rgba8888_to_rgba4444(
void* src, // IN, pointer to source buffer
int cb) // IN size of source buffer, in bytes
{
// this code assumes that a long is 4 bytes and short is 2.
//on some compilers this isnt true
int i;
// compute the actual number of pixel elements in the buffer.
int cpel = cb/4;
unsigned long* psrc = (unsigned long*)src;
// create the RGBA4444 buffer
unsigned short* pdst = (unsigned short*)malloc(cpel*2);
// convert every pixel
for(i=0;i<cpel; i++)
{
// read a source pixel
unsigned pel = psrc[i];
// unpack the source data as 8 bit values
unsigned r = p & 0xff;
unsigned g = (pel >> 8) & 0xff;
unsigned b = (pel >> 16) & 0xff;
unsigned a = (pel >> 24) & 0xff;
//convert to 4 bit vales
r >>= 4;
g >>= 4;
b >>= 4;
a >>= 4;
// and store
pdst[i] = r | g << 4 | b << 8 | a << 12;
}
return pdst;
}
Фактический цикл преобразования я сделал очень расточительно, компоненты могут быть извлечены, преобразованы и перепакованы за один проход, что делает намного более быстрый код. Я сделал это таким образом, чтобы сделать преобразование явным и легко изменить. Кроме того, я не уверен, что я правильно понял порядок компонентов. Так что это может быть b, r, g, a, но это не должно влиять на результат функции, поскольку она перепаковывает в том же порядке в буфер dest.