Well, I did a test. The double shift does clamp the top end. But negative
numbers are twisted to be 255. In bi-cubic interpolation (the reason for all
this nonsense) negative byte (channel) values can occur. The goal is to
clamp to the range [0-255] so -100 goes to 0 and 300 goes to 255.
Here's the snippet:
// sum = (s1[s1PixelOffset]&0xFF) + (s2[s2PixelOffset]&0xFF);
// d[dPixelOffset] = (byte)((((sum<<23) >> 31) | sum) & 0xFF);
int foo = 0;
int bar = 0;
for(int i = -10; i < 265; i++)
{
foo = i;
bar = ((((foo << 23) >> 31) | foo) & 0xFF);
System.err.println(i + ": foo = " + foo + ", bar = " + bar );
}
And here is the abbreviated output:
-4: foo = -4, bar = 255
-3: foo = -3, bar = 255
-2: foo = -2, bar = 255
-1: foo = -1, bar = 255
0: foo = 0, bar = 0
1: foo = 1, bar = 1
2: foo = 2, bar = 2
3: foo = 3, bar = 3
4: foo = 4, bar = 4
.
.
.
252: foo = 252, bar = 252
253: foo = 253, bar = 253
254: foo = 254, bar = 254
255: foo = 255, bar = 255
256: foo = 256, bar = 255
257: foo = 257, bar = 255
258: foo = 258, bar = 255
259: foo = 259, bar = 255
Finally, com.sun.media.jai.util.ImageUtil.java does this to clamp a byte value
which is equivalent to what I was doing. I need to clamp both ends reliably.
I wonder if it can be done with shifts and masks? Maybe I've done the best
that can be done.
public static final byte clampByte(int in) {
return (in > 0xFF ? (byte)0xFF : (in >= 0 ? (byte)in : (byte)0));
}
Ken Warner wrote:
Never mind -- found it...
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.19
At run time, shift operations are performed on the two's complement
integer representation of the value of the left operand.
The value of n<<s is n left-shifted s bit positions; this is equivalent
(even if overflow occurs) to multiplication by two to the power s.
The value of n>>s is n right-shifted s bit positions with
sign-extension. The resulting value is � n/2s⌋. For nonnegative values
of n, this is equivalent to truncating integer division, as computed by
the integer division operator /, by two to the power s.
Now if I could only understand this...
[EMAIL PROTECTED] wrote:
if(r < 0) r = 0;
if(r > 255) r = 255;
if(g < 0) g = 0;
if(g > 255) g = 255;
if(b < 0) b = 0;
if(b > 255) b = 255;
Clumsy and awkward. Is there a better way to clamp
the values?
Maybe with a mask or something?
If your "better" meant "faster", you might like to take a look at this:
https://jai-core.dev.java.net/source/browse/jai-core/src/share/classes/com/sun/media/jai/opimage/AddOpImage.java?rev=1.1&view=markup
under computeRectByte()
//
// The next two lines are a fast way to do
// an add with saturation on U8 elements.
// It eliminates the need to do clamping.
//
sum = (s1[s1PixelOffset]&0xFF) +
(s2[s2PixelOffset]&0xFF);
d[dPixelOffset] = (byte)((((sum<<23) >> 31) | sum)
& 0xFF);
HTH,
-James
[Message sent by forum member 'jxc' (jxc)]
http://forums.java.net/jive/thread.jspa?messageID=230881
===========================================================================
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".
===========================================================================
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".