Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SSW_8_11.doc
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
5 Мб
Скачать
☆

Loading a dib into Memory

Look at the class's constructor, which is shown in Listing 11.9.

Listing 11.9 The CDib Class's Constructor

CDib::CDib(const char* fileName)

{

// Load the bitmap and initialize

// the class's data members.

LoadBitmapFile(fileName);

}

You create a CDib object by calling the CDib class's constructor with the file name of the DIB that you want to load. The constructor passes this file name to the protected member function, LoadBitmapFile(), which actually loads the bitmap. LoadBitmapFile()'s code is fairly complex. In fact, it makes up the bulk of the CDib class's code. The other CDib member functions generally return values calculated by LoadBitmapFile().

First, LoadBitmapFile() constructs an MFC CFile object:

CFile file(fileName, CFile::modeRead);

This line of code not only constructs a CFile object named file but also opens the file (whose name is passed in the fileName argument) in the read-only mode.

Next, the function declares a BITMAPFILEHEADER structure and reads the DIB's file header into the structure:

BITMAPFILEHEADER bmFileHeader;

file.Read((void*)&bmFileHeader, sizeof(bmFileHeader));

The CFile object's Read() member function requires as its arguments a pointer to the buffer in which to store the data and the size of the buffer. In this case, the buffer is the BITMAPFILEHEADER structure.

After the preceding lines, the DIB's file header is stored in the bmFileHeader structure. The first task is to check whether the opened file is actually a bitmap. The function does this (as shown in Listing 11.10) by checking the bfType member for the value 0x4D42, which is the ASCII code for the letters BM.

Listing 11.10 Checking that the File is a Bitmap

if (bmFileHeader.bfType != 0x4d42)

{ AfxMessageBox("Not a bitmap file");

m_pBmFileHeader = 0;

m_pBmInfo = 0;

m_pBmInfoHeader = 0;

m_pRGBTable = 0;

m_pDibBits = 0;

m_numColors = 0;

}

If the bfType structure member does not contain the correct value, the function sets all the class's data members to 0 and exits. Otherwise, LoadBitmapFile() calls the CFile object's GetLength() member function to get the size of the opened file:

DWORD fileLength = file.GetLength();

The function then calculates the size of the DIB by subtracting the size of the file header from the size of the file:

DWORD dibSize = fileLength - sizeof(bmFileHeader);

The program uses the resulting value, dibSize, to allocate enough memory in which to store the DIB:

BYTE* pDib = (BYTE*)GlobalAlloc(0, dibSize);

GlobalAllocPtr() is a Windows function that allocates memory and returns a pointer to that memory. It requires two arguments: a flag indicating how the memory should be allocated and the size of the memory block to be allocated. Refer to your Windows programming manual for more information on GlobalAllocPtr().

After allocating memory, the function calls the CFile object's Read() member function to read the DIB into memory and then closes the file by calling the Close() member function:

file.Read((void*)pDib, dibSize);

file.Close();

At this point, the DIB is stored in memory, and LoadBitmapFile() can now calculate the values that the class needs. The addresses of the DIB's BITMAPINFO and BITMAPINFOHEADER structures are identical, being the same address as the buffer in which the DIB is stored:

m_pBmInfo = (LPBITMAPINFO) pDib;

m_pBmInfoHeader = (LPBITMAPINFOHEADER) pDib;

The function then calculates a pointer to the color table by adding the size of the BITMAPINFOHEADER structure to the address of the DIB in memory:

m_pRGBTable =(RGBQUAD*)(pDib + m_pBmInfoHeader->biSize);

When doing this type of pointer math, be careful that you're using the correct data types. For example, because pDib is a pointer to BYTE, the number of bytes stored in biSize is added to this pointer. However, if pDib were defined as a pointer to a BITMAPINFO structure, the value biSize*sizeof(BITMAPINFO) would be added to pDib. If you don't understand this, you should review how pointer math works. Next, the function initializes the m_numColors data member, by calling the member function GetDibNumColors():

int m_numColors = GetDibNumColors();

The biSizeImage data member of the DIB's BITMAPINFOHEADER structure is filled in by calling yet another CDib member function, GetDibSizeImage():

m_pBmInfoHeader->biSizeImage = GetDibSizeImage();

Next, if the BITMAPINFOHEADER's biClrUsed member is 0, LoadBitmapFile() initializes it to the correct value, which is now stored in the m_numColors data member:

if (m_pBmInfoHeader->biClrUsed == 0)

m_pBmInfoHeader->biClrUsed = m_numColors;

Finally, LoadBitmapFile() calculates the address of the DIB's image by adding the size of the BITMAPINFOHEADER structure and the size of the color table to the pDib pointer, which contains the address of the DIB in memory:

DWORD clrTableSize = m_numColors * sizeof(RGBQUAD);

m_pDibBits = pDib + m_pBmInfoHeader->biSize + clrTableSize;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]