더북(TheBook)

일단 파일 열기가 성공하면 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에 저장하였다.

신간 소식 구독하기
뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.