Where is the rgba blending code?

View: New views
6 Messages — Rating Filter:   Alert me  

Parent Message unknown Where is the rgba blending code?

by Vinnie-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I can't find the class for rendering into a destination buffer of type 'rgba'. Specifically, I want to retain transparency information.

It seems the some of the types are present, for example:

<agg_color_rgba.h>
struct order_rgba; // knows the location of the alpha channel

But when I look in <agg_pixfmt_rgb.h> I can't find any code that writes an alpha channel value!! For example:

struct blender_rgb
{
  p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift);
  p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift);
  p[Order::B] += (value_type)(((cb - p[Order::B]) * alpha) >> base_shift);
}

Okay, where does it assign p[Order::A]? And not only that, but this code is equivlant to the following

v = v0 + alpha*(v1-v0)/256

This is flat out wrong! Using this formula, v will never make it to 255 since (255/256) is always less than one. Sure, the shift is faster...but as anyone who read Graphic Gems 1 knows, dividing by 255 is the only accurate way. How are you guys resolving this? How bad is the performance hit doing it properly?

Well moving on to the next struct:

struct blender_rgb_pre
{
  //...
};

At first this class looks promising but again, no assignment to p[Order::A]. I guess premultiplied RGB values would be helpful if you are going to composite the resulting image onto a fully opaque background. But what if you are composing an image to be used as the image for a partially transparent / irregularly shaped system window? Where is the transparency information? What if you want to perform a hit-test on the opaque regions? Premultiplied rgb images are not the answer.

In fact, nowhere in the entire file of <agg_pixfmt_rgb.h> do we see pdst += 4, we only see pdst += 3. Sure, we see psrc += 4, and we all know that agg supports input images with masks with any order of color planes.

But where is the 4-plane output code? Where is the code that copies the source image to the destination and blends the destination pixel using this formula:

dstalpha = 255 - ( ( 255 - srcalpha ) * (255 - dstalpha ) / 65025 )


Where is the code that takes an input rgb image with no alpha channel and copies it to an rgba destination, by setting:

dest r = src r
dest g = src g
dest b = src b
dest alpha = 255

??? ?????  ???

Where is it??

Where is the stuff?



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: Where is the rgba blending code?

by Stephan Assmus :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

On 2009-08-03 at 21:53:15 [+0200], Vinnie <thevinn@...> wrote:

>
> I can't find the class for rendering into a destination buffer of type
> 'rgba'. Specifically, I want to retain transparency information.
>
> It seems the some of the types are present, for example:
>
> <agg_color_rgba.h>
> struct order_rgba; // knows the location of the alpha channel
>
> But when I look in <agg_pixfmt_rgb.h> I can't find any code that writes
> an alpha channel value!! For example:
>
> struct blender_rgb
> {
>   p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >>
>   base_shift); p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha)
>   >> base_shift); p[Order::B] += (value_type)(((cb - p[Order::B]) *
>   alpha) >> base_shift);
> }
>
> Okay, where does it assign p[Order::A]? And not only that, but this code
> is equivlant to the following
>
> v = v0 + alpha*(v1-v0)/256
>
> This is flat out wrong! Using this formula, v will never make it to 255
> since (255/256) is always less than one. Sure, the shift is faster...but
> as anyone who read Graphic Gems 1 knows, dividing by 255 is the only
> accurate way. How are you guys resolving this? How bad is the performance
> hit doing it properly?

There is a performance hit, but I forgot how bad it is. There are ways to
do it correctly without using a division. The name Alvy Ray Smith or
similar bubbles up from the back of my mind, but I cannot see it clearly...
Another faint memory tells me that I stumbled over the correct blending
function in some AGG code, but not all of this has been fully implemented
for the different colorspaces that support alpha.

> Well moving on to the next struct:
>
> struct blender_rgb_pre
> {
>   //...
> };
>
> At first this class looks promising but again, no assignment to
> p[Order::A]. I guess premultiplied RGB values would be helpful if you are
> going to composite the resulting image onto a fully opaque background.
> But what if you are composing an image to be used as the image for a
> partially transparent / irregularly shaped system window? Where is the
> transparency information? What if you want to perform a hit-test on the
> opaque regions? Premultiplied rgb images are not the answer.
>
> In fact, nowhere in the entire file of <agg_pixfmt_rgb.h> do we see pdst
> += 4, we only see pdst += 3. Sure, we see psrc += 4, and we all know that
> agg supports input images with masks with any order of color planes.
>
> But where is the 4-plane output code? Where is the code that copies the
> source image to the destination and blends the destination pixel using
> this formula:
>
> dstalpha = 255 - ( ( 255 - srcalpha ) * (255 - dstalpha ) / 65025 )
>
>
> Where is the code that takes an input rgb image with no alpha channel and
> copies it to an rgba destination, by setting:
>
> dest r = src r
> dest g = src g
> dest b = src b
> dest alpha = 255
>
> ??? ?????  ???
>
> Where is it??
>
> Where is the stuff?

