Как оптимизировать смешивание путем объединения красного и синего байта без знака? - PullRequest
0 голосов
/ 22 сентября 2019

У меня есть эта функция для смешивания RGB.То, что я пытаюсь сделать, это соединить красный и синий, чтобы уменьшить количество операций.

Вот 'оригинальный код:

#define REDMASK (0xff0000)
#define GREENMASK (0x00ff00)
#define BLUEMASK (0x0000ff)
typedef unsigned int Pixel;
inline Pixel AddBlend( Pixel a_Color1, Pixel a_Color2 )
{
    const unsigned int r = (a_Color1 & REDMASK) + (a_Color2 & REDMASK);
    const unsigned int g = (a_Color1 & GREENMASK) + (a_Color2 & GREENMASK);
    const unsigned int b = (a_Color1 & BLUEMASK) + (a_Color2 & BLUEMASK);
    const unsigned r1 = (r & REDMASK) | (REDMASK * (r >> 24));
    const unsigned g1 = (g & GREENMASK) | (GREENMASK * (g >> 16));
    const unsigned b1 = (b & BLUEMASK) | (BLUEMASK * (b >> 8));
    return (r1 + g1 + b1);
}`

И вот что я получил до сих пор.Моя проблема сейчас заключается в том, что цвета смешиваются неправильно.Что я здесь не так делаю?

typedef unsigned int Pixel;

inline Pixel AddBlend( Pixel a_Color1, Pixel a_Color2 ){
    const unsigned int rb = ( ( a_Color1 & 0xff00ff ) + ( a_Color2 & 0xff00ff ) );
    const unsigned int g = ( a_Color1 & GREENMASK ) + ( a_Color2 & GREENMASK );

    const unsigned rb1 = ( rb & 0xff00ff ) | ( 0xff00ff  * ( rb >> 8 ));    
    const unsigned g1 = (g & GREENMASK)  | (GREENMASK * (g >> 16));
     return (rb1 + g1);
}

1 Ответ

1 голос
/ 22 сентября 2019

Часть типа (REDMASK * (r >> 24)) в исходном коде обрабатывает значения зажима, которые переполняются.Это работает с одной цветной частью, но не с двумя.Вам нужно будет разделить это на две части, одну для обработки красного переполнения и одну для синего.Обработка переполнения для красного цвета может быть выполнена так же, как и в оригинале, но переполнение синего цвета требует небольшой корректировки, чтобы игнорировать любой вклад красного цвета.

BLUE_MASK * ((rb & 0x100) >> 8)

Это приводит к

const unsigned rb1 = (rb & 0xff00ff) | (REDMASK * (r >> 24)) | (BLUE_MASK * ((rb & 0x100) >> 8));

Объединение двух цветов, как это работает, потому что есть промежуток между красным и синим, который может занимать переполнение (зеленые биты).Если вы попробуете это с красным / зеленым или зеленым / синим, переполнение для части, сохраненной в младшем байте, столкнется со значением для части, сохраненной в старшем байте.

...