Для начала обрати внимание, что BMP-изображения хранятся построчно снизу-вверх (но все-таки слева-направо). Там есть 4х байтное выравнивание. Какая битность у входящего изображения? Есть ли альфа-канал?
Удобнее всего работать с 4х-канальным изображением (RGBA), где на каждый канал - 1 байт. Таким образом выравнивание нас не заботит, можно читать вот такие структуры одна за одной:
struct BmpPixel
{
unsigned char Blue;
unsigned char Green;
unsigned char Red;
unsigned char Alpha;
};
В bmp-файле идет сначала заголовок файла, затем, заголовок изображения, потом буфер с данными. В первом узнаешь размер всего файла для чтения, во втором - характеристики изображения (как именно читать, сколько каналов, длинна строки и их количество). Это есть на MSDN.
Об остальном уже сказали. От себя могу посоветовать не преводить в грейкейл, а тупо складывать значение каналов (с альфой тоже можно подумать, например, умножить на три и вычесть из суммы каналов).