agg_pixfmt_rgba.h

Best regards,
-Stephan

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: Where is the rgba blending code?

by Petr Kobalíček :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi guys,

I read this email and I need to answer. There is quite problem for
blending ARGB images (non-premultiplied), because all blending
formulas are for premultiplied ARGB images or RGB images without alpha
channel (here the destination pixel format is important, if
destination is ARGB non-premultiplied, there are several problems).

I'm writing SSE2 code that allows all porter&duff compositing with
combined formats and if anybody needs to blend to
ARGB-nonpremultiplied images, he needs division.

Here are formulas for SRC_OVER operation I'm using (not complete, but
may be useful) in Fog library:

  //! @brief The source is composited over the destination.
  //!
  //! Formulas for PRGB(dst), PRGB(src) colorspaces (SRC_OVER):
  //!   Dca' = Sca.Da + Sca.(1 - Da) + Dca.(1 - Sa)
  //!        = Sca + Dca.(1 - Sa)
  //!   Da'  = Sa.Da + Sa.(1 - Da) + Da.(1 - Sa)
  //!        = Sa + Da.(1 - Sa)
  //!        = Sa + Da - Sa.Da
  //!
  //!   Msk:
  //!
  //!   Dca' = (Sca + Dca.(1 - Sa)).m + Dca.(1 - m)
  //!        = Sca.m + Dca.(1 - Sa.m)
  //!   Da'  = (Sa + Da.(1 - Sa)).m + Da .(1 - m)
  //!        = Sa.m + Da.(1 - Sa.m)
  //!
  //! Formulas for PRGB(dst), RGB(src) colorspaces (SRC):
  //!   Dca' = Sc
  //!   Da'  = 1
  //!
  //!   Msk:
  //!
  //!   Dca' = Sc.m + Dca.(1 - m)
  //!   Da'  = 1.m + Da.(1 - m)
  //!
  //! Formulas for ARGB(dst), PRGB(src) colorspaces (SRC_OVER):
  //!   Dc'  = (Sca + Dc.Da.(1 - Sa)) / Da'
  //!   Da'  = Sa + Da.(1 - Sa)
  //!
  //!   Msk:
  //!
  //!   Dc'  = ((Sca + Dc.Da.(1 - Sa)).m + Dc.Da.(1 - m)) / Da'
  //!        = (Sca.m + Dc.Da.(1 - Sa.m)) / Da'
  //!   Da'  = (Sa + Da.(1 - Sa)).m + Da .(1 - m)
  //!        = Sa.m + Da.(1 - Sa.m)
  //!
  //! Formulas for ARGB(dst), ARGB(src) colorspaces (SRC_OVER):
  //!   Dc'  = (Sc.Sa + Dc.Da.(1 - Sa)) / Da'
  //!        = (Da.(Dc - Dc.Sa) + Sa.Sc) / Da'
  //!   Da'  = Sa + Da.(1 - Sa)
  //!
  //!   Msk:
  //!
  //!   Dc'  = ((Sc.Sa + Dc.Da.(1 - Sa)).m + Dc.Da.(1 - m)) / Da'
  //!        = (Sc.Sa.m + Dc.Da.(1 - Sa.m)) / Da'
  //!   Da'  = (Sa + Da.(1 - Sa)).m + Da .(1 - m)
  //!        = Sa.m + Da.(1 - Sa.m)
  //!
  //! Formulas for ARGB(dst), RGB(src) colorspaces (SRC):
  //!   Dc'  = Sc
  //!   Da'  = 1
  //!
  //!   Msk:
  //!
  //!   Dca' = (Sc.m + Dc.Da.(1 - m)) / Da'
  //!   Da'  = 1.m + Da.(1 - m)
  //!
  //! Formulas for RGB(dst), PRGB(src) colorspaces (SRC):
  //!   Dc'  = Sca
  //!
  //!   Msk:
  //!
  //!   Da'  = Sca.m + Dc.(1 - m)
  //!
  //! Formulas for RGB(dst), RGB(src) colorspaces (SRC):
  //!   Dc'  = Sc
  //!
  //!   Msk:
  //!
  //!   Da'  = Sc.m + Dc.(1 - m)
  //!
  //! Formulas for A(dst), A(src) colorspaces (SRC_OVER):
  //!   Da'  = Da + Sa.(1 - Da)
  //!
  //!   Msk:
  //!
  //!   Da'  = Da + Sa.m.(1 - Da)
  //!
  //! If the source is full opaque (Sa == 1.0 or there is no alpha), it
  //! replaces the destination.
  CompositeSrcOver,

