Я предполагаю, что это было дизайнерское решение для выравнивания для улучшения структуры памяти, при этом не тратя так много места (для изображения шириной 319 пикселей вы бы потратили 3 байта или 0,25%)
Представьте, что вам нужен прямой доступ к какой-то нечетной строке. Вы можете получить доступ к первым 4 пикселям n-й строки, выполнив:
uint8_t *startRow = bmp + n * width * 3; //3 bytes per pixel
uint8_t r1 = startRow[0];
uint8_t g1 = startRow[1];
//... Repeat
uint8_t b4 = startRow[11];
Обратите внимание, что если n и ширина нечетные (а bmp четное), startRow будет нечетным.
Теперь, если вы попытались сделать следующее ускорение:
uint32_t *startRow = (uint32_t *) (bmp + n * width * 3);
uint32_t a = startRow[0]; //Loading register at a time is MUCH faster
uint32_t b = startRow[1]; //but only if address is aligned
uint32_t c = startRow[2]; //else code can hit bus errors!
uint8_t r1 = (a & 0xFF000000) >> 24;
uint8_t g1 = (a & 0x00FF0000) >> 16;
//... Repeat
uint8_t b4 = (c & 0x000000FF) >> 0;
Вы столкнулись с множеством проблем. В лучшем случае (это Intel Cpu) каждую нагрузку a , b и c необходимо разбить на две нагрузки, так как startRow не делится на 4. В худшем случае (например, sun sparc) ваша программа вылетает с «ошибкой шины».
В более новых проектах обычно выравнивание строк выполняется по крайней мере на размер строки кэша L1 (64 байта для intel или 128 байтов для nvidia gpus).