Как эффективно визуализировать 24-битное изображение на 32-битном дисплее?

0

Прежде всего, я программирую в контексте ядра, поэтому существующих библиотек не существует. На самом деле этот код собирается войти в мою собственную библиотеку.

Два вопроса, еще один важный, чем другой:

  1. Как следует из названия, как я могу эффективно отображать изображение 24-bpp на 32-битное устройство, предполагая, что у меня есть адрес буфера кадров?

В настоящее время у меня есть этот код:

void BitmapImage::Render24(uint16_t x, uint16_t y, void (*r)(uint16_t, uint16_t, uint32_t))
{
    uint32_t imght = Math::AbsoluteValue(this->DIB->GetBitmapHeight());
    uint64_t ptr = (uint64_t)this->ActualBMP + this->Header->BitmapArrayOffset;

    uint64_t rowsize = ((this->DIB->GetBitsPerPixel() * this->DIB->GetBitmapWidth() + 31) / 32) * 4;

    uint64_t oposx = x;
    uint64_t posx = oposx;
    uint64_t posy = y + (this->DIB->Type == InfoHeaderV1 && this->DIB->GetBitmapHeight() < 0 ? 0 : this->DIB->GetBitmapHeight());


    for(uint32_t d = 0; d < imght; d++)
    {
        for(uint32_t w = 0; w < rowsize / (this->DIB->GetBitsPerPixel() / 8); w++)
        {
            r(posx, posy, (*((uint32_t*)ptr) & 0xFFFFFF));
            ptr += this->DIB->GetBitsPerPixel() / 8;
            posx++;
        }
        posx = oposx;
        posy--;
    }
}

r является указателем на объект PutPixel-esque, который принимает параметры x, y и color. Очевидно, что этот код ужасно медленный, поскольку построение пикселов по одному никогда не является хорошей идеей.

Для моего кода рендеринга 32-bpp (о котором у меня также возникает вопрос, подробнее об этом позже), я могу легко сохранить память :: Копировать() битмап-массив (я загружаю файлы bmp здесь) в буфер кадров. Однако, как мне это сделать с 24bpp изображениями? На дисплее 24bpp это будет хорошо, но я работаю с 32bpp.

Одно из решений, о котором я могу сейчас подумать, - создать еще один битмап-массив, который по существу содержит значения 0x00 (цвет) и использование, которое нужно рисовать на экране - я не думаю, что это очень хорошо, хотя, поэтому я ищу для лучшей альтернативы.

Следующий вопрос: 2. Учитывая, по очевидным причинам, невозможно просто Memory :: Copy() весь массив сразу в буфер кадра, лучше всего скопировать их по строкам.

Есть ли способ лучше?

  • 0
    Программирование ядра на C ++? Какая ОС?
  • 0
    Мой собственный, конечно
Показать ещё 2 комментария
Теги:
bitmap
osdev

1 ответ

2
Лучший ответ

В основном что-то вроде этого:

for (uint32_t l = 0; l < h; ++l) // l line index in pixels
{
    // srcPitch is distance between lines in bytes
    char*     srcLine = (char*)srcBuffer + l * srcPitch; 
    unsigned* trgLine = ((unsigned*)trgBuffer) + l * trgPitch;

    for (uint32_t c = 0; c < w; ++c) // c is column index in pixels
    {
        // build target pixel. arrange indexes to fit your render target (0, 1, 2)
        ++(*trgLine) = (srcLine[0] << 16) | (srcLine[1] << 8)
           | srcLine[2] | (0xff << 24);
        srcLine += 3;
    }
}

Несколько примечаний: - лучше писать в другой буфер, чем буфер визуализации, чтобы изображение отображалось сразу. - использование функций для размещения пикселей, как и вы, очень (очень очень) медленно.

  • 0
    Понятно, значит, это по сути означает «создать еще один буфер»? Также мне нужно обойти реализацию обратной буферизации
  • 0
    Вы можете ускорить его, обрабатывая 4 исходных пикселя одновременно: 3 целочисленных чтения, которые преобразуются в 4 целочисленных записи. А для обратной буферизации вам все равно понадобится буфер. Из соображений скорости вы бы хотели, чтобы это было в вашем целевом формате.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню