достаточно увеличить значение указателя. Аналогично triple указывает на 24-битный тип RGBTRIPLE.

Внутренний цикл извлекает три цветовые составляющие каждого пикселя и делит их на ранее вычисленную величину. Значения с плавающей точкой, использованные при вычислениях, преобразуются к целым и сдвигаются к нужной позиции в соответствии с переменными loREDbit, loGREENbit и loBLUEbit. Окончательный результат представляет собой тройку «урезанных» цветовых составляющих. Побитовый оператор OR упаковывает составляющие в единую величину, и результат заносится в память поверхности. Указатели pixptr и triple инкрементируются для перехода к следующему пикселю. 

24-битные поверхности

Мы рассмотрели доступ к 16-битным поверхностям, и все самое сложное осталось позади. Для 24- и 32-битных поверхностей сокращение цветов уже не требуется, поэтому вычислить значение пикселя оказывается проще. В основном нам нужно лишь извлечь цветовые составляющие и сдвинуть их в позицию, определяемую расположением и форматом пикселя. Для 24-битных поверхностей процесс можно оптимизировать, если формат пикселей поверхности совпадает с форматом пикселей BMP-файла. 24-битные поверхности обрабатываются функцией Copy_Bmp24_Surface24() (см. листинг 5.3).

Листинг 5.3. Функция Copy_Bmp24_Surface24()

BOOL DirectDrawWin::Copy_Bmp24_Surface24(LPDIRECTDRAWSURFACE surf, BYTE* bmpbuf, int w, int h) {

 if (surf==0 || bmpbuf==0)  return FALSE;

 DDSURFACEDESC desc;

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize = sizeof(desc);

 HRESULT r=surf->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0);

 if (r!=DD_OK) {

  TRACE('Copy_Bmp24_Surface24: Lock() failed ');

  return FALSE;

 }

 int bytesrequired=w*3;

 int bytesgiven=(bytesrequired+3) & ~3;

 BYTE* surfbits = (BYTE*)desc.lpSurface;

 BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);

 // Проверить, совпадает ли формат файла с форматом поверхности

 // Если совпадает, пересылку можно ускорить функцией memcpy()

 if (loREDbit==16 && loGREENbit==8 && loBLUEbit==0) {

  TRACE('using optimized code... ');

  for (int i=0;i<h;i++)  {

   memcpy(surfbits, imagebits, bytesrequired);

   surfbits += desc.lPitch;

   imagebits -= bytesgiven;

  }

 } else {

  TRACE('not using optimated code... ');

  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) {

 if (surf==0 || bmpbuf==0)  return FALSE;

 DDSURFACEDESC desc;

 ZeroMemory(&desc, sizeof(desc));

 desc.dwSize = sizeof(desc);

 HRESULT r=surf->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_WRITEONLY, 0);

 if (r!=DD_OK) {

  TRACE('Copy_Bmp24_Surface32: Lock() failed ');

  return FALSE;

 }

 int bytesrequired=w*3;

 int bytesgiven=(bytesrequired+3) & ~3;

 BYTE* surfbits = (BYTE*)desc.lpSurface;

 BYTE* imagebits = (BYTE*)(&bmpbuf[(h-1)*bytesgiven]);

 for(int i=0; i<h; i++) {

  DWORD* surf=(DWORD*)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++;

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату