Jim,

EXCELLENT!  I need to do a couple of things then.

1) Check to see if the multiplication by the basis functions can possibly
lead to the kind of values that can possibly cause the kind of overflow 
problems you describe.  I think they might.

2) Generate a test case for the code you provided and post results.

The premultiplication problem will not be an issue for my little interpolator 
since I do not composite.  But it would be for someone trying to use my 
interpolator for another purpose than what it was designed for.

The reason for the existence of my interpolator is that the primary function of 
my cylindrical panorama viewer is to project (the best I can) a cylindrical 
image into a rectified viewport.  Interpolation before or after the projection 
simply doesn't work so the interpolator is integrated into the projection code.

It would have been real nice to be able to hand off a chunk of the cylindrical 
image to a Java2D bi-cubic interpolator and get a nicely interpolated rectified 
viewport but that is impossible.  The corners of the source image chunk are 
stretched in a non-linear fashion to fit the canvas.  It's not a simple resize.

But this is really interesting information.  And maybe someday someone will ask 
me about it and I can sound smart... :-)

Ken

Jim Graham wrote:
All of this discussion happened while I was away on vacation.  The code
that came up was pretty much what I tend to use for clamping without
branches, but there are a couple of things to note for this particular
application:

It's only valid for values that overflow in the range MININT=>511 and it
only clamps to the output range 0=>255.

The reason for the first constraint is that c<<23 only sets the high
order bit if the overflow stays under 512.  If you get up to 512 then
the 9th bit is clear again and the "clamp to 255" part fails.  (Though,
it will also correctly clamp values between 768 and 1023 and every other
256-sized range of overflow values up to MAXINT - i.e. the ones that
manage to have the 9th bit set...)

The reason for the second constraint is because of the assumptions in
how the math was constructed.

The first constraint may not be a problem if the Cubic Interpolation
values can never cause the value to sum up to 2x the maximum value for a
component which is probably true, but depends on the cubic formula used
to generate the interpolation coefficients (there are a few such
formulas in common use) and so needs to be proven for a given formula.

The second constraint doesn't seem like a problem if you are always
dealing with 8-bit values which is very typical for today's computer
graphics, except for one issue which has been ignored.

The issue is that image interpolation should really be done in a
premultiplied form - as should alpha compositing.  The reason for this
is that if you blend the 4 components (Alpha, R, G, and B) separately in
a non-premultiplied form then a transparent pixel with a non-zero value
in, say, its red component will contribute some red tinting to the final
answer even though it was transparent and should not have contributed
any energy in the first place.

Java2D, for example, does linear and cubic interpolation internally in
the premultiplied form in the Graphics2D implementation for this reason.

Why is this an issue for the clamping equations?  The reason is that if
your accumulation values are premultiplied then the alpha component
needs to be clamped to 0=>255, but the color components need to be
clamped to the range 0=>alpha.  The different range on the clamping of
the color components means that the proposed equations won't work if you
perform your calculations in the premultiplied form.

What I've used instead is a sequence of operations that can clamp any
input range to an arbitrary 0=>N output range as follows:

    c &= ~(c >> 31);
    c -= N;
    c &= (c >> 31);
    c += N;

After the first line c is in the range 0=>MAXINT with all negative
values mapped to 0.  After the second line c is set up so that all valid
values are in the range -N=>0 and all positive values are overflow
values.  After the third line all values are in the range -N=>0 with the
positive values mapped to 0.  After the fourth line all values are
finally in the range 0=>N...

(Also, I believe it uses the same number of ALU instructions as the
((((c << 23) >> 31) | c) & ~(c>>31))&0xFF formula...)

                       ...jim

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".



===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to