Reply by Nils March 31, 20092009-03-31
Brett Davis wrote:

> That divide by 255 can cost you as much time as the rest of the math on > that line, make it 256 like everyone else does and double your speed. > pixel = ((alpha * foreground + (255 - alpha) * background)) >> 7; > You may also need clamping for results not in range of 0-255. >
Nah - nowadays all compilers know that division by 2^N, 2^N-1 and 2^N+1 are cheap to calculate. In the case of 255 it becomes: int DivideBy255 (int a) { return ((a>>8) + a + 1)>>8; } It could be off one bit if a is negative (haven't checked), but for positive integers it gives identical results. And before the c-standard nazi chimes in: I assume that signed shifts replicate the sign-bits *and* that a range-propagation pass has made sure that no overflow is possible. This is guaranteed in the case of 8 bit integers.
Reply by Brett Davis March 31, 20092009-03-31
In article <slrngt2d1d.c1h.andrews@sdf.lonestar.org>,
 Andrew Smallshaw <andrews@sdf.lonestar.org> wrote:

> On 2009-03-28, doc.bullwinkle@gmail.com <doc.bullwinkle@gmail.com> wrote: > > I want to implement a 32 bit bitmap with alfa channel in an arm7 > > micro....the function is > > new_pixel=alfa*pixel_foreground+(1-alfa)*pixel_background > > alfa is an 8 bit value from zero to one (from zero to 255). This > > function can be done in this way: > > If you are representing data as integers there's really no need to > convert to floating point to do this. Doing so will rob you of a > lot of performance: > > pixel = (alpha * foreground + (255 - alpha) * background + 128) / 255;
That divide by 255 can cost you as much time as the rest of the math on that line, make it 256 like everyone else does and double your speed. pixel = ((alpha * foreground + (255 - alpha) * background)) >> 7; You may also need clamping for results not in range of 0-255.
> For most purposes you can drop the + 128. That is only really > needed if you are being pedantic - it ensures the division is > rounded properly. If the output is a screen you can drop that for > a slight speed improvement and you will never notice the difference. > It may be needed if the result is used as a further basis for > calculation though.
Reply by Andrew Smallshaw March 30, 20092009-03-30
On 2009-03-28, doc.bullwinkle@gmail.com <doc.bullwinkle@gmail.com> wrote:
> I want to implement a 32 bit bitmap with alfa channel in an arm7 > micro....the function is > new_pixel=alfa*pixel_foreground+(1-alfa)*pixel_background > alfa is an 8 bit value from zero to one (from zero to 255). This > function can be done in this way:
If you are representing data as integers there's really no need to convert to floating point to do this. Doing so will rob you of a lot of performance: pixel = (alpha * foreground + (255 - alpha) * background + 128) / 255; For most purposes you can drop the + 128. That is only really needed if you are being pedantic - it ensures the division is rounded properly. If the output is a screen you can drop that for a slight speed improvement and you will never notice the difference. It may be needed if the result is used as a further basis for calculation though. -- Andrew Smallshaw andrews@sdf.lonestar.org
Reply by Nils March 28, 20092009-03-28
doc.bullwinkle@gmail.com wrote:
> This procedure is time consuming and very difficult without > mathematical coprocessor...any better way? > Thanks
Try this code. It rounds different than your approach because that makes it cheaper to avoid the division by 255, but it's a lot faster. unsigned int blend_argb32 (unsigned int a, unsigned int b, ui8 delta) { unsigned int dstrb = a & 0xFF00FF; unsigned int dstag = a >> 8 & 0xFF00FF; unsigned int srcrb = b & 0xFF00FF; unsigned int srcag = b >> 8 & 0xFF00FF; unsigned int drb = ((srcrb - dstrb) * delta)>>8; unsigned int dag = ((srcag - dstag) * delta)>>8; a = (drb + dstrb) & 0x00FF00FF; b = (dag + dstag) << 8 & 0xFF00FF00; return a|b; } Cheers, Nils
Reply by Dombo March 28, 20092009-03-28
doc.bullwinkle@gmail.com schreef:
> I want to implement a 32 bit bitmap with alfa channel in an arm7 > micro....the function is > new_pixel=alfa*pixel_foreground+(1-alfa)*pixel_background > alfa is an 8 bit value from zero to one (from zero to 255). This > function can be done in this way: > 1)float cast of alfa and pixel_foreground > 2)alfa1=alfa/255 > 3)new_value1=alfa1*pixel_foreground > 3)new_pixel=new_value1+new_value2 > 3)int cast af new_pixel > This procedure is time consuming and very difficult without > mathematical coprocessor...any better way? > Thanks
Don't use floating point, rearrange the formula so you can use integer arithmetic.
Reply by March 28, 20092009-03-28
I want to implement a 32 bit bitmap with alfa channel in an arm7
micro....the function is
new_pixel=alfa*pixel_foreground+(1-alfa)*pixel_background
alfa is an 8 bit value from zero to one (from zero to 255). This
function can be done in this way:
1)float cast of alfa and pixel_foreground
2)alfa1=alfa/255
3)new_value1=alfa1*pixel_foreground
3)new_pixel=new_value1+new_value2
3)int cast af new_pixel
This procedure is time consuming and very difficult without
mathematical coprocessor...any better way?
Thanks