Last week, I asked the question:
What is a trick way to clamp a byte to the range of [0-255] An operation that
is needed all the time in image processing. The common strategy to perform
this operation is usually a logical check of the form:
if(foo > 255)foo = 255;
else if(foo < 0)foo = 0;
This is basically the clamping strategy in:
com.sun.media.jai.util.ImageUtil.java
public static final byte clampByte(int in) {
return (in > 0xFF ? (byte)0xFF : (in >= 0 ? (byte)in : (byte)0));
}
James Cheng sent me a snippet from
com.sun.media.jai.opimage.AddOpImage
sum = (s1[s1PixelOffset]&0xFF) + (s2[s2PixelOffset]&0xFF);
d[dPixelOffset] = (byte)((((sum<<23) >> 31) | sum) & 0xFF);
Which clamps the top end to 255 but leaves the bottom end to dangle negative.
Peter West then sent me a mod to the above code --
bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF;
Which clamps the integer to the desired range and is faster quantitatively than
the logical test.
Peter then improved it with a variant to the shift method above by leaving out
the intermediate and trailing mask and cast to byte.
bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31));
Which quantitatively tests a bit faster.
I've attached the test program used to time the various strategies and post the
results below.
In summary, the triple shift with no intermediate mask is 30% to 40% faster
than the logical test strategy. This can mean a lot when you consider that a
bi-cubic interpolation can have 15 clamping ops per pixel -- that's 15,000,000
clamping ops on a 1K x 1K image.
Below are the test results:
(0)- bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF;
(1)- bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF;
(2)- bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31));
(3)- if(foo > 255)foo = 255;
else if(foo < 0)foo = 0;
shiftTest()...
0:----------------
(0)Time = 160
(1)Time = 120
(2)Time = 130
(3)Time = 221
1:----------------
(0)Time = 150
(1)Time = 190
(2)Time = 151
(3)Time = 270
2:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 130
(3)Time = 210
3:----------------
(0)Time = 160
(1)Time = 120
(2)Time = 131
(3)Time = 220
4:----------------
(0)Time = 200
(1)Time = 160
(2)Time = 151
(3)Time = 250
5:----------------
(0)Time = 190
(1)Time = 171
(2)Time = 160
(3)Time = 250
6:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 170
(3)Time = 250
7:----------------
(0)Time = 191
(1)Time = 160
(2)Time = 160
(3)Time = 250
8:----------------
(0)Time = 191
(1)Time = 160
(2)Time = 160
(3)Time = 260
9:----------------
(0)Time = 161
(1)Time = 160
(2)Time = 160
(3)Time = 251
10:----------------
(0)Time = 180
(1)Time = 170
(2)Time = 160
(3)Time = 251
11:----------------
(0)Time = 200
(1)Time = 160
(2)Time = 150
(3)Time = 251
12:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 231
13:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 161
(3)Time = 250
14:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 161
(3)Time = 250
15:----------------
(0)Time = 190
(1)Time = 171
(2)Time = 160
(3)Time = 250
16:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 170
(3)Time = 250
17:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 160
(3)Time = 250
18:----------------
(0)Time = 181
(1)Time = 170
(2)Time = 150
(3)Time = 250
19:----------------
(0)Time = 171
(1)Time = 170
(2)Time = 150
(3)Time = 250
20:----------------
(0)Time = 171
(1)Time = 160
(2)Time = 160
(3)Time = 251
21:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 160
(3)Time = 251
22:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 170
(3)Time = 231
23:----------------
(0)Time = 180
(1)Time = 160
(2)Time = 150
(3)Time = 231
24:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 161
(3)Time = 260
25:----------------
(0)Time = 180
(1)Time = 160
(2)Time = 151
(3)Time = 250
26:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 151
(3)Time = 250
27:----------------
(0)Time = 190
(1)Time = 161
(2)Time = 160
(3)Time = 250
28:----------------
(0)Time = 190
(1)Time = 151
(2)Time = 160
(3)Time = 260
29:----------------
(0)Time = 180
(1)Time = 160
(2)Time = 160
(3)Time = 250
30:----------------
(0)Time = 191
(1)Time = 160
(2)Time = 170
(3)Time = 260
31:----------------
(0)Time = 161
(1)Time = 170
(2)Time = 160
(3)Time = 251
32:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 261
33:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 150
(3)Time = 231
34:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 150
(3)Time = 231
35:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 151
(3)Time = 250
36:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 151
(3)Time = 250
37:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 131
(3)Time = 250
38:----------------
(0)Time = 180
(1)Time = 171
(2)Time = 150
(3)Time = 250
39:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 150
(3)Time = 250
40:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 150
(3)Time = 260
41:----------------
(0)Time = 191
(1)Time = 160
(2)Time = 160
(3)Time = 250
42:----------------
(0)Time = 181
(1)Time = 160
(2)Time = 160
(3)Time = 250
43:----------------
(0)Time = 181
(1)Time = 160
(2)Time = 170
(3)Time = 251
44:----------------
(0)Time = 200
(1)Time = 160
(2)Time = 160
(3)Time = 251
45:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 170
(3)Time = 231
46:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 241
47:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 171
(3)Time = 250
48:----------------
(0)Time = 180
(1)Time = 170
(2)Time = 141
(3)Time = 260
49:----------------
(0)Time = 180
(1)Time = 161
(2)Time = 160
(3)Time = 250
50:----------------
(0)Time = 190
(1)Time = 151
(2)Time = 150
(3)Time = 250
51:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 160
(3)Time = 260
52:----------------
(0)Time = 191
(1)Time = 170
(2)Time = 160
(3)Time = 260
53:----------------
(0)Time = 171
(1)Time = 170
(2)Time = 160
(3)Time = 250
54:----------------
(0)Time = 171
(1)Time = 160
(2)Time = 170
(3)Time = 251
55:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 251
56:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 170
(3)Time = 241
57:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 161
(3)Time = 260
58:----------------
(0)Time = 190
(1)Time = 190
(2)Time = 161
(3)Time = 250
59:----------------
(0)Time = 190
(1)Time = 161
(2)Time = 160
(3)Time = 310
60:----------------
(0)Time = 191
(1)Time = 170
(2)Time = 150
(3)Time = 260
61:----------------
(0)Time = 181
(1)Time = 170
(2)Time = 190
(3)Time = 260
62:----------------
(0)Time = 171
(1)Time = 160
(2)Time = 170
(3)Time = 251
63:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 170
(3)Time = 241
64:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 231
65:----------------
(0)Time = 200
(1)Time = 160
(2)Time = 161
(3)Time = 250
66:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 141
(3)Time = 260
67:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 141
(3)Time = 250
68:----------------
(0)Time = 190
(1)Time = 161
(2)Time = 170
(3)Time = 250
69:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 180
(3)Time = 250
70:----------------
(0)Time = 191
(1)Time = 160
(2)Time = 160
(3)Time = 250
71:----------------
(0)Time = 161
(1)Time = 170
(2)Time = 150
(3)Time = 250
72:----------------
(0)Time = 181
(1)Time = 170
(2)Time = 160
(3)Time = 251
73:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 180
(3)Time = 251
74:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 170
(3)Time = 231
75:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 150
(3)Time = 231
76:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 161
(3)Time = 260
77:----------------
(0)Time = 180
(1)Time = 160
(2)Time = 131
(3)Time = 250
78:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 141
(3)Time = 260
79:----------------
(0)Time = 180
(1)Time = 171
(2)Time = 150
(3)Time = 250
80:----------------
(0)Time = 190
(1)Time = 151
(2)Time = 160
(3)Time = 250
81:----------------
(0)Time = 190
(1)Time = 151
(2)Time = 150
(3)Time = 260
82:----------------
(0)Time = 181
(1)Time = 170
(2)Time = 170
(3)Time = 250
83:----------------
(0)Time = 171
(1)Time = 160
(2)Time = 170
(3)Time = 250
84:----------------
(0)Time = 171
(1)Time = 160
(2)Time = 150
(3)Time = 261
85:----------------
(0)Time = 180
(1)Time = 170
(2)Time = 160
(3)Time = 251
86:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 170
(3)Time = 231
87:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 171
(3)Time = 250
88:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 141
(3)Time = 250
89:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 141
(3)Time = 250
90:----------------
(0)Time = 190
(1)Time = 171
(2)Time = 160
(3)Time = 260
91:----------------
(0)Time = 190
(1)Time = 141
(2)Time = 170
(3)Time = 250
92:----------------
(0)Time = 191
(1)Time = 160
(2)Time = 150
(3)Time = 250
93:----------------
(0)Time = 181
(1)Time = 160
(2)Time = 160
(3)Time = 250
94:----------------
(0)Time = 171
(1)Time = 160
(2)Time = 170
(3)Time = 261
95:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 251
96:----------------
(0)Time = 190
(1)Time = 170
(2)Time = 160
(3)Time = 231
97:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 160
(3)Time = 231
98:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 161
(3)Time = 260
99:----------------
(0)Time = 190
(1)Time = 160
(2)Time = 151
(3)Time = 250
===========================================================================
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".
package miller;
public class Miller
{
public static void main(String[] args)
{
shiftTest();
}
public static void shiftTest()
{
System.err.println("shiftTest()...");
int foo = 0;
int bar = 0;
long t0 = 0l;
long t1 = 0l;
for(int j = 0; j < 100; j++)
{
System.err.println(j + ":----------------");
t0 = System.currentTimeMillis();
for(int i = -10000000; i < 10000000; i++)
{
//foo = (i >>> 31) | (i & 0xFF);
//foo = (i & 0xff);
foo = i;
bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF;
//bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF;
//System.err.println(i + ": foo = " + foo + ", bar = " + bar );
}
t1 = System.currentTimeMillis();
System.err.println("(0)Time = " +(t1 - t0));
t0 = System.currentTimeMillis();
for(int i = -10000000; i < 10000000; i++)
{
//foo = (i >>> 31) | (i & 0xFF);
//foo = (i & 0xff);
foo = i;
bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF;
//bar = (((((foo << 23) >> 31) | foo) & 0xFF) & ~(foo>>31))&0xFF;
//System.err.println(i + ": foo = " + foo + ", bar = " + bar );
}
t1 = System.currentTimeMillis();
System.err.println("(1)Time = " +(t1 - t0));
t0 = System.currentTimeMillis();
for(int i = -10000000; i < 10000000; i++)
{
//foo = (i >>> 31) | (i & 0xFF);
//foo = (i & 0xff);
foo = i;
//bar = ((((foo << 23) >> 31) | foo) & ~(foo>>31))&0xFF;
bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31));
//System.err.println(i + ": foo = " + foo + ", bar = " + bar );
}
t1 = System.currentTimeMillis();
System.err.println("(2)Time = " +(t1 - t0));
t0 = System.currentTimeMillis();
for(int i = -10000000; i < 10000000; i++)
{
foo = i;
if(foo > 255)foo = 255;
else if(foo < 0)foo = 0;
//System.err.println(i + ": foo = " + foo + ", bar = " + bar );
}
t1 = System.currentTimeMillis();
System.err.println("(3)Time = " +(t1 - t0));
// bar = (byte)((((foo << 23) >> 31) | foo) & ~(foo>>31));
}
System.exit(0);
}
}