Author |
Topic: Rounding fixed-point values (Read 741 times) |
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Rounding fixed-point values
« Thread started on: May 19th, 2009, 3:46pm » |
|
My 3x3 box blur routine has the sums of the separate RGB components from a 3x3 sampling matrix stored in EAX, EBX and ECX respectively. To get the average R, G and B values, I divide by 9 in this way:
Code:imul eax, (1/9)*2^20
imul ebx, (1/9)*2^20
imul ecx, (1/9)*2^20
shr eax, 20
shr ebx, 20
shr ecx, 20
The maximum value the R, G and B sums can each be is 9*255 = 2295, which fits into 12 bits, leaving 20 bits 'to play with' as it were.
The problem is that repeated application of the 3x3 box blur leads to an increasingly darker image (it eventually becomes black after typically 200 passes), and I think it's due to the RGB values being truncated (rather than rounded) in the above division by 9.
Is there a fast and preferably neat way of rounding a fixed-point integer after dividing to the required range (in this case, 0 to 255) in order to help alleviate the darkening effect?
Thanks in advance,
David.
PS. This program demonstrates the effect:
http://www.bb4w-games.com/138519651/boxblur3x3_asm.zip
PPS. Yes, I'm aware of the creeping darkening around the borders, that'll be taken care of when I handle the corners and edges pixels.
|
|
Logged
|
|
|
|
admin
Administrator
member is offline


Posts: 1145
|
 |
Re: Rounding fixed-point values
« Reply #1 on: May 19th, 2009, 7:18pm » |
|
Quote:Is there a fast and preferably neat way of rounding a fixed-point integer after dividing to the required range |
|
This is the method I always use (as you would have seen had you looked at the source of CSOAVI.BBC):
Code:shr eax, 20
adc eax, 0
shr ebx, 20
adc ebx, 0
shr ecx, 20
adc ecx, 0 Of course this isn't 'unbiassed' rounding; a fractional part of exactly 0.5 will always be rounded up, when theoretically it should be rounded down half the time.
Unbiassed rounding is rather more complicated, but it's unlikely to be necessary for graphics processing (BB4W itself uses unbiassed rounding - of the 'round to odd' variety - when doing its arithmetic).
Richard.
|
|
Logged
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: Rounding fixed-point values
« Reply #2 on: May 19th, 2009, 7:42pm » |
|
on May 19th, 2009, 7:18pm, Richard Russell wrote:This is the method I always use (as you would have seen had you looked at the source of CSOAVI.BBC): |
|
Actually, I spent a good 40 minutes or so the other day looking at the CSOAVI source with a view to somehow adapting parts of it (with your permission of course) to the application of a background animation movie generator powered by GFXLIB. Could be an interesting project.
on May 19th, 2009, 7:18pm, Richard Russell wrote: Code:shr eax, 20
adc eax, 0
shr ebx, 20
adc ebx, 0
shr ecx, 20
adc ecx, 0 |
|
When I was looking at your CSOAVI code, I did in my profound ignorance wonder what you were up to with the adc <reg>,0 bit! It simply didn't occur to me that it was to do with rounding control. However, thinking back to previous discussions, I'm sure you've mentioned it before.
on May 19th, 2009, 7:18pm, Richard Russell wrote:Of course this isn't 'unbiassed' rounding; a fractional part of exactly 0.5 will always be rounded up, when theoretically it should be rounded down half the time. |
|
In any case, thank you very much for this information. The solution is just what I wanted.... "fast and neat"! :D
EDIT: I'm delighted to say that it has indeed fixed the darkening problem
Regards, David.
|
|
|
|
David Williams
Developer
member is offline

meh

Gender: 
Posts: 452
|
 |
Re: Rounding fixed-point values
« Reply #3 on: May 19th, 2009, 10:07pm » |
|
A properly working 3x3 box blur:
http://www.bb4w-games.com/138519651/blur3x3.zip
It will be included in the next version of GFXLIB, along with a 5x5 and more general NxN routine.
Even the 3x3 routine is hugely suboptimal (too many memory accesses per pixel), but it'll do as a stopgap until I or someone else can come up with a faster replacement.
EDIT (21.05.2009; 03:09): After a few more frustrating hours of bug hunting, I now have a significantly faster 3x3 box blur. Some 3 times faster, in fact.
David.
|
|
|
|
|