PRGB means premultiplied, ARGB means nonpremultiplied, RGB means no
aplha channel, A8 means alpha channel only (mask images). Notice that
for ARGB the correct formula is:

     Dc' = (Da.(Dc - Dc.Sa) + Sa.Sc) / Da'
     Da' = Sa + Da.(1 - Sa)

you need to demultiply pixel back to ARGB colorspace, this means
division and it should be implemented using multiplication by
reciprocal tables.

Second question was about division by 255 vs 256. I think that all
compositing code should divide by 255 and there is quite simple
function to do this:

template<typename T>
static FOG_INLINE T div255(T i)
{
    return (T)( (((uint32_t)i << 8U) + ((uint32_t)i + 256U)) >> 16U );
}

I'm usualy using function to do (x * y) / 255 that can look like this:

// return = (x * a) / 255
static FOG_INLINE uint32_t singlemul(uint32_t x, uint32_t a)
{
  x *= a;
  x = ((x + (x >> 8) + 0x80) >> 8);
  return x;
}

And to multiply four bytes using some tricks:

// return = (x * a) / 255 for each byte
static FOG_INLINE uint32_t bytemul(uint32_t x, uint32_t a)
{
#if FOG_ARCH_BITS == 64
  uint64_t x0 = ((uint64_t)x | ((uint64_t)x << 24)) &
FOG_UINT64_C(0x00FF00FF00FF00FF);
  x0 *= a;
  x0 = (x0 + ((x0 >> 8) & FOG_UINT64_C(0x00FF00FF00FF00FF)) +
FOG_UINT64_C(0x0080008000800080)) >> 8;
  x0 &= FOG_UINT64_C(0x00FF00FF00FF00FF);
  return (uint32_t)(x0 | (x0 >> 24));
#else
  uint32_t t0 = ((x & 0x00FF00FF)     ) * a;
  uint32_t t1 = ((x & 0xFF00FF00) >> 8) * a;

  x  = ((t0 + ((t0 >> 8) & 0x00FF00FF) + 0x00800080) >> 8) & 0x00FF00FF;
  x |= ((t1 + ((t1 >> 8) & 0x00FF00FF) + 0x00800080)     ) & 0xFF00FF00;

  return x;
#endif
}

I think that this trick should be also used in AGG. It's faster than
current solution and it's mathematically correct.

Regards
- Petr

2009/8/4 Stephan Assmus <superstippi@...>:

> Hi,
>
> On 2009-08-03 at 21:53:15 [+0200], Vinnie <thevinn@...> wrote:
>>
>> I can't find the class for rendering into a destination buffer of type
>> 'rgba'. Specifically, I want to retain transparency information.
>>
>> It seems the some of the types are present, for example:
>>
>> <agg_color_rgba.h>
>> struct order_rgba; // knows the location of the alpha channel
>>
>> But when I look in <agg_pixfmt_rgb.h> I can't find any code that writes
>> an alpha channel value!! For example:
>>
>> struct blender_rgb
>> {
>>   p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >>
>>   base_shift); p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha)
>>   >> base_shift); p[Order::B] += (value_type)(((cb - p[Order::B]) *
>>   alpha) >> base_shift);
>> }
>>
>> Okay, where does it assign p[Order::A]? And not only that, but this code
>> is equivlant to the following
>>
>> v = v0 + alpha*(v1-v0)/256
>>
>> This is flat out wrong! Using this formula, v will never make it to 255
>> since (255/256) is always less than one. Sure, the shift is faster...but
>> as anyone who read Graphic Gems 1 knows, dividing by 255 is the only
>> accurate way. How are you guys resolving this? How bad is the performance
>> hit doing it properly?
>
> There is a performance hit, but I forgot how bad it is. There are ways to
> do it correctly without using a division. The name Alvy Ray Smith or
> similar bubbles up from the back of my mind, but I cannot see it clearly...
> Another faint memory tells me that I stumbled over the correct blending
> function in some AGG code, but not all of this has been fully implemented
> for the different colorspaces that support alpha.
>
>> Well moving on to the next struct:
>>
>> struct blender_rgb_pre
>> {
>>   //...
>> };
>>
>> At first this class looks promising but again, no assignment to
>> p[Order::A]. I guess premultiplied RGB values would be helpful if you are
>> going to composite the resulting image onto a fully opaque background.
>> But what if you are composing an image to be used as the image for a
>> partially transparent / irregularly shaped system window? Where is the
>> transparency information? What if you want to perform a hit-test on the
>> opaque regions? Premultiplied rgb images are not the answer.
>>
>> In fact, nowhere in the entire file of <agg_pixfmt_rgb.h> do we see pdst
>> += 4, we only see pdst += 3. Sure, we see psrc += 4, and we all know that
>> agg supports input images with masks with any order of color planes.
>>
>> But where is the 4-plane output code? Where is the code that copies the
>> source image to the destination and blends the destination pixel using
>> this formula:
>>
>> dstalpha = 255 - ( ( 255 - srcalpha ) * (255 - dstalpha ) / 65025 )
>>
>>
>> Where is the code that takes an input rgb image with no alpha channel and
>> copies it to an rgba destination, by setting:
>>
>> dest r = src r
>> dest g = src g
>> dest b = src b
>> dest alpha = 255
>>
>> ??? ?????  ???
>>
>> Where is it??
>>
>> Where is the stuff?
>
> agg_pixfmt_rgba.h
>
> Best regards,
> -Stephan
>
> ------------------------------------------------------------------------------
> Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
> trial. Simplify your report design, integration and deployment - and focus on
> what you do best, core application coding. Discover what's new with
> Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Vector-agg-general mailing list
> Vector-agg-general@...
> https://lists.sourceforge.net/lists/listinfo/vector-agg-general
>

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: Where is the rgba blending code?

