BBC BASIC for Windows
« Rounding fixed-point values »

Welcome Guest. Please Login or Register.
Apr 5th, 2018, 10:29pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

If you require a dump of the post on your message board, please come to the support board and request it.


Thank you Conforums members.

BBC BASIC for Windows Resources
Online BBC BASIC for Windows documentation
BBC BASIC for Windows Beginners' Tutorial
BBC BASIC Home Page
BBC BASIC on Rosetta Code
BBC BASIC discussion group
BBC BASIC for Windows Programmers' Reference

« Previous Topic | Next Topic »
Pages: 1  Notify Send Topic Print
 thread  Author  Topic: Rounding fixed-point values  (Read 741 times)
David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
User IP Logged

admin
Administrator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 1145
xx 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.
User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
« Last Edit: May 19th, 2009, 7:49pm by David Williams » User IP Logged

David Williams
Developer

member is offline

Avatar

meh


PM

Gender: Male
Posts: 452
xx 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.
« Last Edit: May 21st, 2009, 02:09am by David Williams » User IP Logged

Pages: 1  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls