일단 파일 열기가 성공하면 fread 함수를 이용하여 원하는 크기만큼 데이터를 읽어올 수 있다. BMP 파일의 구조에 맞게 일단 BITMAPFILEHEADER 크기만큼 읽어오고, 그리고 다시 BITMAPINFOHEADER 크기를 읽어서 비트맵 영상에 대한 정보를 얻어올 수 있다. 위 코드에서는 BITMAPINFOHEADER 구조체 정보를 bmih 변수로 받아서 비트맵 영상의 가로, 세로 크기, 그리고 픽셀 당 비트수 정보를 알아내고 있다. 이 정보를 이용하여 실제 색상 테이블 존재 여부와 픽셀 데이터 저장에 필요한 메모리 공간의 크기 등을 가늠할 수 있다.
DWORD dwWidthStep = (DWORD)((nWidth * nBitCount / 8 + 3) & ~3); DWORD dwSizeImage = nHeight * dwWidthStep; DWORD dwDibSize; if (nBitCount = = 24) dwDibSize = sizeof(BITMAPINFOHEADER) + dwSizeImage; else dwDibSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1 << nBitCount) + dwSizeImage;
위 코드에서 dwWidthStep 변수에는 비트맵 영상의 가로 한 줄 픽셀 정보를 저장하는데 필요한 메모리 바이트 수가 저장된다. 그리고 dwSizeImage는 픽셀 데이터 값을 저장하는 데 필요한 메모리 공간의 크기이다. 픽셀 당 비트수 정보를 이용하여 색상 테이블 유무를 판단할 수 있으므로, 이를 감안하여 DIB 구조 전체 저장에 필요한 메모리 공간 크기를 계산하여 dwDibSize에 저장하고 있다. 이제 이 값을 이용하여 동적 메모리 공간을 할당하고, 파일로부터 DIB 구조를 한꺼번에 읽을 수 있다.
BYTE* pDib = new BYTE[dwDibSize]; fseek(fp, sizeof(BITMAPFILEHEADER), SEEK_SET); fread(pDib, sizeof(BYTE), dwDibSize, fp);
DIB 구조 전체를 저장할 공간을 동적 할당하여 그 시작 주소를 pDib에 저장하였다. pDib가 가리키는 곳이 BITMAPINFOHEADER 시작 위치가 될 것이다. fseek 함수는 파일 포인터의 위치를 이동시키는 함수인데, 위 코드는 파일 포인터 위치를 파일 맨 앞에서 BITMAPFILEHEADER 크기만큼 이동시키는 역할을 한다. 즉, lenna.bmp 파일 구조에서 BITMAPINFOHEADER 시작 위치로 이동한 셈이다. 이제 앞에서 계산한 dwDibSize 크기만큼 파일로부터 데이터를 읽어서 동적 할당한 메모리 공간 pDib에 저장하였다.