by John Horigan :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Stephan,

I am working on a patch to implement Alvy Ray Smith's blending  
algorithm in gray, rgb, and rgba. I measured about 10% performance  
slow-down with the more exact blending. There is an additional shift  
and add for each color channel. But the new code is very regular and  
looks much easier to optimize with SSE/Altivec, so it probably could  
end up being faster

-- john

On Aug 3, 2009, at 6:23 PM, Stephan Assmus wrote:

>
> There is a performance hit, but I forgot how bad it is. There are  
> ways to
> do it correctly without using a division. The name Alvy Ray Smith or
> similar bubbles up from the back of my mind, but I cannot see it  
> clearly...
> Another faint memory tells me that I stumbled over the correct  
> blending
> function in some AGG code, but not all of this has been fully  
> implemented
> for the different colorspaces that support alpha.
>
>
> agg_pixfmt_rgba.h
>
> Best regards,
> -Stephan
>
> ------------------------------------------------------------------------------
> Let Crystal Reports handle the reporting - Free Crystal Reports 2008  
> 30-Day
> trial. Simplify your report design, integration and deployment - and  
> focus on
> what you do best, core application coding. Discover what's new with
> Crystal Reports now.  http://p.sf.net/sfu/bobj-july
> _______________________________________________
> Vector-agg-general mailing list
> Vector-agg-general@...
> https://lists.sourceforge.net/lists/listinfo/vector-agg-general


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: Where is the rgba blending code?

by Stephan Assmus :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On 2009-08-04 at 03:13:39 [+0200], John Horigan <john@...> wrote:
> I am working on a patch to implement Alvy Ray Smith's blending algorithm
> in gray, rgb, and rgba. I measured about 10% performance slow-down with
> the more exact blending. There is an additional shift and add for each
> color channel. But the new code is very regular and looks much easier to
> optimize with SSE/Altivec, so it probably could end up being faster

That's awesome news! I am very much looking forward to that. One of the
projects I am using is AGG in is Haiku, the Open Source operating system
which reimplements the BeOS. AGG is the backend for all unoptimized drawing
operations and I noticed that screen areas can get darker. It's especially
noticable when the same area had a couple blending operations done to it.

Best regards,
-Stephan

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general

Re: Where is the rgba blending code?

by Jim Barry-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Stephan Assmus wrote:
> That's awesome news! I am very much looking forward to that. One of
> the projects I am using is AGG in is Haiku, the Open Source operating
> system which reimplements the BeOS. AGG is the backend for all
> unoptimized drawing operations and I noticed that screen areas can
> get darker. It's especially noticable when the same area had a couple
> blending operations done to it.

I think that may actually be due to screen gamma. When blending is done in sRGB (non-linear) space, the resulting pixels tend to come out too dark. To get the correct results, blending must be done in linear RGB space.

- Jim

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vector-agg-general mailing list
Vector-agg-general@...
https://lists.sourceforge.net/lists/listinfo/vector-agg-general