Независимо от того, хранится ли DIB в памяти или на диске, его структура практически одинакова. Фактически файл DIB состоит из последовательно расположенных структур нескольких типов. Это структуры BITMAPFILEHEADER, BITMAPINFO, BITMAPINFOHEADER и RGBQUAD. В последующих разделах рассматриваетя каждая из этих структур и ее использование в программах для Windows.
В начале файла DIB расположена структура BITMAPFILEHEADER. В листинге 2.1 приводится ее описание для Windows.
Листинг 2.1. LST2_1.CPP — структура BITMAPFILEHEADER |
typedef struct tagBITMAPFILEHEADER { WORD bfType; DWORD bfSize; WORD bfReserved1; WORD bfreserved2; DWORD bfOffBits; } BITMAPFILEHEADER; |
Хотя данная структура располагается в начале файла на диске, она не обязана присутствовать в растрах, находящихся в памяти. Первое поле структуры, bfType, служит для идентификации файлов растровой графики и должно содержать ASCII-коды символов BM. В шестнадцатиричном виде значение btType должно быть равно 4D42; в противном случае файл, скорее всего, не содержит растрового изображения.
Второе поле структуры, bfSize, должно содержать размер файла в байтах. Однако из-за ошибки в исходной документации Windows значение bfSize ненадежно и пользоваться им не следует. С другой стороны, вы вполне можете положиться на значение bfOffBits, в котором хранится смещение в байтах от начала растрового файла до массива данных. Структура BITMAPINFOHEADER кратко описана в табл. 2.1.
Таблица 2.1. Структура BITMAPFILEHEADER | ||
Поле | Тип | Описание |
bfType | WORD | Содержит ASCII-коды символов «BM» |
bfSize | DWORD | Размер файла |
bfReserved1 | WORD | Всегда равен 0 |
bfReserved2 | WORD | Всегда равен 0 |
bfOffBits | DWORD | Смещение в байтах от начала файла до графических данных |
За структурой BITMAPFILEHEADER следует структура BITMAPINFO. В листинге 2.2 приводится ее описание для Windows.
Листинг 2.2. LST2_2.CPP — структура BITMAPINFO |
typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[1]; } BITMAPINFO; |
Как видите, эта структура состоит из заголовка в виде структуры BITMAPINFOHEADER и цветовой таблицы в виде массива структур RGBQUAD.
В листинге 2.3 приводится описание структуры BITMAPINFOHEADER для Windows.
Листинг 2.3. LST2_3.CPP — структура BITMAPINFOHEADER |
typedef struct tagBITMAPINFOHEADER { DWORD biSize; DWORD biWidth; DWORD biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSizeImage; DWORD biXPelsPerMeter; DWORD biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; |
В поле biSize содержится размер структуры BITMAPINFOHEADER, который должен быть равен 40 байтам. Поля biWidth и biHeight содержат соответственно ширину и высоту растра в пикселях. biPlanes всегда присваивается значение 1. Число в поле biBitCount, обозначающее количество битов на пиксель, может быть равно 1, 2, 4, 8 или 24, что соответствует монохромным, 16-цветным, 256-цветным и, наконец, полноцветным (16,7 миллиона цветов) изображениям. В этой книге нам в основном предстоит работать с 256-цветными (или 8-битными) изображениями.
Поле biCompression показывает тип сжатия (компрессии), использованного в растре; значение 0 означает отсутствие сжатия, 1 — сжатие по алгоритму RLE-8, а 2 — сжатие по алгоритму RLE-4. Если вы не знакомы с техникой сжатия данных, не стоит волноваться — в файлах DIB сжатие применяется редко. Обычно поле biCompression содержит 0.
Поле biSize содержит размер растра в байтах и, как правило, используется только для сжатых растров. При этом учитывается тот факт, что число байтов в каждой строке растра всегда кратно 4. При необходимости строки дополняются пустыми байтами. Однако, только если вы не пишете программу для создания DIB, вам не придется иметь дела с дополнением строк и трудностями, которые при этом возникают.
Поля biXPelsPerMeter и biYPelsPerMeter предназначены для указания количества пикселей на метр по горизонтали и вертикали, но обычно в них содержится 0. Поля biClrUsed и biClrImportant, задающие общее количество использованных цветов и количество значащих цветов соответственно, также обычно остаются равными 0.
Возможно, вы обратили внимание на то, что поля структуры BITMAPINFOHEADER, следующие после biBitCount, обычно равны 0, так что после чтения структуры из дискового файла на их значения полагаться не следует. В этой главе мы узнаем, как вычислить любые необходимые параметры — такие, как количество цветов, использованных в изображении, — и сохранить их в соответствующих полях структуры для будущего использования. Для удобства структура BITMAPINFOHEADER кратко описана в табл. 2.2.
Таблица 2.2. Структура BITMAPINFOHEADER | ||
Поле | Тип | Описание |
biSize | DWORD | Размер данной структуры в байтах |
biWidth | DWORD | Ширина растра в пикселях |
biHeight | DWORD | Высота растра в пикселях |
biPlanes | WORD | Всегда равен 1 |
biBitCount | WORD | Количество битов на пиксель |
biCompression | DWORD | Тип сжатия: 0 = отсутствует, 1 = RLE-8, 2 = RLE-4 |
biSizeImage | DWORD | Размер растра в байтах |
biXPelsPerMeter | DWORD | Количество пикселей на метр по горизонтали |
biYPelsPerMeter | DWORD | Количество пикселей на метр по вертикали |
biClrUsed | DWORD | Количество использованных цветов |
biClrImportant | DWORD | Количество значащих цветов |
Описание последней структуры, RGBQUAD, приведено в листинге 2.4.
Листинг 2.4. LST2_4.CPP — структура RGBQUAD |
typedef struct tagRGBQUAD { BYTE rgbBlue; BYTE rgbGreen; BYTE rgbRed; BYTE rgbReserved; } RGBQUAD; |
В данной структуре всего лишь хранятся интенсивности красной, зеленой и синей составляющих цвета. Каждый цвет в DIB представлен отдельной структурой RGBQUAD. Таким образом, для 16-цветного (4-битного) растра цветовая таблица состоит из 16 структур RGBQUAD, а для 256-цветного (8-битного) цветовая таблица состоит из 256 структур RGBQUAD. Исключение составляют 24-битные изображения, в которых цветовая таблица вообще отсутствует.
За структурой BITMAPINFO в DIB следует массив с данными изображения. Его объем, конечно, зависит от размера изображения. На рис. 2.1 изображена общая структура файла DIB.
Рис. 2.1. Структура DIB