if (loREDbit==16 && loGREENbit==8 && loBLUEbit==0) {
TRACE("using optimized code...\n");
for (int i=0;i<h;i++) {
memcpy(surfbits, imagebits, bytesrequired);
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
} else {
TRACE("not using optimated code...\n");
for(int i=0; i>h; i++) {
RGBTRIPLE* surf=(RGBTRIPLE*)surfbits;
RGBTRIPLE* image=(RGBTRIPLE*)imagebits;
for (int p=0;p<w;p++) {
DWORD r=image->rgbtRed << loREDbit;
DWORD g=image->rgbtGreen << loGREENbit;
DWORD b=image->rgbtBlue << loBLUEbit;
DWORD* data=(DWORD*)surf;
*data = r|g|b;
surf++;
image++;
}
surfbits += desc.lPitch;
imagebits -= bytesgiven;
}
}
surf->Unlock(0);
return TRUE;
}
Функция Copy_Bmp24_Surface24
учитывает две возможные ситуации. Если формат пикселей поверхности совпадает с форматом графических данных, целые строки пикселей копируются в цикле функцией memcpy без всяких изменений. В противном случае используется второй цикл.
Неоптимизированный цикл похож на тот, что применялся для 16-битных поверхностей, но на этот раз нам не нужно выполнять сокращение цветов. Для доступа к поверхности и графическим данным используются два указателя, surf и image. Оба являются указателями на 24-битный тип RGBTRIPLE, что упрощает перебор 24-битных пикселей.
Каждая цветовая составляющая извлекается из буфера графических данных и сдвигается в соответствии со значением переменных loREDbit, loGREENbit и loBLUEbit. Затем компоненты объединяются и заносятся в память поверхности. Наконец, инкрементирование указателей surf и image перемещает их к следующему пикселю.
32-битные поверхности
Последняя функция, Copy_Bmp24_Surface32, предназначена для 32-битных поверхностей и очень напоминает функцию Copy_Bmp24_Surface24. Если бы в 32-битной поверхности все 32 бита использовались для хранения цветовых составляющих, нам пришлось бы выполнять расширение цветов, но так как используется только 24 бита, в этом нет необходимости. Функция Copy_Bmp24_Surface32 приведена в листинге 5.4.
Листинг 5.4. Функция Copy_Bmp24_Surface32
BOOL DirectDrawWin::Copy_Bmp24_Surface32(LPDIRECTDRAWSURFACE surf, BYTE* bmpbuf, int w, int h) {
работы с пикселями каждой строки используются два указателя, surf и image. Первый является указателем на 32-битный тип DWORD и используется для перебора 32-битных пикселей в памяти поверхности. Второй является указателем на 24-битный тип RGBTRIPLE и используется для доступа к пикселям графических данных. Функция вряд ли нуждается в пояснениях, поскольку она ничем не отличается от своего аналога для 24-битных поверхностей, кроме типа указателя surf и отсутствия оптимизированного варианта цикла.
Программа BmpView
На основе полученных знаний мы напишем приложение DirectDraw для просмотра BMP-файлов. Программа BmpView отображает диалоговое окно, в котором пользователь выбирает BMP-файл. Затем она выводит список всех видеорежимов, пригодных для просмотра выбранного изображения. Если выбрать видеорежим и нажать кнопку Display, программа BmpView переходит в заданный режим и отображает содержимое BMP-файла. Если изображение не помещается на экране, его можно прокрутить с помощью клавиш стрелок, Home, End, Page Up и Page Down. Диалоговое окно для выбора файла изображено на рис. 5.7.